Loading services/core/java/android/content/pm/PackageManagerInternal.java +29 −0 Original line number Diff line number Diff line Loading @@ -479,6 +479,35 @@ public abstract class PackageManagerInternal implements PackageSettingsSnapshotP @AppIdInt int recipientAppId, int visibleUid, boolean direct); /** * Grants implicit access based on an interaction between two apps. This grants access to the * from one application to the other's package metadata. * <p> * When an application explicitly tries to interact with another application [via an * activity, service or provider that is either declared in the caller's * manifest via the {@code <queries>} tag or has been exposed via the target apps manifest using * the {@code visibleToInstantApp} attribute], the target application must be able to see * metadata about the calling app. If the calling application uses an implicit intent [ie * action VIEW, category BROWSABLE], it remains hidden from the launched app. * <p> * If an interaction is not explicit, the {@code direct} argument should be set to false as * visibility should not be granted in some cases. This method handles that logic. * <p> * @param userId the user * @param intent the intent that triggered the grant * @param recipientAppId The app ID of the application that is being given access to {@code * visibleUid} * @param visibleUid The uid of the application that is becoming accessible to {@code * recipientAppId} * @param direct true if the access is being made due to direct interaction between visibleUid * and recipientAppId. * @param retainOnUpdate true if the implicit access is retained across package update. */ public abstract void grantImplicitAccess( @UserIdInt int userId, Intent intent, @AppIdInt int recipientAppId, int visibleUid, boolean direct, boolean retainOnUpdate); public abstract boolean isInstantAppInstallerComponent(ComponentName component); /** * Prunes instant apps and state associated with uninstalled Loading services/core/java/com/android/server/pm/AppsFilter.java +49 −5 Original line number Diff line number Diff line Loading @@ -96,6 +96,13 @@ public class AppsFilter implements Watchable, Snappable { */ private final SparseSetArray<Integer> mImplicitlyQueryable = new SparseSetArray<>(); /** * This contains a list of app UIDs that are implicitly queryable because another app explicitly * interacted with it, but could keep across package updates. For example, if application A * grants persistable uri permission to application B; regardless of any manifest entries. */ private final SparseSetArray<Integer> mRetainedImplicitlyQueryable = new SparseSetArray<>(); /** * A mapping from the set of App IDs that query other App IDs via package name to the * list of packages that they can see. Loading Loading @@ -256,6 +263,7 @@ public class AppsFilter implements Watchable, Snappable { */ private AppsFilter(AppsFilter orig) { Snapshots.copy(mImplicitlyQueryable, orig.mImplicitlyQueryable); Snapshots.copy(mRetainedImplicitlyQueryable, orig.mRetainedImplicitlyQueryable); Snapshots.copy(mQueriesViaPackage, orig.mQueriesViaPackage); Snapshots.copy(mQueriesViaComponent, orig.mQueriesViaComponent); Snapshots.copy(mQueryableViaUsesLibrary, orig.mQueryableViaUsesLibrary); Loading Loading @@ -633,15 +641,19 @@ public class AppsFilter implements Watchable, Snappable { * * @param recipientUid the uid gaining visibility of the {@code visibleUid}. * @param visibleUid the uid becoming visible to the {@recipientUid} * @param retainOnUpdate if the implicit access retained across package updates. * @return {@code true} if implicit access was not already granted. */ public boolean grantImplicitAccess(int recipientUid, int visibleUid) { public boolean grantImplicitAccess(int recipientUid, int visibleUid, boolean retainOnUpdate) { if (recipientUid == visibleUid) { return false; } final boolean changed = mImplicitlyQueryable.add(recipientUid, visibleUid); final boolean changed = retainOnUpdate ? mRetainedImplicitlyQueryable.add(recipientUid, visibleUid) : mImplicitlyQueryable.add(recipientUid, visibleUid); if (changed && DEBUG_LOGGING) { Slog.i(TAG, "implicit access granted: " + recipientUid + " -> " + visibleUid); Slog.i(TAG, (retainOnUpdate ? "retained " : "") + "implicit access granted: " + recipientUid + " -> " + visibleUid); } synchronized (mCacheLock) { if (mShouldFilterCache != null) { Loading Loading @@ -677,7 +689,7 @@ public class AppsFilter implements Watchable, Snappable { try { if (isReplace) { // let's first remove any prior rules for this package removePackage(newPkgSetting); removePackage(newPkgSetting, true /*isReplace*/); } mStateProvider.runWithState((settings, users) -> { ArraySet<String> additionalChangedPackages = Loading Loading @@ -1078,8 +1090,9 @@ public class AppsFilter implements Watchable, Snappable { * Removes a package for consideration when filtering visibility between apps. * * @param setting the setting of the package being removed. * @param isReplace if the package is being replaced. */ public void removePackage(PackageSetting setting) { public void removePackage(PackageSetting setting, boolean isReplace) { mStateProvider.runWithState((settings, users) -> { final int userCount = users.length; for (int u = 0; u < userCount; u++) { Loading @@ -1089,6 +1102,16 @@ public class AppsFilter implements Watchable, Snappable { for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) { mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i), removingUid); } if (isReplace) { continue; } mRetainedImplicitlyQueryable.remove(removingUid); for (int i = mRetainedImplicitlyQueryable.size() - 1; i >= 0; i--) { mRetainedImplicitlyQueryable.remove( mRetainedImplicitlyQueryable.keyAt(i), removingUid); } } if (!mQueriesViaComponentRequireRecompute) { Loading Loading @@ -1412,6 +1435,24 @@ public class AppsFilter implements Watchable, Snappable { } } try { if (DEBUG_TRACING) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mRetainedImplicitlyQueryable"); } final int targetUid = UserHandle.getUid(targetUserId, targetAppId); if (mRetainedImplicitlyQueryable.contains(callingUid, targetUid)) { if (DEBUG_LOGGING) { log(callingSetting, targetPkgSetting, "retained implicitly queryable for user"); } return false; } } finally { if (DEBUG_TRACING) { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } } try { if (DEBUG_TRACING) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mOverlayReferenceMapper"); Loading Loading @@ -1550,6 +1591,9 @@ public class AppsFilter implements Watchable, Snappable { dumpQueriesMap(pw, filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId), mImplicitlyQueryable, " ", expandPackages); dumpQueriesMap(pw, filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId), mRetainedImplicitlyQueryable, " ", expandPackages); } pw.println(" queryable via uses-library:"); dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, " ", expandPackages); Loading services/core/java/com/android/server/pm/PackageManagerService.java +12 −3 Original line number Diff line number Diff line Loading @@ -18051,7 +18051,8 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mLock) { mDomainVerificationManager.clearPackage(deletedPs.name); mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName); mAppsFilter.removePackage(getPackageSetting(packageName)); mAppsFilter.removePackage(getPackageSetting(packageName), false /* isReplace */); removedAppId = mSettings.removePackageLPw(packageName); if (outInfo != null) { outInfo.mRemovedAppId = removedAppId; Loading Loading @@ -23787,6 +23788,13 @@ public class PackageManagerService extends IPackageManager.Stub @Override public void grantImplicitAccess(int userId, Intent intent, int recipientAppId, int visibleUid, boolean direct) { grantImplicitAccess(userId, intent, recipientAppId, visibleUid, direct, false /* retainOnUpdate */); } @Override public void grantImplicitAccess(int userId, Intent intent, int recipientAppId, int visibleUid, boolean direct, boolean retainOnUpdate) { synchronized (mLock) { final AndroidPackage visiblePackage = getPackage(visibleUid); final int recipientUid = UserHandle.getUid(userId, recipientAppId); Loading @@ -23807,7 +23815,8 @@ public class PackageManagerService extends IPackageManager.Stub accessGranted = mInstantAppRegistry.grantInstantAccessLPw(userId, intent, recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/); } else { accessGranted = mAppsFilter.grantImplicitAccess(recipientUid, visibleUid); accessGranted = mAppsFilter.grantImplicitAccess(recipientUid, visibleUid, retainOnUpdate); } if (accessGranted) { ApplicationPackageManager.invalidateGetPackagesForUidCache(); Loading Loading @@ -24747,7 +24756,7 @@ public class PackageManagerService extends IPackageManager.Stub } int visibleUid = providerInfo.applicationInfo.uid; mPmInternal.grantImplicitAccess(userId, null /*Intent*/, UserHandle.getAppId(recipientUid), visibleUid, false); visibleUid, false /*direct*/); } boolean canHaveOatDir(String packageName) { services/core/java/com/android/server/uri/UriGrantsManagerService.java +6 −5 Original line number Diff line number Diff line Loading @@ -706,10 +706,10 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub { sourcePkg, targetPkg, targetUid, grantUri); perm.initPersistedModes(modeFlags, createdTime); mPmInternal.grantImplicitAccess( targetUserId, null, targetUserId, null /* intent */, UserHandle.getAppId(targetUid), pi.applicationInfo.uid, false /* direct */); false /* direct */, true /* retainOnUpdate */); } } else { Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg Loading Loading @@ -773,8 +773,9 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub { perm = findOrCreateUriPermissionLocked(pi.packageName, targetPkg, targetUid, grantUri); } perm.grantModes(modeFlags, owner); mPmInternal.grantImplicitAccess(UserHandle.getUserId(targetUid), null, UserHandle.getAppId(targetUid), pi.applicationInfo.uid, false /*direct*/); mPmInternal.grantImplicitAccess(UserHandle.getUserId(targetUid), null /*intent*/, UserHandle.getAppId(targetUid), pi.applicationInfo.uid, false /*direct*/, (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0); } /** Like grantUriPermissionUnchecked, but takes an Intent. */ Loading Loading @@ -1187,7 +1188,7 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub { // provider supports granting permissions mPmInternal.grantImplicitAccess( UserHandle.getUserId(targetUid), null, UserHandle.getAppId(targetUid), pi.applicationInfo.uid, false); UserHandle.getAppId(targetUid), pi.applicationInfo.uid, false /*direct*/); return -1; } Loading services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java +6 −4 Original line number Diff line number Diff line Loading @@ -829,7 +829,7 @@ public class AppsFilterTest { assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_APPID, overlaySetting, actorSetting, SYSTEM_USER)); appsFilter.removePackage(targetSetting); appsFilter.removePackage(targetSetting, false /* isReplace */); // Actor loses visibility to the overlay via removal of the target assertTrue(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSetting, Loading Loading @@ -1074,7 +1074,8 @@ public class AppsFilterTest { watcher.verifyNoChangeReported("getVisibility"); // provider read appsFilter.grantImplicitAccess(hasProviderAppId, queriesProviderAppId); appsFilter.grantImplicitAccess(hasProviderAppId, queriesProviderAppId, false /* retainOnUpdate */); watcher.verifyChangeReported("grantImplicitAccess"); // ensure implicit access is included in the filter Loading Loading @@ -1143,7 +1144,8 @@ public class AppsFilterTest { watcher.verifyNoChangeReported("get"); // provider read appsFilter.grantImplicitAccess(hasProviderAppId, queriesProviderAppId); appsFilter.grantImplicitAccess( hasProviderAppId, queriesProviderAppId, false /* retainOnUpdate */); watcher.verifyChangeReported("grantImplicitAccess"); // ensure implicit access is included in the filter Loading @@ -1154,7 +1156,7 @@ public class AppsFilterTest { watcher.verifyNoChangeReported("get"); // remove a package appsFilter.removePackage(seesNothing); appsFilter.removePackage(seesNothing, false /* isReplace */); watcher.verifyChangeReported("removePackage"); } Loading Loading
services/core/java/android/content/pm/PackageManagerInternal.java +29 −0 Original line number Diff line number Diff line Loading @@ -479,6 +479,35 @@ public abstract class PackageManagerInternal implements PackageSettingsSnapshotP @AppIdInt int recipientAppId, int visibleUid, boolean direct); /** * Grants implicit access based on an interaction between two apps. This grants access to the * from one application to the other's package metadata. * <p> * When an application explicitly tries to interact with another application [via an * activity, service or provider that is either declared in the caller's * manifest via the {@code <queries>} tag or has been exposed via the target apps manifest using * the {@code visibleToInstantApp} attribute], the target application must be able to see * metadata about the calling app. If the calling application uses an implicit intent [ie * action VIEW, category BROWSABLE], it remains hidden from the launched app. * <p> * If an interaction is not explicit, the {@code direct} argument should be set to false as * visibility should not be granted in some cases. This method handles that logic. * <p> * @param userId the user * @param intent the intent that triggered the grant * @param recipientAppId The app ID of the application that is being given access to {@code * visibleUid} * @param visibleUid The uid of the application that is becoming accessible to {@code * recipientAppId} * @param direct true if the access is being made due to direct interaction between visibleUid * and recipientAppId. * @param retainOnUpdate true if the implicit access is retained across package update. */ public abstract void grantImplicitAccess( @UserIdInt int userId, Intent intent, @AppIdInt int recipientAppId, int visibleUid, boolean direct, boolean retainOnUpdate); public abstract boolean isInstantAppInstallerComponent(ComponentName component); /** * Prunes instant apps and state associated with uninstalled Loading
services/core/java/com/android/server/pm/AppsFilter.java +49 −5 Original line number Diff line number Diff line Loading @@ -96,6 +96,13 @@ public class AppsFilter implements Watchable, Snappable { */ private final SparseSetArray<Integer> mImplicitlyQueryable = new SparseSetArray<>(); /** * This contains a list of app UIDs that are implicitly queryable because another app explicitly * interacted with it, but could keep across package updates. For example, if application A * grants persistable uri permission to application B; regardless of any manifest entries. */ private final SparseSetArray<Integer> mRetainedImplicitlyQueryable = new SparseSetArray<>(); /** * A mapping from the set of App IDs that query other App IDs via package name to the * list of packages that they can see. Loading Loading @@ -256,6 +263,7 @@ public class AppsFilter implements Watchable, Snappable { */ private AppsFilter(AppsFilter orig) { Snapshots.copy(mImplicitlyQueryable, orig.mImplicitlyQueryable); Snapshots.copy(mRetainedImplicitlyQueryable, orig.mRetainedImplicitlyQueryable); Snapshots.copy(mQueriesViaPackage, orig.mQueriesViaPackage); Snapshots.copy(mQueriesViaComponent, orig.mQueriesViaComponent); Snapshots.copy(mQueryableViaUsesLibrary, orig.mQueryableViaUsesLibrary); Loading Loading @@ -633,15 +641,19 @@ public class AppsFilter implements Watchable, Snappable { * * @param recipientUid the uid gaining visibility of the {@code visibleUid}. * @param visibleUid the uid becoming visible to the {@recipientUid} * @param retainOnUpdate if the implicit access retained across package updates. * @return {@code true} if implicit access was not already granted. */ public boolean grantImplicitAccess(int recipientUid, int visibleUid) { public boolean grantImplicitAccess(int recipientUid, int visibleUid, boolean retainOnUpdate) { if (recipientUid == visibleUid) { return false; } final boolean changed = mImplicitlyQueryable.add(recipientUid, visibleUid); final boolean changed = retainOnUpdate ? mRetainedImplicitlyQueryable.add(recipientUid, visibleUid) : mImplicitlyQueryable.add(recipientUid, visibleUid); if (changed && DEBUG_LOGGING) { Slog.i(TAG, "implicit access granted: " + recipientUid + " -> " + visibleUid); Slog.i(TAG, (retainOnUpdate ? "retained " : "") + "implicit access granted: " + recipientUid + " -> " + visibleUid); } synchronized (mCacheLock) { if (mShouldFilterCache != null) { Loading Loading @@ -677,7 +689,7 @@ public class AppsFilter implements Watchable, Snappable { try { if (isReplace) { // let's first remove any prior rules for this package removePackage(newPkgSetting); removePackage(newPkgSetting, true /*isReplace*/); } mStateProvider.runWithState((settings, users) -> { ArraySet<String> additionalChangedPackages = Loading Loading @@ -1078,8 +1090,9 @@ public class AppsFilter implements Watchable, Snappable { * Removes a package for consideration when filtering visibility between apps. * * @param setting the setting of the package being removed. * @param isReplace if the package is being replaced. */ public void removePackage(PackageSetting setting) { public void removePackage(PackageSetting setting, boolean isReplace) { mStateProvider.runWithState((settings, users) -> { final int userCount = users.length; for (int u = 0; u < userCount; u++) { Loading @@ -1089,6 +1102,16 @@ public class AppsFilter implements Watchable, Snappable { for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) { mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i), removingUid); } if (isReplace) { continue; } mRetainedImplicitlyQueryable.remove(removingUid); for (int i = mRetainedImplicitlyQueryable.size() - 1; i >= 0; i--) { mRetainedImplicitlyQueryable.remove( mRetainedImplicitlyQueryable.keyAt(i), removingUid); } } if (!mQueriesViaComponentRequireRecompute) { Loading Loading @@ -1412,6 +1435,24 @@ public class AppsFilter implements Watchable, Snappable { } } try { if (DEBUG_TRACING) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mRetainedImplicitlyQueryable"); } final int targetUid = UserHandle.getUid(targetUserId, targetAppId); if (mRetainedImplicitlyQueryable.contains(callingUid, targetUid)) { if (DEBUG_LOGGING) { log(callingSetting, targetPkgSetting, "retained implicitly queryable for user"); } return false; } } finally { if (DEBUG_TRACING) { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } } try { if (DEBUG_TRACING) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mOverlayReferenceMapper"); Loading Loading @@ -1550,6 +1591,9 @@ public class AppsFilter implements Watchable, Snappable { dumpQueriesMap(pw, filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId), mImplicitlyQueryable, " ", expandPackages); dumpQueriesMap(pw, filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId), mRetainedImplicitlyQueryable, " ", expandPackages); } pw.println(" queryable via uses-library:"); dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, " ", expandPackages); Loading
services/core/java/com/android/server/pm/PackageManagerService.java +12 −3 Original line number Diff line number Diff line Loading @@ -18051,7 +18051,8 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mLock) { mDomainVerificationManager.clearPackage(deletedPs.name); mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName); mAppsFilter.removePackage(getPackageSetting(packageName)); mAppsFilter.removePackage(getPackageSetting(packageName), false /* isReplace */); removedAppId = mSettings.removePackageLPw(packageName); if (outInfo != null) { outInfo.mRemovedAppId = removedAppId; Loading Loading @@ -23787,6 +23788,13 @@ public class PackageManagerService extends IPackageManager.Stub @Override public void grantImplicitAccess(int userId, Intent intent, int recipientAppId, int visibleUid, boolean direct) { grantImplicitAccess(userId, intent, recipientAppId, visibleUid, direct, false /* retainOnUpdate */); } @Override public void grantImplicitAccess(int userId, Intent intent, int recipientAppId, int visibleUid, boolean direct, boolean retainOnUpdate) { synchronized (mLock) { final AndroidPackage visiblePackage = getPackage(visibleUid); final int recipientUid = UserHandle.getUid(userId, recipientAppId); Loading @@ -23807,7 +23815,8 @@ public class PackageManagerService extends IPackageManager.Stub accessGranted = mInstantAppRegistry.grantInstantAccessLPw(userId, intent, recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/); } else { accessGranted = mAppsFilter.grantImplicitAccess(recipientUid, visibleUid); accessGranted = mAppsFilter.grantImplicitAccess(recipientUid, visibleUid, retainOnUpdate); } if (accessGranted) { ApplicationPackageManager.invalidateGetPackagesForUidCache(); Loading Loading @@ -24747,7 +24756,7 @@ public class PackageManagerService extends IPackageManager.Stub } int visibleUid = providerInfo.applicationInfo.uid; mPmInternal.grantImplicitAccess(userId, null /*Intent*/, UserHandle.getAppId(recipientUid), visibleUid, false); visibleUid, false /*direct*/); } boolean canHaveOatDir(String packageName) {
services/core/java/com/android/server/uri/UriGrantsManagerService.java +6 −5 Original line number Diff line number Diff line Loading @@ -706,10 +706,10 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub { sourcePkg, targetPkg, targetUid, grantUri); perm.initPersistedModes(modeFlags, createdTime); mPmInternal.grantImplicitAccess( targetUserId, null, targetUserId, null /* intent */, UserHandle.getAppId(targetUid), pi.applicationInfo.uid, false /* direct */); false /* direct */, true /* retainOnUpdate */); } } else { Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg Loading Loading @@ -773,8 +773,9 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub { perm = findOrCreateUriPermissionLocked(pi.packageName, targetPkg, targetUid, grantUri); } perm.grantModes(modeFlags, owner); mPmInternal.grantImplicitAccess(UserHandle.getUserId(targetUid), null, UserHandle.getAppId(targetUid), pi.applicationInfo.uid, false /*direct*/); mPmInternal.grantImplicitAccess(UserHandle.getUserId(targetUid), null /*intent*/, UserHandle.getAppId(targetUid), pi.applicationInfo.uid, false /*direct*/, (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0); } /** Like grantUriPermissionUnchecked, but takes an Intent. */ Loading Loading @@ -1187,7 +1188,7 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub { // provider supports granting permissions mPmInternal.grantImplicitAccess( UserHandle.getUserId(targetUid), null, UserHandle.getAppId(targetUid), pi.applicationInfo.uid, false); UserHandle.getAppId(targetUid), pi.applicationInfo.uid, false /*direct*/); return -1; } Loading
services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java +6 −4 Original line number Diff line number Diff line Loading @@ -829,7 +829,7 @@ public class AppsFilterTest { assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_APPID, overlaySetting, actorSetting, SYSTEM_USER)); appsFilter.removePackage(targetSetting); appsFilter.removePackage(targetSetting, false /* isReplace */); // Actor loses visibility to the overlay via removal of the target assertTrue(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSetting, Loading Loading @@ -1074,7 +1074,8 @@ public class AppsFilterTest { watcher.verifyNoChangeReported("getVisibility"); // provider read appsFilter.grantImplicitAccess(hasProviderAppId, queriesProviderAppId); appsFilter.grantImplicitAccess(hasProviderAppId, queriesProviderAppId, false /* retainOnUpdate */); watcher.verifyChangeReported("grantImplicitAccess"); // ensure implicit access is included in the filter Loading Loading @@ -1143,7 +1144,8 @@ public class AppsFilterTest { watcher.verifyNoChangeReported("get"); // provider read appsFilter.grantImplicitAccess(hasProviderAppId, queriesProviderAppId); appsFilter.grantImplicitAccess( hasProviderAppId, queriesProviderAppId, false /* retainOnUpdate */); watcher.verifyChangeReported("grantImplicitAccess"); // ensure implicit access is included in the filter Loading @@ -1154,7 +1156,7 @@ public class AppsFilterTest { watcher.verifyNoChangeReported("get"); // remove a package appsFilter.removePackage(seesNothing); appsFilter.removePackage(seesNothing, false /* isReplace */); watcher.verifyChangeReported("removePackage"); } Loading