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

Commit 9aae5e01 authored by Songchun Fan's avatar Songchun Fan
Browse files

Lock for AppsFilter

mLock to ensure the list fields are synchronized when a snapshot is
taken which prevents stale snapshots.

BUG: 226668722
Test: atest AppsFilterImplTest
Change-Id: Ia068f9074f22edd625bdbe781eec1593bff45cfb
parent dd2636a4
Loading
Loading
Loading
Loading
+230 −189
Original line number Original line Diff line number Diff line
@@ -103,6 +103,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
     * application B is implicitly allowed to query for application A; regardless of any manifest
     * application B is implicitly allowed to query for application A; regardless of any manifest
     * entries.
     * entries.
     */
     */
    @GuardedBy("mLock")
    @Watched
    @Watched
    private final WatchedSparseSetArray<Integer> mImplicitlyQueryable;
    private final WatchedSparseSetArray<Integer> mImplicitlyQueryable;
    private final SnapshotCache<WatchedSparseSetArray<Integer>> mImplicitQueryableSnapshot;
    private final SnapshotCache<WatchedSparseSetArray<Integer>> mImplicitQueryableSnapshot;
@@ -112,6 +113,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
     * interacted with it, but could keep across package updates. For example, if application A
     * interacted with it, but could keep across package updates. For example, if application A
     * grants persistable uri permission to application B; regardless of any manifest entries.
     * grants persistable uri permission to application B; regardless of any manifest entries.
     */
     */
    @GuardedBy("mLock")
    @Watched
    @Watched
    private final WatchedSparseSetArray<Integer> mRetainedImplicitlyQueryable;
    private final WatchedSparseSetArray<Integer> mRetainedImplicitlyQueryable;
    private final SnapshotCache<WatchedSparseSetArray<Integer>>
    private final SnapshotCache<WatchedSparseSetArray<Integer>>
@@ -121,6 +123,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
     * A mapping from the set of App IDs that query other App IDs via package name to the
     * A mapping from the set of App IDs that query other App IDs via package name to the
     * list of packages that they can see.
     * list of packages that they can see.
     */
     */
    @GuardedBy("mLock")
    @Watched
    @Watched
    private final WatchedSparseSetArray<Integer> mQueriesViaPackage;
    private final WatchedSparseSetArray<Integer> mQueriesViaPackage;
    private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueriesViaPackageSnapshot;
    private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueriesViaPackageSnapshot;
@@ -129,6 +132,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
     * A mapping from the set of App IDs that query others via component match to the list
     * A mapping from the set of App IDs that query others via component match to the list
     * of packages that the they resolve to.
     * of packages that the they resolve to.
     */
     */
    @GuardedBy("mLock")
    @Watched
    @Watched
    private final WatchedSparseSetArray<Integer> mQueriesViaComponent;
    private final WatchedSparseSetArray<Integer> mQueriesViaComponent;
    private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueriesViaComponentSnapshot;
    private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueriesViaComponentSnapshot;
@@ -137,6 +141,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
     * A mapping from the set of App IDs that query other App IDs via library name to the
     * A mapping from the set of App IDs that query other App IDs via library name to the
     * list of packages that they can see.
     * list of packages that they can see.
     */
     */
    @GuardedBy("mLock")
    @Watched
    @Watched
    private final WatchedSparseSetArray<Integer> mQueryableViaUsesLibrary;
    private final WatchedSparseSetArray<Integer> mQueryableViaUsesLibrary;
    private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesLibrarySnapshot;
    private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesLibrarySnapshot;
@@ -159,6 +164,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
     * A set of App IDs that are always queryable by any package, regardless of their manifest
     * A set of App IDs that are always queryable by any package, regardless of their manifest
     * content.
     * content.
     */
     */
    @GuardedBy("mLock")
    @Watched
    @Watched
    private final WatchedArraySet<Integer> mForceQueryable;
    private final WatchedArraySet<Integer> mForceQueryable;
    private final SnapshotCache<WatchedArraySet<Integer>> mForceQueryableSnapshot;
    private final SnapshotCache<WatchedArraySet<Integer>> mForceQueryableSnapshot;
