Loading services/core/java/com/android/server/am/AppPermissionTracker.java +35 −18 Original line number Diff line number Diff line Loading @@ -64,6 +64,8 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy @GuardedBy("mLock") private SparseArray<ArraySet<String>> mUidGrantedPermissionsInMonitor = new SparseArray<>(); private volatile boolean mLockedBootCompleted = false; AppPermissionTracker(Context context, AppRestrictionController controller) { this(context, controller, null, null); } Loading @@ -85,13 +87,12 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy final PackageManagerInternal pmi = mInjector.getPackageManagerInternal(); final PermissionManagerServiceInternal pm = mInjector.getPermissionManagerServiceInternal(); final String[] permissions = mInjector.getPolicy().getBgPermissionsInMonitor(); final SparseArray<ArraySet<String>> uidPerms = mUidGrantedPermissionsInMonitor; for (int userId : allUsers) { final List<ApplicationInfo> apps = pmi.getInstalledApplications(0, userId, SYSTEM_UID); if (apps == null) { continue; } synchronized (mLock) { final SparseArray<ArraySet<String>> uidPerms = mUidGrantedPermissionsInMonitor; final long now = SystemClock.elapsedRealtime(); for (int i = 0, size = apps.size(); i < size; i++) { final ApplicationInfo ai = apps.get(i); Loading @@ -99,6 +100,7 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy if (pm.checkUidPermission(ai.uid, permission) != PERMISSION_GRANTED) { continue; } synchronized (mLock) { ArraySet<String> grantedPermissions = uidPerms.get(ai.uid); if (grantedPermissions == null) { grantedPermissions = new ArraySet<String>(); Loading Loading @@ -132,25 +134,30 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy private void handlePermissionsChanged(int uid) { final String[] permissions = mInjector.getPolicy().getBgPermissionsInMonitor(); if (permissions != null && permissions.length > 0) { final PermissionManagerServiceInternal pm = mInjector.getPermissionManagerServiceInternal(); final boolean[] states = new boolean[permissions.length]; for (int i = 0; i < permissions.length; i++) { states[i] = pm.checkUidPermission(uid, permissions[i]) == PERMISSION_GRANTED; if (DEBUG_PERMISSION_TRACKER) { Slog.i(TAG, UserHandle.formatUid(uid) + " " + permissions[i] + "=" + states[i]); } } synchronized (mLock) { handlePermissionsChangedLocked(uid); handlePermissionsChangedLocked(uid, permissions, states); } } } @GuardedBy("mLock") private void handlePermissionsChangedLocked(int uid) { final PermissionManagerServiceInternal pm = mInjector.getPermissionManagerServiceInternal(); private void handlePermissionsChangedLocked(int uid, String[] permissions, boolean[] states) { final int index = mUidGrantedPermissionsInMonitor.indexOfKey(uid); ArraySet<String> grantedPermissions = index >= 0 ? mUidGrantedPermissionsInMonitor.valueAt(index) : null; final String[] permissions = mInjector.getPolicy().getBgPermissionsInMonitor(); final long now = SystemClock.elapsedRealtime(); for (String permission: permissions) { boolean granted = pm.checkUidPermission(uid, permission) == PERMISSION_GRANTED; if (DEBUG_PERMISSION_TRACKER) { Slog.i(TAG, UserHandle.formatUid(uid) + " " + permission + "=" + granted); } for (int i = 0; i < permissions.length; i++) { final String permission = permissions[i]; final boolean granted = states[i]; boolean changed = false; if (granted) { if (grantedPermissions == null) { Loading Loading @@ -200,6 +207,10 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy } private void onPermissionTrackerEnabled(boolean enabled) { if (!mLockedBootCompleted) { // Not ready, bail out. return; } final PermissionManager pm = mInjector.getPermissionManager(); if (enabled) { pm.addOnPermissionsChangeListener(this); Loading @@ -210,6 +221,12 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy } } @Override void onLockedBootCompleted() { mLockedBootCompleted = true; onPermissionTrackerEnabled(mInjector.getPolicy().isEnabled()); } @Override void dump(PrintWriter pw, String prefix) { pw.print(prefix); Loading services/core/java/com/android/server/am/AppRestrictionController.java +32 −4 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ import static android.os.PowerExemptionManager.REASON_SYSTEM_MODULE; import static android.os.PowerExemptionManager.REASON_SYSTEM_UID; import static android.os.PowerExemptionManager.reasonCodeToString; import static android.os.Process.SYSTEM_UID; import static android.os.Process.THREAD_PRIORITY_BACKGROUND; import static com.android.internal.notification.SystemNotificationChannels.ABUSIVE_BACKGROUND_APPS; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; Loading Loading @@ -792,7 +793,7 @@ public final class AppRestrictionController { mInjector = injector; mContext = injector.getContext(); mActivityManagerService = service; mBgHandlerThread = new HandlerThread("bgres-controller"); mBgHandlerThread = new HandlerThread("bgres-controller", THREAD_PRIORITY_BACKGROUND); mBgHandlerThread.start(); mBgHandler = new BgHandler(mBgHandlerThread.getLooper(), injector); mBgExecutor = new HandlerExecutor(mBgHandler); Loading @@ -816,9 +817,11 @@ public final class AppRestrictionController { mInjector.getAppStandbyInternal().addListener(mAppIdleStateChangeListener); mInjector.getRoleManager().addOnRoleHoldersChangedListenerAsUser(mBgExecutor, mRoleHolderChangedListener, UserHandle.ALL); mInjector.scheduleInitTrackers(mBgHandler, () -> { for (int i = 0, size = mAppStateTrackers.size(); i < size; i++) { mAppStateTrackers.get(i).onSystemReady(); } }); } @VisibleForTesting Loading Loading @@ -2137,6 +2140,10 @@ public final class AppRestrictionController { } return null; } void scheduleInitTrackers(Handler handler, Runnable initializers) { handler.post(initializers); } } private void registerForSystemBroadcasts() { Loading Loading @@ -2221,6 +2228,21 @@ public final class AppRestrictionController { userFilter.addAction(Intent.ACTION_USER_REMOVED); userFilter.addAction(Intent.ACTION_UID_REMOVED); mContext.registerReceiverForAllUsers(broadcastReceiver, userFilter, null, mBgHandler); final BroadcastReceiver bootReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); switch (intent.getAction()) { case Intent.ACTION_LOCKED_BOOT_COMPLETED: { onLockedBootCompleted(); } break; } } }; final IntentFilter bootFilter = new IntentFilter(); bootFilter.addAction(Intent.ACTION_LOCKED_BOOT_COMPLETED); mContext.registerReceiverAsUser(bootReceiver, UserHandle.SYSTEM, bootFilter, null, mBgHandler); } void forEachTracker(Consumer<BaseAppStateTracker> sink) { Loading Loading @@ -2275,6 +2297,12 @@ public final class AppRestrictionController { mRestrictionSettings.removeUid(uid); } private void onLockedBootCompleted() { for (int i = 0, size = mAppStateTrackers.size(); i < size; i++) { mAppStateTrackers.get(i).onLockedBootCompleted(); } } boolean isBgAutoRestrictedBucketFeatureFlagEnabled() { return mConstantsObserver.mBgAutoRestrictedBucket; } Loading services/core/java/com/android/server/am/BaseAppStateTracker.java +6 −0 Original line number Diff line number Diff line Loading @@ -203,6 +203,12 @@ public abstract class BaseAppStateTracker<T extends BaseAppStatePolicy> { void onUserRemoved(final @UserIdInt int userId) { } /** * Called when the system sends LOCKED_BOOT_COMPLETED. */ void onLockedBootCompleted() { } /** * Called when a device config property in the activity manager namespace * has changed. Loading services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java +5 −0 Original line number Diff line number Diff line Loading @@ -2648,6 +2648,11 @@ public final class BackgroundRestrictionTest { AppPermissionTracker getAppPermissionTracker() { return mAppPermissionTracker; } @Override void scheduleInitTrackers(Handler handler, Runnable initializers) { initializers.run(); } } private class TestBaseTrackerInjector<T extends BaseAppStatePolicy> Loading Loading
services/core/java/com/android/server/am/AppPermissionTracker.java +35 −18 Original line number Diff line number Diff line Loading @@ -64,6 +64,8 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy @GuardedBy("mLock") private SparseArray<ArraySet<String>> mUidGrantedPermissionsInMonitor = new SparseArray<>(); private volatile boolean mLockedBootCompleted = false; AppPermissionTracker(Context context, AppRestrictionController controller) { this(context, controller, null, null); } Loading @@ -85,13 +87,12 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy final PackageManagerInternal pmi = mInjector.getPackageManagerInternal(); final PermissionManagerServiceInternal pm = mInjector.getPermissionManagerServiceInternal(); final String[] permissions = mInjector.getPolicy().getBgPermissionsInMonitor(); final SparseArray<ArraySet<String>> uidPerms = mUidGrantedPermissionsInMonitor; for (int userId : allUsers) { final List<ApplicationInfo> apps = pmi.getInstalledApplications(0, userId, SYSTEM_UID); if (apps == null) { continue; } synchronized (mLock) { final SparseArray<ArraySet<String>> uidPerms = mUidGrantedPermissionsInMonitor; final long now = SystemClock.elapsedRealtime(); for (int i = 0, size = apps.size(); i < size; i++) { final ApplicationInfo ai = apps.get(i); Loading @@ -99,6 +100,7 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy if (pm.checkUidPermission(ai.uid, permission) != PERMISSION_GRANTED) { continue; } synchronized (mLock) { ArraySet<String> grantedPermissions = uidPerms.get(ai.uid); if (grantedPermissions == null) { grantedPermissions = new ArraySet<String>(); Loading Loading @@ -132,25 +134,30 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy private void handlePermissionsChanged(int uid) { final String[] permissions = mInjector.getPolicy().getBgPermissionsInMonitor(); if (permissions != null && permissions.length > 0) { final PermissionManagerServiceInternal pm = mInjector.getPermissionManagerServiceInternal(); final boolean[] states = new boolean[permissions.length]; for (int i = 0; i < permissions.length; i++) { states[i] = pm.checkUidPermission(uid, permissions[i]) == PERMISSION_GRANTED; if (DEBUG_PERMISSION_TRACKER) { Slog.i(TAG, UserHandle.formatUid(uid) + " " + permissions[i] + "=" + states[i]); } } synchronized (mLock) { handlePermissionsChangedLocked(uid); handlePermissionsChangedLocked(uid, permissions, states); } } } @GuardedBy("mLock") private void handlePermissionsChangedLocked(int uid) { final PermissionManagerServiceInternal pm = mInjector.getPermissionManagerServiceInternal(); private void handlePermissionsChangedLocked(int uid, String[] permissions, boolean[] states) { final int index = mUidGrantedPermissionsInMonitor.indexOfKey(uid); ArraySet<String> grantedPermissions = index >= 0 ? mUidGrantedPermissionsInMonitor.valueAt(index) : null; final String[] permissions = mInjector.getPolicy().getBgPermissionsInMonitor(); final long now = SystemClock.elapsedRealtime(); for (String permission: permissions) { boolean granted = pm.checkUidPermission(uid, permission) == PERMISSION_GRANTED; if (DEBUG_PERMISSION_TRACKER) { Slog.i(TAG, UserHandle.formatUid(uid) + " " + permission + "=" + granted); } for (int i = 0; i < permissions.length; i++) { final String permission = permissions[i]; final boolean granted = states[i]; boolean changed = false; if (granted) { if (grantedPermissions == null) { Loading Loading @@ -200,6 +207,10 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy } private void onPermissionTrackerEnabled(boolean enabled) { if (!mLockedBootCompleted) { // Not ready, bail out. return; } final PermissionManager pm = mInjector.getPermissionManager(); if (enabled) { pm.addOnPermissionsChangeListener(this); Loading @@ -210,6 +221,12 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy } } @Override void onLockedBootCompleted() { mLockedBootCompleted = true; onPermissionTrackerEnabled(mInjector.getPolicy().isEnabled()); } @Override void dump(PrintWriter pw, String prefix) { pw.print(prefix); Loading
services/core/java/com/android/server/am/AppRestrictionController.java +32 −4 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ import static android.os.PowerExemptionManager.REASON_SYSTEM_MODULE; import static android.os.PowerExemptionManager.REASON_SYSTEM_UID; import static android.os.PowerExemptionManager.reasonCodeToString; import static android.os.Process.SYSTEM_UID; import static android.os.Process.THREAD_PRIORITY_BACKGROUND; import static com.android.internal.notification.SystemNotificationChannels.ABUSIVE_BACKGROUND_APPS; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; Loading Loading @@ -792,7 +793,7 @@ public final class AppRestrictionController { mInjector = injector; mContext = injector.getContext(); mActivityManagerService = service; mBgHandlerThread = new HandlerThread("bgres-controller"); mBgHandlerThread = new HandlerThread("bgres-controller", THREAD_PRIORITY_BACKGROUND); mBgHandlerThread.start(); mBgHandler = new BgHandler(mBgHandlerThread.getLooper(), injector); mBgExecutor = new HandlerExecutor(mBgHandler); Loading @@ -816,9 +817,11 @@ public final class AppRestrictionController { mInjector.getAppStandbyInternal().addListener(mAppIdleStateChangeListener); mInjector.getRoleManager().addOnRoleHoldersChangedListenerAsUser(mBgExecutor, mRoleHolderChangedListener, UserHandle.ALL); mInjector.scheduleInitTrackers(mBgHandler, () -> { for (int i = 0, size = mAppStateTrackers.size(); i < size; i++) { mAppStateTrackers.get(i).onSystemReady(); } }); } @VisibleForTesting Loading Loading @@ -2137,6 +2140,10 @@ public final class AppRestrictionController { } return null; } void scheduleInitTrackers(Handler handler, Runnable initializers) { handler.post(initializers); } } private void registerForSystemBroadcasts() { Loading Loading @@ -2221,6 +2228,21 @@ public final class AppRestrictionController { userFilter.addAction(Intent.ACTION_USER_REMOVED); userFilter.addAction(Intent.ACTION_UID_REMOVED); mContext.registerReceiverForAllUsers(broadcastReceiver, userFilter, null, mBgHandler); final BroadcastReceiver bootReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); switch (intent.getAction()) { case Intent.ACTION_LOCKED_BOOT_COMPLETED: { onLockedBootCompleted(); } break; } } }; final IntentFilter bootFilter = new IntentFilter(); bootFilter.addAction(Intent.ACTION_LOCKED_BOOT_COMPLETED); mContext.registerReceiverAsUser(bootReceiver, UserHandle.SYSTEM, bootFilter, null, mBgHandler); } void forEachTracker(Consumer<BaseAppStateTracker> sink) { Loading Loading @@ -2275,6 +2297,12 @@ public final class AppRestrictionController { mRestrictionSettings.removeUid(uid); } private void onLockedBootCompleted() { for (int i = 0, size = mAppStateTrackers.size(); i < size; i++) { mAppStateTrackers.get(i).onLockedBootCompleted(); } } boolean isBgAutoRestrictedBucketFeatureFlagEnabled() { return mConstantsObserver.mBgAutoRestrictedBucket; } Loading
services/core/java/com/android/server/am/BaseAppStateTracker.java +6 −0 Original line number Diff line number Diff line Loading @@ -203,6 +203,12 @@ public abstract class BaseAppStateTracker<T extends BaseAppStatePolicy> { void onUserRemoved(final @UserIdInt int userId) { } /** * Called when the system sends LOCKED_BOOT_COMPLETED. */ void onLockedBootCompleted() { } /** * Called when a device config property in the activity manager namespace * has changed. Loading
services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java +5 −0 Original line number Diff line number Diff line Loading @@ -2648,6 +2648,11 @@ public final class BackgroundRestrictionTest { AppPermissionTracker getAppPermissionTracker() { return mAppPermissionTracker; } @Override void scheduleInitTrackers(Handler handler, Runnable initializers) { initializers.run(); } } private class TestBaseTrackerInjector<T extends BaseAppStatePolicy> Loading