Merge "Add a permissions filter in AppsFilter"

This commit is contained in:
TreeHugger Robot
2022-07-15 02:21:42 +00:00
committed by Android (Google) Code Review
5 changed files with 410 additions and 86 deletions

View File

@@ -127,6 +127,16 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
@NonNull
protected SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesLibrarySnapshot;
/**
* A mapping from the set of App IDs that query other App IDs via custom permissions to the
* list of packages that they can see.
*/
@NonNull
@Watched
protected WatchedSparseSetArray<Integer> mQueryableViaUsesPermission;
@NonNull
protected SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesPermissionSnapshot;
/**
* Handler for running reasonably short background tasks such as building the initial
* visibility cache.
@@ -217,6 +227,10 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
return mQueryableViaUsesLibrary.contains(callingAppId, targetAppId);
}
protected boolean isQueryableViaUsesPermission(int callingAppId, int targetAppId) {
return mQueryableViaUsesPermission.contains(callingAppId, targetAppId);
}
protected boolean isQueryableViaComponentWhenRequireRecompute(
ArrayMap<String, ? extends PackageStateInternal> existingSettings,
PackageStateInternal callingPkgSetting,
@@ -628,6 +642,22 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
}
}
try {
if (DEBUG_TRACING) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueryableViaUsesPermission");
}
if (isQueryableViaUsesPermission(callingAppId, targetAppId)) {
if (DEBUG_LOGGING) {
log(callingSetting, targetPkgSetting, "queryable for permission users");
}
return false;
}
} finally {
if (DEBUG_TRACING) {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
return true;
} finally {
if (DEBUG_TRACING) {
@@ -763,6 +793,13 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
expandPackages);
}
protected void dumpQueriesViaUsesPermission(PrintWriter pw, @Nullable Integer filteringAppId,
ToString<Integer> expandPackages) {
pw.println(" queryable via uses-permission:");
dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesPermission, " ",
expandPackages);
}
private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId,
WatchedSparseSetArray<Integer> queriesMap, String spacing,
@Nullable ToString<Integer> toString) {

View File

@@ -55,6 +55,8 @@ import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.component.ParsedInstrumentation;
import com.android.server.pm.pkg.component.ParsedPermission;
import com.android.server.pm.pkg.component.ParsedUsesPermission;
import com.android.server.utils.Snappable;
import com.android.server.utils.SnapshotCache;
import com.android.server.utils.Watchable;
@@ -68,8 +70,11 @@ import com.android.server.utils.Watcher;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* Implementation of the methods that update the internal structures of AppsFilter. Because of the
@@ -89,6 +94,26 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
*/
private final WatchableImpl mWatchable = new WatchableImpl();
/**
* A cache that maps parsed {@link android.R.styleable#AndroidManifestPermission
* &lt;permission&gt;} to the packages that define them. While computing visibility based on
* permissions, this cache is used to save the cost of reading through every existing package
* to determine the App Ids that define a particular permission.
*/
@GuardedBy("mQueryableViaUsesPermissionLock")
@NonNull
private HashMap<String, Set<Integer>> mPermissionToUids;
/**
* A cache that maps parsed {@link android.R.styleable#AndroidManifestUsesPermission
* &lt;uses-permission&gt;} to the packages that request them. While computing visibility based
* on permissions, this cache is used to save the cost of reading through every existing
* package to determine the App Ids that request a particular permission.
*/
@GuardedBy("mQueryableViaUsesPermissionLock")
@NonNull
private HashMap<String, Set<Integer>> mUsesPermissionToUids;
/**
* Ensures an observer is in the list, exactly once. The observer cannot be null. The
* function quietly returns if the observer is already in the list.
@@ -179,12 +204,18 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Auto<>(
mQueryableViaUsesLibrary, mQueryableViaUsesLibrary,
"AppsFilter.mQueryableViaUsesLibrary");
mQueryableViaUsesPermission = new WatchedSparseSetArray<>();
mQueryableViaUsesPermissionSnapshot = new SnapshotCache.Auto<>(
mQueryableViaUsesPermission, mQueryableViaUsesPermission,
"AppsFilter.mQueryableViaUsesPermission");
mForceQueryable = new WatchedArraySet<>();
mForceQueryableSnapshot = new SnapshotCache.Auto<>(
mForceQueryable, mForceQueryable, "AppsFilter.mForceQueryable");
mProtectedBroadcasts = new WatchedArrayList<>();
mProtectedBroadcastsSnapshot = new SnapshotCache.Auto<>(
mProtectedBroadcasts, mProtectedBroadcasts, "AppsFilter.mProtectedBroadcasts");
mPermissionToUids = new HashMap<>();
mUsesPermissionToUids = new HashMap<>();
mSnapshot = new SnapshotCache<AppsFilterSnapshot>(this, this) {
@Override
@@ -532,6 +563,54 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
}
}
if (!newPkg.getUsesPermissions().isEmpty()) {
// newPkg requests some permissions
synchronized (mQueryableViaUsesPermissionLock) {
for (ParsedUsesPermission usesPermission : newPkg.getUsesPermissions()) {
String usesPermissionName = usesPermission.getName();
// Lookup in the mPermissionToUids cache if installed packages have
// defined this permission.
if (mPermissionToUids.containsKey(usesPermissionName)) {
for (int targetAppId : mPermissionToUids.get(usesPermissionName)) {
if (targetAppId != newPkgSetting.getAppId()) {
mQueryableViaUsesPermission.add(newPkgSetting.getAppId(),
targetAppId);
}
}
}
// Record in mUsesPermissionToUids that a permission was requested
// by a new package
if (!mUsesPermissionToUids.containsKey(usesPermissionName)) {
mUsesPermissionToUids.put(usesPermissionName, new HashSet<>());
}
mUsesPermissionToUids.get(usesPermissionName).add(newPkgSetting.getAppId());
}
}
}
if (!newPkg.getPermissions().isEmpty()) {
synchronized (mQueryableViaUsesPermissionLock) {
// newPkg defines some permissions
for (ParsedPermission permission : newPkg.getPermissions()) {
String permissionName = permission.getName();
// Lookup in the mUsesPermissionToUids cache if installed packages have
// requested this permission.
if (mUsesPermissionToUids.containsKey(permissionName)) {
for (int queryingAppId : mUsesPermissionToUids.get(permissionName)) {
if (queryingAppId != newPkgSetting.getAppId()) {
mQueryableViaUsesPermission.add(queryingAppId,
newPkgSetting.getAppId());
}
}
}
// Record in mPermissionToUids that a permission was defined by a new package
if (!mPermissionToUids.containsKey(permissionName)) {
mPermissionToUids.put(permissionName, new HashSet<>());
}
mPermissionToUids.get(permissionName).add(newPkgSetting.getAppId());
}
}
}
for (int i = existingSettings.size() - 1; i >= 0; i--) {
final PackageStateInternal existingSetting = existingSettings.valueAt(i);
if (existingSetting.getAppId() == newPkgSetting.getAppId()
@@ -960,6 +1039,32 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
}
}
synchronized (mQueryableViaUsesPermissionLock) {
if (setting.getPkg() != null && !setting.getPkg().getPermissions().isEmpty()) {
for (ParsedPermission permission : setting.getPkg().getPermissions()) {
String permissionName = permission.getName();
if (mPermissionToUids.containsKey(permissionName)) {
mPermissionToUids.get(permissionName).remove(setting.getAppId());
if (mPermissionToUids.get(permissionName).isEmpty()) {
mPermissionToUids.remove(permissionName);
}
}
}
}
if (setting.getPkg() != null && !setting.getPkg().getUsesPermissions().isEmpty()) {
for (ParsedUsesPermission usesPermission : setting.getPkg().getUsesPermissions()) {
String usesPermissionName = usesPermission.getName();
if (mUsesPermissionToUids.containsKey(usesPermissionName)) {
mUsesPermissionToUids.get(usesPermissionName).remove(setting.getAppId());
if (mUsesPermissionToUids.get(usesPermissionName).isEmpty()) {
mUsesPermissionToUids.remove(usesPermissionName);
}
}
}
}
mQueryableViaUsesPermission.remove(setting.getAppId());
}
synchronized (mForceQueryableLock) {
mForceQueryable.remove(setting.getAppId());
}

View File

@@ -33,10 +33,11 @@ abstract class AppsFilterLocked extends AppsFilterBase {
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();
protected final Object mQueryableViaUsesPermissionLock = new Object();
/**
* Guards the access for {@link AppsFilterBase#mShouldFilterCache};
@@ -85,6 +86,13 @@ abstract class AppsFilterLocked extends AppsFilterBase {
}
}
@Override
protected boolean isQueryableViaUsesPermission(int callingAppId, int targetAppId) {
synchronized (mQueryableViaUsesPermissionLock) {
return super.isQueryableViaUsesPermission(callingAppId, targetAppId);
}
}
@Override
protected boolean shouldFilterApplicationUsingCache(int callingUid, int appId, int userId) {
synchronized (mCacheLock) {

View File

@@ -44,6 +44,10 @@ public final class AppsFilterSnapshotImpl extends AppsFilterBase {
mQueryableViaUsesLibrary = orig.mQueryableViaUsesLibrarySnapshot.snapshot();
}
mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Sealed<>();
synchronized (orig.mQueryableViaUsesPermissionLock) {
mQueryableViaUsesPermission = orig.mQueryableViaUsesPermissionSnapshot.snapshot();
}
mQueryableViaUsesPermissionSnapshot = new SnapshotCache.Sealed<>();
synchronized (orig.mForceQueryableLock) {
mForceQueryable = orig.mForceQueryableSnapshot.snapshot();
}

View File

@@ -52,9 +52,13 @@ import com.android.server.pm.parsing.pkg.PackageImpl;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.pkg.component.ParsedActivity;
import com.android.server.pm.pkg.component.ParsedActivityImpl;
import com.android.server.pm.pkg.component.ParsedComponentImpl;
import com.android.server.pm.pkg.component.ParsedInstrumentationImpl;
import com.android.server.pm.pkg.component.ParsedIntentInfoImpl;
import com.android.server.pm.pkg.component.ParsedPermission;
import com.android.server.pm.pkg.component.ParsedPermissionImpl;
import com.android.server.pm.pkg.component.ParsedProviderImpl;
import com.android.server.pm.pkg.component.ParsedUsesPermissionImpl;
import com.android.server.pm.pkg.parsing.ParsingPackage;
import com.android.server.utils.WatchableTester;
@@ -160,6 +164,17 @@ public class AppsFilterImplTest {
return pkg(packageName).addLibraryName(libName);
}
private static ParsingPackage pkgWithCustomPermissions(String packageName,
String... permNames) {
ParsingPackage newPkg = pkg(packageName);
for (String permName : permNames) {
ParsedPermission permission = new ParsedPermissionImpl();
((ParsedComponentImpl) permission).setName(permName);
newPkg.addPermission(permission);
}
return newPkg;
}
private static ParsedActivity createActivity(String packageName, IntentFilter[] filters) {
ParsedActivityImpl activity = new ParsedActivityImpl();
activity.setPackageName(packageName);
@@ -227,8 +242,8 @@ public class AppsFilterImplTest {
@Test
public void testSystemReadyPropogates() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
appsFilter.onSystemReady(mPmInternal);
@@ -239,8 +254,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesAction_FilterMatches() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -264,8 +279,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
final Signature frameworkSignature = Mockito.mock(Signature.class);
@@ -313,8 +328,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesProvider_FilterMatches() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -338,8 +353,8 @@ public class AppsFilterImplTest {
@Test
public void testOnUserUpdated_FilterMatches() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -386,8 +401,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesDifferentProvider_Filters() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -411,8 +426,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -430,8 +445,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesAction_NoMatchingAction_Filters() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -447,8 +462,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -469,8 +484,8 @@ public class AppsFilterImplTest {
@Test
public void testNoQueries_Filters() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -486,10 +501,9 @@ public class AppsFilterImplTest {
@Test
public void testNoUsesLibrary_Filters() throws Exception {
final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
mMockHandler);
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -513,10 +527,9 @@ public class AppsFilterImplTest {
@Test
public void testUsesLibrary_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
mMockHandler);
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -541,10 +554,9 @@ public class AppsFilterImplTest {
@Test
public void testUsesOptionalLibrary_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
mMockHandler);
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -569,10 +581,9 @@ public class AppsFilterImplTest {
@Test
public void testUsesLibrary_ShareUid_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
mMockHandler);
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -603,8 +614,8 @@ public class AppsFilterImplTest {
@Test
public void testForceQueryable_SystemDoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -623,8 +634,8 @@ public class AppsFilterImplTest {
@Test
public void testForceQueryable_NonSystemFilters() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -641,9 +652,8 @@ public class AppsFilterImplTest {
@Test
public void testForceQueryableByDevice_SystemCaller_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock,
new String[]{"com.some.package"}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{"com.some.package"},
/* systemAppsQueryable */ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -662,8 +672,8 @@ public class AppsFilterImplTest {
@Test
public void testSystemSignedTarget_DoesntFilter() throws CertificateException {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
appsFilter.onSystemReady(mPmInternal);
final Signature frameworkSignature = Mockito.mock(Signature.class);
@@ -692,9 +702,8 @@ public class AppsFilterImplTest {
@Test
public void testForceQueryableByDevice_NonSystemCaller_Filters() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock,
new String[]{"com.some.package"}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{"com.some.package"},
/* systemAppsQueryable */ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -712,8 +721,8 @@ public class AppsFilterImplTest {
@Test
public void testSystemQueryable_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{},
true /* system force queryable */, null, mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
true, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -731,8 +740,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesPackage_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -751,8 +760,8 @@ public class AppsFilterImplTest {
when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class)))
.thenReturn(false);
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -769,8 +778,8 @@ public class AppsFilterImplTest {
@Test
public void testSystemUid_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -786,8 +795,8 @@ public class AppsFilterImplTest {
@Test
public void testSystemUidSecondaryUser_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -804,8 +813,8 @@ public class AppsFilterImplTest {
@Test
public void testNonSystemUid_NoCallingSetting_Filters() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -817,10 +826,10 @@ public class AppsFilterImplTest {
}
@Test
public void testNoTargetPackage_filters() throws Exception {
public void testNoTargetPackage_Filters() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -991,8 +1000,8 @@ public class AppsFilterImplTest {
@Test
public void testInitiatingApp_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -1010,8 +1019,8 @@ public class AppsFilterImplTest {
@Test
public void testUninstalledInitiatingApp_Filters() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -1029,8 +1038,8 @@ public class AppsFilterImplTest {
@Test
public void testOriginatingApp_Filters() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -1055,8 +1064,8 @@ public class AppsFilterImplTest {
@Test
public void testInstallingApp_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -1081,8 +1090,8 @@ public class AppsFilterImplTest {
@Test
public void testInstrumentation_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -1110,8 +1119,8 @@ public class AppsFilterImplTest {
@Test
public void testWhoCanSee() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -1185,8 +1194,8 @@ public class AppsFilterImplTest {
@Test
public void testOnChangeReport() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -1260,8 +1269,8 @@ public class AppsFilterImplTest {
@Test
public void testOnChangeReportedFilter() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange filter");
@@ -1287,8 +1296,8 @@ public class AppsFilterImplTest {
public void testAppsFilterRead() throws Exception {
when(mFeatureConfigMock.snapshot()).thenReturn(mFeatureConfigMock);
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -1338,8 +1347,8 @@ public class AppsFilterImplTest {
@Test
public void testSdkSandbox_canSeeForceQueryable() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -1358,8 +1367,8 @@ public class AppsFilterImplTest {
@Test
public void testSdkSandbox_cannotSeeNonForceQueryable() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -1408,6 +1417,167 @@ public class AppsFilterImplTest {
null /* callingSetting */, target, SYSTEM_USER));
}
@Test
public void testUsesPermission_installPermissionDefinerBeforeRequester_DoesntFilter()
throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
final PackageSetting target = simulateAddPackage(appsFilter,
pkgWithCustomPermissions("com.some.package",
"com.some.custom_permission"),
DUMMY_TARGET_APPID);
final PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package").addUsesPermission(
new ParsedUsesPermissionImpl("com.some.custom_permission", 0)),
DUMMY_CALLING_APPID);
assertFalse(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
}
@Test
public void testUsesPermission_installPermissionRequesterBeforeDefiner_DoesntFilter()
throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
final PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package").addUsesPermission(
new ParsedUsesPermissionImpl("com.some.custom_permission", 0)),
DUMMY_CALLING_APPID);
final PackageSetting target = simulateAddPackage(appsFilter,
pkgWithCustomPermissions("com.some.package",
"com.some.custom_permission"),
DUMMY_TARGET_APPID);
assertFalse(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
}
@Test
public void testUsesPermission_visibilityFromPermissionDefinerToRequester_Filters()
throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
final PackageSetting calling = simulateAddPackage(appsFilter,
pkgWithCustomPermissions("com.some.package",
"com.some.custom_permission"),
DUMMY_CALLING_APPID);
final PackageSetting target = simulateAddPackage(appsFilter,
pkg("com.some.other.package").addUsesPermission(
new ParsedUsesPermissionImpl("com.some.custom_permission", 0)),
DUMMY_TARGET_APPID);
assertTrue(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
}
@Test
public void testUsesPermission_multipleCustomPermissions() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
final PackageSetting target = simulateAddPackage(appsFilter,
pkgWithCustomPermissions("com.some.package",
"com.some.custom_permission1", "com.some.custom_permission2"),
DUMMY_TARGET_APPID);
final PackageSetting calling1 = simulateAddPackage(appsFilter,
pkg("com.some.other.package")
.addUsesPermission(new ParsedUsesPermissionImpl(
"com.some.custom_permission1", 0)),
DUMMY_CALLING_APPID);
final PackageSetting calling2 = simulateAddPackage(appsFilter,
pkg("com.some.another.package")
.addUsesPermission(new ParsedUsesPermissionImpl(
"com.some.custom_permission2", 0))
.addUsesPermission(new ParsedUsesPermissionImpl(
"com.some.custom_permission3", 0)),
DUMMY_CALLING_APPID + 1);
assertFalse(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling1, target,
SYSTEM_USER));
assertFalse(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID + 1,
calling2, target, SYSTEM_USER));
assertTrue(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling1,
calling2, SYSTEM_USER));
}
@Test
public void testUsesPermission_multiplePermissionDefiners_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
final PackageSetting target1 = simulateAddPackage(appsFilter,
pkgWithCustomPermissions("com.some.package1", "com.some.custom_permission"),
DUMMY_TARGET_APPID);
final PackageSetting target2 = simulateAddPackage(appsFilter,
pkgWithCustomPermissions("com.some.package2", "com.some.custom_permission"),
DUMMY_TARGET_APPID + 1);
final PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package")
.addUsesPermission(new ParsedUsesPermissionImpl(
"com.some.custom_permission", 0)),
DUMMY_CALLING_APPID);
assertFalse(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target1,
SYSTEM_USER));
assertFalse(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target2,
SYSTEM_USER));
}
@Test
public void testNoUsesPermission_Filters() throws Exception {
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
final PackageSetting target = simulateAddPackage(appsFilter,
pkgWithCustomPermissions("com.some.package", "com.some.custom_permission"),
DUMMY_TARGET_APPID);
final PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package"),
DUMMY_CALLING_APPID);
assertTrue(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
}
private List<Integer> toList(int[] array) {
ArrayList<Integer> ret = new ArrayList<>(array.length);
for (int i = 0; i < array.length; i++) {