Merge "[AppsFilter] fix cache lock and rebuild cache if needed" into tm-dev
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 (mLock) {
|
||||
dumpQueryables(pw, filteringAppId, users, 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 (mQueryableViaUsesLibraryLock) {
|
||||
super.dumpQueriesViaUsesLibrary(pw, filteringAppId, expandPackages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<>();
|
||||
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;
|
||||
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<>();
|
||||
}
|
||||
|
||||
mBackgroundExecutor = null;
|
||||
mSystemReady = orig.mSystemReady;
|
||||
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<>();
|
||||
|
||||
mBackgroundHandler = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user