diff options
| author | 2022-05-16 15:48:37 +0000 | |
|---|---|---|
| committer | 2022-05-16 15:48:37 +0000 | |
| commit | cd1a10a216eeb9bcae0c6899df8d3c368284c5bc (patch) | |
| tree | 98686f66ef70c599519c6259041019a79b2d660a | |
| parent | 8a91edd4a35353e1868665722c313a1022269396 (diff) | |
| parent | b9b16f3a01c99c7368abb5e85d1707e7c19ed447 (diff) | |
Merge "[AppsFilter] fix cache lock and rebuild cache if needed" into tm-dev
5 files changed, 338 insertions, 174 deletions
diff --git a/services/core/java/com/android/server/pm/AppsFilterBase.java b/services/core/java/com/android/server/pm/AppsFilterBase.java index 7004c7363122..78e7b0a17764 100644 --- a/services/core/java/com/android/server/pm/AppsFilterBase.java +++ b/services/core/java/com/android/server/pm/AppsFilterBase.java @@ -26,6 +26,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.pm.SigningDetails; import android.os.Binder; +import android.os.Handler; import android.os.Process; import android.os.Trace; import android.os.UserHandle; @@ -53,7 +54,7 @@ import java.io.PrintWriter; import java.util.Arrays; import java.util.Collection; import java.util.Objects; -import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; /** * AppsFilter is the entity responsible for filtering visibility between apps based on declarations @@ -68,6 +69,11 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { protected static final boolean DEBUG_LOGGING = false; public static final boolean DEBUG_TRACING = false; + // Allow some time for cache rebuilds. + protected static final int CACHE_REBUILD_DELAY_MIN_MS = 10000; + // With each new rebuild the delay doubles until it reaches max delay. + protected static final int CACHE_REBUILD_DELAY_MAX_MS = 10000; + /** * This contains a list of app UIDs that are implicitly queryable because another app explicitly * interacted with it. For example, if application A starts a service in application B, @@ -122,10 +128,10 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { protected SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesLibrarySnapshot; /** - * Executor for running reasonably short background tasks such as building the initial + * Handler for running reasonably short background tasks such as building the initial * visibility cache. */ - protected Executor mBackgroundExecutor; + protected Handler mBackgroundHandler; /** * Pending full recompute of mQueriesViaComponent. Occurs when a package adds a new set of @@ -133,7 +139,7 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { * computationally expensive recomputing. * Full recompute is done lazily at the point when we use mQueriesViaComponent to filter apps. */ - protected boolean mQueriesViaComponentRequireRecompute = false; + protected AtomicBoolean mQueriesViaComponentRequireRecompute = new AtomicBoolean(false); /** * A set of App IDs that are always queryable by any package, regardless of their manifest @@ -173,7 +179,7 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { * {@link #shouldFilterApplicationInternal(PackageDataSnapshot, 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 #mSystemReady} is true. + * initial scam and is empty until {@link #mCacheReady} is true. */ @NonNull @Watched @@ -181,7 +187,11 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { @NonNull protected SnapshotCache<WatchedSparseBooleanMatrix> mShouldFilterCacheSnapshot; - protected volatile boolean mSystemReady = false; + protected volatile boolean mCacheReady = false; + + protected static final boolean CACHE_VALID = true; + protected static final boolean CACHE_INVALID = false; + protected AtomicBoolean mCacheValid = new AtomicBoolean(CACHE_INVALID); protected boolean isForceQueryable(int callingAppId) { return mForceQueryable.contains(callingAppId); @@ -312,7 +322,7 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { || callingAppId == targetPkgSetting.getAppId()) { return false; } - if (mSystemReady) { // use cache + if (mCacheReady) { // use cache if (!shouldFilterApplicationUsingCache(callingUid, targetPkgSetting.getAppId(), userId)) { @@ -506,7 +516,7 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { if (DEBUG_TRACING) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaComponent"); } - if (!mQueriesViaComponentRequireRecompute) { + if (!mQueriesViaComponentRequireRecompute.get()) { if (isQueryableViaComponent(callingAppId, targetAppId)) { if (DEBUG_LOGGING) { log(callingSetting, targetPkgSetting, "queries component"); @@ -702,17 +712,34 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { } } pw.println(" system apps queryable: " + mSystemAppsQueryable); - dumpQueryables(pw, filteringAppId, users, expandPackages); + dumpForceQueryable(pw, filteringAppId, expandPackages); + dumpQueriesViaPackage(pw, filteringAppId, expandPackages); + dumpQueriesViaComponent(pw, filteringAppId, expandPackages); + dumpQueriesViaImplicitlyQueryable(pw, filteringAppId, users, expandPackages); + dumpQueriesViaUsesLibrary(pw, filteringAppId, expandPackages); } - protected void dumpQueryables(PrintWriter pw, @Nullable Integer filteringAppId, int[] users, + protected void dumpForceQueryable(PrintWriter pw, @Nullable Integer filteringAppId, ToString<Integer> expandPackages) { + pw.println(" queries via forceQueryable:"); dumpPackageSet(pw, filteringAppId, mForceQueryable.untrackedStorage(), "forceQueryable", " ", expandPackages); + } + + protected void dumpQueriesViaPackage(PrintWriter pw, @Nullable Integer filteringAppId, + ToString<Integer> expandPackages) { pw.println(" queries via package name:"); dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, " ", expandPackages); + } + + protected void dumpQueriesViaComponent(PrintWriter pw, @Nullable Integer filteringAppId, + ToString<Integer> expandPackages) { pw.println(" queries via component:"); dumpQueriesMap(pw, filteringAppId, mQueriesViaComponent, " ", expandPackages); + } + + protected void dumpQueriesViaImplicitlyQueryable(PrintWriter pw, + @Nullable Integer filteringAppId, int[] users, ToString<Integer> expandPackages) { pw.println(" queryable via interaction:"); for (int user : users) { pw.append(" User ").append(Integer.toString(user)).println(":"); @@ -723,6 +750,10 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId), mRetainedImplicitlyQueryable, " ", expandPackages); } + } + + protected void dumpQueriesViaUsesLibrary(PrintWriter pw, @Nullable Integer filteringAppId, + ToString<Integer> expandPackages) { pw.println(" queryable via uses-library:"); dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, " ", expandPackages); diff --git a/services/core/java/com/android/server/pm/AppsFilterImpl.java b/services/core/java/com/android/server/pm/AppsFilterImpl.java index 952711db1735..9fddc76b78c3 100644 --- a/services/core/java/com/android/server/pm/AppsFilterImpl.java +++ b/services/core/java/com/android/server/pm/AppsFilterImpl.java @@ -35,6 +35,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.SigningDetails; import android.content.pm.UserInfo; +import android.os.Handler; import android.os.Trace; import android.os.UserHandle; import android.provider.DeviceConfig; @@ -70,7 +71,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Objects; -import java.util.concurrent.Executor; /** * Implementation of the methods that update the internal structures of AppsFilter. Because of the @@ -83,7 +83,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, * A cached snapshot. */ @NonNull - private SnapshotCache<AppsFilterSnapshot> mSnapshot; + private final SnapshotCache<AppsFilterSnapshot> mSnapshot; /** * Watchable machinery @@ -142,18 +142,24 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, dispatchChange(this); } + private void invalidateCache(String reason) { + if (mCacheValid.compareAndSet(CACHE_VALID, CACHE_INVALID)) { + Slog.i(TAG, "Invalidating cache: " + reason); + } + } + @VisibleForTesting(visibility = PRIVATE) AppsFilterImpl(FeatureConfig featureConfig, String[] forceQueryableList, boolean systemAppsQueryable, @Nullable OverlayReferenceMapper.Provider overlayProvider, - Executor backgroundExecutor) { + Handler backgroundHandler) { mFeatureConfig = featureConfig; mForceQueryableByDevicePackageNames = forceQueryableList; mSystemAppsQueryable = systemAppsQueryable; mOverlayReferenceMapper = new OverlayReferenceMapper(true /*deferRebuild*/, overlayProvider); - mBackgroundExecutor = backgroundExecutor; + mBackgroundHandler = backgroundHandler; mShouldFilterCache = new WatchedSparseBooleanMatrix(); mShouldFilterCacheSnapshot = new SnapshotCache.Auto<>( mShouldFilterCache, mShouldFilterCache, "AppsFilter.mShouldFilterCache"); @@ -371,7 +377,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, } AppsFilterImpl appsFilter = new AppsFilterImpl(featureConfig, forcedQueryablePackageNames, forceSystemAppsQueryable, null, - injector.getBackgroundExecutor()); + injector.getBackgroundHandler()); featureConfig.setAppsFilter(appsFilter); return appsFilter; } @@ -394,7 +400,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, return false; } final boolean changed; - synchronized (mLock) { + synchronized (mImplicitlyQueryableLock) { changed = retainOnUpdate ? mRetainedImplicitlyQueryable.add(recipientUid, visibleUid) : mImplicitlyQueryable.add(recipientUid, visibleUid); @@ -404,12 +410,13 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, + recipientUid + " -> " + visibleUid); } - if (mSystemReady) { + if (mCacheReady) { synchronized (mCacheLock) { - // update the cache in a one-off manner since we've got all the information we - // need. + // Update the cache in a one-off manner since we've got all the information we need. mShouldFilterCache.put(recipientUid, visibleUid, false); } + } else if (changed) { + invalidateCache("grantImplicitAccess: " + recipientUid + " -> " + visibleUid); } onChanged(); return changed; @@ -420,7 +427,6 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, mFeatureConfig.onSystemReady(); updateEntireShouldFilterCacheAsync(pmInternal); - mSystemReady = true; } /** @@ -444,7 +450,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, final UserInfo[] users = snapshot.getUserInfos(); final ArraySet<String> additionalChangedPackages = addPackageInternal(newPkgSetting, settings); - if (mSystemReady) { + if (mCacheReady) { synchronized (mCacheLock) { updateShouldFilterCacheForPackage(snapshot, null, newPkgSetting, settings, users, USER_ALL, settings.size()); @@ -463,7 +469,9 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, } } } - } // else, rebuild entire cache when system is ready + } else { + invalidateCache("addPackage: " + newPkgSetting.getPackageName()); + } } finally { onChanged(); if (DEBUG_TRACING) { @@ -486,7 +494,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, // packages for signature matches for (PackageStateInternal setting : existingSettings.values()) { if (isSystemSigned(mSystemSigningDetails, setting)) { - synchronized (mLock) { + synchronized (mForceQueryableLock) { mForceQueryable.add(setting.getAppId()); } } @@ -498,13 +506,18 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, return null; } - synchronized (mLock) { - if (mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts())) { - mQueriesViaComponentRequireRecompute = true; - } + final boolean protectedBroadcastsChanged; + synchronized (mProtectedBroadcastsLock) { + protectedBroadcastsChanged = + mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts()); + } + if (protectedBroadcastsChanged) { + mQueriesViaComponentRequireRecompute.set(true); + } - final boolean newIsForceQueryable = - mForceQueryable.contains(newPkgSetting.getAppId()) + final boolean newIsForceQueryable; + synchronized (mForceQueryableLock) { + newIsForceQueryable = mForceQueryable.contains(newPkgSetting.getAppId()) /* shared user that is already force queryable */ || newPkgSetting.isForceQueryableOverride() /* adb override */ || (newPkgSetting.isSystem() && (mSystemAppsQueryable @@ -516,58 +529,77 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, && 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; - } - 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)) { + 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.get() + && canQueryViaComponents(existingPkg, newPkg, mProtectedBroadcasts)) { + synchronized (mQueriesViaComponentLock) { mQueriesViaComponent.add(existingSetting.getAppId(), newPkgSetting.getAppId()); } - if (canQueryViaPackage(existingPkg, newPkg) - || canQueryAsInstaller(existingSetting, newPkg)) { + } + if (canQueryViaPackage(existingPkg, newPkg) + || canQueryAsInstaller(existingSetting, newPkg)) { + synchronized (mQueriesViaPackageLock) { mQueriesViaPackage.add(existingSetting.getAppId(), newPkgSetting.getAppId()); } - if (canQueryViaUsesLibrary(existingPkg, newPkg)) { + } + if (canQueryViaUsesLibrary(existingPkg, newPkg)) { + synchronized (mQueryableViaUsesLibraryLock) { 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)) { + } + final boolean existingIsForceQueryable; + synchronized (mForceQueryableLock) { + existingIsForceQueryable = mForceQueryable.contains(existingSetting.getAppId()); + } + // now we'll evaluate our new package's ability to see existing packages + if (!existingIsForceQueryable) { + if (!mQueriesViaComponentRequireRecompute.get() + && canQueryViaComponents(newPkg, existingPkg, mProtectedBroadcasts)) { + synchronized (mQueriesViaComponentLock) { mQueriesViaComponent.add(newPkgSetting.getAppId(), existingSetting.getAppId()); } - if (canQueryViaPackage(newPkg, existingPkg) - || canQueryAsInstaller(newPkgSetting, existingPkg)) { + } + if (canQueryViaPackage(newPkg, existingPkg) + || canQueryAsInstaller(newPkgSetting, existingPkg)) { + synchronized (mQueriesViaPackageLock) { mQueriesViaPackage.add(newPkgSetting.getAppId(), existingSetting.getAppId()); } - if (canQueryViaUsesLibrary(newPkg, existingPkg)) { + } + if (canQueryViaUsesLibrary(newPkg, existingPkg)) { + synchronized (mQueryableViaUsesLibraryLock) { 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()))) { + } + // 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()))) { + synchronized (mQueriesViaPackageLock) { mQueriesViaPackage.add(newPkgSetting.getAppId(), existingSetting.getAppId()); mQueriesViaPackage.add(existingSetting.getAppId(), newPkgSetting.getAppId()); } } } + int existingSize = existingSettings.size(); ArrayMap<String, AndroidPackage> existingPkgs = new ArrayMap<>(existingSize); for (int index = 0; index < existingSize; index++) { @@ -586,9 +618,6 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, } private void removeAppIdFromVisibilityCache(int appId) { - if (!mSystemReady) { - return; - } synchronized (mCacheLock) { for (int i = 0; i < mShouldFilterCache.size(); i++) { if (UserHandle.getAppId(mShouldFilterCache.keyAt(i)) == appId) { @@ -642,7 +671,17 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, } private void updateEntireShouldFilterCacheAsync(PackageManagerInternal pmInternal) { - mBackgroundExecutor.execute(() -> { + updateEntireShouldFilterCacheAsync(pmInternal, CACHE_REBUILD_DELAY_MIN_MS); + } + + private void updateEntireShouldFilterCacheAsync(PackageManagerInternal pmInternal, + long delayMs) { + mBackgroundHandler.postDelayed(() -> { + if (!mCacheValid.compareAndSet(CACHE_INVALID, CACHE_VALID)) { + // Cache is already valid. + return; + } + final ArrayMap<String, AndroidPackage> packagesCache = new ArrayMap<>(); final UserInfo[][] usersRef = new UserInfo[1][]; final PackageDataSnapshot snapshot = pmInternal.snapshot(); @@ -661,18 +700,27 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, updateEntireShouldFilterCacheInner(snapshot, settings, usersRef[0], USER_ALL); onChanged(); - }); + + if (!mCacheValid.compareAndSet(CACHE_VALID, CACHE_VALID)) { + Slog.i(TAG, "Cache invalidated while building, retrying."); + updateEntireShouldFilterCacheAsync(pmInternal, + Math.min(delayMs * 2, CACHE_REBUILD_DELAY_MAX_MS)); + return; + } + + mCacheReady = true; + }, delayMs); } public void onUserCreated(PackageDataSnapshot snapshot, int newUserId) { - if (!mSystemReady) { + if (!mCacheReady) { return; } updateEntireShouldFilterCache(snapshot, newUserId); } public void onUserDeleted(@UserIdInt int userId) { - if (!mSystemReady) { + if (!mCacheReady) { return; } removeShouldFilterCacheForUser(userId); @@ -681,7 +729,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, private void updateShouldFilterCacheForPackage(PackageDataSnapshot snapshot, String packageName) { - if (!mSystemReady) { + if (!mCacheReady) { return; } final ArrayMap<String, ? extends PackageStateInternal> settings = @@ -772,7 +820,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, private void collectProtectedBroadcasts( ArrayMap<String, ? extends PackageStateInternal> existingSettings, @Nullable String excludePackage) { - synchronized (mLock) { + synchronized (mProtectedBroadcastsLock) { mProtectedBroadcasts.clear(); for (int i = existingSettings.size() - 1; i >= 0; i--) { PackageStateInternal setting = existingSettings.valueAt(i); @@ -806,30 +854,37 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, */ private void recomputeComponentVisibility( ArrayMap<String, ? extends PackageStateInternal> existingSettings) { - synchronized (mLock) { + synchronized (mQueriesViaComponentLock) { mQueriesViaComponent.clear(); - for (int i = existingSettings.size() - 1; i >= 0; i--) { - PackageStateInternal setting = existingSettings.valueAt(i); - if (setting.getPkg() == null || requestsQueryAllPackages(setting.getPkg())) { + } + for (int i = existingSettings.size() - 1; i >= 0; i--) { + PackageStateInternal setting = existingSettings.valueAt(i); + if (setting.getPkg() == null || requestsQueryAllPackages(setting.getPkg())) { + continue; + } + for (int j = existingSettings.size() - 1; j >= 0; j--) { + if (i == j) { continue; } - for (int j = existingSettings.size() - 1; j >= 0; j--) { - if (i == j) { - continue; - } - final PackageStateInternal otherSetting = existingSettings.valueAt(j); - if (otherSetting.getPkg() == null || mForceQueryable.contains( - otherSetting.getAppId())) { - continue; - } - if (canQueryViaComponents(setting.getPkg(), otherSetting.getPkg(), - mProtectedBroadcasts)) { + final PackageStateInternal otherSetting = existingSettings.valueAt(j); + if (otherSetting.getPkg() == null || mForceQueryable.contains( + otherSetting.getAppId())) { + continue; + } + final boolean canQueryViaComponents; + synchronized (mProtectedBroadcastsLock) { + canQueryViaComponents = canQueryViaComponents(setting.getPkg(), + otherSetting.getPkg(), mProtectedBroadcasts); + } + if (canQueryViaComponents) { + synchronized (mQueriesViaComponentLock) { mQueriesViaComponent.add(setting.getAppId(), otherSetting.getAppId()); } } } } - mQueriesViaComponentRequireRecompute = false; + + mQueriesViaComponentRequireRecompute.set(false); onChanged(); } @@ -857,7 +912,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, final UserInfo[] users = snapshot.getUserInfos(); final Collection<SharedUserSetting> sharedUserSettings = snapshot.getAllSharedUsers(); final int userCount = users.length; - synchronized (mLock) { + synchronized (mImplicitlyQueryableLock) { for (int u = 0; u < userCount; u++) { final int userId = users[u].id; final int removingUid = UserHandle.getUid(userId, setting.getAppId()); @@ -877,39 +932,53 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, mRetainedImplicitlyQueryable.keyAt(i), removingUid); } } + } - if (!mQueriesViaComponentRequireRecompute) { + if (!mQueriesViaComponentRequireRecompute.get()) { + synchronized (mQueriesViaComponentLock) { mQueriesViaComponent.remove(setting.getAppId()); for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) { - mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), - setting.getAppId()); + mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), setting.getAppId()); } } + } + + synchronized (mQueriesViaPackageLock) { mQueriesViaPackage.remove(setting.getAppId()); for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) { mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), setting.getAppId()); } + } + + synchronized (mQueryableViaUsesLibraryLock) { mQueryableViaUsesLibrary.remove(setting.getAppId()); for (int i = mQueryableViaUsesLibrary.size() - 1; i >= 0; i--) { mQueryableViaUsesLibrary.remove(mQueryableViaUsesLibrary.keyAt(i), setting.getAppId()); } + } + synchronized (mForceQueryableLock) { mForceQueryable.remove(setting.getAppId()); + } + boolean protectedBroadcastsChanged = false; + synchronized (mProtectedBroadcastsLock) { if (setting.getPkg() != null && !setting.getPkg().getProtectedBroadcasts().isEmpty()) { final String removingPackageName = setting.getPkg().getPackageName(); - final ArrayList<String> protectedBroadcasts = new ArrayList<>(); - protectedBroadcasts.addAll(mProtectedBroadcasts.untrackedStorage()); + final ArrayList<String> protectedBroadcasts = new ArrayList<>( + mProtectedBroadcasts.untrackedStorage()); collectProtectedBroadcasts(settings, removingPackageName); - if (!mProtectedBroadcasts.containsAll(protectedBroadcasts)) { - mQueriesViaComponentRequireRecompute = true; - } + protectedBroadcastsChanged = !mProtectedBroadcasts.containsAll(protectedBroadcasts); } } + if (protectedBroadcastsChanged) { + mQueriesViaComponentRequireRecompute.set(true); + } + additionalChangedPackages = mOverlayReferenceMapper.removePkg(setting.getPackageName()); mFeatureConfig.updatePackageState(setting, true /*removed*/); @@ -929,25 +998,26 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, } } - removeAppIdFromVisibilityCache(setting.getAppId()); - if (mSystemReady && setting.hasSharedUser()) { - final ArraySet<? extends PackageStateInternal> sharedUserPackages = - getSharedUserPackages(setting.getSharedUserAppId(), sharedUserSettings); - for (int i = sharedUserPackages.size() - 1; i >= 0; i--) { - PackageStateInternal siblingSetting = - sharedUserPackages.valueAt(i); - if (siblingSetting == setting) { - continue; - } - synchronized (mCacheLock) { - updateShouldFilterCacheForPackage(snapshot, - setting.getPackageName(), siblingSetting, settings, - users, USER_ALL, settings.size()); + if (mCacheReady) { + removeAppIdFromVisibilityCache(setting.getAppId()); + + if (setting.hasSharedUser()) { + final ArraySet<? extends PackageStateInternal> sharedUserPackages = + getSharedUserPackages(setting.getSharedUserAppId(), sharedUserSettings); + for (int i = sharedUserPackages.size() - 1; i >= 0; i--) { + PackageStateInternal siblingSetting = + sharedUserPackages.valueAt(i); + if (siblingSetting == setting) { + continue; + } + synchronized (mCacheLock) { + updateShouldFilterCacheForPackage(snapshot, + setting.getPackageName(), siblingSetting, settings, + users, USER_ALL, settings.size()); + } } } - } - if (mSystemReady) { if (additionalChangedPackages != null) { for (int index = 0; index < additionalChangedPackages.size(); index++) { String changedPackage = additionalChangedPackages.valueAt(index); @@ -964,6 +1034,8 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, } } } + } else { + invalidateCache("removePackage: " + setting.getPackageName()); } onChanged(); } diff --git a/services/core/java/com/android/server/pm/AppsFilterLocked.java b/services/core/java/com/android/server/pm/AppsFilterLocked.java index e8e6cd9e8edb..30eb09e61d3f 100644 --- a/services/core/java/com/android/server/pm/AppsFilterLocked.java +++ b/services/core/java/com/android/server/pm/AppsFilterLocked.java @@ -26,52 +26,61 @@ import java.io.PrintWriter; */ abstract class AppsFilterLocked extends AppsFilterBase { /** - * Guards the accesses for the list/set class members + * The following locks guard the accesses for the list/set class members */ - protected final Object mLock = new Object(); + protected final Object mForceQueryableLock = new Object(); + protected final Object mQueriesViaPackageLock = new Object(); + protected final Object mQueriesViaComponentLock = new Object(); + /** + * This lock covers both {@link #mImplicitlyQueryable} and {@link #mRetainedImplicitlyQueryable} + */ + protected final Object mImplicitlyQueryableLock = new Object(); + protected final Object mQueryableViaUsesLibraryLock = new Object(); + protected final Object mProtectedBroadcastsLock = new Object(); + /** * Guards the access for {@link AppsFilterBase#mShouldFilterCache}; */ - protected Object mCacheLock = new Object(); + protected final Object mCacheLock = new Object(); @Override protected boolean isForceQueryable(int appId) { - synchronized (mLock) { + synchronized (mForceQueryableLock) { return super.isForceQueryable(appId); } } @Override protected boolean isQueryableViaPackage(int callingAppId, int targetAppId) { - synchronized (mLock) { + synchronized (mQueriesViaPackageLock) { return super.isQueryableViaPackage(callingAppId, targetAppId); } } @Override protected boolean isQueryableViaComponent(int callingAppId, int targetAppId) { - synchronized (mLock) { + synchronized (mQueriesViaComponentLock) { return super.isQueryableViaComponent(callingAppId, targetAppId); } } @Override protected boolean isImplicitlyQueryable(int callingAppId, int targetAppId) { - synchronized (mLock) { + synchronized (mImplicitlyQueryableLock) { return super.isImplicitlyQueryable(callingAppId, targetAppId); } } @Override protected boolean isRetainedImplicitlyQueryable(int callingAppId, int targetAppId) { - synchronized (mLock) { + synchronized (mImplicitlyQueryableLock) { return super.isRetainedImplicitlyQueryable(callingAppId, targetAppId); } } @Override protected boolean isQueryableViaUsesLibrary(int callingAppId, int targetAppId) { - synchronized (mLock) { + synchronized (mQueryableViaUsesLibraryLock) { return super.isQueryableViaUsesLibrary(callingAppId, targetAppId); } } @@ -84,10 +93,42 @@ abstract class AppsFilterLocked extends AppsFilterBase { } @Override - protected void dumpQueryables(PrintWriter pw, @Nullable Integer filteringAppId, int[] users, + protected void dumpForceQueryable(PrintWriter pw, @Nullable Integer filteringAppId, + ToString<Integer> expandPackages) { + synchronized (mForceQueryableLock) { + super.dumpForceQueryable(pw, filteringAppId, expandPackages); + } + } + + @Override + protected void dumpQueriesViaPackage(PrintWriter pw, @Nullable Integer filteringAppId, + ToString<Integer> expandPackages) { + synchronized (mQueriesViaPackageLock) { + super.dumpQueriesViaPackage(pw, filteringAppId, expandPackages); + } + } + + @Override + protected void dumpQueriesViaComponent(PrintWriter pw, @Nullable Integer filteringAppId, + ToString<Integer> expandPackages) { + synchronized (mQueriesViaComponentLock) { + super.dumpQueriesViaComponent(pw, filteringAppId, expandPackages); + } + } + + @Override + protected void dumpQueriesViaImplicitlyQueryable(PrintWriter pw, + @Nullable Integer filteringAppId, int[] users, ToString<Integer> expandPackages) { + synchronized (mImplicitlyQueryableLock) { + super.dumpQueriesViaImplicitlyQueryable(pw, filteringAppId, users, expandPackages); + } + } + + @Override + protected void dumpQueriesViaUsesLibrary(PrintWriter pw, @Nullable Integer filteringAppId, ToString<Integer> expandPackages) { - synchronized (mLock) { - dumpQueryables(pw, filteringAppId, users, expandPackages); + synchronized (mQueryableViaUsesLibraryLock) { + super.dumpQueriesViaUsesLibrary(pw, filteringAppId, expandPackages); } } } diff --git a/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java b/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java index c12aa6d485a4..6ae6efae1230 100644 --- a/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java +++ b/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java @@ -17,6 +17,7 @@ package com.android.server.pm; import com.android.server.utils.SnapshotCache; +import com.android.server.utils.WatchedSparseBooleanMatrix; import java.util.Arrays; @@ -25,22 +26,32 @@ import java.util.Arrays; */ public final class AppsFilterSnapshotImpl extends AppsFilterBase { AppsFilterSnapshotImpl(AppsFilterImpl orig) { - synchronized (orig.mLock) { + synchronized (orig.mImplicitlyQueryableLock) { mImplicitlyQueryable = orig.mImplicitQueryableSnapshot.snapshot(); - mImplicitQueryableSnapshot = new SnapshotCache.Sealed<>(); mRetainedImplicitlyQueryable = orig.mRetainedImplicitlyQueryableSnapshot.snapshot(); - mRetainedImplicitlyQueryableSnapshot = new SnapshotCache.Sealed<>(); + } + mImplicitQueryableSnapshot = new SnapshotCache.Sealed<>(); + mRetainedImplicitlyQueryableSnapshot = new SnapshotCache.Sealed<>(); + synchronized (orig.mQueriesViaPackageLock) { mQueriesViaPackage = orig.mQueriesViaPackageSnapshot.snapshot(); - mQueriesViaPackageSnapshot = new SnapshotCache.Sealed<>(); + } + mQueriesViaPackageSnapshot = new SnapshotCache.Sealed<>(); + synchronized (orig.mQueriesViaComponentLock) { mQueriesViaComponent = orig.mQueriesViaComponentSnapshot.snapshot(); - mQueriesViaComponentSnapshot = new SnapshotCache.Sealed<>(); + } + mQueriesViaComponentSnapshot = new SnapshotCache.Sealed<>(); + synchronized (orig.mQueryableViaUsesLibraryLock) { mQueryableViaUsesLibrary = orig.mQueryableViaUsesLibrarySnapshot.snapshot(); - mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Sealed<>(); + } + mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Sealed<>(); + synchronized (orig.mForceQueryableLock) { mForceQueryable = orig.mForceQueryableSnapshot.snapshot(); - mForceQueryableSnapshot = new SnapshotCache.Sealed<>(); + } + mForceQueryableSnapshot = new SnapshotCache.Sealed<>(); + synchronized (orig.mProtectedBroadcastsLock) { mProtectedBroadcasts = orig.mProtectedBroadcastsSnapshot.snapshot(); - mProtectedBroadcastsSnapshot = new SnapshotCache.Sealed<>(); } + mProtectedBroadcastsSnapshot = new SnapshotCache.Sealed<>(); mQueriesViaComponentRequireRecompute = orig.mQueriesViaComponentRequireRecompute; mForceQueryableByDevicePackageNames = Arrays.copyOf(orig.mForceQueryableByDevicePackageNames, @@ -49,12 +60,18 @@ public final class AppsFilterSnapshotImpl extends AppsFilterBase { mFeatureConfig = orig.mFeatureConfig.snapshot(); mOverlayReferenceMapper = orig.mOverlayReferenceMapper; mSystemSigningDetails = orig.mSystemSigningDetails; - synchronized (orig.mCacheLock) { - mShouldFilterCache = orig.mShouldFilterCacheSnapshot.snapshot(); - mShouldFilterCacheSnapshot = new SnapshotCache.Sealed<>(); + + mCacheReady = orig.mCacheReady; + if (mCacheReady) { + synchronized (orig.mCacheLock) { + mShouldFilterCache = orig.mShouldFilterCacheSnapshot.snapshot(); + } + } else { + // cache is not ready, use an empty cache for the snapshot + mShouldFilterCache = new WatchedSparseBooleanMatrix(); } + mShouldFilterCacheSnapshot = new SnapshotCache.Sealed<>(); - mBackgroundExecutor = null; - mSystemReady = orig.mSystemReady; + mBackgroundHandler = null; } } diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java index 7974718512a8..9674ebd75677 100644 --- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java @@ -22,7 +22,7 @@ import static org.hamcrest.Matchers.contains; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doAnswer; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -35,6 +35,8 @@ import android.content.pm.Signature; import android.content.pm.SigningDetails; import android.content.pm.UserInfo; import android.os.Build; +import android.os.Handler; +import android.os.Message; import android.os.Process; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; @@ -74,7 +76,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.Executor; @Presubmit @RunWith(JUnit4.class) @@ -103,7 +104,7 @@ public class AppsFilterImplTest { @Mock PackageDataSnapshot mSnapshot; @Mock - Executor mMockExecutor; + Handler mMockHandler; @Mock PackageManagerInternal mPmInternal; @@ -210,10 +211,12 @@ public class AppsFilterImplTest { when(mSnapshot.getUserInfos()).thenReturn(USER_INFO_LIST); when(mPmInternal.snapshot()).thenReturn(mSnapshot); - doAnswer(invocation -> { - ((Runnable) invocation.getArgument(0)).run(); - return new Object(); - }).when(mMockExecutor).execute(any(Runnable.class)); + // Can't mock postDelayed because of some weird bug in Mockito. + when(mMockHandler.sendMessageDelayed(any(Message.class), anyLong())).thenAnswer( + invocation -> { + ((Message) invocation.getArgument(0)).getCallback().run(); + return null; + }); when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true); when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))).thenAnswer( @@ -226,7 +229,7 @@ public class AppsFilterImplTest { public void testSystemReadyPropogates() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); appsFilter.onSystemReady(mPmInternal); @@ -238,7 +241,7 @@ public class AppsFilterImplTest { public void testQueriesAction_FilterMatches() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); simulateAddBasicAndroid(appsFilter); @@ -263,7 +266,7 @@ public class AppsFilterImplTest { public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); final Signature frameworkSignature = Mockito.mock(Signature.class); @@ -312,7 +315,7 @@ public class AppsFilterImplTest { public void testQueriesProvider_FilterMatches() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); simulateAddBasicAndroid(appsFilter); @@ -337,7 +340,7 @@ public class AppsFilterImplTest { public void testOnUserUpdated_FilterMatches() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -385,7 +388,7 @@ public class AppsFilterImplTest { public void testQueriesDifferentProvider_Filters() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); simulateAddBasicAndroid(appsFilter); @@ -410,7 +413,7 @@ public class AppsFilterImplTest { public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -429,7 +432,7 @@ public class AppsFilterImplTest { public void testQueriesAction_NoMatchingAction_Filters() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -446,7 +449,7 @@ public class AppsFilterImplTest { public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -468,7 +471,7 @@ public class AppsFilterImplTest { public void testNoQueries_Filters() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -486,7 +489,7 @@ public class AppsFilterImplTest { public void testNoUsesLibrary_Filters() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -513,7 +516,7 @@ public class AppsFilterImplTest { public void testUsesLibrary_DoesntFilter() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -541,7 +544,7 @@ public class AppsFilterImplTest { public void testUsesOptionalLibrary_DoesntFilter() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -569,7 +572,7 @@ public class AppsFilterImplTest { public void testUsesLibrary_ShareUid_DoesntFilter() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -602,7 +605,7 @@ public class AppsFilterImplTest { public void testForceQueryable_SystemDoesntFilter() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -622,7 +625,7 @@ public class AppsFilterImplTest { public void testForceQueryable_NonSystemFilters() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -641,7 +644,7 @@ public class AppsFilterImplTest { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{"com.some.package"}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -661,7 +664,7 @@ public class AppsFilterImplTest { public void testSystemSignedTarget_DoesntFilter() throws CertificateException { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); appsFilter.onSystemReady(mPmInternal); final Signature frameworkSignature = Mockito.mock(Signature.class); @@ -692,7 +695,7 @@ public class AppsFilterImplTest { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{"com.some.package"}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -711,7 +714,7 @@ public class AppsFilterImplTest { public void testSystemQueryable_DoesntFilter() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, - true /* system force queryable */, null, mMockExecutor); + true /* system force queryable */, null, mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -730,7 +733,7 @@ public class AppsFilterImplTest { public void testQueriesPackage_DoesntFilter() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -750,7 +753,7 @@ public class AppsFilterImplTest { .thenReturn(false); final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -768,7 +771,7 @@ public class AppsFilterImplTest { public void testSystemUid_DoesntFilter() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -785,7 +788,7 @@ public class AppsFilterImplTest { public void testSystemUidSecondaryUser_DoesntFilter() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -803,7 +806,7 @@ public class AppsFilterImplTest { public void testNonSystemUid_NoCallingSetting_Filters() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -818,7 +821,7 @@ public class AppsFilterImplTest { public void testNoTargetPackage_filters() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -876,7 +879,7 @@ public class AppsFilterImplTest { return Collections.emptyMap(); } }, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -966,7 +969,7 @@ public class AppsFilterImplTest { return Collections.emptyMap(); } }, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -990,7 +993,7 @@ public class AppsFilterImplTest { public void testInitiatingApp_DoesntFilter() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -1009,7 +1012,7 @@ public class AppsFilterImplTest { public void testUninstalledInitiatingApp_Filters() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); @@ -1028,7 +1031,7 @@ public class AppsFilterImplTest { public void testOriginatingApp_Filters() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); simulateAddBasicAndroid(appsFilter); @@ -1054,7 +1057,7 @@ public class AppsFilterImplTest { public void testInstallingApp_DoesntFilter() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); simulateAddBasicAndroid(appsFilter); @@ -1080,7 +1083,7 @@ public class AppsFilterImplTest { public void testInstrumentation_DoesntFilter() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); simulateAddBasicAndroid(appsFilter); @@ -1109,7 +1112,7 @@ public class AppsFilterImplTest { public void testWhoCanSee() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); simulateAddBasicAndroid(appsFilter); @@ -1184,7 +1187,7 @@ public class AppsFilterImplTest { public void testOnChangeReport() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); simulateAddBasicAndroid(appsFilter); @@ -1259,7 +1262,7 @@ public class AppsFilterImplTest { public void testOnChangeReportedFilter() throws Exception { final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange filter"); @@ -1286,7 +1289,7 @@ public class AppsFilterImplTest { when(mFeatureConfigMock.snapshot()).thenReturn(mFeatureConfigMock); final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + mMockHandler); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(mPmInternal); |