From 2cde8d7196e18efd7bce4eb688ee80a5c87814cd Mon Sep 17 00:00:00 2001 From: Jing Ji Date: Mon, 14 Feb 2022 09:55:39 -0800 Subject: [PATCH] Move the init of trackers in the app restriction controller to bg. Also postpone the initialization of the permission tracker as it doesn't need to be done before system ready. Bug: 219140433 Test: BootTimeTest Change-Id: I2c13252ec6ded1f51f3a13832c8c0a55da359b95 --- .../server/am/AppPermissionTracker.java | 53 ++++++++++++------- .../server/am/AppRestrictionController.java | 36 +++++++++++-- .../server/am/BaseAppStateTracker.java | 6 +++ .../server/am/BackgroundRestrictionTest.java | 5 ++ 4 files changed, 78 insertions(+), 22 deletions(-) diff --git a/services/core/java/com/android/server/am/AppPermissionTracker.java b/services/core/java/com/android/server/am/AppPermissionTracker.java index 7f48d527ac776..69f70ca0d0e08 100644 --- a/services/core/java/com/android/server/am/AppPermissionTracker.java +++ b/services/core/java/com/android/server/am/AppPermissionTracker.java @@ -64,6 +64,8 @@ final class AppPermissionTracker extends BaseAppStateTracker> mUidGrantedPermissionsInMonitor = new SparseArray<>(); + private volatile boolean mLockedBootCompleted = false; + AppPermissionTracker(Context context, AppRestrictionController controller) { this(context, controller, null, null); } @@ -85,20 +87,20 @@ final class AppPermissionTracker extends BaseAppStateTracker> uidPerms = mUidGrantedPermissionsInMonitor; for (int userId : allUsers) { final List apps = pmi.getInstalledApplications(0, userId, SYSTEM_UID); if (apps == null) { continue; } - synchronized (mLock) { - final SparseArray> uidPerms = mUidGrantedPermissionsInMonitor; - final long now = SystemClock.elapsedRealtime(); - for (int i = 0, size = apps.size(); i < size; i++) { - final ApplicationInfo ai = apps.get(i); - for (String permission : permissions) { - if (pm.checkUidPermission(ai.uid, permission) != PERMISSION_GRANTED) { - continue; - } + final long now = SystemClock.elapsedRealtime(); + for (int i = 0, size = apps.size(); i < size; i++) { + final ApplicationInfo ai = apps.get(i); + for (String permission : permissions) { + if (pm.checkUidPermission(ai.uid, permission) != PERMISSION_GRANTED) { + continue; + } + synchronized (mLock) { ArraySet grantedPermissions = uidPerms.get(ai.uid); if (grantedPermissions == null) { grantedPermissions = new ArraySet(); @@ -132,25 +134,30 @@ final class AppPermissionTracker extends BaseAppStateTracker 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 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) { @@ -200,6 +207,10 @@ final class AppPermissionTracker extends BaseAppStateTracker { + for (int i = 0, size = mAppStateTrackers.size(); i < size; i++) { + mAppStateTrackers.get(i).onSystemReady(); + } + }); } @VisibleForTesting @@ -2137,6 +2140,10 @@ public final class AppRestrictionController { } return null; } + + void scheduleInitTrackers(Handler handler, Runnable initializers) { + handler.post(initializers); + } } private void registerForSystemBroadcasts() { @@ -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 sink) { @@ -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; } diff --git a/services/core/java/com/android/server/am/BaseAppStateTracker.java b/services/core/java/com/android/server/am/BaseAppStateTracker.java index 482d69751d700..0fada53d622e4 100644 --- a/services/core/java/com/android/server/am/BaseAppStateTracker.java +++ b/services/core/java/com/android/server/am/BaseAppStateTracker.java @@ -203,6 +203,12 @@ public abstract class BaseAppStateTracker { 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. diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java index 936940fcde6e8..e6bb0ce318fe1 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java @@ -2648,6 +2648,11 @@ public final class BackgroundRestrictionTest { AppPermissionTracker getAppPermissionTracker() { return mAppPermissionTracker; } + + @Override + void scheduleInitTrackers(Handler handler, Runnable initializers) { + initializers.run(); + } } private class TestBaseTrackerInjector