Merge "[AppsFilter] fix cache lock and rebuild cache if needed" into tm-dev

This commit is contained in:
Songchun Fan
2022-05-16 15:48:37 +00:00
committed by Android (Google) Code Review
5 changed files with 344 additions and 180 deletions

View File

@@ -26,6 +26,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.content.pm.SigningDetails; import android.content.pm.SigningDetails;
import android.os.Binder; import android.os.Binder;
import android.os.Handler;
import android.os.Process; import android.os.Process;
import android.os.Trace; import android.os.Trace;
import android.os.UserHandle; import android.os.UserHandle;
@@ -53,7 +54,7 @@ import java.io.PrintWriter;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Objects; 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 * 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; protected static final boolean DEBUG_LOGGING = false;
public static final boolean DEBUG_TRACING = 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 * 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, * 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; 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. * visibility cache.
*/ */
protected Executor mBackgroundExecutor; protected Handler mBackgroundHandler;
/** /**
* Pending full recompute of mQueriesViaComponent. Occurs when a package adds a new set of * 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. * computationally expensive recomputing.
* Full recompute is done lazily at the point when we use mQueriesViaComponent to filter apps. * 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 * 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, * {@link #shouldFilterApplicationInternal(PackageDataSnapshot, int, Object,
* PackageStateInternal, int)} call. * PackageStateInternal, int)} call.
* NOTE: It can only be relied upon after the system is ready to avoid unnecessary update on * 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 @NonNull
@Watched @Watched
@@ -181,7 +187,11 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
@NonNull @NonNull
protected SnapshotCache<WatchedSparseBooleanMatrix> mShouldFilterCacheSnapshot; 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) { protected boolean isForceQueryable(int callingAppId) {
return mForceQueryable.contains(callingAppId); return mForceQueryable.contains(callingAppId);
@@ -312,7 +322,7 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
|| callingAppId == targetPkgSetting.getAppId()) { || callingAppId == targetPkgSetting.getAppId()) {
return false; return false;
} }
if (mSystemReady) { // use cache if (mCacheReady) { // use cache
if (!shouldFilterApplicationUsingCache(callingUid, if (!shouldFilterApplicationUsingCache(callingUid,
targetPkgSetting.getAppId(), targetPkgSetting.getAppId(),
userId)) { userId)) {
@@ -506,7 +516,7 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
if (DEBUG_TRACING) { if (DEBUG_TRACING) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaComponent"); Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaComponent");
} }
if (!mQueriesViaComponentRequireRecompute) { if (!mQueriesViaComponentRequireRecompute.get()) {
if (isQueryableViaComponent(callingAppId, targetAppId)) { if (isQueryableViaComponent(callingAppId, targetAppId)) {
if (DEBUG_LOGGING) { if (DEBUG_LOGGING) {
log(callingSetting, targetPkgSetting, "queries component"); log(callingSetting, targetPkgSetting, "queries component");
@@ -702,17 +712,34 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
} }
} }
pw.println(" system apps queryable: " + mSystemAppsQueryable); 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) { ToString<Integer> expandPackages) {
pw.println(" queries via forceQueryable:");
dumpPackageSet(pw, filteringAppId, mForceQueryable.untrackedStorage(), dumpPackageSet(pw, filteringAppId, mForceQueryable.untrackedStorage(),
"forceQueryable", " ", expandPackages); "forceQueryable", " ", expandPackages);
}
protected void dumpQueriesViaPackage(PrintWriter pw, @Nullable Integer filteringAppId,
ToString<Integer> expandPackages) {
pw.println(" queries via package name:"); pw.println(" queries via package name:");
dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, " ", expandPackages); dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, " ", expandPackages);
}
protected void dumpQueriesViaComponent(PrintWriter pw, @Nullable Integer filteringAppId,
ToString<Integer> expandPackages) {
pw.println(" queries via component:"); pw.println(" queries via component:");
dumpQueriesMap(pw, filteringAppId, mQueriesViaComponent, " ", expandPackages); dumpQueriesMap(pw, filteringAppId, mQueriesViaComponent, " ", expandPackages);
}
protected void dumpQueriesViaImplicitlyQueryable(PrintWriter pw,
@Nullable Integer filteringAppId, int[] users, ToString<Integer> expandPackages) {
pw.println(" queryable via interaction:"); pw.println(" queryable via interaction:");
for (int user : users) { for (int user : users) {
pw.append(" User ").append(Integer.toString(user)).println(":"); 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), filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId),
mRetainedImplicitlyQueryable, " ", expandPackages); mRetainedImplicitlyQueryable, " ", expandPackages);
} }
}
protected void dumpQueriesViaUsesLibrary(PrintWriter pw, @Nullable Integer filteringAppId,
ToString<Integer> expandPackages) {
pw.println(" queryable via uses-library:"); pw.println(" queryable via uses-library:");
dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, " ", dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, " ",
expandPackages); expandPackages);

View File

@@ -35,6 +35,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManagerInternal;
import android.content.pm.SigningDetails; import android.content.pm.SigningDetails;
import android.content.pm.UserInfo; import android.content.pm.UserInfo;
import android.os.Handler;
import android.os.Trace; import android.os.Trace;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.DeviceConfig; import android.provider.DeviceConfig;
@@ -70,7 +71,6 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.Executor;
/** /**
* Implementation of the methods that update the internal structures of AppsFilter. Because of the * 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. * A cached snapshot.
*/ */
@NonNull @NonNull
private SnapshotCache<AppsFilterSnapshot> mSnapshot; private final SnapshotCache<AppsFilterSnapshot> mSnapshot;
/** /**
* Watchable machinery * Watchable machinery
@@ -142,18 +142,24 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
dispatchChange(this); dispatchChange(this);
} }
private void invalidateCache(String reason) {
if (mCacheValid.compareAndSet(CACHE_VALID, CACHE_INVALID)) {
Slog.i(TAG, "Invalidating cache: " + reason);
}
}
@VisibleForTesting(visibility = PRIVATE) @VisibleForTesting(visibility = PRIVATE)
AppsFilterImpl(FeatureConfig featureConfig, AppsFilterImpl(FeatureConfig featureConfig,
String[] forceQueryableList, String[] forceQueryableList,
boolean systemAppsQueryable, boolean systemAppsQueryable,
@Nullable OverlayReferenceMapper.Provider overlayProvider, @Nullable OverlayReferenceMapper.Provider overlayProvider,
Executor backgroundExecutor) { Handler backgroundHandler) {
mFeatureConfig = featureConfig; mFeatureConfig = featureConfig;
mForceQueryableByDevicePackageNames = forceQueryableList; mForceQueryableByDevicePackageNames = forceQueryableList;
mSystemAppsQueryable = systemAppsQueryable; mSystemAppsQueryable = systemAppsQueryable;
mOverlayReferenceMapper = new OverlayReferenceMapper(true /*deferRebuild*/, mOverlayReferenceMapper = new OverlayReferenceMapper(true /*deferRebuild*/,
overlayProvider); overlayProvider);
mBackgroundExecutor = backgroundExecutor; mBackgroundHandler = backgroundHandler;
mShouldFilterCache = new WatchedSparseBooleanMatrix(); mShouldFilterCache = new WatchedSparseBooleanMatrix();
mShouldFilterCacheSnapshot = new SnapshotCache.Auto<>( mShouldFilterCacheSnapshot = new SnapshotCache.Auto<>(
mShouldFilterCache, mShouldFilterCache, "AppsFilter.mShouldFilterCache"); mShouldFilterCache, mShouldFilterCache, "AppsFilter.mShouldFilterCache");
@@ -371,7 +377,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
} }
AppsFilterImpl appsFilter = new AppsFilterImpl(featureConfig, AppsFilterImpl appsFilter = new AppsFilterImpl(featureConfig,
forcedQueryablePackageNames, forceSystemAppsQueryable, null, forcedQueryablePackageNames, forceSystemAppsQueryable, null,
injector.getBackgroundExecutor()); injector.getBackgroundHandler());
featureConfig.setAppsFilter(appsFilter); featureConfig.setAppsFilter(appsFilter);
return appsFilter; return appsFilter;
} }
@@ -394,7 +400,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
return false; return false;
} }
final boolean changed; final boolean changed;
synchronized (mLock) { synchronized (mImplicitlyQueryableLock) {
changed = retainOnUpdate changed = retainOnUpdate
? mRetainedImplicitlyQueryable.add(recipientUid, visibleUid) ? mRetainedImplicitlyQueryable.add(recipientUid, visibleUid)
: mImplicitlyQueryable.add(recipientUid, visibleUid); : mImplicitlyQueryable.add(recipientUid, visibleUid);
@@ -404,12 +410,13 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
+ recipientUid + " -> " + visibleUid); + recipientUid + " -> " + visibleUid);
} }
if (mSystemReady) { if (mCacheReady) {
synchronized (mCacheLock) { synchronized (mCacheLock) {
// update the cache in a one-off manner since we've got all the information we // Update the cache in a one-off manner since we've got all the information we need.
// need.
mShouldFilterCache.put(recipientUid, visibleUid, false); mShouldFilterCache.put(recipientUid, visibleUid, false);
} }
} else if (changed) {
invalidateCache("grantImplicitAccess: " + recipientUid + " -> " + visibleUid);
} }
onChanged(); onChanged();
return changed; return changed;
@@ -420,7 +427,6 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
mFeatureConfig.onSystemReady(); mFeatureConfig.onSystemReady();
updateEntireShouldFilterCacheAsync(pmInternal); updateEntireShouldFilterCacheAsync(pmInternal);
mSystemReady = true;
} }
/** /**
@@ -444,7 +450,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
final UserInfo[] users = snapshot.getUserInfos(); final UserInfo[] users = snapshot.getUserInfos();
final ArraySet<String> additionalChangedPackages = final ArraySet<String> additionalChangedPackages =
addPackageInternal(newPkgSetting, settings); addPackageInternal(newPkgSetting, settings);
if (mSystemReady) { if (mCacheReady) {
synchronized (mCacheLock) { synchronized (mCacheLock) {
updateShouldFilterCacheForPackage(snapshot, null, newPkgSetting, updateShouldFilterCacheForPackage(snapshot, null, newPkgSetting,
settings, users, USER_ALL, settings.size()); 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 { } finally {
onChanged(); onChanged();
if (DEBUG_TRACING) { if (DEBUG_TRACING) {
@@ -486,7 +494,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
// packages for signature matches // packages for signature matches
for (PackageStateInternal setting : existingSettings.values()) { for (PackageStateInternal setting : existingSettings.values()) {
if (isSystemSigned(mSystemSigningDetails, setting)) { if (isSystemSigned(mSystemSigningDetails, setting)) {
synchronized (mLock) { synchronized (mForceQueryableLock) {
mForceQueryable.add(setting.getAppId()); mForceQueryable.add(setting.getAppId());
} }
} }
@@ -498,13 +506,18 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
return null; return null;
} }
synchronized (mLock) { final boolean protectedBroadcastsChanged;
if (mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts())) { synchronized (mProtectedBroadcastsLock) {
mQueriesViaComponentRequireRecompute = true; protectedBroadcastsChanged =
mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts());
}
if (protectedBroadcastsChanged) {
mQueriesViaComponentRequireRecompute.set(true);
} }
final boolean newIsForceQueryable = final boolean newIsForceQueryable;
mForceQueryable.contains(newPkgSetting.getAppId()) synchronized (mForceQueryableLock) {
newIsForceQueryable = mForceQueryable.contains(newPkgSetting.getAppId())
/* shared user that is already force queryable */ /* shared user that is already force queryable */
|| newPkgSetting.isForceQueryableOverride() /* adb override */ || newPkgSetting.isForceQueryableOverride() /* adb override */
|| (newPkgSetting.isSystem() && (mSystemAppsQueryable || (newPkgSetting.isSystem() && (mSystemAppsQueryable
@@ -516,6 +529,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
&& isSystemSigned(mSystemSigningDetails, newPkgSetting))) { && isSystemSigned(mSystemSigningDetails, newPkgSetting))) {
mForceQueryable.add(newPkgSetting.getAppId()); mForceQueryable.add(newPkgSetting.getAppId());
} }
}
for (int i = existingSettings.size() - 1; i >= 0; i--) { for (int i = existingSettings.size() - 1; i >= 0; i--) {
final PackageStateInternal existingSetting = existingSettings.valueAt(i); final PackageStateInternal existingSetting = existingSettings.valueAt(i);
@@ -527,47 +541,65 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
final AndroidPackage existingPkg = existingSetting.getPkg(); final AndroidPackage existingPkg = existingSetting.getPkg();
// let's evaluate the ability of already added packages to see this new package // let's evaluate the ability of already added packages to see this new package
if (!newIsForceQueryable) { if (!newIsForceQueryable) {
if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(existingPkg, if (!mQueriesViaComponentRequireRecompute.get()
newPkg, mProtectedBroadcasts)) { && canQueryViaComponents(existingPkg, newPkg, mProtectedBroadcasts)) {
synchronized (mQueriesViaComponentLock) {
mQueriesViaComponent.add(existingSetting.getAppId(), mQueriesViaComponent.add(existingSetting.getAppId(),
newPkgSetting.getAppId()); newPkgSetting.getAppId());
} }
}
if (canQueryViaPackage(existingPkg, newPkg) if (canQueryViaPackage(existingPkg, newPkg)
|| canQueryAsInstaller(existingSetting, newPkg)) { || canQueryAsInstaller(existingSetting, newPkg)) {
synchronized (mQueriesViaPackageLock) {
mQueriesViaPackage.add(existingSetting.getAppId(), mQueriesViaPackage.add(existingSetting.getAppId(),
newPkgSetting.getAppId()); newPkgSetting.getAppId());
} }
}
if (canQueryViaUsesLibrary(existingPkg, newPkg)) { if (canQueryViaUsesLibrary(existingPkg, newPkg)) {
synchronized (mQueryableViaUsesLibraryLock) {
mQueryableViaUsesLibrary.add(existingSetting.getAppId(), mQueryableViaUsesLibrary.add(existingSetting.getAppId(),
newPkgSetting.getAppId()); newPkgSetting.getAppId());
} }
} }
}
final boolean existingIsForceQueryable;
synchronized (mForceQueryableLock) {
existingIsForceQueryable = mForceQueryable.contains(existingSetting.getAppId());
}
// now we'll evaluate our new package's ability to see existing packages // now we'll evaluate our new package's ability to see existing packages
if (!mForceQueryable.contains(existingSetting.getAppId())) { if (!existingIsForceQueryable) {
if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(newPkg, if (!mQueriesViaComponentRequireRecompute.get()
existingPkg, mProtectedBroadcasts)) { && canQueryViaComponents(newPkg, existingPkg, mProtectedBroadcasts)) {
synchronized (mQueriesViaComponentLock) {
mQueriesViaComponent.add(newPkgSetting.getAppId(), mQueriesViaComponent.add(newPkgSetting.getAppId(),
existingSetting.getAppId()); existingSetting.getAppId());
} }
}
if (canQueryViaPackage(newPkg, existingPkg) if (canQueryViaPackage(newPkg, existingPkg)
|| canQueryAsInstaller(newPkgSetting, existingPkg)) { || canQueryAsInstaller(newPkgSetting, existingPkg)) {
synchronized (mQueriesViaPackageLock) {
mQueriesViaPackage.add(newPkgSetting.getAppId(), mQueriesViaPackage.add(newPkgSetting.getAppId(),
existingSetting.getAppId()); existingSetting.getAppId());
} }
}
if (canQueryViaUsesLibrary(newPkg, existingPkg)) { if (canQueryViaUsesLibrary(newPkg, existingPkg)) {
synchronized (mQueryableViaUsesLibraryLock) {
mQueryableViaUsesLibrary.add(newPkgSetting.getAppId(), mQueryableViaUsesLibrary.add(newPkgSetting.getAppId(),
existingSetting.getAppId()); existingSetting.getAppId());
} }
} }
}
// if either package instruments the other, mark both as visible to one another // if either package instruments the other, mark both as visible to one another
if (newPkgSetting.getPkg() != null && existingSetting.getPkg() != null if (newPkgSetting.getPkg() != null && existingSetting.getPkg() != null
&& (pkgInstruments(newPkgSetting.getPkg(), existingSetting.getPkg()) && (pkgInstruments(newPkgSetting.getPkg(), existingSetting.getPkg())
|| pkgInstruments(existingSetting.getPkg(), newPkgSetting.getPkg()))) { || pkgInstruments(existingSetting.getPkg(), newPkgSetting.getPkg()))) {
synchronized (mQueriesViaPackageLock) {
mQueriesViaPackage.add(newPkgSetting.getAppId(), existingSetting.getAppId()); mQueriesViaPackage.add(newPkgSetting.getAppId(), existingSetting.getAppId());
mQueriesViaPackage.add(existingSetting.getAppId(), newPkgSetting.getAppId()); mQueriesViaPackage.add(existingSetting.getAppId(), newPkgSetting.getAppId());
} }
} }
} }
int existingSize = existingSettings.size(); int existingSize = existingSettings.size();
ArrayMap<String, AndroidPackage> existingPkgs = new ArrayMap<>(existingSize); ArrayMap<String, AndroidPackage> existingPkgs = new ArrayMap<>(existingSize);
for (int index = 0; index < existingSize; index++) { for (int index = 0; index < existingSize; index++) {
@@ -586,9 +618,6 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
} }
private void removeAppIdFromVisibilityCache(int appId) { private void removeAppIdFromVisibilityCache(int appId) {
if (!mSystemReady) {
return;
}
synchronized (mCacheLock) { synchronized (mCacheLock) {
for (int i = 0; i < mShouldFilterCache.size(); i++) { for (int i = 0; i < mShouldFilterCache.size(); i++) {
if (UserHandle.getAppId(mShouldFilterCache.keyAt(i)) == appId) { if (UserHandle.getAppId(mShouldFilterCache.keyAt(i)) == appId) {
@@ -642,7 +671,17 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
} }
private void updateEntireShouldFilterCacheAsync(PackageManagerInternal pmInternal) { 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 ArrayMap<String, AndroidPackage> packagesCache = new ArrayMap<>();
final UserInfo[][] usersRef = new UserInfo[1][]; final UserInfo[][] usersRef = new UserInfo[1][];
final PackageDataSnapshot snapshot = pmInternal.snapshot(); final PackageDataSnapshot snapshot = pmInternal.snapshot();
@@ -661,18 +700,27 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
updateEntireShouldFilterCacheInner(snapshot, settings, usersRef[0], USER_ALL); updateEntireShouldFilterCacheInner(snapshot, settings, usersRef[0], USER_ALL);
onChanged(); 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) { public void onUserCreated(PackageDataSnapshot snapshot, int newUserId) {
if (!mSystemReady) { if (!mCacheReady) {
return; return;
} }
updateEntireShouldFilterCache(snapshot, newUserId); updateEntireShouldFilterCache(snapshot, newUserId);
} }
public void onUserDeleted(@UserIdInt int userId) { public void onUserDeleted(@UserIdInt int userId) {
if (!mSystemReady) { if (!mCacheReady) {
return; return;
} }
removeShouldFilterCacheForUser(userId); removeShouldFilterCacheForUser(userId);
@@ -681,7 +729,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
private void updateShouldFilterCacheForPackage(PackageDataSnapshot snapshot, private void updateShouldFilterCacheForPackage(PackageDataSnapshot snapshot,
String packageName) { String packageName) {
if (!mSystemReady) { if (!mCacheReady) {
return; return;
} }
final ArrayMap<String, ? extends PackageStateInternal> settings = final ArrayMap<String, ? extends PackageStateInternal> settings =
@@ -772,7 +820,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
private void collectProtectedBroadcasts( private void collectProtectedBroadcasts(
ArrayMap<String, ? extends PackageStateInternal> existingSettings, ArrayMap<String, ? extends PackageStateInternal> existingSettings,
@Nullable String excludePackage) { @Nullable String excludePackage) {
synchronized (mLock) { synchronized (mProtectedBroadcastsLock) {
mProtectedBroadcasts.clear(); mProtectedBroadcasts.clear();
for (int i = existingSettings.size() - 1; i >= 0; i--) { for (int i = existingSettings.size() - 1; i >= 0; i--) {
PackageStateInternal setting = existingSettings.valueAt(i); PackageStateInternal setting = existingSettings.valueAt(i);
@@ -806,8 +854,9 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
*/ */
private void recomputeComponentVisibility( private void recomputeComponentVisibility(
ArrayMap<String, ? extends PackageStateInternal> existingSettings) { ArrayMap<String, ? extends PackageStateInternal> existingSettings) {
synchronized (mLock) { synchronized (mQueriesViaComponentLock) {
mQueriesViaComponent.clear(); mQueriesViaComponent.clear();
}
for (int i = existingSettings.size() - 1; i >= 0; i--) { for (int i = existingSettings.size() - 1; i >= 0; i--) {
PackageStateInternal setting = existingSettings.valueAt(i); PackageStateInternal setting = existingSettings.valueAt(i);
if (setting.getPkg() == null || requestsQueryAllPackages(setting.getPkg())) { if (setting.getPkg() == null || requestsQueryAllPackages(setting.getPkg())) {
@@ -822,14 +871,20 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
otherSetting.getAppId())) { otherSetting.getAppId())) {
continue; continue;
} }
if (canQueryViaComponents(setting.getPkg(), otherSetting.getPkg(), final boolean canQueryViaComponents;
mProtectedBroadcasts)) { synchronized (mProtectedBroadcastsLock) {
canQueryViaComponents = canQueryViaComponents(setting.getPkg(),
otherSetting.getPkg(), mProtectedBroadcasts);
}
if (canQueryViaComponents) {
synchronized (mQueriesViaComponentLock) {
mQueriesViaComponent.add(setting.getAppId(), otherSetting.getAppId()); mQueriesViaComponent.add(setting.getAppId(), otherSetting.getAppId());
} }
} }
} }
} }
mQueriesViaComponentRequireRecompute = false;
mQueriesViaComponentRequireRecompute.set(false);
onChanged(); onChanged();
} }
@@ -857,7 +912,7 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
final UserInfo[] users = snapshot.getUserInfos(); final UserInfo[] users = snapshot.getUserInfos();
final Collection<SharedUserSetting> sharedUserSettings = snapshot.getAllSharedUsers(); final Collection<SharedUserSetting> sharedUserSettings = snapshot.getAllSharedUsers();
final int userCount = users.length; final int userCount = users.length;
synchronized (mLock) { synchronized (mImplicitlyQueryableLock) {
for (int u = 0; u < userCount; u++) { for (int u = 0; u < userCount; u++) {
final int userId = users[u].id; final int userId = users[u].id;
final int removingUid = UserHandle.getUid(userId, setting.getAppId()); final int removingUid = UserHandle.getUid(userId, setting.getAppId());
@@ -877,37 +932,51 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
mRetainedImplicitlyQueryable.keyAt(i), removingUid); mRetainedImplicitlyQueryable.keyAt(i), removingUid);
} }
} }
}
if (!mQueriesViaComponentRequireRecompute) { if (!mQueriesViaComponentRequireRecompute.get()) {
synchronized (mQueriesViaComponentLock) {
mQueriesViaComponent.remove(setting.getAppId()); mQueriesViaComponent.remove(setting.getAppId());
for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) { for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) {
mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), setting.getAppId());
setting.getAppId());
} }
} }
}
synchronized (mQueriesViaPackageLock) {
mQueriesViaPackage.remove(setting.getAppId()); mQueriesViaPackage.remove(setting.getAppId());
for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) { for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) {
mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i),
setting.getAppId()); setting.getAppId());
} }
}
synchronized (mQueryableViaUsesLibraryLock) {
mQueryableViaUsesLibrary.remove(setting.getAppId()); mQueryableViaUsesLibrary.remove(setting.getAppId());
for (int i = mQueryableViaUsesLibrary.size() - 1; i >= 0; i--) { for (int i = mQueryableViaUsesLibrary.size() - 1; i >= 0; i--) {
mQueryableViaUsesLibrary.remove(mQueryableViaUsesLibrary.keyAt(i), mQueryableViaUsesLibrary.remove(mQueryableViaUsesLibrary.keyAt(i),
setting.getAppId()); setting.getAppId());
} }
}
synchronized (mForceQueryableLock) {
mForceQueryable.remove(setting.getAppId()); mForceQueryable.remove(setting.getAppId());
}
boolean protectedBroadcastsChanged = false;
synchronized (mProtectedBroadcastsLock) {
if (setting.getPkg() != null if (setting.getPkg() != null
&& !setting.getPkg().getProtectedBroadcasts().isEmpty()) { && !setting.getPkg().getProtectedBroadcasts().isEmpty()) {
final String removingPackageName = setting.getPkg().getPackageName(); final String removingPackageName = setting.getPkg().getPackageName();
final ArrayList<String> protectedBroadcasts = new ArrayList<>(); final ArrayList<String> protectedBroadcasts = new ArrayList<>(
protectedBroadcasts.addAll(mProtectedBroadcasts.untrackedStorage()); mProtectedBroadcasts.untrackedStorage());
collectProtectedBroadcasts(settings, removingPackageName); collectProtectedBroadcasts(settings, removingPackageName);
if (!mProtectedBroadcasts.containsAll(protectedBroadcasts)) { protectedBroadcastsChanged = !mProtectedBroadcasts.containsAll(protectedBroadcasts);
mQueriesViaComponentRequireRecompute = true;
} }
} }
if (protectedBroadcastsChanged) {
mQueriesViaComponentRequireRecompute.set(true);
} }
additionalChangedPackages = mOverlayReferenceMapper.removePkg(setting.getPackageName()); additionalChangedPackages = mOverlayReferenceMapper.removePkg(setting.getPackageName());
@@ -929,8 +998,10 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
} }
} }
if (mCacheReady) {
removeAppIdFromVisibilityCache(setting.getAppId()); removeAppIdFromVisibilityCache(setting.getAppId());
if (mSystemReady && setting.hasSharedUser()) {
if (setting.hasSharedUser()) {
final ArraySet<? extends PackageStateInternal> sharedUserPackages = final ArraySet<? extends PackageStateInternal> sharedUserPackages =
getSharedUserPackages(setting.getSharedUserAppId(), sharedUserSettings); getSharedUserPackages(setting.getSharedUserAppId(), sharedUserSettings);
for (int i = sharedUserPackages.size() - 1; i >= 0; i--) { for (int i = sharedUserPackages.size() - 1; i >= 0; i--) {
@@ -947,7 +1018,6 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
} }
} }
if (mSystemReady) {
if (additionalChangedPackages != null) { if (additionalChangedPackages != null) {
for (int index = 0; index < additionalChangedPackages.size(); index++) { for (int index = 0; index < additionalChangedPackages.size(); index++) {
String changedPackage = additionalChangedPackages.valueAt(index); String changedPackage = additionalChangedPackages.valueAt(index);
@@ -964,6 +1034,8 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
} }
} }
} }
} else {
invalidateCache("removePackage: " + setting.getPackageName());
} }
onChanged(); onChanged();
} }

