From 0931466b55413901ee3d21dba0b3958fde702b39 Mon Sep 17 00:00:00 2001 From: Rhed Jao Date: Thu, 22 Dec 2022 16:18:21 +0800 Subject: [PATCH] Improve the cache rebuild latency of AppsFilter on boot #2 Instead of iterating the list of all shared users, using the getSharedUser api to get a better lookup time. Bug: 262515424 Test: atest CtsAppEnumerationTestCases Change-Id: I301a7f78231e1430e965bccd7870e387f77810e9 --- .../com/android/server/pm/AppsFilterBase.java | 21 ++++++------------- .../com/android/server/pm/AppsFilterImpl.java | 13 ++++++------ .../android/server/pm/AppsFilterImplTest.java | 8 +++++++ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/services/core/java/com/android/server/pm/AppsFilterBase.java b/services/core/java/com/android/server/pm/AppsFilterBase.java index 4f7059d8a5e54..1021e07cf9464 100644 --- a/services/core/java/com/android/server/pm/AppsFilterBase.java +++ b/services/core/java/com/android/server/pm/AppsFilterBase.java @@ -41,6 +41,7 @@ import com.android.internal.util.function.QuadFunction; import com.android.server.om.OverlayReferenceMapper; import com.android.server.pm.pkg.AndroidPackage; import com.android.server.pm.pkg.PackageStateInternal; +import com.android.server.pm.pkg.SharedUserApi; import com.android.server.pm.snapshot.PackageDataSnapshot; import com.android.server.utils.SnapshotCache; import com.android.server.utils.Watched; @@ -51,7 +52,6 @@ import com.android.server.utils.WatchedSparseSetArray; import java.io.PrintWriter; import java.util.Arrays; -import java.util.Collection; import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; @@ -409,9 +409,11 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { final PackageStateInternal packageState = (PackageStateInternal) callingSetting; if (packageState.hasSharedUser()) { callingPkgSetting = null; - callingSharedPkgSettings.addAll(getSharedUserPackages( - packageState.getSharedUserAppId(), snapshot.getAllSharedUsers())); - + final SharedUserApi sharedUserApi = + snapshot.getSharedUser(packageState.getSharedUserAppId()); + if (sharedUserApi != null) { + callingSharedPkgSettings.addAll(sharedUserApi.getPackageStates()); + } } else { callingPkgSetting = packageState; } @@ -698,17 +700,6 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { + targetPkgSetting + " " + description); } - protected ArraySet getSharedUserPackages(int sharedUserAppId, - Collection sharedUserSettings) { - for (SharedUserSetting setting : sharedUserSettings) { - if (setting.mAppId != sharedUserAppId) { - continue; - } - return setting.getPackageStates(); - } - return new ArraySet<>(); - } - /** * See {@link AppsFilterSnapshot#dumpQueries(PrintWriter, Integer, DumpState, int[], * QuadFunction)} diff --git a/services/core/java/com/android/server/pm/AppsFilterImpl.java b/services/core/java/com/android/server/pm/AppsFilterImpl.java index f73deb3aa6a94..5ff1909b54e4f 100644 --- a/services/core/java/com/android/server/pm/AppsFilterImpl.java +++ b/services/core/java/com/android/server/pm/AppsFilterImpl.java @@ -66,6 +66,7 @@ import com.android.server.pm.AppsFilterUtils.ParallelComputeComponentVisibility; import com.android.server.pm.parsing.pkg.AndroidPackageUtils; import com.android.server.pm.pkg.AndroidPackage; import com.android.server.pm.pkg.PackageStateInternal; +import com.android.server.pm.pkg.SharedUserApi; import com.android.server.pm.pkg.component.ParsedInstrumentation; import com.android.server.pm.pkg.component.ParsedPermission; import com.android.server.pm.pkg.component.ParsedUsesPermission; @@ -80,7 +81,6 @@ import com.android.server.utils.Watcher; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.List; import java.util.Objects; @@ -1047,7 +1047,6 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, final ArrayMap settings = snapshot.getPackageStates(); final UserInfo[] users = snapshot.getUserInfos(); - final Collection sharedUserSettings = snapshot.getAllSharedUsers(); final int userCount = users.length; if (!isReplace || !retainImplicitGrantOnReplace) { synchronized (mImplicitlyQueryableLock) { @@ -1156,9 +1155,11 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, // shared user members to re-establish visibility between them and other packages. // NOTE: this must come after all removals from data structures but before we update the // cache - if (setting.hasSharedUser()) { + final SharedUserApi sharedUserApi = setting.hasSharedUser() + ? snapshot.getSharedUser(setting.getSharedUserAppId()) : null; + if (sharedUserApi != null) { final ArraySet sharedUserPackages = - getSharedUserPackages(setting.getSharedUserAppId(), sharedUserSettings); + sharedUserApi.getPackageStates(); for (int i = sharedUserPackages.size() - 1; i >= 0; i--) { if (sharedUserPackages.valueAt(i) == setting) { continue; @@ -1171,9 +1172,9 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, if (mCacheReady) { removeAppIdFromVisibilityCache(setting.getAppId()); - if (setting.hasSharedUser()) { + if (sharedUserApi != null) { final ArraySet sharedUserPackages = - getSharedUserPackages(setting.getSharedUserAppId(), sharedUserSettings); + sharedUserApi.getPackageStates(); for (int i = sharedUserPackages.size() - 1; i >= 0; i--) { PackageStateInternal siblingSetting = sharedUserPackages.valueAt(i); diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/AppsFilterImplTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/AppsFilterImplTest.java index 3575b57934caa..7c4b9f8688d18 100644 --- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/AppsFilterImplTest.java +++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/AppsFilterImplTest.java @@ -24,6 +24,7 @@ import static org.hamcrest.Matchers.contains; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -225,6 +226,13 @@ public class AppsFilterImplTest { when(mSnapshot.getPackageStates()).thenAnswer(x -> mExisting); when(mSnapshot.getAllSharedUsers()).thenReturn(mSharedUserSettings); when(mSnapshot.getUserInfos()).thenReturn(USER_INFO_LIST); + when(mSnapshot.getSharedUser(anyInt())).thenAnswer(invocation -> { + final int sharedUserAppId = invocation.getArgument(0); + return mSharedUserSettings.stream() + .filter(sharedUserSetting -> sharedUserSetting.getAppId() == sharedUserAppId) + .findAny() + .orElse(null); + }); when(mPmInternal.snapshot()).thenReturn(mSnapshot); // Can't mock postDelayed because of some weird bug in Mockito.