diff --git a/core/java/android/util/SparseSetArray.java b/core/java/android/util/SparseSetArray.java index eb53b425a228e..f5025f7a9e994 100644 --- a/core/java/android/util/SparseSetArray.java +++ b/core/java/android/util/SparseSetArray.java @@ -21,26 +21,9 @@ package android.util; * @hide */ public class SparseSetArray { - private final SparseArray> mData; + private final SparseArray> mData = new SparseArray<>(); public SparseSetArray() { - mData = new SparseArray<>(); - } - - /** - * Copy constructor - */ - public SparseSetArray(SparseSetArray src) { - final int arraySize = src.size(); - mData = new SparseArray<>(arraySize); - for (int i = 0; i < arraySize; i++) { - final int key = src.keyAt(i); - final ArraySet set = src.get(key); - final int setSize = set.size(); - for (int j = 0; j < setSize; j++) { - add(key, set.valueAt(j)); - } - } } /** diff --git a/services/core/java/com/android/server/pm/AppsFilterImpl.java b/services/core/java/com/android/server/pm/AppsFilter.java similarity index 64% rename from services/core/java/com/android/server/pm/AppsFilterImpl.java rename to services/core/java/com/android/server/pm/AppsFilter.java index 17dc403cf2c54..152c74553d329 100644 --- a/services/core/java/com/android/server/pm/AppsFilterImpl.java +++ b/services/core/java/com/android/server/pm/AppsFilter.java @@ -44,6 +44,7 @@ import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; +import android.util.SparseSetArray; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; @@ -51,6 +52,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.function.QuadFunction; import com.android.server.FgThread; +import com.android.server.LocalServices; import com.android.server.compat.CompatChange; import com.android.server.om.OverlayReferenceMapper; import com.android.server.pm.parsing.pkg.AndroidPackage; @@ -63,18 +65,14 @@ import com.android.server.pm.pkg.component.ParsedMainComponent; import com.android.server.pm.pkg.component.ParsedProvider; import com.android.server.utils.Snappable; import com.android.server.utils.SnapshotCache; +import com.android.server.utils.Snapshots; import com.android.server.utils.Watchable; import com.android.server.utils.WatchableImpl; -import com.android.server.utils.Watched; -import com.android.server.utils.WatchedArrayList; import com.android.server.utils.WatchedArrayMap; -import com.android.server.utils.WatchedArraySet; import com.android.server.utils.WatchedSparseBooleanMatrix; -import com.android.server.utils.WatchedSparseSetArray; import com.android.server.utils.Watcher; import java.io.PrintWriter; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -87,7 +85,7 @@ import java.util.concurrent.Executor; * manifests. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) -public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable { +public class AppsFilter implements Watchable, Snappable { private static final String TAG = "AppsFilter"; @@ -102,48 +100,32 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable * application B is implicitly allowed to query for application A; regardless of any manifest * entries. */ - @GuardedBy("mLock") - @Watched - private final WatchedSparseSetArray mImplicitlyQueryable; - private final SnapshotCache> mImplicitQueryableSnapshot; + private final SparseSetArray mImplicitlyQueryable = new SparseSetArray<>(); /** * This contains a list of app UIDs that are implicitly queryable because another app explicitly * 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. */ - @GuardedBy("mLock") - @Watched - private final WatchedSparseSetArray mRetainedImplicitlyQueryable; - private final SnapshotCache> - mRetainedImplicitlyQueryableSnapshot; + private final SparseSetArray mRetainedImplicitlyQueryable = new SparseSetArray<>(); /** * 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. */ - @GuardedBy("mLock") - @Watched - private final WatchedSparseSetArray mQueriesViaPackage; - private final SnapshotCache> mQueriesViaPackageSnapshot; + private final SparseSetArray mQueriesViaPackage = new SparseSetArray<>(); /** * A mapping from the set of App IDs that query others via component match to the list * of packages that the they resolve to. */ - @GuardedBy("mLock") - @Watched - private final WatchedSparseSetArray mQueriesViaComponent; - private final SnapshotCache> mQueriesViaComponentSnapshot; + private final SparseSetArray mQueriesViaComponent = new SparseSetArray<>(); /** * 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. */ - @GuardedBy("mLock") - @Watched - private final WatchedSparseSetArray mQueryableViaUsesLibrary; - private final SnapshotCache> mQueryableViaUsesLibrarySnapshot; + private final SparseSetArray mQueryableViaUsesLibrary = new SparseSetArray<>(); /** * Executor for running reasonably short background tasks such as building the initial @@ -163,10 +145,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable * A set of App IDs that are always queryable by any package, regardless of their manifest * content. */ - @Watched - @GuardedBy("mLock") - private final WatchedArraySet mForceQueryable; - private final SnapshotCache> mForceQueryableSnapshot; + private final ArraySet mForceQueryable = new ArraySet<>(); /** * The set of package names provided by the device that should be force queryable regardless of @@ -176,16 +155,14 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable /** True if all system apps should be made queryable by default. */ private final boolean mSystemAppsQueryable; + private final FeatureConfig mFeatureConfig; private final OverlayReferenceMapper mOverlayReferenceMapper; private final StateProvider mStateProvider; private final PackageManagerInternal mPmInternal; - private SigningDetails mSystemSigningDetails; - @GuardedBy("mLock") - @Watched - private final WatchedArrayList mProtectedBroadcasts; - private final SnapshotCache> mProtectedBroadcastsSnapshot; + private SigningDetails mSystemSigningDetails; + private Set mProtectedBroadcasts = new ArraySet<>(); private final Object mCacheLock = new Object(); @@ -194,47 +171,29 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable * filtered to the second. It's essentially a cache of the * {@link #shouldFilterApplicationInternal(int, Object, PackageStateInternal, int)} call. * NOTE: It can only be relied upon after the system is ready to avoid unnecessary update on - * initial scam and is empty until {@link #onSystemReady()} is called. + * initial scam and is null until {@link #onSystemReady()} is called. */ @GuardedBy("mCacheLock") - @NonNull - private final WatchedSparseBooleanMatrix mShouldFilterCache; - private final SnapshotCache mShouldFilterCacheSnapshot; - - /** - * Guards the accesses for the list/set fields except for {@link #mShouldFilterCache} - */ - private final Object mLock = new Object(); + private volatile WatchedSparseBooleanMatrix mShouldFilterCache; /** * A cached snapshot. */ - private final SnapshotCache mSnapshot; + private final SnapshotCache mSnapshot; - private SnapshotCache makeCache() { - return new SnapshotCache(this, this) { + private SnapshotCache makeCache() { + return new SnapshotCache(this, this) { @Override - public AppsFilterImpl createSnapshot() { - AppsFilterImpl s = new AppsFilterImpl(mSource); - s.mWatchable.seal(); + public AppsFilter createSnapshot() { + AppsFilter s = new AppsFilter(mSource); return s; - } - }; + }}; } /** * Watchable machinery */ private final WatchableImpl mWatchable = new WatchableImpl(); - /** - * The observer that watches for changes from array members - */ - private final Watcher mObserver = new Watcher() { - @Override - public void onChange(@Nullable Watchable what) { - AppsFilterImpl.this.dispatchChange(what); - } - }; /** * Ensures an observer is in the list, exactly once. The observer cannot be null. The @@ -260,7 +219,6 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable /** * Return true if the {@link Watcher) is a registered observer. - * * @param observer A {@link Watcher} that might be registered * @return true if the observer is registered with this {@link Watchable}. */ @@ -289,7 +247,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable } @VisibleForTesting(visibility = PRIVATE) - AppsFilterImpl(StateProvider stateProvider, + AppsFilter(StateProvider stateProvider, FeatureConfig featureConfig, String[] forceQueryableList, boolean systemAppsQueryable, @@ -304,70 +262,34 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable mStateProvider = stateProvider; mPmInternal = pmInternal; mBackgroundExecutor = backgroundExecutor; - mImplicitlyQueryable = new WatchedSparseSetArray<>(); - mImplicitQueryableSnapshot = new SnapshotCache.Auto<>( - mImplicitlyQueryable, mImplicitlyQueryable, "AppsFilter.mImplicitlyQueryable"); - mRetainedImplicitlyQueryable = new WatchedSparseSetArray<>(); - mRetainedImplicitlyQueryableSnapshot = new SnapshotCache.Auto<>( - mRetainedImplicitlyQueryable, mRetainedImplicitlyQueryable, - "AppsFilter.mRetainedImplicitlyQueryable"); - mQueriesViaPackage = new WatchedSparseSetArray<>(); - mQueriesViaPackageSnapshot = new SnapshotCache.Auto<>( - mQueriesViaPackage, mQueriesViaPackage, "AppsFilter.mQueriesViaPackage"); - mQueriesViaComponent = new WatchedSparseSetArray<>(); - mQueriesViaComponentSnapshot = new SnapshotCache.Auto<>( - mQueriesViaComponent, mQueriesViaComponent, "AppsFilter.mQueriesViaComponent"); - mQueryableViaUsesLibrary = new WatchedSparseSetArray<>(); - mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Auto<>( - mQueryableViaUsesLibrary, mQueryableViaUsesLibrary, - "AppsFilter.mQueryableViaUsesLibrary"); - mForceQueryable = new WatchedArraySet<>(); - mForceQueryableSnapshot = new SnapshotCache.Auto<>( - mForceQueryable, mForceQueryable, "AppsFilter.mForceQueryable"); - mProtectedBroadcasts = new WatchedArrayList<>(); - mProtectedBroadcastsSnapshot = new SnapshotCache.Auto<>( - mProtectedBroadcasts, mProtectedBroadcasts, "AppsFilter.mProtectedBroadcasts"); - mShouldFilterCache = new WatchedSparseBooleanMatrix(); - mShouldFilterCacheSnapshot = new SnapshotCache.Auto<>( - mShouldFilterCache, mShouldFilterCache, "AppsFilter.mShouldFilterCache"); - - registerObservers(); - Watchable.verifyWatchedAttributes(this, mObserver); mSnapshot = makeCache(); } /** * The copy constructor is used by PackageManagerService to construct a snapshot. + * Attributes are not deep-copied since these are supposed to be immutable. + * TODO: deep-copy the attributes, if necessary. */ - private AppsFilterImpl(AppsFilterImpl orig) { - synchronized (orig.mLock) { - mImplicitlyQueryable = orig.mImplicitQueryableSnapshot.snapshot(); - mImplicitQueryableSnapshot = new SnapshotCache.Sealed<>(); - mRetainedImplicitlyQueryable = orig.mRetainedImplicitlyQueryableSnapshot.snapshot(); - mRetainedImplicitlyQueryableSnapshot = new SnapshotCache.Sealed<>(); - mQueriesViaPackage = orig.mQueriesViaPackageSnapshot.snapshot(); - mQueriesViaPackageSnapshot = new SnapshotCache.Sealed<>(); - mQueriesViaComponent = orig.mQueriesViaComponentSnapshot.snapshot(); - mQueriesViaComponentSnapshot = new SnapshotCache.Sealed<>(); - mQueryableViaUsesLibrary = orig.mQueryableViaUsesLibrarySnapshot.snapshot(); - mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Sealed<>(); - mForceQueryable = orig.mForceQueryableSnapshot.snapshot(); - mForceQueryableSnapshot = new SnapshotCache.Sealed<>(); - mProtectedBroadcasts = orig.mProtectedBroadcastsSnapshot.snapshot(); - mProtectedBroadcastsSnapshot = new SnapshotCache.Sealed<>(); - } + private AppsFilter(AppsFilter orig) { + Snapshots.copy(mImplicitlyQueryable, orig.mImplicitlyQueryable); + Snapshots.copy(mRetainedImplicitlyQueryable, orig.mRetainedImplicitlyQueryable); + Snapshots.copy(mQueriesViaPackage, orig.mQueriesViaPackage); + Snapshots.copy(mQueriesViaComponent, orig.mQueriesViaComponent); + Snapshots.copy(mQueryableViaUsesLibrary, orig.mQueryableViaUsesLibrary); mQueriesViaComponentRequireRecompute = orig.mQueriesViaComponentRequireRecompute; - mForceQueryableByDevicePackageNames = - Arrays.copyOf(orig.mForceQueryableByDevicePackageNames, - orig.mForceQueryableByDevicePackageNames.length); + mForceQueryable.addAll(orig.mForceQueryable); + mForceQueryableByDevicePackageNames = orig.mForceQueryableByDevicePackageNames; mSystemAppsQueryable = orig.mSystemAppsQueryable; mFeatureConfig = orig.mFeatureConfig; mOverlayReferenceMapper = orig.mOverlayReferenceMapper; mStateProvider = orig.mStateProvider; mSystemSigningDetails = orig.mSystemSigningDetails; - synchronized (orig.mCacheLock) { - mShouldFilterCache = orig.mShouldFilterCacheSnapshot.snapshot(); - mShouldFilterCacheSnapshot = new SnapshotCache.Sealed<>(); + mProtectedBroadcasts = orig.mProtectedBroadcasts; + mShouldFilterCache = orig.mShouldFilterCache; + if (mShouldFilterCache != null) { + synchronized (orig.mCacheLock) { + mShouldFilterCache = mShouldFilterCache.snapshot(); + } } mBackgroundExecutor = null; @@ -375,24 +297,12 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable mSnapshot = new SnapshotCache.Sealed<>(); } - @SuppressWarnings("GuardedBy") - private void registerObservers() { - mImplicitlyQueryable.registerObserver(mObserver); - mRetainedImplicitlyQueryable.registerObserver(mObserver); - mQueriesViaPackage.registerObserver(mObserver); - mQueriesViaComponent.registerObserver(mObserver); - mQueryableViaUsesLibrary.registerObserver(mObserver); - mForceQueryable.registerObserver(mObserver); - mProtectedBroadcasts.registerObserver(mObserver); - mShouldFilterCache.registerObserver(mObserver); - } - /** * Return a snapshot. If the cached snapshot is null, build a new one. The logic in * the function ensures that this function returns a valid snapshot even if a race * condition causes the cached snapshot to be cleared asynchronously to this method. */ - public AppsFilterSnapshot snapshot() { + public AppsFilter snapshot() { return mSnapshot.snapshot(); } @@ -453,7 +363,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable @Nullable private SparseBooleanArray mLoggingEnabled = null; - private AppsFilterImpl mAppsFilter; + private AppsFilter mAppsFilter; private FeatureConfigImpl( PackageManagerInternal pmInternal, PackageManagerServiceInjector injector) { @@ -461,7 +371,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable mInjector = injector; } - public void setAppsFilter(AppsFilterImpl filter) { + public void setAppsFilter(AppsFilter filter) { mAppsFilter = filter; } @@ -565,9 +475,8 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable @Override public void updatePackageState(PackageStateInternal setting, boolean removed) { - final boolean enableLogging = setting.getPkg() != null - && !removed && (setting.getPkg().isTestOnly() - || setting.getPkg().isDebuggable()); + final boolean enableLogging = setting.getPkg() != null && + !removed && (setting.getPkg().isTestOnly() || setting.getPkg().isDebuggable()); enableLogging(setting.getAppId(), enableLogging); if (removed) { mDisabledPackages.remove(setting.getPackageName()); @@ -578,7 +487,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable } /** Builder method for an AppsFilter */ - public static AppsFilterImpl create(@NonNull PackageManagerServiceInjector injector, + public static AppsFilter create(@NonNull PackageManagerServiceInjector injector, @NonNull PackageManagerInternal pmInt) { final boolean forceSystemAppsQueryable = injector.getContext().getResources() @@ -602,7 +511,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable injector.getUserManagerInternal().getUserInfos()); } }; - AppsFilterImpl appsFilter = new AppsFilterImpl(stateProvider, featureConfig, + AppsFilter appsFilter = new AppsFilter(stateProvider, featureConfig, forcedQueryablePackageNames, forceSystemAppsQueryable, null, injector.getBackgroundExecutor(), pmInt); featureConfig.setAppsFilter(appsFilter); @@ -615,7 +524,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable /** Returns true if the querying package may query for the potential target package */ private static boolean canQueryViaComponents(AndroidPackage querying, - AndroidPackage potentialTarget, WatchedArrayList protectedBroadcasts) { + AndroidPackage potentialTarget, Set protectedBroadcasts) { if (!querying.getQueriesIntents().isEmpty()) { for (Intent intent : querying.getQueriesIntents()) { if (matchesPackage(intent, potentialTarget, protectedBroadcasts)) { @@ -687,7 +596,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable } private static boolean matchesPackage(Intent intent, AndroidPackage potentialTarget, - WatchedArrayList protectedBroadcasts) { + Set protectedBroadcasts) { if (matchesAnyComponents( intent, potentialTarget.getServices(), null /*protectedBroadcasts*/)) { return true; @@ -708,7 +617,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable private static boolean matchesAnyComponents(Intent intent, List components, - WatchedArrayList protectedBroadcasts) { + Set protectedBroadcasts) { for (int i = ArrayUtils.size(components) - 1; i >= 0; i--) { ParsedMainComponent component = components.get(i); if (!component.isExported()) { @@ -722,7 +631,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable } private static boolean matchesAnyFilter(Intent intent, ParsedComponent component, - WatchedArrayList protectedBroadcasts) { + Set protectedBroadcasts) { List intents = component.getIntents(); for (int i = ArrayUtils.size(intents) - 1; i >= 0; i--) { IntentFilter intentFilter = intents.get(i).getIntentFilter(); @@ -734,38 +643,38 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable } private static boolean matchesIntentFilter(Intent intent, IntentFilter intentFilter, - @Nullable WatchedArrayList protectedBroadcasts) { + @Nullable Set protectedBroadcasts) { return intentFilter.match(intent.getAction(), intent.getType(), intent.getScheme(), - intent.getData(), intent.getCategories(), "AppsFilter", true, - protectedBroadcasts != null ? protectedBroadcasts.untrackedStorage() : null) > 0; + intent.getData(), intent.getCategories(), "AppsFilter", true, protectedBroadcasts) + > 0; } /** * Grants access based on an interaction between a calling and target package, granting * visibility of the caller from the target. * - * @param recipientUid the uid gaining visibility of the {@code visibleUid}. - * @param visibleUid the uid becoming visible to the {@recipientUid} - * @param retainOnUpdate if the implicit access retained across package updates. + * @param recipientUid the uid gaining visibility of the {@code visibleUid}. + * @param visibleUid the uid becoming visible to the {@recipientUid} + * @param retainOnUpdate if the implicit access retained across package updates. * @return {@code true} if implicit access was not already granted. */ public boolean grantImplicitAccess(int recipientUid, int visibleUid, boolean retainOnUpdate) { if (recipientUid == visibleUid) { return false; } - final boolean changed; - synchronized (mLock) { - changed = retainOnUpdate - ? mRetainedImplicitlyQueryable.add(recipientUid, visibleUid) - : mImplicitlyQueryable.add(recipientUid, visibleUid); - if (changed && DEBUG_LOGGING) { - Slog.i(TAG, (retainOnUpdate ? "retained " : "") + "implicit access granted: " - + recipientUid + " -> " + visibleUid); - } + final boolean changed = retainOnUpdate + ? mRetainedImplicitlyQueryable.add(recipientUid, visibleUid) + : mImplicitlyQueryable.add(recipientUid, visibleUid); + if (changed && DEBUG_LOGGING) { + Slog.i(TAG, (retainOnUpdate ? "retained " : "") + "implicit access granted: " + + recipientUid + " -> " + visibleUid); } synchronized (mCacheLock) { - // update the cache in a one-off manner since we've got all the information we need. - mShouldFilterCache.put(recipientUid, visibleUid, false); + if (mShouldFilterCache != null) { + // update the cache in a one-off manner since we've got all the information we + // need. + mShouldFilterCache.put(recipientUid, visibleUid, false); + } } if (changed) { onChanged(); @@ -785,7 +694,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable * Adds a package that should be considered when filtering visibility between apps. * * @param newPkgSetting the new setting being added - * @param isReplace if the package is being replaced and may need extra cleanup. + * @param isReplace if the package is being replaced and may need extra cleanup. */ public void addPackage(PackageStateInternal newPkgSetting, boolean isReplace) { if (DEBUG_TRACING) { @@ -800,25 +709,27 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable ArraySet additionalChangedPackages = addPackageInternal(newPkgSetting, settings); synchronized (mCacheLock) { - updateShouldFilterCacheForPackage(mShouldFilterCache, null, newPkgSetting, - settings, users, USER_ALL, settings.size()); - if (additionalChangedPackages != null) { - for (int index = 0; index < additionalChangedPackages.size(); index++) { - String changedPackage = additionalChangedPackages.valueAt(index); - PackageStateInternal changedPkgSetting = - settings.get(changedPackage); - if (changedPkgSetting == null) { - // It's possible for the overlay mapper to know that an actor - // package changed via an explicit reference, even if the actor - // isn't installed, so skip if that's the case. - continue; - } + if (mShouldFilterCache != null) { + updateShouldFilterCacheForPackage(mShouldFilterCache, null, newPkgSetting, + settings, users, USER_ALL, settings.size()); + if (additionalChangedPackages != null) { + for (int index = 0; index < additionalChangedPackages.size(); index++) { + String changedPackage = additionalChangedPackages.valueAt(index); + PackageStateInternal changedPkgSetting = + settings.get(changedPackage); + if (changedPkgSetting == null) { + // It's possible for the overlay mapper to know that an actor + // package changed via an explicit reference, even if the actor + // isn't installed, so skip if that's the case. + continue; + } - updateShouldFilterCacheForPackage(mShouldFilterCache, null, - changedPkgSetting, settings, users, USER_ALL, - settings.size()); + updateShouldFilterCacheForPackage(mShouldFilterCache, null, + changedPkgSetting, settings, users, USER_ALL, + settings.size()); + } } - } + } // else, rebuild entire cache when system is ready } }); } finally { @@ -841,11 +752,9 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable mSystemSigningDetails = newPkgSetting.getSigningDetails(); // and since we add overlays before we add the framework, let's revisit already added // packages for signature matches - synchronized (mLock) { - for (PackageStateInternal setting : existingSettings.values()) { - if (isSystemSigned(mSystemSigningDetails, setting)) { - mForceQueryable.add(setting.getAppId()); - } + for (PackageStateInternal setting : existingSettings.values()) { + if (isSystemSigned(mSystemSigningDetails, setting)) { + mForceQueryable.add(setting.getAppId()); } } } @@ -855,74 +764,67 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable return null; } - synchronized (mLock) { - if (mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts())) { - mQueriesViaComponentRequireRecompute = true; - } + if (mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts())) { + mQueriesViaComponentRequireRecompute = true; + } - final boolean newIsForceQueryable = - mForceQueryable.contains(newPkgSetting.getAppId()) - /* shared user that is already force queryable */ - || newPkgSetting.isForceQueryableOverride() /* adb override */ - || (newPkgSetting.isSystem() && (mSystemAppsQueryable - || newPkg.isForceQueryable() - || ArrayUtils.contains(mForceQueryableByDevicePackageNames, - newPkg.getPackageName()))); - if (newIsForceQueryable - || (mSystemSigningDetails != null - && isSystemSigned(mSystemSigningDetails, newPkgSetting))) { - mForceQueryable.add(newPkgSetting.getAppId()); - } + final boolean newIsForceQueryable = + mForceQueryable.contains(newPkgSetting.getAppId()) + /* shared user that is already force queryable */ + || newPkgSetting.isForceQueryableOverride() /* adb override */ + || (newPkgSetting.isSystem() && (mSystemAppsQueryable + || newPkg.isForceQueryable() + || ArrayUtils.contains(mForceQueryableByDevicePackageNames, + newPkg.getPackageName()))); + if (newIsForceQueryable + || (mSystemSigningDetails != null + && isSystemSigned(mSystemSigningDetails, newPkgSetting))) { + mForceQueryable.add(newPkgSetting.getAppId()); + } - for (int i = existingSettings.size() - 1; i >= 0; i--) { - final PackageStateInternal existingSetting = existingSettings.valueAt(i); - if (existingSetting.getAppId() == newPkgSetting.getAppId() - || existingSetting.getPkg() - == null) { - continue; + for (int i = existingSettings.size() - 1; i >= 0; i--) { + final PackageStateInternal existingSetting = existingSettings.valueAt(i); + if (existingSetting.getAppId() == newPkgSetting.getAppId() || existingSetting.getPkg() + == null) { + continue; + } + final AndroidPackage existingPkg = existingSetting.getPkg(); + // let's evaluate the ability of already added packages to see this new package + if (!newIsForceQueryable) { + if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(existingPkg, + newPkg, mProtectedBroadcasts)) { + mQueriesViaComponent.add(existingSetting.getAppId(), newPkgSetting.getAppId()); } - final AndroidPackage existingPkg = existingSetting.getPkg(); - // let's evaluate the ability of already added packages to see this new package - if (!newIsForceQueryable) { - if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(existingPkg, - newPkg, mProtectedBroadcasts)) { - mQueriesViaComponent.add(existingSetting.getAppId(), - newPkgSetting.getAppId()); - } - if (canQueryViaPackage(existingPkg, newPkg) - || canQueryAsInstaller(existingSetting, newPkg)) { - mQueriesViaPackage.add(existingSetting.getAppId(), - newPkgSetting.getAppId()); - } - if (canQueryViaUsesLibrary(existingPkg, newPkg)) { - mQueryableViaUsesLibrary.add(existingSetting.getAppId(), - newPkgSetting.getAppId()); - } - } - // now we'll evaluate our new package's ability to see existing packages - if (!mForceQueryable.contains(existingSetting.getAppId())) { - if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(newPkg, - existingPkg, mProtectedBroadcasts)) { - mQueriesViaComponent.add(newPkgSetting.getAppId(), - existingSetting.getAppId()); - } - if (canQueryViaPackage(newPkg, existingPkg) - || canQueryAsInstaller(newPkgSetting, existingPkg)) { - mQueriesViaPackage.add(newPkgSetting.getAppId(), - existingSetting.getAppId()); - } - if (canQueryViaUsesLibrary(newPkg, existingPkg)) { - mQueryableViaUsesLibrary.add(newPkgSetting.getAppId(), - existingSetting.getAppId()); - } - } - // if either package instruments the other, mark both as visible to one another - if (newPkgSetting.getPkg() != null && existingSetting.getPkg() != null - && (pkgInstruments(newPkgSetting.getPkg(), existingSetting.getPkg()) - || pkgInstruments(existingSetting.getPkg(), newPkgSetting.getPkg()))) { - mQueriesViaPackage.add(newPkgSetting.getAppId(), existingSetting.getAppId()); + if (canQueryViaPackage(existingPkg, newPkg) + || canQueryAsInstaller(existingSetting, newPkg)) { mQueriesViaPackage.add(existingSetting.getAppId(), newPkgSetting.getAppId()); } + if (canQueryViaUsesLibrary(existingPkg, newPkg)) { + mQueryableViaUsesLibrary.add(existingSetting.getAppId(), + newPkgSetting.getAppId()); + } + } + // now we'll evaluate our new package's ability to see existing packages + if (!mForceQueryable.contains(existingSetting.getAppId())) { + if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(newPkg, + existingPkg, mProtectedBroadcasts)) { + mQueriesViaComponent.add(newPkgSetting.getAppId(), existingSetting.getAppId()); + } + if (canQueryViaPackage(newPkg, existingPkg) + || canQueryAsInstaller(newPkgSetting, existingPkg)) { + mQueriesViaPackage.add(newPkgSetting.getAppId(), existingSetting.getAppId()); + } + if (canQueryViaUsesLibrary(newPkg, existingPkg)) { + mQueryableViaUsesLibrary.add(newPkgSetting.getAppId(), + existingSetting.getAppId()); + } + } + // if either package instruments the other, mark both as visible to one another + if (newPkgSetting.getPkg() != null && existingSetting.getPkg() != null + && (pkgInstruments(newPkgSetting.getPkg(), existingSetting.getPkg()) + || pkgInstruments(existingSetting.getPkg(), newPkgSetting.getPkg()))) { + mQueriesViaPackage.add(newPkgSetting.getAppId(), existingSetting.getAppId()); + mQueriesViaPackage.add(existingSetting.getAppId(), newPkgSetting.getAppId()); } } @@ -943,17 +845,19 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable return changedPackages; } + @GuardedBy("mCacheLock") private void removeAppIdFromVisibilityCache(int appId) { - synchronized (mCacheLock) { - for (int i = 0; i < mShouldFilterCache.size(); i++) { - if (UserHandle.getAppId(mShouldFilterCache.keyAt(i)) == appId) { - mShouldFilterCache.removeAt(i); - // The key was deleted so the list of keys has shifted left. That means i - // is now pointing at the next key to be examined. The decrement here and - // the loop increment together mean that i will be unchanged in the need - // iteration and will correctly point to the next key to be examined. - i--; - } + if (mShouldFilterCache == null) { + return; + } + for (int i = 0; i < mShouldFilterCache.size(); i++) { + if (UserHandle.getAppId(mShouldFilterCache.keyAt(i)) == appId) { + mShouldFilterCache.removeAt(i); + // The key was deleted so the list of keys has shifted left. That means i + // is now pointing at the next key to be examined. The decrement here and + // the loop increment together mean that i will be unchanged in the need + // iteration and will correctly point to the next key to be examined. + i--; } } } @@ -979,12 +883,11 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable WatchedSparseBooleanMatrix cache = updateEntireShouldFilterCacheInner(settings, users, userId); synchronized (mCacheLock) { - mShouldFilterCache.copyFrom(cache); + mShouldFilterCache = cache; } }); } - @NonNull private WatchedSparseBooleanMatrix updateEntireShouldFilterCacheInner( ArrayMap settings, UserInfo[] users, int subjectUserId) { @@ -1045,25 +948,36 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable } } else { synchronized (mCacheLock) { - mShouldFilterCache.copyFrom(cache); + mShouldFilterCache = cache; } } }); } public void onUserCreated(int newUserId) { - updateEntireShouldFilterCache(newUserId); - onChanged(); + synchronized (mCacheLock) { + if (mShouldFilterCache != null) { + updateEntireShouldFilterCache(newUserId); + onChanged(); + } + } } public void onUserDeleted(@UserIdInt int userId) { - removeShouldFilterCacheForUser(userId); - onChanged(); + synchronized (mCacheLock) { + if (mShouldFilterCache != null) { + removeShouldFilterCacheForUser(userId); + onChanged(); + } + } } private void updateShouldFilterCacheForPackage(String packageName) { mStateProvider.runWithState((settings, users) -> { synchronized (mCacheLock) { + if (mShouldFilterCache == null) { + return; + } updateShouldFilterCacheForPackage(mShouldFilterCache, null /* skipPackage */, settings.get(packageName), settings, users, USER_ALL, settings.size() /*maxIndex*/); @@ -1071,7 +985,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable }); } - private void updateShouldFilterCacheForPackage(@NonNull WatchedSparseBooleanMatrix cache, + private void updateShouldFilterCacheForPackage(WatchedSparseBooleanMatrix cache, @Nullable String skipPackageName, PackageStateInternal subjectSetting, ArrayMap allSettings, UserInfo[] allUsers, int subjectUserId, int maxIndex) { @@ -1097,7 +1011,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable } } - private void updateShouldFilterCacheForUser(@NonNull WatchedSparseBooleanMatrix cache, + private void updateShouldFilterCacheForUser(WatchedSparseBooleanMatrix cache, PackageStateInternal subjectSetting, UserInfo[] allUsers, PackageStateInternal otherSetting, int subjectUserId) { for (int ou = 0; ou < allUsers.length; ou++) { @@ -1113,28 +1027,27 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable } } + @GuardedBy("mCacheLock") private void removeShouldFilterCacheForUser(int userId) { - synchronized (mCacheLock) { - // Sorted uids with the ascending order - final int[] cacheUids = mShouldFilterCache.keys(); - final int size = cacheUids.length; - int pos = Arrays.binarySearch(cacheUids, UserHandle.getUid(userId, 0)); - final int fromIndex = (pos >= 0 ? pos : ~pos); - if (fromIndex >= size || UserHandle.getUserId(cacheUids[fromIndex]) != userId) { - Slog.w(TAG, "Failed to remove should filter cache for user " + userId - + ", fromIndex=" + fromIndex); - return; - } - pos = Arrays.binarySearch(cacheUids, UserHandle.getUid(userId + 1, 0) - 1); - final int toIndex = (pos >= 0 ? pos + 1 : ~pos); - if (fromIndex >= toIndex || UserHandle.getUserId(cacheUids[toIndex - 1]) != userId) { - Slog.w(TAG, "Failed to remove should filter cache for user " + userId - + ", fromIndex=" + fromIndex + ", toIndex=" + toIndex); - return; - } - mShouldFilterCache.removeRange(fromIndex, toIndex); - mShouldFilterCache.compact(); + // Sorted uids with the ascending order + final int[] cacheUids = mShouldFilterCache.keys(); + final int size = cacheUids.length; + int pos = Arrays.binarySearch(cacheUids, UserHandle.getUid(userId, 0)); + final int fromIndex = (pos >= 0 ? pos : ~pos); + if (fromIndex >= size || UserHandle.getUserId(cacheUids[fromIndex]) != userId) { + Slog.w(TAG, "Failed to remove should filter cache for user " + userId + + ", fromIndex=" + fromIndex); + return; } + pos = Arrays.binarySearch(cacheUids, UserHandle.getUid(userId + 1, 0) - 1); + final int toIndex = (pos >= 0 ? pos + 1 : ~pos); + if (fromIndex >= toIndex || UserHandle.getUserId(cacheUids[toIndex - 1]) != userId) { + Slog.w(TAG, "Failed to remove should filter cache for user " + userId + + ", fromIndex=" + fromIndex + ", toIndex=" + toIndex); + return; + } + mShouldFilterCache.removeRange(fromIndex, toIndex); + mShouldFilterCache.compact(); } private static boolean isSystemSigned(@NonNull SigningDetails sysSigningDetails, @@ -1143,30 +1056,28 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable && pkgSetting.getSigningDetails().signaturesMatchExactly(sysSigningDetails); } - private void collectProtectedBroadcasts( + private ArraySet collectProtectedBroadcasts( ArrayMap existingSettings, @Nullable String excludePackage) { - synchronized (mLock) { - mProtectedBroadcasts.clear(); - for (int i = existingSettings.size() - 1; i >= 0; i--) { - PackageStateInternal setting = existingSettings.valueAt(i); - if (setting.getPkg() == null || setting.getPkg().getPackageName().equals( - excludePackage)) { - continue; - } - final List protectedBroadcasts = setting.getPkg().getProtectedBroadcasts(); - if (!protectedBroadcasts.isEmpty()) { - mProtectedBroadcasts.addAll(protectedBroadcasts); - } + ArraySet ret = new ArraySet<>(); + for (int i = existingSettings.size() - 1; i >= 0; i--) { + PackageStateInternal setting = existingSettings.valueAt(i); + if (setting.getPkg() == null || setting.getPkg().getPackageName().equals( + excludePackage)) { + continue; + } + final List protectedBroadcasts = setting.getPkg().getProtectedBroadcasts(); + if (!protectedBroadcasts.isEmpty()) { + ret.addAll(protectedBroadcasts); } } + return ret; } /** * This method recomputes all component / intent-based visibility and is intended to match the * relevant logic of {@link #addPackageInternal(PackageStateInternal, ArrayMap)} */ - @GuardedBy("mLock") private void recomputeComponentVisibility( ArrayMap existingSettings) { mQueriesViaComponent.clear(); @@ -1194,16 +1105,24 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable } /** - * See {@link AppsFilterSnapshot#getVisibilityAllowList(PackageStateInternal, int[], ArrayMap)} + * Fetches all app Ids that a given setting is currently visible to, per provided user. This + * only includes UIDs >= {@link Process#FIRST_APPLICATION_UID} as all other UIDs can already see + * all applications. + * + * If the setting is visible to all UIDs, null is returned. If an app is not visible to any + * applications, the int array will be empty. + * + * @param users the set of users that should be evaluated for this calculation + * @param existingSettings the set of all package settings that currently exist on device + * @return a SparseArray mapping userIds to a sorted int array of appIds that may view the + * provided setting or null if the app is visible to all and no allow list should be + * applied. */ - @Override @Nullable public SparseArray getVisibilityAllowList(PackageStateInternal setting, int[] users, ArrayMap existingSettings) { - synchronized (mLock) { - if (mForceQueryable.contains(setting.getAppId())) { - return null; - } + if (mForceQueryable.contains(setting.getAppId())) { + return null; } // let's reserve max memory to limit the number of allocations SparseArray result = new SparseArray<>(users.length); @@ -1252,8 +1171,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable /** * Equivalent to calling {@link #addPackage(PackageStateInternal, boolean)} with * {@code isReplace} equal to {@code false}. - * - * @see AppsFilterImpl#addPackage(PackageStateInternal, boolean) + * @see AppsFilter#addPackage(PackageStateInternal, boolean) */ public void addPackage(PackageStateInternal newPkgSetting) { addPackage(newPkgSetting, false /* isReplace */); @@ -1262,69 +1180,63 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable /** * Removes a package for consideration when filtering visibility between apps. * - * @param setting the setting of the package being removed. + * @param setting the setting of the package being removed. * @param isReplace if the package is being replaced. */ public void removePackage(PackageStateInternal setting, boolean isReplace) { mStateProvider.runWithState((settings, users) -> { - final ArraySet additionalChangedPackages; - synchronized (mLock) { - final int userCount = users.length; - for (int u = 0; u < userCount; u++) { - final int userId = users[u].id; - final int removingUid = UserHandle.getUid(userId, setting.getAppId()); - mImplicitlyQueryable.remove(removingUid); - for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) { - mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i), removingUid); - } - - if (isReplace) { - continue; - } - - mRetainedImplicitlyQueryable.remove(removingUid); - for (int i = mRetainedImplicitlyQueryable.size() - 1; i >= 0; i--) { - mRetainedImplicitlyQueryable.remove( - mRetainedImplicitlyQueryable.keyAt(i), removingUid); - } + final int userCount = users.length; + for (int u = 0; u < userCount; u++) { + final int userId = users[u].id; + final int removingUid = UserHandle.getUid(userId, setting.getAppId()); + mImplicitlyQueryable.remove(removingUid); + for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) { + mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i), removingUid); } - if (!mQueriesViaComponentRequireRecompute) { - mQueriesViaComponent.remove(setting.getAppId()); - for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) { - mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), - setting.getAppId()); - } - } - mQueriesViaPackage.remove(setting.getAppId()); - for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) { - mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), setting.getAppId()); - } - mQueryableViaUsesLibrary.remove(setting.getAppId()); - for (int i = mQueryableViaUsesLibrary.size() - 1; i >= 0; i--) { - mQueryableViaUsesLibrary.remove(mQueryableViaUsesLibrary.keyAt(i), - setting.getAppId()); + if (isReplace) { + continue; } - mForceQueryable.remove(setting.getAppId()); - - if (setting.getPkg() != null - && !setting.getPkg().getProtectedBroadcasts().isEmpty()) { - final String removingPackageName = setting.getPkg().getPackageName(); - final ArrayList protectedBroadcasts = new ArrayList<>(); - protectedBroadcasts.addAll(mProtectedBroadcasts.untrackedStorage()); - collectProtectedBroadcasts(settings, removingPackageName); - if (!mProtectedBroadcasts.containsAll(protectedBroadcasts)) { - mQueriesViaComponentRequireRecompute = true; - } + mRetainedImplicitlyQueryable.remove(removingUid); + for (int i = mRetainedImplicitlyQueryable.size() - 1; i >= 0; i--) { + mRetainedImplicitlyQueryable.remove( + mRetainedImplicitlyQueryable.keyAt(i), removingUid); } - - additionalChangedPackages = - mOverlayReferenceMapper.removePkg(setting.getPackageName()); - - mFeatureConfig.updatePackageState(setting, true /*removed*/); } + if (!mQueriesViaComponentRequireRecompute) { + mQueriesViaComponent.remove(setting.getAppId()); + for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) { + mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), setting.getAppId()); + } + } + mQueriesViaPackage.remove(setting.getAppId()); + for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) { + mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), setting.getAppId()); + } + mQueryableViaUsesLibrary.remove(setting.getAppId()); + for (int i = mQueryableViaUsesLibrary.size() - 1; i >= 0; i--) { + mQueryableViaUsesLibrary.remove(mQueryableViaUsesLibrary.keyAt(i), + setting.getAppId()); + } + + mForceQueryable.remove(setting.getAppId()); + + if (setting.getPkg() != null && !setting.getPkg().getProtectedBroadcasts().isEmpty()) { + final String removingPackageName = setting.getPkg().getPackageName(); + final Set protectedBroadcasts = mProtectedBroadcasts; + mProtectedBroadcasts = collectProtectedBroadcasts(settings, removingPackageName); + if (!mProtectedBroadcasts.containsAll(protectedBroadcasts)) { + mQueriesViaComponentRequireRecompute = true; + } + } + + ArraySet additionalChangedPackages = + mOverlayReferenceMapper.removePkg(setting.getPackageName()); + + mFeatureConfig.updatePackageState(setting, true /*removed*/); + // After removing all traces of the package, if it's part of a shared user, re-add other // 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 @@ -1341,49 +1253,56 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable } } - removeAppIdFromVisibilityCache(setting.getAppId()); - if (setting.hasSharedUser()) { - final ArraySet sharedUserPackages = - mPmInternal.getSharedUserPackages(setting.getSharedUserAppId()); - for (int i = sharedUserPackages.size() - 1; i >= 0; i--) { - PackageStateInternal siblingSetting = - sharedUserPackages.valueAt(i); - if (siblingSetting == setting) { - continue; - } - synchronized (mCacheLock) { + synchronized (mCacheLock) { + removeAppIdFromVisibilityCache(setting.getAppId()); + if (mShouldFilterCache != null && setting.hasSharedUser()) { + final ArraySet sharedUserPackages = + mPmInternal.getSharedUserPackages(setting.getSharedUserAppId()); + for (int i = sharedUserPackages.size() - 1; i >= 0; i--) { + PackageStateInternal siblingSetting = + sharedUserPackages.valueAt(i); + if (siblingSetting == setting) { + continue; + } updateShouldFilterCacheForPackage(mShouldFilterCache, setting.getPackageName(), siblingSetting, settings, users, USER_ALL, settings.size()); } } - } - if (additionalChangedPackages != null) { - for (int index = 0; index < additionalChangedPackages.size(); index++) { - String changedPackage = additionalChangedPackages.valueAt(index); - PackageStateInternal changedPkgSetting = settings.get(changedPackage); - if (changedPkgSetting == null) { - // It's possible for the overlay mapper to know that an actor - // package changed via an explicit reference, even if the actor - // isn't installed, so skip if that's the case. - continue; - } - synchronized (mCacheLock) { - updateShouldFilterCacheForPackage(mShouldFilterCache, null, - changedPkgSetting, settings, users, USER_ALL, settings.size()); + if (mShouldFilterCache != null) { + if (additionalChangedPackages != null) { + for (int index = 0; index < additionalChangedPackages.size(); index++) { + String changedPackage = additionalChangedPackages.valueAt(index); + PackageStateInternal changedPkgSetting = settings.get(changedPackage); + if (changedPkgSetting == null) { + // It's possible for the overlay mapper to know that an actor + // package changed via an explicit reference, even if the actor + // isn't installed, so skip if that's the case. + continue; + } + + updateShouldFilterCacheForPackage(mShouldFilterCache, null, + changedPkgSetting, settings, users, USER_ALL, settings.size()); + } } } + + onChanged(); } - onChanged(); }); } /** - * See {@link AppsFilterSnapshot#shouldFilterApplication(int, Object, PackageStateInternal, - * int)} + * Returns true if the calling package should not be able to see the target package, false if no + * filtering should be done. + * + * @param callingUid the uid of the caller attempting to access a package + * @param callingSetting the setting attempting to access a package or null if it could not be + * found + * @param targetPkgSetting the package being accessed + * @param userId the user in which this access is being attempted */ - @Override public boolean shouldFilterApplication(int callingUid, @Nullable Object callingSetting, PackageStateInternal targetPkgSetting, int userId) { if (DEBUG_TRACING) { @@ -1396,22 +1315,31 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable || callingAppId == targetPkgSetting.getAppId()) { return false; } - final boolean shouldUseCache; synchronized (mCacheLock) { - shouldUseCache = mShouldFilterCache.size() != 0; - } - if (shouldUseCache) { // use cache - if (!shouldFilterApplicationUsingCache(callingUid, targetPkgSetting.getAppId(), - userId)) { - return false; - } - } else { - if (!shouldFilterApplicationInternal( - callingUid, callingSetting, targetPkgSetting, userId)) { - return false; + if (mShouldFilterCache != null) { // use cache + final int callingIndex = mShouldFilterCache.indexOfKey(callingUid); + if (callingIndex < 0) { + Slog.wtf(TAG, "Encountered calling uid with no cached rules: " + + callingUid); + return true; + } + final int targetUid = UserHandle.getUid(userId, targetPkgSetting.getAppId()); + final int targetIndex = mShouldFilterCache.indexOfKey(targetUid); + if (targetIndex < 0) { + Slog.w(TAG, "Encountered calling -> target with no cached rules: " + + callingUid + " -> " + targetUid); + return true; + } + if (!mShouldFilterCache.valueAt(callingIndex, targetIndex)) { + return false; + } + } else { + if (!shouldFilterApplicationInternal( + callingUid, callingSetting, targetPkgSetting, userId)) { + return false; + } } } - if (DEBUG_LOGGING || mFeatureConfig.isLoggingEnabled(callingAppId)) { log(callingSetting, targetPkgSetting, "BLOCKED"); } @@ -1423,25 +1351,6 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable } } - private boolean shouldFilterApplicationUsingCache(int callingUid, int appId, int userId) { - synchronized (mCacheLock) { - final int callingIndex = mShouldFilterCache.indexOfKey(callingUid); - if (callingIndex < 0) { - Slog.wtf(TAG, "Encountered calling uid with no cached rules: " - + callingUid); - return true; - } - final int targetUid = UserHandle.getUid(userId, appId); - final int targetIndex = mShouldFilterCache.indexOfKey(targetUid); - if (targetIndex < 0) { - Slog.w(TAG, "Encountered calling -> target with no cached rules: " - + callingUid + " -> " + targetUid); - return true; - } - return mShouldFilterCache.valueAt(callingIndex, targetIndex); - } - } - private boolean shouldFilterApplicationInternal(int callingUid, Object callingSetting, PackageStateInternal targetPkgSetting, int targetUserId) { if (DEBUG_TRACING) { @@ -1528,10 +1437,10 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "requestsQueryAllPackages"); } if (callingPkgSetting != null) { - if (callingPkgSetting.getPkg() != null - && requestsQueryAllPackages(callingPkgSetting.getPkg())) { - return false; - } + if (callingPkgSetting.getPkg() != null + && requestsQueryAllPackages(callingPkgSetting.getPkg())) { + return false; + } } else { for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) { AndroidPackage pkg = callingSharedPkgSettings.valueAt(i).getPkg(); @@ -1560,147 +1469,142 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable return false; } - synchronized (mLock) { - try { - if (DEBUG_TRACING) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mForceQueryable"); - } - if (mForceQueryable.contains(targetAppId)) { - if (DEBUG_LOGGING) { - log(callingSetting, targetPkgSetting, "force queryable"); - } - return false; - } - } finally { - if (DEBUG_TRACING) { - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - } + try { + if (DEBUG_TRACING) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mForceQueryable"); } - try { - if (DEBUG_TRACING) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaPackage"); - } - if (mQueriesViaPackage.contains(callingAppId, targetAppId)) { - if (DEBUG_LOGGING) { - log(callingSetting, targetPkgSetting, "queries package"); - } - return false; - } - } finally { - if (DEBUG_TRACING) { - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + if (mForceQueryable.contains(targetAppId)) { + if (DEBUG_LOGGING) { + log(callingSetting, targetPkgSetting, "force queryable"); } + return false; } - try { - if (DEBUG_TRACING) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaComponent"); - } - if (mQueriesViaComponentRequireRecompute) { - mStateProvider.runWithState((settings, users) -> { - synchronized (mLock) { - recomputeComponentVisibility(settings); - } - }); - } - if (mQueriesViaComponent.contains(callingAppId, targetAppId)) { - if (DEBUG_LOGGING) { - log(callingSetting, targetPkgSetting, "queries component"); - } - return false; - } - } finally { - if (DEBUG_TRACING) { - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - } + } finally { + if (DEBUG_TRACING) { + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } + } + try { + if (DEBUG_TRACING) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaPackage"); + } + if (mQueriesViaPackage.contains(callingAppId, targetAppId)) { + if (DEBUG_LOGGING) { + log(callingSetting, targetPkgSetting, "queries package"); + } + return false; + } + } finally { + if (DEBUG_TRACING) { + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } + } + try { + if (DEBUG_TRACING) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaComponent"); + } + if (mQueriesViaComponentRequireRecompute) { + mStateProvider.runWithState((settings, users) -> { + recomputeComponentVisibility(settings); + }); + } + if (mQueriesViaComponent.contains(callingAppId, targetAppId)) { + if (DEBUG_LOGGING) { + log(callingSetting, targetPkgSetting, "queries component"); + } + return false; + } + } finally { + if (DEBUG_TRACING) { + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } + } - try { - if (DEBUG_TRACING) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mImplicitlyQueryable"); - } - final int targetUid = UserHandle.getUid(targetUserId, targetAppId); - if (mImplicitlyQueryable.contains(callingUid, targetUid)) { - if (DEBUG_LOGGING) { - log(callingSetting, targetPkgSetting, "implicitly queryable for user"); - } - return false; - } - } finally { - if (DEBUG_TRACING) { - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - } + try { + if (DEBUG_TRACING) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mImplicitlyQueryable"); } - - try { - if (DEBUG_TRACING) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mRetainedImplicitlyQueryable"); - } - final int targetUid = UserHandle.getUid(targetUserId, targetAppId); - if (mRetainedImplicitlyQueryable.contains(callingUid, targetUid)) { - if (DEBUG_LOGGING) { - log(callingSetting, targetPkgSetting, - "retained implicitly queryable for user"); - } - return false; - } - } finally { - if (DEBUG_TRACING) { - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + final int targetUid = UserHandle.getUid(targetUserId, targetAppId); + if (mImplicitlyQueryable.contains(callingUid, targetUid)) { + if (DEBUG_LOGGING) { + log(callingSetting, targetPkgSetting, "implicitly queryable for user"); } + return false; } + } finally { + if (DEBUG_TRACING) { + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } + } - try { - if (DEBUG_TRACING) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mOverlayReferenceMapper"); + try { + if (DEBUG_TRACING) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mRetainedImplicitlyQueryable"); + } + final int targetUid = UserHandle.getUid(targetUserId, targetAppId); + if (mRetainedImplicitlyQueryable.contains(callingUid, targetUid)) { + if (DEBUG_LOGGING) { + log(callingSetting, targetPkgSetting, + "retained implicitly queryable for user"); } - final String targetName = targetPkg.getPackageName(); - if (callingSharedPkgSettings != null) { - int size = callingSharedPkgSettings.size(); - for (int index = 0; index < size; index++) { - PackageStateInternal pkgSetting = callingSharedPkgSettings.valueAt( - index); - if (mOverlayReferenceMapper.isValidActor(targetName, - pkgSetting.getPackageName())) { - if (DEBUG_LOGGING) { - log(callingPkgSetting, targetPkgSetting, - "matches shared user of package that acts on target of " - + "overlay"); - } - return false; - } - } - } else { + return false; + } + } finally { + if (DEBUG_TRACING) { + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } + } + + try { + if (DEBUG_TRACING) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mOverlayReferenceMapper"); + } + final String targetName = targetPkg.getPackageName(); + if (callingSharedPkgSettings != null) { + int size = callingSharedPkgSettings.size(); + for (int index = 0; index < size; index++) { + PackageStateInternal pkgSetting = callingSharedPkgSettings.valueAt(index); if (mOverlayReferenceMapper.isValidActor(targetName, - callingPkgSetting.getPackageName())) { + pkgSetting.getPackageName())) { if (DEBUG_LOGGING) { log(callingPkgSetting, targetPkgSetting, - "acts on target of overlay"); + "matches shared user of package that acts on target of " + + "overlay"); } return false; } } - } finally { - if (DEBUG_TRACING) { - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - } - } - - try { - if (DEBUG_TRACING) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueryableViaUsesLibrary"); - } - if (mQueryableViaUsesLibrary.contains(callingAppId, targetAppId)) { + } else { + if (mOverlayReferenceMapper.isValidActor(targetName, + callingPkgSetting.getPackageName())) { if (DEBUG_LOGGING) { - log(callingSetting, targetPkgSetting, "queryable for library users"); + log(callingPkgSetting, targetPkgSetting, "acts on target of overlay"); } return false; } - } finally { - if (DEBUG_TRACING) { - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - } + } + } finally { + if (DEBUG_TRACING) { + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } } + + try { + if (DEBUG_TRACING) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueryableViaUsesLibrary"); + } + if (mQueryableViaUsesLibrary.contains(callingAppId, targetAppId)) { + if (DEBUG_LOGGING) { + log(callingSetting, targetPkgSetting, "queryable for library users"); + } + return false; + } + } finally { + if (DEBUG_TRACING) { + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } + } + return true; } finally { if (DEBUG_TRACING) { @@ -1709,11 +1613,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable } } - /** - * See {@link AppsFilterSnapshot#canQueryPackage(AndroidPackage, String)} - */ - @Override - public boolean canQueryPackage(@NonNull AndroidPackage querying, String potentialTarget) { + boolean canQueryPackage(@NonNull AndroidPackage querying, String potentialTarget) { int appId = UserHandle.getAppId(querying.getUid()); if (appId < Process.FIRST_APPLICATION_UID) { return true; @@ -1768,11 +1668,6 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable + targetPkgSetting + " " + description); } - /** - * See {@link AppsFilterSnapshot#dumpQueries(PrintWriter, Integer, DumpState, int[], - * QuadFunction)} - */ - @Override public void dumpQueries( PrintWriter pw, @Nullable Integer filteringAppId, DumpState dumpState, int[] users, QuadFunction getPackagesForUid) { @@ -1807,30 +1702,27 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable } } pw.println(" system apps queryable: " + mSystemAppsQueryable); - synchronized (mLock) { - dumpPackageSet(pw, filteringAppId, mForceQueryable.untrackedStorage(), - "forceQueryable", " ", expandPackages); - pw.println(" queries via package name:"); - dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, " ", expandPackages); - pw.println(" queries via component:"); - dumpQueriesMap(pw, filteringAppId, mQueriesViaComponent, " ", expandPackages); - pw.println(" queryable via interaction:"); - for (int user : users) { - pw.append(" User ").append(Integer.toString(user)).println(":"); - dumpQueriesMap(pw, - filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId), - mImplicitlyQueryable, " ", expandPackages); - dumpQueriesMap(pw, - filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId), - mRetainedImplicitlyQueryable, " ", expandPackages); - } - pw.println(" queryable via uses-library:"); - dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, " ", expandPackages); + dumpPackageSet(pw, filteringAppId, mForceQueryable, "forceQueryable", " ", expandPackages); + pw.println(" queries via package name:"); + dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, " ", expandPackages); + pw.println(" queries via component:"); + dumpQueriesMap(pw, filteringAppId, mQueriesViaComponent, " ", expandPackages); + pw.println(" queryable via interaction:"); + for (int user : users) { + pw.append(" User ").append(Integer.toString(user)).println(":"); + dumpQueriesMap(pw, + filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId), + mImplicitlyQueryable, " ", expandPackages); + dumpQueriesMap(pw, + filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId), + mRetainedImplicitlyQueryable, " ", expandPackages); } + pw.println(" queryable via uses-library:"); + dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, " ", expandPackages); } private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId, - WatchedSparseSetArray queriesMap, String spacing, + SparseSetArray queriesMap, String spacing, @Nullable ToString toString) { for (int i = 0; i < queriesMap.size(); i++) { Integer callingId = queriesMap.keyAt(i); @@ -1858,7 +1750,7 @@ public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable } private static void dumpPackageSet(PrintWriter pw, @Nullable T filteringId, - ArraySet targetPkgSet, String subTitle, String spacing, + Set targetPkgSet, String subTitle, String spacing, @Nullable ToString toString) { if (targetPkgSet != null && targetPkgSet.size() > 0 && (filteringId == null || targetPkgSet.contains(filteringId))) { diff --git a/services/core/java/com/android/server/pm/AppsFilterSnapshot.java b/services/core/java/com/android/server/pm/AppsFilterSnapshot.java deleted file mode 100644 index cb8c649ded00b..0000000000000 --- a/services/core/java/com/android/server/pm/AppsFilterSnapshot.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.pm; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.os.Process; -import android.util.ArrayMap; -import android.util.SparseArray; - -import com.android.internal.util.function.QuadFunction; -import com.android.server.pm.parsing.pkg.AndroidPackage; -import com.android.server.pm.pkg.PackageStateInternal; - -import java.io.PrintWriter; - -/** - * Read-only interface used by computer and snapshots to query the visibility of packages - */ -public interface AppsFilterSnapshot { - /** - * Fetches all app Ids that a given setting is currently visible to, per provided user. This - * only includes UIDs >= {@link Process#FIRST_APPLICATION_UID} as all other UIDs can already see - * all applications. - * - * If the setting is visible to all UIDs, null is returned. If an app is not visible to any - * applications, the int array will be empty. - * - * @param users the set of users that should be evaluated for this calculation - * @param existingSettings the set of all package settings that currently exist on device - * @return a SparseArray mapping userIds to a sorted int array of appIds that may view the - * provided setting or null if the app is visible to all and no allow list should be - * applied. - */ - SparseArray getVisibilityAllowList(PackageStateInternal setting, int[] users, - ArrayMap existingSettings); - - /** - * Returns true if the calling package should not be able to see the target package, false if no - * filtering should be done. - * - * @param callingUid the uid of the caller attempting to access a package - * @param callingSetting the setting attempting to access a package or null if it could not be - * found - * @param targetPkgSetting the package being accessed - * @param userId the user in which this access is being attempted - */ - boolean shouldFilterApplication(int callingUid, @Nullable Object callingSetting, - PackageStateInternal targetPkgSetting, int userId); - - /** - * Returns whether the querying package is allowed to see the target package. - * - * @param querying the querying package - * @param potentialTarget the package name of the target package - */ - boolean canQueryPackage(@NonNull AndroidPackage querying, String potentialTarget); - - /** - * Dump the packages that are queryable by the querying package. - * - * @param pw the output print writer - * @param filteringAppId the querying package's app ID - * @param dumpState the state of the dumping - * @param users the users for which the packages are installed - * @param getPackagesForUid the function that produces the package names for given uids - */ - void dumpQueries(PrintWriter pw, @Nullable Integer filteringAppId, DumpState dumpState, - int[] users, - QuadFunction getPackagesForUid); - -} diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java index 2e8bf6725e199..4abfd3404295a 100644 --- a/services/core/java/com/android/server/pm/ComputerEngine.java +++ b/services/core/java/com/android/server/pm/ComputerEngine.java @@ -348,7 +348,7 @@ public class ComputerEngine implements Computer { private final ResolveInfo mInstantAppInstallerInfo; private final InstantAppRegistry mInstantAppRegistry; private final ApplicationInfo mLocalAndroidApplication; - private final AppsFilterSnapshot mAppsFilter; + private final AppsFilter mAppsFilter; private final WatchedArrayMap mFrozenPackages; // Immutable service attribute diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 24febe16505ca..4c7243decb078 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -724,7 +724,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService } @Watched - final AppsFilterImpl mAppsFilter; + final AppsFilter mAppsFilter; final PackageParser2.Callback mPackageParserCallback; @@ -981,7 +981,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService public final InstantAppRegistry instantAppRegistry; public final ApplicationInfo androidApplication; public final String appPredictionServicePackage; - public final AppsFilterSnapshot appsFilter; + public final AppsFilter appsFilter; public final ComponentResolverApi componentResolver; public final PackageManagerService service; public final WatchedArrayMap frozenPackages; @@ -1433,8 +1433,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService RuntimePermissionsPersistence.createInstance(), i.getPermissionManagerServiceInternal(), domainVerificationService, lock), - (i, pm) -> AppsFilterImpl.create(i, - i.getLocalService(PackageManagerInternal.class)), + (i, pm) -> AppsFilter.create(i, i.getLocalService(PackageManagerInternal.class)), (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"), (i, pm) -> SystemConfig.getInstance(), (i, pm) -> new PackageDexOptimizer(i.getInstaller(), i.getInstallLock(), diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java b/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java index 396994b045144..a02237fa90ce0 100644 --- a/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java +++ b/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java @@ -99,7 +99,7 @@ public class PackageManagerServiceInjector { private final Singleton mUserManagerProducer; private final Singleton mSettingsProducer; - private final Singleton mAppsFilterProducer; + private final Singleton mAppsFilterProducer; private final Singleton mPlatformCompatProducer; private final Singleton mSystemConfigProducer; @@ -148,7 +148,7 @@ public class PackageManagerServiceInjector { Producer permissionManagerServiceProducer, Producer userManagerProducer, Producer settingsProducer, - Producer appsFilterProducer, + Producer appsFilterProducer, Producer platformCompatProducer, Producer systemConfigProducer, Producer packageDexOptimizerProducer, @@ -282,7 +282,7 @@ public class PackageManagerServiceInjector { return mSettingsProducer.get(this, mPackageManager); } - public AppsFilterImpl getAppsFilter() { + public AppsFilter getAppsFilter() { return mAppsFilterProducer.get(this, mPackageManager); } diff --git a/services/core/java/com/android/server/utils/WatchedArrayList.java b/services/core/java/com/android/server/utils/WatchedArrayList.java index 6059f9675e343..bb0ba1329d864 100644 --- a/services/core/java/com/android/server/utils/WatchedArrayList.java +++ b/services/core/java/com/android/server/utils/WatchedArrayList.java @@ -272,13 +272,6 @@ public class WatchedArrayList extends WatchableImpl return mStorage.contains(o); } - /** - * Return true if all the objects in the given collection are in this array list. - */ - public boolean containsAll(Collection c) { - return mStorage.containsAll(c); - } - /** * Ensure capacity. */ diff --git a/services/core/java/com/android/server/utils/WatchedSparseBooleanMatrix.java b/services/core/java/com/android/server/utils/WatchedSparseBooleanMatrix.java index c43e7f9babe62..25ae00004b3e1 100644 --- a/services/core/java/com/android/server/utils/WatchedSparseBooleanMatrix.java +++ b/services/core/java/com/android/server/utils/WatchedSparseBooleanMatrix.java @@ -18,7 +18,6 @@ package com.android.server.utils; import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; -import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; @@ -169,19 +168,12 @@ public class WatchedSparseBooleanMatrix extends WatchableImpl implements Snappab * A copy constructor that can be used for snapshotting. */ private WatchedSparseBooleanMatrix(WatchedSparseBooleanMatrix r) { - copyFrom(r); - } - - /** - * Copy from src to this. - */ - public void copyFrom(@NonNull WatchedSparseBooleanMatrix src) { - mOrder = src.mOrder; - mSize = src.mSize; - mKeys = src.mKeys.clone(); - mMap = src.mMap.clone(); - mInUse = src.mInUse.clone(); - mValues = src.mValues.clone(); + mOrder = r.mOrder; + mSize = r.mSize; + mKeys = r.mKeys.clone(); + mMap = r.mMap.clone(); + mInUse = r.mInUse.clone(); + mValues = r.mValues.clone(); } /** diff --git a/services/core/java/com/android/server/utils/WatchedSparseSetArray.java b/services/core/java/com/android/server/utils/WatchedSparseSetArray.java deleted file mode 100644 index 05db12e49a13d..0000000000000 --- a/services/core/java/com/android/server/utils/WatchedSparseSetArray.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.utils; - -import android.annotation.NonNull; -import android.util.ArraySet; -import android.util.SparseSetArray; - - -/** - * A watched variant of SparseSetArray. Changes to the array are notified to - * registered {@link Watcher}s. - * @param The element type, stored in the SparseSetArray. - */ -public class WatchedSparseSetArray extends WatchableImpl implements Snappable { - // The storage - private final SparseSetArray mStorage; - - // A private convenience function - private void onChanged() { - dispatchChange(this); - } - - public WatchedSparseSetArray() { - mStorage = new SparseSetArray(); - } - - /** - * Creates a new WatchedSparseSetArray from an existing WatchedSparseSetArray and copy its data - */ - public WatchedSparseSetArray(@NonNull WatchedSparseSetArray watchedSparseSetArray) { - mStorage = new SparseSetArray(watchedSparseSetArray.untrackedStorage()); - } - - /** - * Return the underlying storage. This breaks the wrapper but is necessary when - * passing the array to distant methods. - */ - public SparseSetArray untrackedStorage() { - return mStorage; - } - - /** - * Add a value for key n. - * @return FALSE when the value already existed for the given key, TRUE otherwise. - */ - public boolean add(int n, T value) { - final boolean res = mStorage.add(n, value); - onChanged(); - return res; - } - - /** - * Removes all mappings from this SparseSetArray. - */ - public void clear() { - mStorage.clear(); - onChanged(); - } - - /** - * @return whether the value exists for the key n. - */ - public boolean contains(int n, T value) { - return mStorage.contains(n, value); - } - - /** - * @return the set of items of key n - */ - public ArraySet get(int n) { - return mStorage.get(n); - } - - /** - * Remove a value for key n. - * @return TRUE when the value existed for the given key and removed, FALSE otherwise. - */ - public boolean remove(int n, T value) { - if (mStorage.remove(n, value)) { - onChanged(); - return true; - } - return false; - } - - /** - * Remove all values for key n. - */ - public void remove(int n) { - mStorage.remove(n); - onChanged(); - } - - /** - * Return the size of the SparseSetArray. - */ - public int size() { - return mStorage.size(); - } - - /** - * Return the key stored at the given index. - */ - public int keyAt(int index) { - return mStorage.keyAt(index); - } - - /** - * Return the size of the array at the given index. - */ - public int sizeAt(int index) { - return mStorage.sizeAt(index); - } - - /** - * Return the value in the SetArray at the given key index and value index. - */ - public T valueAt(int intIndex, int valueIndex) { - return (T) mStorage.valueAt(intIndex, valueIndex); - } - - @NonNull - @Override - public Object snapshot() { - WatchedSparseSetArray l = new WatchedSparseSetArray(this); - l.seal(); - return l; - } - - /** - * Make a snapshot of the argument. Note that is immutable when the - * method returns. must be empty when the function is called. - * @param r The source array, which is copied into - */ - public void snapshot(@NonNull WatchedSparseSetArray r) { - snapshot(this, r); - } - - /** - * Make the destination a copy of the source. If the element is a subclass of Snapper then the - * copy contains snapshots of the elements. Otherwise the copy contains references to the - * elements. The destination must be initially empty. Upon return, the destination is - * immutable. - * @param dst The destination array. It must be empty. - * @param src The source array. It is not modified. - */ - public static void snapshot(@NonNull WatchedSparseSetArray dst, - @NonNull WatchedSparseSetArray src) { - if (dst.size() != 0) { - throw new IllegalArgumentException("snapshot destination is not empty"); - } - final int arraySize = src.size(); - for (int i = 0; i < arraySize; i++) { - final ArraySet set = src.get(i); - final int setSize = set.size(); - for (int j = 0; j < setSize; j++) { - dst.add(src.keyAt(i), set.valueAt(j)); - } - } - dst.seal(); - } -} diff --git a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt index 7b152247eb9cc..7017440a86bbd 100644 --- a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt +++ b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt @@ -34,6 +34,7 @@ import com.android.server.pm.test.override.PackageManagerComponentLabelIconOverr import com.android.server.testutils.TestHandler import com.android.server.testutils.mock import com.android.server.testutils.mockThrowOnUnmocked +import com.android.server.testutils.spy import com.android.server.testutils.whenever import com.android.server.wm.ActivityTaskManagerInternal import com.google.common.truth.Truth.assertThat @@ -45,9 +46,13 @@ import org.junit.runner.RunWith import org.junit.runners.Parameterized import org.mockito.Mockito.any import org.mockito.Mockito.anyInt +import org.mockito.Mockito.clearInvocations +import org.mockito.Mockito.doAnswer import org.mockito.Mockito.doReturn import org.mockito.Mockito.intThat +import org.mockito.Mockito.never import org.mockito.Mockito.same +import org.mockito.Mockito.verify import org.testng.Assert.assertThrows import java.io.File import java.util.UUID @@ -360,7 +365,7 @@ class PackageManagerComponentLabelIconOverrideTest { val mockActivityTaskManager: ActivityTaskManagerInternal = mockThrowOnUnmocked { whenever(this.isCallerRecents(anyInt())) { false } } - val mockAppsFilter: AppsFilterImpl = mockThrowOnUnmocked { + val mockAppsFilter: AppsFilter = mockThrowOnUnmocked { whenever(this.shouldFilterApplication(anyInt(), any(), any(), anyInt())) { false } whenever(this.snapshot()) { this@mockThrowOnUnmocked } diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt index c3ffed652b35b..cb9f003b6e3e7 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt +++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt @@ -194,7 +194,7 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) { val packageParser: PackageParser2 = mock() val keySetManagerService: KeySetManagerService = mock() val packageAbiHelper: PackageAbiHelper = mock() - val appsFilter: AppsFilterImpl = mock { + val appsFilter: AppsFilter = mock { whenever(snapshot()) { this@mock } } val dexManager: DexManager = mock() diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java similarity index 87% rename from services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java rename to services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java index d8f4349b95bfc..b72b8d2ec6e8d 100644 --- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java @@ -77,7 +77,7 @@ import java.util.concurrent.Executor; @Presubmit @RunWith(JUnit4.class) -public class AppsFilterImplTest { +public class AppsFilterTest { private static final int DUMMY_CALLING_APPID = 10345; private static final int DUMMY_TARGET_APPID = 10556; @@ -98,9 +98,9 @@ public class AppsFilterImplTest { } @Mock - AppsFilterImpl.FeatureConfig mFeatureConfigMock; + AppsFilter.FeatureConfig mFeatureConfigMock; @Mock - AppsFilterImpl.StateProvider mStateProvider; + AppsFilter.StateProvider mStateProvider; @Mock Executor mMockExecutor; @Mock @@ -204,11 +204,11 @@ public class AppsFilterImplTest { MockitoAnnotations.initMocks(this); doAnswer(invocation -> { - ((AppsFilterImpl.StateProvider.CurrentStateCallback) invocation.getArgument(0)) + ((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0)) .currentState(mExisting, USER_INFO_LIST); return new Object(); }).when(mStateProvider) - .runWithState(any(AppsFilterImpl.StateProvider.CurrentStateCallback.class)); + .runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class)); doAnswer(invocation -> { ((Runnable) invocation.getArgument(0)).run(); @@ -218,14 +218,14 @@ public class AppsFilterImplTest { when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true); when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))).thenAnswer( (Answer) invocation -> - ((AndroidPackage) invocation.getArgument(SYSTEM_USER)).getTargetSdkVersion() + ((AndroidPackage)invocation.getArgument(SYSTEM_USER)).getTargetSdkVersion() >= Build.VERSION_CODES.R); } @Test public void testSystemReadyPropogates() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -236,8 +236,8 @@ public class AppsFilterImplTest { @Test public void testQueriesAction_FilterMatches() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -259,8 +259,8 @@ public class AppsFilterImplTest { } @Test public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -308,8 +308,8 @@ public class AppsFilterImplTest { @Test public void testQueriesProvider_FilterMatches() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -333,8 +333,8 @@ public class AppsFilterImplTest { @Test public void testOnUserUpdated_FilterMatches() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); @@ -356,11 +356,11 @@ public class AppsFilterImplTest { // adds new user doAnswer(invocation -> { - ((AppsFilterImpl.StateProvider.CurrentStateCallback) invocation.getArgument(0)) + ((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0)) .currentState(mExisting, USER_INFO_LIST_WITH_ADDED); return new Object(); }).when(mStateProvider) - .runWithState(any(AppsFilterImpl.StateProvider.CurrentStateCallback.class)); + .runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class)); appsFilter.onUserCreated(ADDED_USER); for (int subjectUserId : USER_ARRAY_WITH_ADDED) { @@ -373,11 +373,11 @@ public class AppsFilterImplTest { // delete user doAnswer(invocation -> { - ((AppsFilterImpl.StateProvider.CurrentStateCallback) invocation.getArgument(0)) + ((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0)) .currentState(mExisting, USER_INFO_LIST); return new Object(); }).when(mStateProvider) - .runWithState(any(AppsFilterImpl.StateProvider.CurrentStateCallback.class)); + .runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class)); appsFilter.onUserDeleted(ADDED_USER); for (int subjectUserId : USER_ARRAY) { @@ -391,8 +391,8 @@ public class AppsFilterImplTest { @Test public void testQueriesDifferentProvider_Filters() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -416,8 +416,8 @@ public class AppsFilterImplTest { @Test public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -435,8 +435,8 @@ public class AppsFilterImplTest { @Test public void testQueriesAction_NoMatchingAction_Filters() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -452,8 +452,8 @@ public class AppsFilterImplTest { @Test public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -473,8 +473,8 @@ public class AppsFilterImplTest { @Test public void testNoQueries_Filters() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -490,7 +490,7 @@ public class AppsFilterImplTest { @Test public void testNoUsesLibrary_Filters() throws Exception { - final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock, + final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, mMockExecutor, mMockPmInternal); @@ -516,7 +516,7 @@ public class AppsFilterImplTest { @Test public void testUsesLibrary_DoesntFilter() throws Exception { - final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock, + final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, mMockExecutor, mMockPmInternal); @@ -543,7 +543,7 @@ public class AppsFilterImplTest { @Test public void testUsesOptionalLibrary_DoesntFilter() throws Exception { - final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock, + final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, mMockExecutor, mMockPmInternal); @@ -570,7 +570,7 @@ public class AppsFilterImplTest { @Test public void testUsesLibrary_ShareUid_DoesntFilter() throws Exception { - final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock, + final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, mMockExecutor, mMockPmInternal); @@ -602,8 +602,8 @@ public class AppsFilterImplTest { @Test public void testForceQueryable_SystemDoesntFilter() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -621,8 +621,8 @@ public class AppsFilterImplTest { @Test public void testForceQueryable_NonSystemFilters() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -638,10 +638,9 @@ public class AppsFilterImplTest { @Test public void testForceQueryableByDevice_SystemCaller_DoesntFilter() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, - new String[]{"com.some.package"}, false, null, - mMockExecutor, mMockPmInternal); + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"}, + false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -658,8 +657,8 @@ public class AppsFilterImplTest { @Test public void testSystemSignedTarget_DoesntFilter() throws CertificateException { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); appsFilter.onSystemReady(); @@ -687,10 +686,9 @@ public class AppsFilterImplTest { @Test public void testForceQueryableByDevice_NonSystemCaller_Filters() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, - new String[]{"com.some.package"}, false, null, - mMockExecutor, mMockPmInternal); + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"}, + false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -706,8 +704,8 @@ public class AppsFilterImplTest { @Test public void testSystemQueryable_DoesntFilter() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, true /* system force queryable */, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); @@ -725,8 +723,8 @@ public class AppsFilterImplTest { @Test public void testQueriesPackage_DoesntFilter() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -744,8 +742,8 @@ public class AppsFilterImplTest { public void testNoQueries_FeatureOff_DoesntFilter() throws Exception { when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))) .thenReturn(false); - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -761,8 +759,8 @@ public class AppsFilterImplTest { @Test public void testSystemUid_DoesntFilter() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -777,8 +775,8 @@ public class AppsFilterImplTest { @Test public void testSystemUidSecondaryUser_DoesntFilter() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -794,8 +792,8 @@ public class AppsFilterImplTest { @Test public void testNonSystemUid_NoCallingSetting_Filters() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -809,8 +807,8 @@ public class AppsFilterImplTest { @Test public void testNoTargetPackage_filters() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -840,7 +838,7 @@ public class AppsFilterImplTest { .setOverlayTargetOverlayableName("overlayableName"); ParsingPackage actor = pkg("com.some.package.actor"); - final AppsFilterImpl appsFilter = new AppsFilterImpl( + final AppsFilter appsFilter = new AppsFilter( mStateProvider, mFeatureConfigMock, new String[]{}, @@ -935,7 +933,7 @@ public class AppsFilterImplTest { when(mMockPmInternal.getSharedUserPackages(any(Integer.class))).thenReturn( actorSharedSettingPackages ); - final AppsFilterImpl appsFilter = new AppsFilterImpl( + final AppsFilter appsFilter = new AppsFilter( mStateProvider, mFeatureConfigMock, new String[]{}, @@ -987,8 +985,8 @@ public class AppsFilterImplTest { @Test public void testInitiatingApp_DoesntFilter() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -1005,8 +1003,8 @@ public class AppsFilterImplTest { @Test public void testUninstalledInitiatingApp_Filters() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -1023,8 +1021,8 @@ public class AppsFilterImplTest { @Test public void testOriginatingApp_Filters() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -1048,8 +1046,8 @@ public class AppsFilterImplTest { @Test public void testInstallingApp_DoesntFilter() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -1073,8 +1071,8 @@ public class AppsFilterImplTest { @Test public void testInstrumentation_DoesntFilter() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -1102,8 +1100,8 @@ public class AppsFilterImplTest { @Test public void testWhoCanSee() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -1175,8 +1173,8 @@ public class AppsFilterImplTest { @Test public void testOnChangeReport() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -1248,8 +1246,8 @@ public class AppsFilterImplTest { @Test public void testOnChangeReportedFilter() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -1272,53 +1270,6 @@ public class AppsFilterImplTest { watcher.verifyNoChangeReported("shouldFilterApplication"); } - @Test - public void testAppsFilterRead() throws Exception { - final AppsFilterImpl appsFilter = - new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor, mMockPmInternal); - simulateAddBasicAndroid(appsFilter); - appsFilter.onSystemReady(); - - PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"), - DUMMY_TARGET_APPID); - PackageSetting instrumentation = simulateAddPackage(appsFilter, - pkgWithInstrumentation("com.some.other.package", "com.some.package"), - DUMMY_CALLING_APPID); - - final int hasProviderAppId = Process.FIRST_APPLICATION_UID + 1; - final int queriesProviderAppId = Process.FIRST_APPLICATION_UID + 2; - PackageSetting queriesProvider = simulateAddPackage(appsFilter, - pkgQueriesProvider("com.yet.some.other.package", "com.some.authority"), - queriesProviderAppId); - appsFilter.grantImplicitAccess( - hasProviderAppId, queriesProviderAppId, false /* retainOnUpdate */); - - AppsFilterSnapshot snapshot = appsFilter.snapshot(); - assertFalse( - snapshot.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target, - SYSTEM_USER)); - assertFalse( - snapshot.shouldFilterApplication(DUMMY_TARGET_APPID, target, instrumentation, - SYSTEM_USER)); - - SparseArray queriesProviderFilter = - snapshot.getVisibilityAllowList(queriesProvider, USER_ARRAY, mExisting); - assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)), contains(queriesProviderAppId)); - assertTrue(snapshot.canQueryPackage(instrumentation.getPkg(), - target.getPackageName())); - - // New changes don't affect the snapshot - appsFilter.removePackage(target, false); - assertTrue( - appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target, - SYSTEM_USER)); - assertFalse( - snapshot.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target, - SYSTEM_USER)); - - } - private List toList(int[] array) { ArrayList ret = new ArrayList<>(array.length); for (int i = 0; i < array.length; i++) { @@ -1331,7 +1282,7 @@ public class AppsFilterImplTest { PackageSettingBuilder withBuilder(PackageSettingBuilder builder); } - private void simulateAddBasicAndroid(AppsFilterImpl appsFilter) throws Exception { + private void simulateAddBasicAndroid(AppsFilter appsFilter) throws Exception { final Signature frameworkSignature = Mockito.mock(Signature.class); final SigningDetails frameworkSigningDetails = new SigningDetails(new Signature[]{frameworkSignature}, 1); @@ -1340,17 +1291,17 @@ public class AppsFilterImplTest { b -> b.setSigningDetails(frameworkSigningDetails)); } - private PackageSetting simulateAddPackage(AppsFilterImpl filter, + private PackageSetting simulateAddPackage(AppsFilter filter, ParsingPackage newPkgBuilder, int appId) { return simulateAddPackage(filter, newPkgBuilder, appId, null /*settingBuilder*/); } - private PackageSetting simulateAddPackage(AppsFilterImpl filter, + private PackageSetting simulateAddPackage(AppsFilter filter, ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action) { return simulateAddPackage(filter, newPkgBuilder, appId, action, null /*sharedUserSetting*/); } - private PackageSetting simulateAddPackage(AppsFilterImpl filter, + private PackageSetting simulateAddPackage(AppsFilter filter, ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action, @Nullable SharedUserSetting sharedUserSetting) { final PackageSetting setting = @@ -1373,7 +1324,7 @@ public class AppsFilterImplTest { return setting; } - private void simulateAddPackage(PackageSetting setting, AppsFilterImpl filter, + private void simulateAddPackage(PackageSetting setting, AppsFilter filter, @Nullable SharedUserSetting sharedUserSetting) { mExisting.put(setting.getPackageName(), setting); if (sharedUserSetting != null) { diff --git a/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java b/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java index 37c95f735d893..4ed4c236535fc 100644 --- a/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java +++ b/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java @@ -17,7 +17,6 @@ package com.android.server.utils; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -861,54 +860,6 @@ public class WatcherTest { } } - @Test - public void testWatchedSparseSetArray() { - final String name = "WatchedSparseSetArray"; - WatchableTester tester; - - // Test WatchedSparseSetArray - WatchedSparseSetArray array = new WatchedSparseSetArray(); - tester = new WatchableTester(array, name); - tester.verify(0, "Initial array - no registration"); - array.add(INDEX_A, 1); - tester.verify(0, "Updates with no registration"); - tester.register(); - tester.verify(0, "Updates with no registration"); - array.add(INDEX_B, 2); - tester.verify(1, "Updates with registration"); - array.add(INDEX_B, 4); - array.add(INDEX_C, 5); - tester.verify(3, "Updates with registration"); - // Special methods - assertTrue(array.remove(INDEX_C, 5)); - tester.verify(4, "Removed 5 from key 3"); - array.remove(INDEX_B); - tester.verify(5, "Removed everything for key 2"); - - // Snapshot - { - WatchedSparseSetArray arraySnap = (WatchedSparseSetArray) array.snapshot(); - tester.verify(5, "Generate snapshot"); - // Verify that the snapshot is a proper copy of the source. - assertEquals("WatchedSparseSetArray snap same size", - array.size(), arraySnap.size()); - for (int i = 0; i < array.size(); i++) { - ArraySet set = array.get(array.keyAt(i)); - ArraySet setSnap = arraySnap.get(arraySnap.keyAt(i)); - assertNotNull(set); - assertTrue(set.equals(setSnap)); - } - array.add(INDEX_D, 9); - tester.verify(6, "Tick after snapshot"); - // Verify that the array is sealed - verifySealed(name, ()->arraySnap.add(INDEX_D, 10)); - assertTrue(!array.isSealed()); - assertTrue(arraySnap.isSealed()); - } - array.clear(); - tester.verify(7, "Cleared all entries"); - } - private static class IndexGenerator { private final int mSeed; private final Random mRandom; @@ -1133,18 +1084,6 @@ public class WatcherTest { assertEquals(a.equals(s), true); a.put(rowIndex, colIndex, !a.get(rowIndex, colIndex)); assertEquals(a.equals(s), false); - - // Verify copy-in/out - { - final String msg = name + " copy"; - WatchedSparseBooleanMatrix copy = new WatchedSparseBooleanMatrix(); - copy.copyFrom(matrix); - final int end = copy.size(); - assertTrue(msg + " size mismatch " + end + " " + matrix.size(), end == matrix.size()); - for (int i = 0; i < end; i++) { - assertEquals(copy.keyAt(i), keys[i]); - } - } } @Test