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

Commit 51bbf5a5 authored by Jeremy Meyer's avatar Jeremy Meyer
Browse files

Guard access to OMS.PackageManagerHelperImpl.mCache

Test: automated
Fixes: 357896224
Flag: EXEMPT bugfix
Change-Id: Ida7bd35701ce88113dbdf1309f9367d890345ea4
parent a15ab608
Loading
Loading
Loading
Loading
+52 −32
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ import android.util.EventLog;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.KeepForWeakReference;
import com.android.internal.content.PackageMonitor;
import com.android.internal.content.om.OverlayConfig;
@@ -1180,6 +1181,7 @@ public final class OverlayManagerService extends SystemService {
        // intent, querying the PackageManagerService for the actual current
        // state may lead to contradictions within OMS. Better then to lag
        // behind until all pending intents have been processed.
        @GuardedBy("itself")
        private final ArrayMap<String, PackageStateUsers> mCache = new ArrayMap<>();
        private final ArraySet<Integer> mInitializedUsers = new ArraySet<>();

@@ -1207,12 +1209,14 @@ public final class OverlayManagerService extends SystemService {
            }

            final ArrayMap<String, PackageState> userPackages = new ArrayMap<>();
            synchronized (mCache) {
                for (int i = 0, n = mCache.size(); i < n; i++) {
                    final PackageStateUsers pkg = mCache.valueAt(i);
                    if (pkg.mInstalledUsers.contains(userId)) {
                        userPackages.put(mCache.keyAt(i), pkg.mPackageState);
                    }
                }
            }
            return userPackages;
        }

@@ -1220,7 +1224,11 @@ public final class OverlayManagerService extends SystemService {
        @Nullable
        public PackageState getPackageStateForUser(@NonNull final String packageName,
                final int userId) {
            final PackageStateUsers pkg = mCache.get(packageName);
            final PackageStateUsers pkg;

            synchronized (mCache) {
                pkg = mCache.get(packageName);
            }
            if (pkg != null && pkg.mInstalledUsers.contains(userId)) {
                return pkg.mPackageState;
            }
@@ -1251,13 +1259,16 @@ public final class OverlayManagerService extends SystemService {
        @NonNull
        private PackageState addPackageUser(@NonNull final PackageState pkg,
                final int user) {
            PackageStateUsers pkgUsers = mCache.get(pkg.getPackageName());
            PackageStateUsers pkgUsers;
            synchronized (mCache) {
                pkgUsers = mCache.get(pkg.getPackageName());
                if (pkgUsers == null) {
                    pkgUsers = new PackageStateUsers(pkg);
                    mCache.put(pkg.getPackageName(), pkgUsers);
                } else {
                    pkgUsers.mPackageState = pkg;
                }
            }
            pkgUsers.mInstalledUsers.add(user);
            return pkgUsers.mPackageState;
        }
@@ -1265,20 +1276,26 @@ public final class OverlayManagerService extends SystemService {

        @NonNull
        private void removePackageUser(@NonNull final String packageName, final int user) {
            // synchronize should include the call to the other removePackageUser() method so that
            // the access and modification happen under the same lock.
            synchronized (mCache) {
                final PackageStateUsers pkgUsers = mCache.get(packageName);
                if (pkgUsers == null) {
                    return;
                }
                removePackageUser(pkgUsers, user);
            }
        }

        @NonNull
        private void removePackageUser(@NonNull final PackageStateUsers pkg, final int user) {
            pkg.mInstalledUsers.remove(user);
            if (pkg.mInstalledUsers.isEmpty()) {
                synchronized (mCache) {
                    mCache.remove(pkg.mPackageState.getPackageName());
                }
            }
        }

        @Nullable
        public PackageState onPackageAdded(@NonNull final String packageName, final int userId) {
@@ -1386,10 +1403,12 @@ public final class OverlayManagerService extends SystemService {
        public void forgetAllPackageInfos(final int userId) {
            // Iterate in reverse order since removing the package in all users will remove the
            // package from the cache.
            synchronized (mCache) {
                for (int i = mCache.size() - 1; i >= 0; i--) {
                    removePackageUser(mCache.valueAt(i), userId);
                }
            }
        }

        @Nullable
        @Override
@@ -1405,7 +1424,7 @@ public final class OverlayManagerService extends SystemService {

        public void dump(@NonNull final PrintWriter pw, @NonNull DumpState dumpState) {
            pw.println("AndroidPackage cache");

            synchronized (mCache) {
                if (!dumpState.isVerbose()) {
                    pw.println(TAB1 + mCache.size() + " package(s)");
                    return;
@@ -1424,6 +1443,7 @@ public final class OverlayManagerService extends SystemService {
                }
            }
        }
    }

    private void updateTargetPackagesLocked(@Nullable UserPackage updatedTarget) {
        if (updatedTarget != null) {