@@ -176,6 +182,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
    private final StateProvider mStateProvider;
    private final StateProvider mStateProvider;
    private SigningDetails mSystemSigningDetails;
    private SigningDetails mSystemSigningDetails;


    @GuardedBy("mLock")
    @Watched
    @Watched
    private final WatchedArrayList<String> mProtectedBroadcasts;
    private final WatchedArrayList<String> mProtectedBroadcasts;
    private final SnapshotCache<WatchedArrayList<String>> mProtectedBroadcastsSnapshot;
    private final SnapshotCache<WatchedArrayList<String>> mProtectedBroadcastsSnapshot;
@@ -196,6 +203,11 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable


    private volatile boolean mSystemReady = false;
    private volatile boolean mSystemReady = false;


    /**
     * Guards the accesses for the list/set fields except for {@link #mShouldFilterCache}
     */
    private final Object mLock = new Object();

    /**
    /**
     * A cached snapshot.
     * A cached snapshot.
     */
     */
@@ -328,6 +340,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
     * The copy constructor is used by PackageManagerService to construct a snapshot.
     * The copy constructor is used by PackageManagerService to construct a snapshot.
     */
     */
    private AppsFilterImpl(AppsFilterImpl orig) {
    private AppsFilterImpl(AppsFilterImpl orig) {
        synchronized (orig.mLock) {
            mImplicitlyQueryable = orig.mImplicitQueryableSnapshot.snapshot();
            mImplicitlyQueryable = orig.mImplicitQueryableSnapshot.snapshot();
            mImplicitQueryableSnapshot = new SnapshotCache.Sealed<>();
            mImplicitQueryableSnapshot = new SnapshotCache.Sealed<>();
            mRetainedImplicitlyQueryable = orig.mRetainedImplicitlyQueryableSnapshot.snapshot();
            mRetainedImplicitlyQueryable = orig.mRetainedImplicitlyQueryableSnapshot.snapshot();
@@ -342,6 +355,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
            mForceQueryableSnapshot = new SnapshotCache.Sealed<>();
            mForceQueryableSnapshot = new SnapshotCache.Sealed<>();
            mProtectedBroadcasts = orig.mProtectedBroadcastsSnapshot.snapshot();
            mProtectedBroadcasts = orig.mProtectedBroadcastsSnapshot.snapshot();
            mProtectedBroadcastsSnapshot = new SnapshotCache.Sealed<>();
            mProtectedBroadcastsSnapshot = new SnapshotCache.Sealed<>();
        }
        mQueriesViaComponentRequireRecompute = orig.mQueriesViaComponentRequireRecompute;
        mQueriesViaComponentRequireRecompute = orig.mQueriesViaComponentRequireRecompute;
        mForceQueryableByDevicePackageNames =
        mForceQueryableByDevicePackageNames =
                Arrays.copyOf(orig.mForceQueryableByDevicePackageNames,
                Arrays.copyOf(orig.mForceQueryableByDevicePackageNames,
@@ -742,9 +756,11 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
            return false;
            return false;
        }
        }
        final boolean changed;
        final boolean changed;
        synchronized (mLock) {
            changed = retainOnUpdate
            changed = retainOnUpdate
                    ? mRetainedImplicitlyQueryable.add(recipientUid, visibleUid)
                    ? mRetainedImplicitlyQueryable.add(recipientUid, visibleUid)
                    : mImplicitlyQueryable.add(recipientUid, visibleUid);
                    : mImplicitlyQueryable.add(recipientUid, visibleUid);
        }
        if (changed && DEBUG_LOGGING) {
        if (changed && DEBUG_LOGGING) {
            Slog.i(TAG, (retainOnUpdate ? "retained " : "") + "implicit access granted: "
            Slog.i(TAG, (retainOnUpdate ? "retained " : "") + "implicit access granted: "
                    + recipientUid + " -> " + visibleUid);
                    + recipientUid + " -> " + visibleUid);
@@ -833,16 +849,19 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
            // packages for signature matches
            // packages for signature matches
            for (PackageStateInternal setting : existingSettings.values()) {
            for (PackageStateInternal setting : existingSettings.values()) {
                if (isSystemSigned(mSystemSigningDetails, setting)) {
                if (isSystemSigned(mSystemSigningDetails, setting)) {
                    synchronized (mLock) {
                        mForceQueryable.add(setting.getAppId());
                        mForceQueryable.add(setting.getAppId());
                    }
                    }
                }
                }
            }
            }
        }


        final AndroidPackage newPkg = newPkgSetting.getPkg();
        final AndroidPackage newPkg = newPkgSetting.getPkg();
        if (newPkg == null) {
        if (newPkg == null) {
            return null;
            return null;
        }
        }


        synchronized (mLock) {
            if (mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts())) {
            if (mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts())) {
                mQueriesViaComponentRequireRecompute = true;
                mQueriesViaComponentRequireRecompute = true;
            }
            }
@@ -911,7 +930,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
                    mQueriesViaPackage.add(existingSetting.getAppId(), newPkgSetting.getAppId());
                    mQueriesViaPackage.add(existingSetting.getAppId(), newPkgSetting.getAppId());
                }
                }
            }
            }

        }
        int existingSize = existingSettings.size();
        int existingSize = existingSettings.size();
        ArrayMap<String, AndroidPackage> existingPkgs = new ArrayMap<>(existingSize);
        ArrayMap<String, AndroidPackage> existingPkgs = new ArrayMap<>(existingSize);
        for (int index = 0; index < existingSize; index++) {
        for (int index = 0; index < existingSize; index++) {
@@ -1138,6 +1157,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
    private void collectProtectedBroadcasts(
    private void collectProtectedBroadcasts(
            ArrayMap<String, ? extends PackageStateInternal> existingSettings,
            ArrayMap<String, ? extends PackageStateInternal> existingSettings,
            @Nullable String excludePackage) {
            @Nullable String excludePackage) {
        synchronized (mLock) {
            mProtectedBroadcasts.clear();
            mProtectedBroadcasts.clear();
            for (int i = existingSettings.size() - 1; i >= 0; i--) {
            for (int i = existingSettings.size() - 1; i >= 0; i--) {
                PackageStateInternal setting = existingSettings.valueAt(i);
                PackageStateInternal setting = existingSettings.valueAt(i);
@@ -1151,6 +1171,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
                }
                }
            }
            }
        }
        }
    }


    /**
    /**
     * This method recomputes all component / intent-based visibility and is intended to match the
     * This method recomputes all component / intent-based visibility and is intended to match the
@@ -1158,6 +1179,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
     */
     */
    private void recomputeComponentVisibility(
    private void recomputeComponentVisibility(
            ArrayMap<String, ? extends PackageStateInternal> existingSettings) {
            ArrayMap<String, ? extends PackageStateInternal> existingSettings) {
        synchronized (mLock) {
            mQueriesViaComponent.clear();
            mQueriesViaComponent.clear();
            for (int i = existingSettings.size() - 1; i >= 0; i--) {
            for (int i = existingSettings.size() - 1; i >= 0; i--) {
                PackageStateInternal setting = existingSettings.valueAt(i);
                PackageStateInternal setting = existingSettings.valueAt(i);
@@ -1179,6 +1201,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
                    }
                    }
                }
                }
            }
            }
        }
        mQueriesViaComponentRequireRecompute = false;
        mQueriesViaComponentRequireRecompute = false;
    }
    }


