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