Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0931466b authored by Rhed Jao's avatar Rhed Jao
Browse files

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
parent c285dbe1
Loading
Loading
Loading
Loading
+6 −15
Original line number Diff line number Diff line
@@ -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<? extends PackageStateInternal> getSharedUserPackages(int sharedUserAppId,
            Collection<SharedUserSetting> 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)}
+7 −6
Original line number Diff line number Diff line
@@ -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<String, ? extends PackageStateInternal> settings =
                snapshot.getPackageStates();
        final UserInfo[] users = snapshot.getUserInfos();
        final Collection<SharedUserSetting> 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<? extends PackageStateInternal> 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<? extends PackageStateInternal> sharedUserPackages =
                        getSharedUserPackages(setting.getSharedUserAppId(), sharedUserSettings);
                        sharedUserApi.getPackageStates();
                for (int i = sharedUserPackages.size() - 1; i >= 0; i--) {
                    PackageStateInternal siblingSetting =
                            sharedUserPackages.valueAt(i);
+8 −0
Original line number Diff line number Diff line
@@ -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.