@@ -1189,9 +1212,11 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
    @Nullable
    @Nullable
    public SparseArray<int[]> getVisibilityAllowList(PackageStateInternal setting, int[] users,
    public SparseArray<int[]> getVisibilityAllowList(PackageStateInternal setting, int[] users,
            ArrayMap<String, ? extends PackageStateInternal> existingSettings) {
            ArrayMap<String, ? extends PackageStateInternal> existingSettings) {
        synchronized (mLock) {
            if (mForceQueryable.contains(setting.getAppId())) {
            if (mForceQueryable.contains(setting.getAppId())) {
                return null;
                return null;
            }
            }
        }
        // let's reserve max memory to limit the number of allocations
        // let's reserve max memory to limit the number of allocations
        SparseArray<int[]> result = new SparseArray<>(users.length);
        SparseArray<int[]> result = new SparseArray<>(users.length);
        for (int u = 0; u < users.length; u++) {
        for (int u = 0; u < users.length; u++) {
@@ -1256,6 +1281,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
        mStateProvider.runWithState((settings, sharedUserSettings, users) -> {
        mStateProvider.runWithState((settings, sharedUserSettings, users) -> {
            final ArraySet<String> additionalChangedPackages;
            final ArraySet<String> additionalChangedPackages;
            final int userCount = users.length;
            final int userCount = users.length;
            synchronized (mLock) {
                for (int u = 0; u < userCount; u++) {
                for (int u = 0; u < userCount; u++) {
                    final int userId = users[u].id;
                    final int userId = users[u].id;
                    final int removingUid = UserHandle.getUid(userId, setting.getAppId());
                    final int removingUid = UserHandle.getUid(userId, setting.getAppId());
@@ -1306,6 +1332,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
                        mQueriesViaComponentRequireRecompute = true;
                        mQueriesViaComponentRequireRecompute = true;
                    }
                    }
                }
                }
            }


            additionalChangedPackages = mOverlayReferenceMapper.removePkg(setting.getPackageName());
            additionalChangedPackages = mOverlayReferenceMapper.removePkg(setting.getPackageName());
            mFeatureConfig.updatePackageState(setting, true /*removed*/);
            mFeatureConfig.updatePackageState(setting, true /*removed*/);
@@ -1562,12 +1589,14 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
                if (DEBUG_TRACING) {
                if (DEBUG_TRACING) {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mForceQueryable");
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mForceQueryable");
                }
                }
                synchronized (mLock) {
                    if (mForceQueryable.contains(targetAppId)) {
                    if (mForceQueryable.contains(targetAppId)) {
                        if (DEBUG_LOGGING) {
                        if (DEBUG_LOGGING) {
                            log(callingSetting, targetPkgSetting, "force queryable");
                            log(callingSetting, targetPkgSetting, "force queryable");
                        }
                        }
                        return false;
                        return false;
                    }
                    }
                }
            } finally {
            } finally {
                if (DEBUG_TRACING) {
                if (DEBUG_TRACING) {
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -1577,12 +1606,14 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
                if (DEBUG_TRACING) {
                if (DEBUG_TRACING) {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaPackage");
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaPackage");
                }
                }
                synchronized (mLock) {
                    if (mQueriesViaPackage.contains(callingAppId, targetAppId)) {
                    if (mQueriesViaPackage.contains(callingAppId, targetAppId)) {
                        if (DEBUG_LOGGING) {
                        if (DEBUG_LOGGING) {
                            log(callingSetting, targetPkgSetting, "queries package");
                            log(callingSetting, targetPkgSetting, "queries package");
                        }
                        }
                        return false;
                        return false;
                    }
                    }
                }
            } finally {
            } finally {
                if (DEBUG_TRACING) {
                if (DEBUG_TRACING) {
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -1597,12 +1628,14 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
                        recomputeComponentVisibility(settings);
                        recomputeComponentVisibility(settings);
                    });
                    });
                }
                }
                synchronized (mLock) {
                    if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
                    if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
                        if (DEBUG_LOGGING) {
                        if (DEBUG_LOGGING) {
                            log(callingSetting, targetPkgSetting, "queries component");
                            log(callingSetting, targetPkgSetting, "queries component");
                        }
                        }
                        return false;
                        return false;
                    }
                    }
                }
            } finally {
            } finally {
                if (DEBUG_TRACING) {
                if (DEBUG_TRACING) {
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -1614,12 +1647,14 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mImplicitlyQueryable");
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mImplicitlyQueryable");
                }
                }
                final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
                final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
                synchronized (mLock) {
                    if (mImplicitlyQueryable.contains(callingUid, targetUid)) {
                    if (mImplicitlyQueryable.contains(callingUid, targetUid)) {
                        if (DEBUG_LOGGING) {
                        if (DEBUG_LOGGING) {
                            log(callingSetting, targetPkgSetting, "implicitly queryable for user");
                            log(callingSetting, targetPkgSetting, "implicitly queryable for user");
                        }
                        }
                        return false;
                        return false;
                    }
                    }
                }
            } finally {
            } finally {
                if (DEBUG_TRACING) {
                if (DEBUG_TRACING) {
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -1631,6 +1666,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mRetainedImplicitlyQueryable");
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mRetainedImplicitlyQueryable");
                }
                }
                final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
                final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
                synchronized (mLock) {
                    if (mRetainedImplicitlyQueryable.contains(callingUid, targetUid)) {
                    if (mRetainedImplicitlyQueryable.contains(callingUid, targetUid)) {
                        if (DEBUG_LOGGING) {
                        if (DEBUG_LOGGING) {
                            log(callingSetting, targetPkgSetting,
                            log(callingSetting, targetPkgSetting,
@@ -1638,6 +1674,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
                        }
                        }
                        return false;
                        return false;
                    }
                    }
                }
            } finally {
            } finally {
                if (DEBUG_TRACING) {
                if (DEBUG_TRACING) {
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -1682,12 +1719,14 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
                if (DEBUG_TRACING) {
                if (DEBUG_TRACING) {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueryableViaUsesLibrary");
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueryableViaUsesLibrary");
                }
                }
                synchronized (mLock) {
                    if (mQueryableViaUsesLibrary.contains(callingAppId, targetAppId)) {
                    if (mQueryableViaUsesLibrary.contains(callingAppId, targetAppId)) {
                        if (DEBUG_LOGGING) {
                        if (DEBUG_LOGGING) {
                            log(callingSetting, targetPkgSetting, "queryable for library users");
                            log(callingSetting, targetPkgSetting, "queryable for library users");
                        }
                        }
                        return false;
                        return false;
                    }
                    }
                }
            } finally {
            } finally {
                if (DEBUG_TRACING) {
                if (DEBUG_TRACING) {
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -1802,6 +1841,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
        pw.println("  system apps queryable: " + mSystemAppsQueryable);
        pw.println("  system apps queryable: " + mSystemAppsQueryable);
        dumpPackageSet(pw, filteringAppId, mForceQueryable.untrackedStorage(),
        dumpPackageSet(pw, filteringAppId, mForceQueryable.untrackedStorage(),
                "forceQueryable", "  ", expandPackages);
                "forceQueryable", "  ", expandPackages);
        synchronized (mLock) {
            pw.println("  queries via package name:");
            pw.println("  queries via package name:");
            dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, "    ", expandPackages);
            dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, "    ", expandPackages);
            pw.println("  queries via component:");
            pw.println("  queries via component:");
@@ -1820,6 +1860,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable
            dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, "    ",
            dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, "    ",
                    expandPackages);
                    expandPackages);
        }
        }
    }


    private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId,
    private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId,
            WatchedSparseSetArray<Integer> queriesMap, String spacing,
            WatchedSparseSetArray<Integer> queriesMap, String spacing,