View File

@@ -26,52 +26,61 @@ import java.io.PrintWriter;
*/ */
abstract class AppsFilterLocked extends AppsFilterBase { 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}; * Guards the access for {@link AppsFilterBase#mShouldFilterCache};
*/ */
protected Object mCacheLock = new Object(); protected final Object mCacheLock = new Object();
@Override @Override
protected boolean isForceQueryable(int appId) { protected boolean isForceQueryable(int appId) {
synchronized (mLock) { synchronized (mForceQueryableLock) {
return super.isForceQueryable(appId); return super.isForceQueryable(appId);
} }
} }
@Override @Override
protected boolean isQueryableViaPackage(int callingAppId, int targetAppId) { protected boolean isQueryableViaPackage(int callingAppId, int targetAppId) {
synchronized (mLock) { synchronized (mQueriesViaPackageLock) {
return super.isQueryableViaPackage(callingAppId, targetAppId); return super.isQueryableViaPackage(callingAppId, targetAppId);
} }
} }
@Override @Override
protected boolean isQueryableViaComponent(int callingAppId, int targetAppId) { protected boolean isQueryableViaComponent(int callingAppId, int targetAppId) {
synchronized (mLock) { synchronized (mQueriesViaComponentLock) {
return super.isQueryableViaComponent(callingAppId, targetAppId); return super.isQueryableViaComponent(callingAppId, targetAppId);
} }
} }
@Override @Override
protected boolean isImplicitlyQueryable(int callingAppId, int targetAppId) { protected boolean isImplicitlyQueryable(int callingAppId, int targetAppId) {
synchronized (mLock) { synchronized (mImplicitlyQueryableLock) {
return super.isImplicitlyQueryable(callingAppId, targetAppId); return super.isImplicitlyQueryable(callingAppId, targetAppId);
} }
} }
@Override @Override
protected boolean isRetainedImplicitlyQueryable(int callingAppId, int targetAppId) { protected boolean isRetainedImplicitlyQueryable(int callingAppId, int targetAppId) {
synchronized (mLock) { synchronized (mImplicitlyQueryableLock) {
return super.isRetainedImplicitlyQueryable(callingAppId, targetAppId); return super.isRetainedImplicitlyQueryable(callingAppId, targetAppId);
} }
} }
@Override @Override
protected boolean isQueryableViaUsesLibrary(int callingAppId, int targetAppId) { protected boolean isQueryableViaUsesLibrary(int callingAppId, int targetAppId) {
synchronized (mLock) { synchronized (mQueryableViaUsesLibraryLock) {
return super.isQueryableViaUsesLibrary(callingAppId, targetAppId); return super.isQueryableViaUsesLibrary(callingAppId, targetAppId);
} }
} }
@@ -84,10 +93,42 @@ abstract class AppsFilterLocked extends AppsFilterBase {
} }
@Override @Override
protected void dumpQueryables(PrintWriter pw, @Nullable Integer filteringAppId, int[] users, protected void dumpForceQueryable(PrintWriter pw, @Nullable Integer filteringAppId,
ToString<Integer> expandPackages) { ToString<Integer> expandPackages) {
synchronized (mLock) { synchronized (mForceQueryableLock) {
dumpQueryables(pw, filteringAppId, users, expandPackages); 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 (mQueryableViaUsesLibraryLock) {
super.dumpQueriesViaUsesLibrary(pw, filteringAppId, expandPackages);
} }
} }
} }

