1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.am;
18 
19 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
20 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
21 
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.annotation.UserIdInt;
25 import android.app.ActivityManagerInternal;
26 import android.app.AppOpsManager;
27 import android.app.role.RoleManager;
28 import android.content.Context;
29 import android.content.pm.PackageManager;
30 import android.content.pm.PackageManagerInternal;
31 import android.media.session.MediaSessionManager;
32 import android.os.BatteryManagerInternal;
33 import android.os.BatteryStatsInternal;
34 import android.os.Handler;
35 import android.os.ServiceManager;
36 import android.permission.PermissionManager;
37 import android.util.Slog;
38 import android.util.proto.ProtoOutputStream;
39 
40 import com.android.internal.app.IAppOpsService;
41 import com.android.server.DeviceIdleInternal;
42 import com.android.server.LocalServices;
43 import com.android.server.am.AppRestrictionController.TrackerType;
44 import com.android.server.notification.NotificationManagerInternal;
45 import com.android.server.pm.UserManagerInternal;
46 import com.android.server.pm.permission.PermissionManagerServiceInternal;
47 
48 import java.io.PrintWriter;
49 import java.lang.reflect.Constructor;
50 import java.util.ArrayList;
51 
52 /**
53  * Base class to track certain state of the app, could be used to determine the restriction level.
54  *
55  * @param <T> A class derived from BaseAppStatePolicy.
56  */
57 public abstract class BaseAppStateTracker<T extends BaseAppStatePolicy> {
58     protected static final String TAG = TAG_WITH_CLASS_NAME ? "BaseAppStatePolicy" : TAG_AM;
59 
60     static final long ONE_MINUTE = 60 * 1_000L;
61     static final long ONE_HOUR = 60 * ONE_MINUTE;
62     static final long ONE_DAY = 24 * ONE_HOUR;
63 
64     static final int STATE_TYPE_MEDIA_SESSION = 1;
65     static final int STATE_TYPE_FGS_MEDIA_PLAYBACK = 1 << 1;
66     static final int STATE_TYPE_FGS_LOCATION = 1 << 2;
67     static final int STATE_TYPE_FGS_WITH_NOTIFICATION = 1 << 3;
68     static final int STATE_TYPE_PERMISSION = 1 << 4;
69     static final int STATE_TYPE_NUM = 5;
70 
71     static final int STATE_TYPE_INDEX_MEDIA_SESSION = 0;
72     static final int STATE_TYPE_INDEX_FGS_MEDIA_PLAYBACK = 1;
73     static final int STATE_TYPE_INDEX_FGS_LOCATION = 2;
74     static final int STATE_TYPE_INDEX_FGS_WITH_NOTIFICATION = 3;
75     static final int STATE_TYPE_INDEX_PERMISSION = 4;
76 
77     protected final AppRestrictionController mAppRestrictionController;
78     protected final Injector<T> mInjector;
79     protected final Context mContext;
80     protected final Handler mBgHandler;
81     protected final Object mLock;
82     protected final ArrayList<StateListener> mStateListeners = new ArrayList<>();
83 
84     interface StateListener {
onStateChange(int uid, String packageName, boolean start, long now, int stateType)85         void onStateChange(int uid, String packageName, boolean start, long now, int stateType);
86     }
87 
BaseAppStateTracker(Context context, AppRestrictionController controller, @Nullable Constructor<? extends Injector<T>> injector, Object outerContext)88     BaseAppStateTracker(Context context, AppRestrictionController controller,
89             @Nullable Constructor<? extends Injector<T>> injector, Object outerContext) {
90         mContext = context;
91         mAppRestrictionController = controller;
92         mBgHandler = controller.getBackgroundHandler();
93         mLock = controller.getLock();
94         if (injector == null) {
95             mInjector = new Injector<>();
96         } else {
97             Injector<T> localInjector = null;
98             try {
99                 localInjector = injector.newInstance(outerContext);
100             } catch (Exception e) {
101                 Slog.w(TAG, "Unable to instantiate " + injector, e);
102             }
103             mInjector = (localInjector == null) ? new Injector<>() : localInjector;
104         }
105     }
106 
stateTypeToIndex(int stateType)107     static int stateTypeToIndex(int stateType) {
108         return Integer.numberOfTrailingZeros(stateType);
109     }
110 
stateIndexToType(int stateTypeIndex)111     static int stateIndexToType(int stateTypeIndex) {
112         return 1 << stateTypeIndex;
113     }
114 
stateTypesToString(int stateTypes)115     static String stateTypesToString(int stateTypes) {
116         final StringBuilder sb = new StringBuilder("[");
117         boolean needDelimiter = false;
118         for (int stateType = Integer.highestOneBit(stateTypes); stateType != 0;
119                 stateType = Integer.highestOneBit(stateTypes)) {
120             if (needDelimiter) {
121                 sb.append('|');
122             }
123             needDelimiter = true;
124             switch (stateType) {
125                 case STATE_TYPE_MEDIA_SESSION:
126                     sb.append("MEDIA_SESSION");
127                     break;
128                 case STATE_TYPE_FGS_MEDIA_PLAYBACK:
129                     sb.append("FGS_MEDIA_PLAYBACK");
130                     break;
131                 case STATE_TYPE_FGS_LOCATION:
132                     sb.append("FGS_LOCATION");
133                     break;
134                 case STATE_TYPE_FGS_WITH_NOTIFICATION:
135                     sb.append("FGS_NOTIFICATION");
136                     break;
137                 case STATE_TYPE_PERMISSION:
138                     sb.append("PERMISSION");
139                     break;
140                 default:
141                     return "[UNKNOWN(" + Integer.toHexString(stateTypes) + ")]";
142             }
143             stateTypes &= ~stateType;
144         }
145         sb.append("]");
146         return sb.toString();
147     }
148 
registerStateListener(@onNull StateListener listener)149     void registerStateListener(@NonNull StateListener listener) {
150         synchronized (mLock) {
151             mStateListeners.add(listener);
152         }
153     }
154 
notifyListenersOnStateChange(int uid, String packageName, boolean start, long now, int stateType)155     void notifyListenersOnStateChange(int uid, String packageName,
156             boolean start, long now, int stateType) {
157         synchronized (mLock) {
158             for (int i = 0, size = mStateListeners.size(); i < size; i++) {
159                 mStateListeners.get(i).onStateChange(uid, packageName, start, now, stateType);
160             }
161         }
162     }
163 
164     /**
165      * Return the type of tracker (as defined by AppRestrictionController.TrackerType)
166      */
getType()167     @TrackerType int getType() {
168         return AppRestrictionController.TRACKER_TYPE_UNKNOWN;
169     }
170 
171     /**
172      * Return the relevant info object for the tracker for the given uid, used for statsd.
173      */
getTrackerInfoForStatsd(int uid)174     byte[] getTrackerInfoForStatsd(int uid) {
175         return null;
176     }
177 
178     /**
179      * Return the policy holder of this tracker.
180      */
getPolicy()181     T getPolicy() {
182         return mInjector.getPolicy();
183     }
184 
185     /**
186      * Called when the system is ready to rock.
187      */
onSystemReady()188     void onSystemReady() {
189         mInjector.onSystemReady();
190     }
191 
192     /**
193      * Called when a user with the given uid is added.
194      */
onUidAdded(final int uid)195     void onUidAdded(final int uid) {
196     }
197 
198     /**
199      * Called when a user with the given uid is removed.
200      */
onUidRemoved(final int uid)201     void onUidRemoved(final int uid) {
202     }
203 
204     /**
205      * Called when a user with the given userId is added.
206      */
onUserAdded(final @UserIdInt int userId)207     void onUserAdded(final @UserIdInt int userId) {
208     }
209 
210     /**
211      * Called when a user with the given userId is started.
212      */
onUserStarted(final @UserIdInt int userId)213     void onUserStarted(final @UserIdInt int userId) {
214     }
215 
216     /**
217      * Called when a user with the given userId is stopped.
218      */
onUserStopped(final @UserIdInt int userId)219     void onUserStopped(final @UserIdInt int userId) {
220     }
221 
222     /**
223      * Called when a user with the given userId is removed.
224      */
onUserRemoved(final @UserIdInt int userId)225     void onUserRemoved(final @UserIdInt int userId) {
226     }
227 
228     /**
229      * Called when the system sends LOCKED_BOOT_COMPLETED.
230      */
onLockedBootCompleted()231     void onLockedBootCompleted() {
232     }
233 
234     /**
235      * Called when a device config property in the activity manager namespace
236      * has changed.
237      */
onPropertiesChanged(@onNull String name)238     void onPropertiesChanged(@NonNull String name) {
239         getPolicy().onPropertiesChanged(name);
240     }
241 
242     /**
243      * Called when an app has transitioned into an active state due to user interaction.
244      */
onUserInteractionStarted(String packageName, int uid)245     void onUserInteractionStarted(String packageName, int uid) {
246     }
247 
248     /**
249      * Called when the background restriction settings of the given app is changed.
250      */
onBackgroundRestrictionChanged(int uid, String pkgName, boolean restricted)251     void onBackgroundRestrictionChanged(int uid, String pkgName, boolean restricted) {
252     }
253 
254     /**
255      * Called when the process state of the given UID has been changed.
256      *
257      * <p>Note: as of now, for simplification, we're tracking the TOP state changes only.</p>
258      */
onUidProcStateChanged(int uid, int procState)259     void onUidProcStateChanged(int uid, int procState) {
260     }
261 
262     /**
263      * Called when all the processes in the given UID have died.
264      */
onUidGone(int uid)265     void onUidGone(int uid) {
266     }
267 
268     /**
269      * Dump to the given printer writer.
270      */
dump(PrintWriter pw, String prefix)271     void dump(PrintWriter pw, String prefix) {
272         mInjector.getPolicy().dump(pw, "  " + prefix);
273     }
274 
dumpAsProto(ProtoOutputStream proto, int uid)275     void dumpAsProto(ProtoOutputStream proto, int uid) {
276     }
277 
278     static class Injector<T extends BaseAppStatePolicy> {
279         T mAppStatePolicy;
280 
281         ActivityManagerInternal mActivityManagerInternal;
282         BatteryManagerInternal mBatteryManagerInternal;
283         BatteryStatsInternal mBatteryStatsInternal;
284         DeviceIdleInternal mDeviceIdleInternal;
285         UserManagerInternal mUserManagerInternal;
286         PackageManager mPackageManager;
287         PackageManagerInternal mPackageManagerInternal;
288         PermissionManager mPermissionManager;
289         PermissionManagerServiceInternal mPermissionManagerServiceInternal;
290         AppOpsManager mAppOpsManager;
291         MediaSessionManager mMediaSessionManager;
292         RoleManager mRoleManager;
293         NotificationManagerInternal mNotificationManagerInternal;
294         IAppOpsService mIAppOpsService;
295 
setPolicy(T policy)296         void setPolicy(T policy) {
297             mAppStatePolicy = policy;
298         }
299 
onSystemReady()300         void onSystemReady() {
301             mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
302             mBatteryManagerInternal = LocalServices.getService(BatteryManagerInternal.class);
303             mBatteryStatsInternal = LocalServices.getService(BatteryStatsInternal.class);
304             mDeviceIdleInternal = LocalServices.getService(DeviceIdleInternal.class);
305             mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
306             mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
307             mPermissionManagerServiceInternal = LocalServices.getService(
308                     PermissionManagerServiceInternal.class);
309             final Context context = mAppStatePolicy.mTracker.mContext;
310             mPackageManager = context.getPackageManager();
311             mAppOpsManager = context.getSystemService(AppOpsManager.class);
312             mMediaSessionManager = context.getSystemService(MediaSessionManager.class);
313             mPermissionManager = context.getSystemService(PermissionManager.class);
314             mRoleManager = context.getSystemService(RoleManager.class);
315             mNotificationManagerInternal = LocalServices.getService(
316                     NotificationManagerInternal.class);
317             mIAppOpsService = IAppOpsService.Stub.asInterface(
318                     ServiceManager.getService(Context.APP_OPS_SERVICE));
319 
320             getPolicy().onSystemReady();
321         }
322 
getActivityManagerInternal()323         ActivityManagerInternal getActivityManagerInternal() {
324             return mActivityManagerInternal;
325         }
326 
getBatteryManagerInternal()327         BatteryManagerInternal getBatteryManagerInternal() {
328             return mBatteryManagerInternal;
329         }
330 
getBatteryStatsInternal()331         BatteryStatsInternal getBatteryStatsInternal() {
332             return mBatteryStatsInternal;
333         }
334 
getPolicy()335         T getPolicy() {
336             return mAppStatePolicy;
337         }
338 
getDeviceIdleInternal()339         DeviceIdleInternal getDeviceIdleInternal() {
340             return mDeviceIdleInternal;
341         }
342 
getUserManagerInternal()343         UserManagerInternal getUserManagerInternal() {
344             return mUserManagerInternal;
345         }
346 
347         /**
348          * Equivalent to {@link java.lang.System#currentTimeMillis}.
349          */
currentTimeMillis()350         long currentTimeMillis() {
351             return System.currentTimeMillis();
352         }
353 
getPackageManager()354         PackageManager getPackageManager() {
355             return mPackageManager;
356         }
357 
getPackageManagerInternal()358         PackageManagerInternal getPackageManagerInternal() {
359             return mPackageManagerInternal;
360         }
361 
getPermissionManager()362         PermissionManager getPermissionManager() {
363             return mPermissionManager;
364         }
365 
getPermissionManagerServiceInternal()366         PermissionManagerServiceInternal getPermissionManagerServiceInternal() {
367             return mPermissionManagerServiceInternal;
368         }
369 
getAppOpsManager()370         AppOpsManager getAppOpsManager() {
371             return mAppOpsManager;
372         }
373 
getMediaSessionManager()374         MediaSessionManager getMediaSessionManager() {
375             return mMediaSessionManager;
376         }
377 
getServiceStartForegroundTimeout()378         long getServiceStartForegroundTimeout() {
379             return mActivityManagerInternal.getServiceStartForegroundTimeout();
380         }
381 
getRoleManager()382         RoleManager getRoleManager() {
383             return mRoleManager;
384         }
385 
getNotificationManagerInternal()386         NotificationManagerInternal getNotificationManagerInternal() {
387             return mNotificationManagerInternal;
388         }
389 
getIAppOpsService()390         IAppOpsService getIAppOpsService() {
391             return mIAppOpsService;
392         }
393     }
394 }
395