View File

@@ -17,6 +17,7 @@
package com.android.server.pm; package com.android.server.pm;
import com.android.server.utils.SnapshotCache; import com.android.server.utils.SnapshotCache;
import com.android.server.utils.WatchedSparseBooleanMatrix;
import java.util.Arrays; import java.util.Arrays;
@@ -25,22 +26,32 @@ import java.util.Arrays;
*/ */
public final class AppsFilterSnapshotImpl extends AppsFilterBase { public final class AppsFilterSnapshotImpl extends AppsFilterBase {
AppsFilterSnapshotImpl(AppsFilterImpl orig) { AppsFilterSnapshotImpl(AppsFilterImpl orig) {
synchronized (orig.mLock) { synchronized (orig.mImplicitlyQueryableLock) {
mImplicitlyQueryable = orig.mImplicitQueryableSnapshot.snapshot(); mImplicitlyQueryable = orig.mImplicitQueryableSnapshot.snapshot();
mImplicitQueryableSnapshot = new SnapshotCache.Sealed<>();
mRetainedImplicitlyQueryable = orig.mRetainedImplicitlyQueryableSnapshot.snapshot(); 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<>();
} }
mImplicitQueryableSnapshot = new SnapshotCache.Sealed<>();
mRetainedImplicitlyQueryableSnapshot = new SnapshotCache.Sealed<>();
synchronized (orig.mQueriesViaPackageLock) {
mQueriesViaPackage = orig.mQueriesViaPackageSnapshot.snapshot();
}
mQueriesViaPackageSnapshot = new SnapshotCache.Sealed<>();
synchronized (orig.mQueriesViaComponentLock) {
mQueriesViaComponent = orig.mQueriesViaComponentSnapshot.snapshot();
}
mQueriesViaComponentSnapshot = new SnapshotCache.Sealed<>();
synchronized (orig.mQueryableViaUsesLibraryLock) {
mQueryableViaUsesLibrary = orig.mQueryableViaUsesLibrarySnapshot.snapshot();
}
mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Sealed<>();
synchronized (orig.mForceQueryableLock) {
mForceQueryable = orig.mForceQueryableSnapshot.snapshot();
}
mForceQueryableSnapshot = new SnapshotCache.Sealed<>();
synchronized (orig.mProtectedBroadcastsLock) {
mProtectedBroadcasts = orig.mProtectedBroadcastsSnapshot.snapshot();
}
mProtectedBroadcastsSnapshot = new SnapshotCache.Sealed<>();
mQueriesViaComponentRequireRecompute = orig.mQueriesViaComponentRequireRecompute; mQueriesViaComponentRequireRecompute = orig.mQueriesViaComponentRequireRecompute;
mForceQueryableByDevicePackageNames = mForceQueryableByDevicePackageNames =
Arrays.copyOf(orig.mForceQueryableByDevicePackageNames, Arrays.copyOf(orig.mForceQueryableByDevicePackageNames,
@@ -49,12 +60,18 @@ public final class AppsFilterSnapshotImpl extends AppsFilterBase {
mFeatureConfig = orig.mFeatureConfig.snapshot(); mFeatureConfig = orig.mFeatureConfig.snapshot();
mOverlayReferenceMapper = orig.mOverlayReferenceMapper; mOverlayReferenceMapper = orig.mOverlayReferenceMapper;
mSystemSigningDetails = orig.mSystemSigningDetails; mSystemSigningDetails = orig.mSystemSigningDetails;
mCacheReady = orig.mCacheReady;
if (mCacheReady) {
synchronized (orig.mCacheLock) { synchronized (orig.mCacheLock) {
mShouldFilterCache = orig.mShouldFilterCacheSnapshot.snapshot(); mShouldFilterCache = orig.mShouldFilterCacheSnapshot.snapshot();
}
} else {
// cache is not ready, use an empty cache for the snapshot
mShouldFilterCache = new WatchedSparseBooleanMatrix();
}
mShouldFilterCacheSnapshot = new SnapshotCache.Sealed<>(); mShouldFilterCacheSnapshot = new SnapshotCache.Sealed<>();
}
mBackgroundExecutor = null; mBackgroundHandler = null;
mSystemReady = orig.mSystemReady;
} }
} }

View File

@@ -22,7 +22,7 @@ import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any; 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.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -35,6 +35,8 @@ import android.content.pm.Signature;
import android.content.pm.SigningDetails; import android.content.pm.SigningDetails;
import android.content.pm.UserInfo; import android.content.pm.UserInfo;
import android.os.Build; import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.Process; import android.os.Process;
import android.os.UserHandle; import android.os.UserHandle;
import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit;
@@ -74,7 +76,6 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Executor;
@Presubmit @Presubmit
@RunWith(JUnit4.class) @RunWith(JUnit4.class)
@@ -103,7 +104,7 @@ public class AppsFilterImplTest {
@Mock @Mock
PackageDataSnapshot mSnapshot; PackageDataSnapshot mSnapshot;
@Mock @Mock
Executor mMockExecutor; Handler mMockHandler;
@Mock @Mock
PackageManagerInternal mPmInternal; PackageManagerInternal mPmInternal;
@@ -210,10 +211,12 @@ public class AppsFilterImplTest {
when(mSnapshot.getUserInfos()).thenReturn(USER_INFO_LIST); when(mSnapshot.getUserInfos()).thenReturn(USER_INFO_LIST);
when(mPmInternal.snapshot()).thenReturn(mSnapshot); when(mPmInternal.snapshot()).thenReturn(mSnapshot);
doAnswer(invocation -> { // Can't mock postDelayed because of some weird bug in Mockito.
((Runnable) invocation.getArgument(0)).run(); when(mMockHandler.sendMessageDelayed(any(Message.class), anyLong())).thenAnswer(
return new Object(); invocation -> {
}).when(mMockExecutor).execute(any(Runnable.class)); ((Message) invocation.getArgument(0)).getCallback().run();
return null;
});
when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true); when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true);
when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))).thenAnswer( when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))).thenAnswer(
@@ -226,7 +229,7 @@ public class AppsFilterImplTest {
public void testSystemReadyPropogates() throws Exception { public void testSystemReadyPropogates() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register(); watcher.register();
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -238,7 +241,7 @@ public class AppsFilterImplTest {
public void testQueriesAction_FilterMatches() throws Exception { public void testQueriesAction_FilterMatches() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register(); watcher.register();
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
@@ -263,7 +266,7 @@ public class AppsFilterImplTest {
public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception { public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register(); watcher.register();
final Signature frameworkSignature = Mockito.mock(Signature.class); final Signature frameworkSignature = Mockito.mock(Signature.class);
@@ -312,7 +315,7 @@ public class AppsFilterImplTest {
public void testQueriesProvider_FilterMatches() throws Exception { public void testQueriesProvider_FilterMatches() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register(); watcher.register();
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
@@ -337,7 +340,7 @@ public class AppsFilterImplTest {
public void testOnUserUpdated_FilterMatches() throws Exception { public void testOnUserUpdated_FilterMatches() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -385,7 +388,7 @@ public class AppsFilterImplTest {
public void testQueriesDifferentProvider_Filters() throws Exception { public void testQueriesDifferentProvider_Filters() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register(); watcher.register();
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
@@ -410,7 +413,7 @@ public class AppsFilterImplTest {
public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception { public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -429,7 +432,7 @@ public class AppsFilterImplTest {
public void testQueriesAction_NoMatchingAction_Filters() throws Exception { public void testQueriesAction_NoMatchingAction_Filters() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -446,7 +449,7 @@ public class AppsFilterImplTest {
public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception { public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -468,7 +471,7 @@ public class AppsFilterImplTest {
public void testNoQueries_Filters() throws Exception { public void testNoQueries_Filters() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -486,7 +489,7 @@ public class AppsFilterImplTest {
public void testNoUsesLibrary_Filters() throws Exception { public void testNoUsesLibrary_Filters() throws Exception {
final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -513,7 +516,7 @@ public class AppsFilterImplTest {
public void testUsesLibrary_DoesntFilter() throws Exception { public void testUsesLibrary_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -541,7 +544,7 @@ public class AppsFilterImplTest {
public void testUsesOptionalLibrary_DoesntFilter() throws Exception { public void testUsesOptionalLibrary_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -569,7 +572,7 @@ public class AppsFilterImplTest {
public void testUsesLibrary_ShareUid_DoesntFilter() throws Exception { public void testUsesLibrary_ShareUid_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock, final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -602,7 +605,7 @@ public class AppsFilterImplTest {
public void testForceQueryable_SystemDoesntFilter() throws Exception { public void testForceQueryable_SystemDoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -622,7 +625,7 @@ public class AppsFilterImplTest {
public void testForceQueryable_NonSystemFilters() throws Exception { public void testForceQueryable_NonSystemFilters() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -641,7 +644,7 @@ public class AppsFilterImplTest {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new AppsFilterImpl(mFeatureConfigMock,
new String[]{"com.some.package"}, false, null, new String[]{"com.some.package"}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -661,7 +664,7 @@ public class AppsFilterImplTest {
public void testSystemSignedTarget_DoesntFilter() throws CertificateException { public void testSystemSignedTarget_DoesntFilter() throws CertificateException {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
final Signature frameworkSignature = Mockito.mock(Signature.class); final Signature frameworkSignature = Mockito.mock(Signature.class);
@@ -692,7 +695,7 @@ public class AppsFilterImplTest {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new AppsFilterImpl(mFeatureConfigMock,
new String[]{"com.some.package"}, false, null, new String[]{"com.some.package"}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -711,7 +714,7 @@ public class AppsFilterImplTest {
public void testSystemQueryable_DoesntFilter() throws Exception { public void testSystemQueryable_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, new AppsFilterImpl(mFeatureConfigMock, new String[]{},
true /* system force queryable */, null, mMockExecutor); true /* system force queryable */, null, mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -730,7 +733,7 @@ public class AppsFilterImplTest {
public void testQueriesPackage_DoesntFilter() throws Exception { public void testQueriesPackage_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -750,7 +753,7 @@ public class AppsFilterImplTest {
.thenReturn(false); .thenReturn(false);
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -768,7 +771,7 @@ public class AppsFilterImplTest {
public void testSystemUid_DoesntFilter() throws Exception { public void testSystemUid_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -785,7 +788,7 @@ public class AppsFilterImplTest {
public void testSystemUidSecondaryUser_DoesntFilter() throws Exception { public void testSystemUidSecondaryUser_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -803,7 +806,7 @@ public class AppsFilterImplTest {
public void testNonSystemUid_NoCallingSetting_Filters() throws Exception { public void testNonSystemUid_NoCallingSetting_Filters() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -818,7 +821,7 @@ public class AppsFilterImplTest {
public void testNoTargetPackage_filters() throws Exception { public void testNoTargetPackage_filters() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -876,7 +879,7 @@ public class AppsFilterImplTest {
return Collections.emptyMap(); return Collections.emptyMap();
} }
}, },
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -966,7 +969,7 @@ public class AppsFilterImplTest {
return Collections.emptyMap(); return Collections.emptyMap();
} }
}, },
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -990,7 +993,7 @@ public class AppsFilterImplTest {
public void testInitiatingApp_DoesntFilter() throws Exception { public void testInitiatingApp_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -1009,7 +1012,7 @@ public class AppsFilterImplTest {
public void testUninstalledInitiatingApp_Filters() throws Exception { public void testUninstalledInitiatingApp_Filters() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
@@ -1028,7 +1031,7 @@ public class AppsFilterImplTest {
public void testOriginatingApp_Filters() throws Exception { public void testOriginatingApp_Filters() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register(); watcher.register();
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
@@ -1054,7 +1057,7 @@ public class AppsFilterImplTest {
public void testInstallingApp_DoesntFilter() throws Exception { public void testInstallingApp_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register(); watcher.register();
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
@@ -1080,7 +1083,7 @@ public class AppsFilterImplTest {
public void testInstrumentation_DoesntFilter() throws Exception { public void testInstrumentation_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register(); watcher.register();
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
@@ -1109,7 +1112,7 @@ public class AppsFilterImplTest {
public void testWhoCanSee() throws Exception { public void testWhoCanSee() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register(); watcher.register();
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
@@ -1184,7 +1187,7 @@ public class AppsFilterImplTest {
public void testOnChangeReport() throws Exception { public void testOnChangeReport() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register(); watcher.register();
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
@@ -1259,7 +1262,7 @@ public class AppsFilterImplTest {
public void testOnChangeReportedFilter() throws Exception { public void testOnChangeReportedFilter() throws Exception {
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange filter"); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange filter");
@@ -1286,7 +1289,7 @@ public class AppsFilterImplTest {
when(mFeatureConfigMock.snapshot()).thenReturn(mFeatureConfigMock); when(mFeatureConfigMock.snapshot()).thenReturn(mFeatureConfigMock);
final AppsFilterImpl appsFilter = final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null, new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor); mMockHandler);
simulateAddBasicAndroid(appsFilter); simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal); appsFilter.onSystemReady(mPmInternal);