Merge "Revert "Pre-cache filter results"" into rvc-dev am: c357f2cafd

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11820080

Change-Id: I5c08424778f31a912a89459c816fcfd08d0284d0
This commit is contained in:
Patrick Baumann
2020-06-10 15:39:52 +00:00
committed by Automerger Merge Worker
3 changed files with 311 additions and 562 deletions

View File

@@ -19,8 +19,6 @@ package com.android.server.pm;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -111,25 +109,12 @@ public class AppsFilter {
private final boolean mSystemAppsQueryable;
private final FeatureConfig mFeatureConfig;
private final OverlayReferenceMapper mOverlayReferenceMapper;
private final StateProvider mStateProvider;
private final OverlayReferenceMapper mOverlayReferenceMapper;
private PackageParser.SigningDetails mSystemSigningDetails;
private Set<String> mProtectedBroadcasts = new ArraySet<>();
/**
* This structure maps uid -> uid and indicates whether access from the first should be
* filtered to the second. It's essentially a cache of the
* {@link #shouldFilterApplicationInternal(int, SettingBase, PackageSetting, int)} call.
* NOTE: It can only be relied upon after the system is ready to avoid unnecessary update on
* initial scan and is null until {@link #onSystemReady()} is called.
*/
private volatile SparseArray<SparseBooleanArray> mShouldFilterCache;
@VisibleForTesting(visibility = PRIVATE)
AppsFilter(StateProvider stateProvider,
FeatureConfig featureConfig,
String[] forceQueryableWhitelist,
AppsFilter(FeatureConfig featureConfig, String[] forceQueryableWhitelist,
boolean systemAppsQueryable,
@Nullable OverlayReferenceMapper.Provider overlayProvider) {
mFeatureConfig = featureConfig;
@@ -137,23 +122,8 @@ public class AppsFilter {
mSystemAppsQueryable = systemAppsQueryable;
mOverlayReferenceMapper = new OverlayReferenceMapper(true /*deferRebuild*/,
overlayProvider);
mStateProvider = stateProvider;
}
/**
* Provides system state to AppsFilter via {@link CurrentStateCallback} after properly guarding
* the data with the package lock.
*/
@VisibleForTesting(visibility = PRIVATE)
public interface StateProvider {
void runWithState(CurrentStateCallback callback);
interface CurrentStateCallback {
void currentState(ArrayMap<String, PackageSetting> settings, int[] users);
}
}
@VisibleForTesting(visibility = PRIVATE)
public interface FeatureConfig {
/** Called when the system is ready and components can be queried. */
@@ -170,7 +140,6 @@ public class AppsFilter {
/**
* Turns on logging for the given appId
*
* @param enable true if logging should be enabled, false if disabled.
*/
void enableLogging(int appId, boolean enable);
@@ -178,7 +147,6 @@ public class AppsFilter {
/**
* Initializes the package enablement state for the given package. This gives opportunity
* to do any expensive operations ahead of the actual checks.
*
* @param removed true if adding, false if removing
*/
void updatePackageState(PackageSetting setting, boolean removed);
@@ -194,7 +162,6 @@ public class AppsFilter {
@Nullable
private SparseBooleanArray mLoggingEnabled = null;
private AppsFilter mAppsFilter;
private FeatureConfigImpl(
PackageManagerInternal pmInternal, PackageManagerService.Injector injector) {
@@ -202,10 +169,6 @@ public class AppsFilter {
mInjector = injector;
}
public void setAppsFilter(AppsFilter filter) {
mAppsFilter = filter;
}
@Override
public void onSystemReady() {
mFeatureEnabled = DeviceConfig.getBoolean(
@@ -272,25 +235,24 @@ public class AppsFilter {
@Override
public void onCompatChange(String packageName) {
final long token = Binder.clearCallingIdentity();
try {
updateEnabledState(mPmInternal.getPackage(packageName));
mAppsFilter.updateShouldFilterCacheForPackage(packageName);
} finally {
Binder.restoreCallingIdentity(token);
}
updateEnabledState(mPmInternal.getPackage(packageName));
}
private void updateEnabledState(AndroidPackage pkg) {
// TODO(b/135203078): Do not use toAppInfo
final boolean enabled =
mInjector.getCompatibility().isChangeEnabled(
PackageManager.FILTER_APPLICATION_QUERY,
pkg.toAppInfoWithoutState());
if (enabled) {
mDisabledPackages.remove(pkg.getPackageName());
} else {
mDisabledPackages.add(pkg.getPackageName());
final long token = Binder.clearCallingIdentity();
try {
// TODO(b/135203078): Do not use toAppInfo
final boolean enabled =
mInjector.getCompatibility().isChangeEnabled(
PackageManager.FILTER_APPLICATION_QUERY,
pkg.toAppInfoWithoutState());
if (enabled) {
mDisabledPackages.remove(pkg.getPackageName());
} else {
mDisabledPackages.add(pkg.getPackageName());
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
@@ -313,7 +275,7 @@ public class AppsFilter {
final boolean forceSystemAppsQueryable =
injector.getContext().getResources()
.getBoolean(R.bool.config_forceSystemPackagesQueryable);
final FeatureConfigImpl featureConfig = new FeatureConfigImpl(pms, injector);
final FeatureConfig featureConfig = new FeatureConfigImpl(pms, injector);
final String[] forcedQueryablePackageNames;
if (forceSystemAppsQueryable) {
// all system apps already queryable, no need to read and parse individual exceptions
@@ -326,16 +288,8 @@ public class AppsFilter {
forcedQueryablePackageNames[i] = forcedQueryablePackageNames[i].intern();
}
}
final StateProvider stateProvider = command -> {
synchronized (injector.getLock()) {
command.currentState(injector.getSettings().mPackages,
injector.getUserManagerInternal().getUserIds());
}
};
AppsFilter appsFilter = new AppsFilter(stateProvider, featureConfig,
forcedQueryablePackageNames, forceSystemAppsQueryable, null);
featureConfig.setAppsFilter(appsFilter);
return appsFilter;
return new AppsFilter(featureConfig, forcedQueryablePackageNames,
forceSystemAppsQueryable, null);
}
public FeatureConfig getFeatureConfig() {
@@ -458,54 +412,28 @@ public class AppsFilter {
* visibility of the caller from the target.
*
* @param recipientUid the uid gaining visibility of the {@code visibleUid}.
* @param visibleUid the uid becoming visible to the {@recipientUid}
* @param visibleUid the uid becoming visible to the {@recipientUid}
*/
public void grantImplicitAccess(int recipientUid, int visibleUid) {
if (recipientUid != visibleUid) {
if (mImplicitlyQueryable.add(recipientUid, visibleUid) && DEBUG_LOGGING) {
Slog.i(TAG, "implicit access granted: " + recipientUid + " -> " + visibleUid);
}
if (mShouldFilterCache != null) {
// update the cache in a one-off manner since we've got all the information we need.
SparseBooleanArray visibleUids = mShouldFilterCache.get(recipientUid);
if (visibleUids == null) {
visibleUids = new SparseBooleanArray();
mShouldFilterCache.put(recipientUid, visibleUids);
}
visibleUids.put(visibleUid, false);
}
if (recipientUid != visibleUid
&& mImplicitlyQueryable.add(recipientUid, visibleUid) && DEBUG_LOGGING) {
Slog.i(TAG, "implicit access granted: " + recipientUid + " -> " + visibleUid);
}
}
public void onSystemReady() {
mShouldFilterCache = new SparseArray<>();
mFeatureConfig.onSystemReady();
mOverlayReferenceMapper.rebuildIfDeferred();
updateEntireShouldFilterCache();
}
/**
* Adds a package that should be considered when filtering visibility between apps.
*
* @param newPkgSetting the new setting being added
* @param newPkgSetting the new setting being added
* @param existingSettings all other settings currently on the device.
*/
public void addPackage(PackageSetting newPkgSetting) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.addPackage");
try {
mStateProvider.runWithState((settings, users) -> {
addPackageInternal(newPkgSetting, settings, users);
if (mShouldFilterCache != null) {
updateShouldFilterCacheForPackage(
null, newPkgSetting, settings, users, settings.size());
} // else, rebuild entire cache when system is ready
});
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
private void addPackageInternal(PackageSetting newPkgSetting,
ArrayMap<String, PackageSetting> existingSettings, int[] allUsers) {
public void addPackage(PackageSetting newPkgSetting,
ArrayMap<String, PackageSetting> existingSettings) {
if (Objects.equals("android", newPkgSetting.name)) {
// let's set aside the framework signatures
mSystemSigningDetails = newPkgSetting.signatures.mSigningDetails;
@@ -518,151 +446,79 @@ public class AppsFilter {
}
}
final AndroidPackage newPkg = newPkgSetting.pkg;
if (newPkg == null) {
// nothing to add
return;
}
if (!newPkg.getProtectedBroadcasts().isEmpty()) {
mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts());
recomputeComponentVisibility(existingSettings, newPkg.getPackageName());
}
final boolean newIsForceQueryable =
mForceQueryable.contains(newPkgSetting.appId)
/* shared user that is already force queryable */
|| newPkg.isForceQueryable()
|| newPkgSetting.forceQueryableOverride
|| (newPkgSetting.isSystem() && (mSystemAppsQueryable
|| ArrayUtils.contains(mForceQueryableByDevicePackageNames,
newPkg.getPackageName())));
if (newIsForceQueryable
|| (mSystemSigningDetails != null
&& isSystemSigned(mSystemSigningDetails, newPkgSetting))) {
mForceQueryable.add(newPkgSetting.appId);
}
for (int i = existingSettings.size() - 1; i >= 0; i--) {
final PackageSetting existingSetting = existingSettings.valueAt(i);
if (existingSetting.appId == newPkgSetting.appId || existingSetting.pkg == null) {
continue;
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.addPackage");
try {
final AndroidPackage newPkg = newPkgSetting.pkg;
if (newPkg == null) {
// nothing to add
return;
}
final AndroidPackage existingPkg = existingSetting.pkg;
// let's evaluate the ability of already added packages to see this new package
if (!newIsForceQueryable) {
if (canQueryViaComponents(existingPkg, newPkg, mProtectedBroadcasts)) {
mQueriesViaComponent.add(existingSetting.appId, newPkgSetting.appId);
if (!newPkg.getProtectedBroadcasts().isEmpty()) {
mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts());
recomputeComponentVisibility(existingSettings, newPkg.getPackageName());
}
final boolean newIsForceQueryable =
mForceQueryable.contains(newPkgSetting.appId)
/* shared user that is already force queryable */
|| newPkg.isForceQueryable()
|| newPkgSetting.forceQueryableOverride
|| (newPkgSetting.isSystem() && (mSystemAppsQueryable
|| ArrayUtils.contains(mForceQueryableByDevicePackageNames,
newPkg.getPackageName())));
if (newIsForceQueryable
|| (mSystemSigningDetails != null
&& isSystemSigned(mSystemSigningDetails, newPkgSetting))) {
mForceQueryable.add(newPkgSetting.appId);
}
for (int i = existingSettings.size() - 1; i >= 0; i--) {
final PackageSetting existingSetting = existingSettings.valueAt(i);
if (existingSetting.appId == newPkgSetting.appId || existingSetting.pkg == null) {
continue;
}
if (canQueryViaPackage(existingPkg, newPkg)
|| canQueryAsInstaller(existingSetting, newPkg)) {
final AndroidPackage existingPkg = existingSetting.pkg;
// let's evaluate the ability of already added packages to see this new package
if (!newIsForceQueryable) {
if (canQueryViaComponents(existingPkg, newPkg, mProtectedBroadcasts)) {
mQueriesViaComponent.add(existingSetting.appId, newPkgSetting.appId);
}
if (canQueryViaPackage(existingPkg, newPkg)
|| canQueryAsInstaller(existingSetting, newPkg)) {
mQueriesViaPackage.add(existingSetting.appId, newPkgSetting.appId);
}
}
// now we'll evaluate our new package's ability to see existing packages
if (!mForceQueryable.contains(existingSetting.appId)) {
if (canQueryViaComponents(newPkg, existingPkg, mProtectedBroadcasts)) {
mQueriesViaComponent.add(newPkgSetting.appId, existingSetting.appId);
}
if (canQueryViaPackage(newPkg, existingPkg)
|| canQueryAsInstaller(newPkgSetting, existingPkg)) {
mQueriesViaPackage.add(newPkgSetting.appId, existingSetting.appId);
}
}
// if either package instruments the other, mark both as visible to one another
if (pkgInstruments(newPkgSetting, existingSetting)
|| pkgInstruments(existingSetting, newPkgSetting)) {
mQueriesViaPackage.add(newPkgSetting.appId, existingSetting.appId);
mQueriesViaPackage.add(existingSetting.appId, newPkgSetting.appId);
}
}
// now we'll evaluate our new package's ability to see existing packages
if (!mForceQueryable.contains(existingSetting.appId)) {
if (canQueryViaComponents(newPkg, existingPkg, mProtectedBroadcasts)) {
mQueriesViaComponent.add(newPkgSetting.appId, existingSetting.appId);
}
if (canQueryViaPackage(newPkg, existingPkg)
|| canQueryAsInstaller(newPkgSetting, existingPkg)) {
mQueriesViaPackage.add(newPkgSetting.appId, existingSetting.appId);
}
}
// if either package instruments the other, mark both as visible to one another
if (pkgInstruments(newPkgSetting, existingSetting)
|| pkgInstruments(existingSetting, newPkgSetting)) {
mQueriesViaPackage.add(newPkgSetting.appId, existingSetting.appId);
mQueriesViaPackage.add(existingSetting.appId, newPkgSetting.appId);
}
}
int existingSize = existingSettings.size();
ArrayMap<String, AndroidPackage> existingPkgs = new ArrayMap<>(existingSize);
for (int index = 0; index < existingSize; index++) {
PackageSetting pkgSetting = existingSettings.valueAt(index);
if (pkgSetting.pkg != null) {
existingPkgs.put(pkgSetting.name, pkgSetting.pkg);
}
}
mOverlayReferenceMapper.addPkg(newPkgSetting.pkg, existingPkgs);
mFeatureConfig.updatePackageState(newPkgSetting, false /*removed*/);
}
private void removeAppIdFromVisibilityCache(int appId) {
if (mShouldFilterCache == null) {
return;
}
for (int i = mShouldFilterCache.size() - 1; i >= 0; i--) {
if (UserHandle.getAppId(mShouldFilterCache.keyAt(i)) == appId) {
mShouldFilterCache.removeAt(i);
continue;
}
SparseBooleanArray targetSparseArray = mShouldFilterCache.valueAt(i);
for (int j = targetSparseArray.size() - 1; j >= 0; j--) {
if (UserHandle.getAppId(targetSparseArray.keyAt(j)) == appId) {
targetSparseArray.removeAt(j);
}
}
}
}
private void updateEntireShouldFilterCache() {
mStateProvider.runWithState((settings, users) -> {
mShouldFilterCache.clear();
for (int i = settings.size() - 1; i >= 0; i--) {
updateShouldFilterCacheForPackage(
null /*skipPackage*/, settings.valueAt(i), settings, users, i);
}
});
}
public void onUsersChanged() {
if (mShouldFilterCache != null) {
updateEntireShouldFilterCache();
}
}
private void updateShouldFilterCacheForPackage(String packageName) {
mStateProvider.runWithState((settings, users) -> {
updateShouldFilterCacheForPackage(null /* skipPackage */, settings.get(packageName),
settings, users, settings.size() /*maxIndex*/);
});
}
private void updateShouldFilterCacheForPackage(@Nullable String skipPackageName,
PackageSetting subjectSetting, ArrayMap<String, PackageSetting> allSettings,
int[] allUsers, int maxIndex) {
for (int i = Math.min(maxIndex, allSettings.size() - 1); i >= 0; i--) {
PackageSetting otherSetting = allSettings.valueAt(i);
if (subjectSetting.appId == otherSetting.appId) {
continue;
}
//noinspection StringEquality
if (subjectSetting.name == skipPackageName || otherSetting.name == skipPackageName) {
continue;
}
for (int su = 0; su < allUsers.length; su++) {
int subjectUser = allUsers[su];
for (int ou = su; ou < allUsers.length; ou++) {
int otherUser = allUsers[ou];
int subjectUid = UserHandle.getUid(subjectUser, subjectSetting.appId);
if (!mShouldFilterCache.contains(subjectUid)) {
mShouldFilterCache.put(subjectUid, new SparseBooleanArray());
}
int otherUid = UserHandle.getUid(otherUser, otherSetting.appId);
if (!mShouldFilterCache.contains(otherUid)) {
mShouldFilterCache.put(otherUid, new SparseBooleanArray());
}
mShouldFilterCache.get(subjectUid).put(otherUid,
shouldFilterApplicationInternal(
subjectUid, subjectSetting, otherSetting, otherUser));
mShouldFilterCache.get(otherUid).put(subjectUid,
shouldFilterApplicationInternal(
otherUid, otherSetting, subjectSetting, subjectUser));
int existingSize = existingSettings.size();
ArrayMap<String, AndroidPackage> existingPkgs = new ArrayMap<>(existingSize);
for (int index = 0; index < existingSize; index++) {
PackageSetting pkgSetting = existingSettings.valueAt(index);
if (pkgSetting.pkg != null) {
existingPkgs.put(pkgSetting.name, pkgSetting.pkg);
}
}
mOverlayReferenceMapper.addPkg(newPkgSetting.pkg, existingPkgs);
mFeatureConfig.updatePackageState(newPkgSetting, false /*removed*/);
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
@@ -713,7 +569,6 @@ public class AppsFilter {
}
}
}
/**
* Fetches all app Ids that a given setting is currently visible to, per provided user. This
* only includes UIDs >= {@link Process#FIRST_APPLICATION_UID} as all other UIDs can already see
@@ -722,11 +577,11 @@ public class AppsFilter {
* If the setting is visible to all UIDs, null is returned. If an app is not visible to any
* applications, the int array will be empty.
*
* @param users the set of users that should be evaluated for this calculation
* @param users the set of users that should be evaluated for this calculation
* @param existingSettings the set of all package settings that currently exist on device
* @return a SparseArray mapping userIds to a sorted int array of appIds that may view the
* provided setting or null if the app is visible to all and no whitelist should be
* applied.
* provided setting or null if the app is visible to all and no whitelist should be
* applied.
*/
@Nullable
public SparseArray<int[]> getVisibilityWhitelist(PackageSetting setting, int[] users,
@@ -771,60 +626,52 @@ public class AppsFilter {
/**
* Removes a package for consideration when filtering visibility between apps.
*
* @param setting the setting of the package being removed.
* @param setting the setting of the package being removed.
* @param allUsers array of all current users on device.
*/
public void removePackage(PackageSetting setting) {
removeAppIdFromVisibilityCache(setting.appId);
mStateProvider.runWithState((settings, users) -> {
for (int u = 0; u < users.length; u++) {
final int userId = users[u];
final int removingUid = UserHandle.getUid(userId, setting.appId);
mImplicitlyQueryable.remove(removingUid);
for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) {
mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i), removingUid);
}
}
mQueriesViaComponent.remove(setting.appId);
for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) {
mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), setting.appId);
}
mQueriesViaPackage.remove(setting.appId);
for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) {
mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), setting.appId);
}
// re-add other shared user members to re-establish visibility between them and other
// packages
if (setting.sharedUser != null) {
for (int i = setting.sharedUser.packages.size() - 1; i >= 0; i--) {
if (setting.sharedUser.packages.valueAt(i) == setting) {
continue;
}
addPackageInternal(
setting.sharedUser.packages.valueAt(i), settings, users);
}
}
if (!setting.pkg.getProtectedBroadcasts().isEmpty()) {
final String removingPackageName = setting.pkg.getPackageName();
mProtectedBroadcasts.clear();
mProtectedBroadcasts.addAll(
collectProtectedBroadcasts(settings, removingPackageName));
recomputeComponentVisibility(settings, removingPackageName);
}
mOverlayReferenceMapper.removePkg(setting.name);
mFeatureConfig.updatePackageState(setting, true /*removed*/);
if (mShouldFilterCache != null) {
updateShouldFilterCacheForPackage(
setting.name, setting, settings, users, settings.size());
}
});
public void removePackage(PackageSetting setting, int[] allUsers,
ArrayMap<String, PackageSetting> existingSettings) {
mForceQueryable.remove(setting.appId);
for (int u = 0; u < allUsers.length; u++) {
final int userId = allUsers[u];
final int removingUid = UserHandle.getUid(userId, setting.appId);
mImplicitlyQueryable.remove(removingUid);
for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) {
mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i), removingUid);
}
}
mQueriesViaComponent.remove(setting.appId);
for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) {
mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), setting.appId);
}
mQueriesViaPackage.remove(setting.appId);
for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) {
mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), setting.appId);
}
// re-add other shared user members to re-establish visibility between them and other
// packages
if (setting.sharedUser != null) {
for (int i = setting.sharedUser.packages.size() - 1; i >= 0; i--) {
if (setting.sharedUser.packages.valueAt(i) == setting) {
continue;
}
addPackage(setting.sharedUser.packages.valueAt(i), existingSettings);
}
}
if (!setting.pkg.getProtectedBroadcasts().isEmpty()) {
final String removingPackageName = setting.pkg.getPackageName();
mProtectedBroadcasts.clear();
mProtectedBroadcasts.addAll(
collectProtectedBroadcasts(existingSettings, removingPackageName));
recomputeComponentVisibility(existingSettings, removingPackageName);
}
mOverlayReferenceMapper.removePkg(setting.name);
mFeatureConfig.updatePackageState(setting, true /*removed*/);
}
/**
@@ -841,32 +688,11 @@ public class AppsFilter {
PackageSetting targetPkgSetting, int userId) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplication");
try {
if (callingUid < Process.FIRST_APPLICATION_UID
|| UserHandle.getAppId(callingUid) == targetPkgSetting.appId) {
if (!shouldFilterApplicationInternal(
callingUid, callingSetting, targetPkgSetting, userId)) {
return false;
}
if (mShouldFilterCache != null) { // use cache
SparseBooleanArray shouldFilterTargets = mShouldFilterCache.get(callingUid);
final int targetUid = UserHandle.getUid(userId, targetPkgSetting.appId);
if (shouldFilterTargets == null) {
Slog.wtf(TAG, "Encountered calling uid with no cached rules: " + callingUid);
return true;
}
int indexOfTargetUid = shouldFilterTargets.indexOfKey(targetUid);
if (indexOfTargetUid < 0) {
Slog.w(TAG, "Encountered calling -> target with no cached rules: "
+ callingUid + " -> " + targetUid);
return true;
}
if (!shouldFilterTargets.valueAt(indexOfTargetUid)) {
return false;
}
} else {
if (!shouldFilterApplicationInternal(
callingUid, callingSetting, targetPkgSetting, userId)) {
return false;
}
}
if (DEBUG_LOGGING || mFeatureConfig.isLoggingEnabled(UserHandle.getAppId(callingUid))) {
log(callingSetting, targetPkgSetting, "BLOCKED");
}
@@ -877,7 +703,7 @@ public class AppsFilter {
}
private boolean shouldFilterApplicationInternal(int callingUid, SettingBase callingSetting,
PackageSetting targetPkgSetting, int targetUserId) {
PackageSetting targetPkgSetting, int userId) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplicationInternal");
try {
final boolean featureEnabled = mFeatureConfig.isGloballyEnabled();
@@ -887,6 +713,12 @@ public class AppsFilter {
}
return false;
}
if (callingUid < Process.FIRST_APPLICATION_UID) {
if (DEBUG_LOGGING) {
Slog.d(TAG, "filtering skipped; " + callingUid + " is system");
}
return false;
}
if (callingSetting == null) {
Slog.wtf(TAG, "No setting found for non system uid " + callingUid);
return true;
@@ -895,14 +727,8 @@ public class AppsFilter {
final ArraySet<PackageSetting> callingSharedPkgSettings;
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "callingSetting instanceof");
if (callingSetting instanceof PackageSetting) {
if (((PackageSetting) callingSetting).sharedUser == null) {
callingPkgSetting = (PackageSetting) callingSetting;
callingSharedPkgSettings = null;
} else {
callingPkgSetting = null;
callingSharedPkgSettings =
((PackageSetting) callingSetting).sharedUser.packages;
}
callingPkgSetting = (PackageSetting) callingSetting;
callingSharedPkgSettings = null;
} else {
callingPkgSetting = null;
callingSharedPkgSettings = ((SharedUserSetting) callingSetting).packages;
@@ -960,17 +786,13 @@ public class AppsFilter {
}
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "requestsQueryAllPackages");
if (callingPkgSetting != null) {
if (requestsQueryAllPackages(callingPkgSetting)) {
return false;
}
} else {
for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
if (requestsQueryAllPackages(callingSharedPkgSettings.valueAt(i))) {
return false;
}
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "hasPermission");
if (callingSetting.getPermissionsState().hasPermission(
Manifest.permission.QUERY_ALL_PACKAGES, UserHandle.getUserId(callingUid))) {
if (DEBUG_LOGGING) {
log(callingSetting, targetPkgSetting, "has query-all permission");
}
return false;
}
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -1011,7 +833,7 @@ public class AppsFilter {
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mImplicitlyQueryable");
final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
final int targetUid = UserHandle.getUid(userId, targetAppId);
if (mImplicitlyQueryable.contains(callingUid, targetUid)) {
if (DEBUG_LOGGING) {
log(callingSetting, targetPkgSetting, "implicitly queryable for user");
@@ -1049,20 +871,13 @@ public class AppsFilter {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
return true;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
private static boolean requestsQueryAllPackages(PackageSetting pkgSetting) {
// we're not guaranteed to have permissions yet analyzed at package add, so we inspect the
// package directly
return pkgSetting.pkg.getRequestedPermissions().contains(
Manifest.permission.QUERY_ALL_PACKAGES);
}
/** Returns {@code true} if the source package instruments the target package. */
private static boolean pkgInstruments(PackageSetting source, PackageSetting target) {
try {

View File

@@ -12362,7 +12362,7 @@ public class PackageManagerService extends IPackageManager.Stub
ksms.addScannedPackageLPw(pkg);
mComponentResolver.addAllComponents(pkg, chatty);
mAppsFilter.addPackage(pkgSetting);
mAppsFilter.addPackage(pkgSetting, mSettings.mPackages);
// Don't allow ephemeral applications to define new permissions groups.
if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
@@ -12536,6 +12536,8 @@ public class PackageManagerService extends IPackageManager.Stub
void cleanPackageDataStructuresLILPw(AndroidPackage pkg, boolean chatty) {
mComponentResolver.removeAllComponents(pkg, chatty);
mAppsFilter.removePackage(getPackageSetting(pkg.getPackageName()),
mInjector.getUserManagerInternal().getUserIds(), mSettings.mPackages);
mPermissionManager.removeAllPermissions(pkg, chatty);
final int instrumentationSize = ArrayUtils.size(pkg.getInstrumentations());
@@ -14251,7 +14253,7 @@ public class PackageManagerService extends IPackageManager.Stub
// Okay!
targetPackageSetting.setInstallerPackageName(installerPackageName);
mSettings.addInstallerPackageNames(targetPackageSetting.installSource);
mAppsFilter.addPackage(targetPackageSetting);
mAppsFilter.addPackage(targetPackageSetting, mSettings.mPackages);
scheduleWriteSettingsLocked();
}
}
@@ -18704,7 +18706,6 @@ public class PackageManagerService extends IPackageManager.Stub
clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL, true);
clearDefaultBrowserIfNeeded(packageName);
mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
mAppsFilter.removePackage(getPackageSetting(packageName));
removedAppId = mSettings.removePackageLPw(packageName);
if (outInfo != null) {
outInfo.removedAppId = removedAppId;
@@ -23462,7 +23463,6 @@ public class PackageManagerService extends IPackageManager.Stub
scheduleWritePackageRestrictionsLocked(userId);
scheduleWritePackageListLocked(userId);
primeDomainVerificationsLPw(userId);
mAppsFilter.onUsersChanged();
}
}

View File

@@ -23,7 +23,6 @@ import static org.hamcrest.Matchers.empty;
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.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -58,7 +57,6 @@ import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
import java.security.cert.CertificateException;
import java.util.ArrayList;
@@ -71,20 +69,16 @@ import java.util.Set;
@RunWith(JUnit4.class)
public class AppsFilterTest {
private static final int DUMMY_CALLING_APPID = 10345;
private static final int DUMMY_TARGET_APPID = 10556;
private static final int DUMMY_ACTOR_APPID = 10656;
private static final int DUMMY_OVERLAY_APPID = 10756;
private static final int SYSTEM_USER = 0;
private static final int[] SINGLE_USER_ARRAY = {SYSTEM_USER};
private static final int DUMMY_CALLING_UID = 10345;
private static final int DUMMY_TARGET_UID = 10556;
private static final int DUMMY_ACTOR_UID = 10656;
private static final int DUMMY_OVERLAY_UID = 10756;
private static final int DUMMY_ACTOR_TWO_UID = 10856;
@Mock
AppsFilter.FeatureConfig mFeatureConfigMock;
@Mock
AppsFilter.StateProvider mStateProvider;
private ArrayMap<String, PackageSetting> mExisting = new ArrayMap<>();
private Object mDummyLock = new Object();
private static ParsingPackage pkg(String packageName) {
return PackageImpl.forTesting(packageName)
@@ -176,24 +170,15 @@ public class AppsFilterTest {
mExisting = new ArrayMap<>();
MockitoAnnotations.initMocks(this);
doAnswer(invocation -> {
((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0))
.currentState(mExisting, SINGLE_USER_ARRAY);
return null;
}).when(mStateProvider)
.runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class));
when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true);
when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))).thenAnswer(
(Answer<Boolean>) invocation ->
((AndroidPackage)invocation.getArgument(SYSTEM_USER)).getTargetSdkVersion()
>= Build.VERSION_CODES.R);
when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class)))
.thenReturn(true);
}
@Test
public void testSystemReadyPropogates() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
appsFilter.onSystemReady();
verify(mFeatureConfigMock).onSystemReady();
}
@@ -201,23 +186,22 @@ public class AppsFilterTest {
@Test
public void testQueriesAction_FilterMatches() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkg("com.some.package", new IntentFilter("TEST_ACTION")), DUMMY_TARGET_APPID);
pkg("com.some.package", new IntentFilter("TEST_ACTION")), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_APPID);
pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
final Signature frameworkSignature = Mockito.mock(Signature.class);
final PackageParser.SigningDetails frameworkSigningDetails =
new PackageParser.SigningDetails(new Signature[]{frameworkSignature}, 1);
@@ -227,174 +211,164 @@ public class AppsFilterTest {
b -> b.setSigningDetails(frameworkSigningDetails));
appsFilter.onSystemReady();
final int activityUid = DUMMY_TARGET_APPID;
final int activityUid = DUMMY_TARGET_UID;
PackageSetting targetActivity = simulateAddPackage(appsFilter,
pkg("com.target.activity", new IntentFilter("TEST_ACTION")), activityUid);
final int receiverUid = DUMMY_TARGET_APPID + 1;
final int receiverUid = DUMMY_TARGET_UID + 1;
PackageSetting targetReceiver = simulateAddPackage(appsFilter,
pkgWithReceiver("com.target.receiver", new IntentFilter("TEST_ACTION")),
receiverUid);
final int callingUid = DUMMY_CALLING_APPID;
final int callingUid = DUMMY_CALLING_UID;
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.calling.action", new Intent("TEST_ACTION")), callingUid);
final int wildcardUid = DUMMY_CALLING_APPID + 1;
final int wildcardUid = DUMMY_CALLING_UID + 1;
PackageSetting callingWildCard = simulateAddPackage(appsFilter,
pkg("com.calling.wildcard", new Intent("*")), wildcardUid);
assertFalse(appsFilter.shouldFilterApplication(callingUid, calling, targetActivity,
SYSTEM_USER));
assertTrue(appsFilter.shouldFilterApplication(callingUid, calling, targetReceiver,
SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(callingUid, calling, targetActivity, 0));
assertTrue(appsFilter.shouldFilterApplication(callingUid, calling, targetReceiver, 0));
assertFalse(appsFilter.shouldFilterApplication(
wildcardUid, callingWildCard, targetActivity, SYSTEM_USER));
wildcardUid, callingWildCard, targetActivity, 0));
assertTrue(appsFilter.shouldFilterApplication(
wildcardUid, callingWildCard, targetReceiver, SYSTEM_USER));
wildcardUid, callingWildCard, targetReceiver, 0));
}
@Test
public void testQueriesProvider_FilterMatches() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_APPID);
pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
pkgQueriesProvider("com.some.other.package", "com.some.authority"),
DUMMY_CALLING_APPID);
DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testQueriesDifferentProvider_Filters() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_APPID);
pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
pkgQueriesProvider("com.some.other.package", "com.some.other.authority"),
DUMMY_CALLING_APPID);
DUMMY_CALLING_UID);
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkgWithProvider("com.some.package", "com.some.authority;com.some.other.authority"),
DUMMY_TARGET_APPID);
DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
pkgQueriesProvider("com.some.other.package", "com.some.authority"),
DUMMY_CALLING_APPID);
DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testQueriesAction_NoMatchingAction_Filters() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkg("com.some.package"), DUMMY_TARGET_APPID);
pkg("com.some.package"), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_APPID);
pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_UID);
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkg("com.some.package"), DUMMY_TARGET_APPID);
ParsingPackage callingPkg = pkg("com.some.other.package",
new Intent("TEST_ACTION"))
.setTargetSdkVersion(Build.VERSION_CODES.P);
PackageSetting calling = simulateAddPackage(appsFilter, callingPkg,
DUMMY_CALLING_APPID);
pkg("com.some.package"), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package",
new Intent("TEST_ACTION"))
.setTargetSdkVersion(Build.VERSION_CODES.P),
DUMMY_CALLING_UID);
when(mFeatureConfigMock.packageIsEnabled(calling.pkg)).thenReturn(false);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testNoQueries_Filters() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkg("com.some.package"), DUMMY_TARGET_APPID);
pkg("com.some.package"), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package"), DUMMY_CALLING_APPID);
pkg("com.some.other.package"), DUMMY_CALLING_UID);
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testForceQueryable_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_APPID);
pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package"), DUMMY_CALLING_APPID);
pkg("com.some.other.package"), DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testForceQueryableByDevice_SystemCaller_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"},
false, null);
new AppsFilter(mFeatureConfigMock, new String[]{"com.some.package"}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkg("com.some.package"), DUMMY_TARGET_APPID,
pkg("com.some.package"), DUMMY_TARGET_UID,
setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package"), DUMMY_CALLING_APPID);
pkg("com.some.other.package"), DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testSystemSignedTarget_DoesntFilter() throws CertificateException {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
appsFilter.onSystemReady();
final Signature frameworkSignature = Mockito.mock(Signature.class);
@@ -408,67 +382,62 @@ public class AppsFilterTest {
simulateAddPackage(appsFilter, pkg("android"), 1000,
b -> b.setSigningDetails(frameworkSigningDetails));
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
DUMMY_TARGET_APPID,
DUMMY_TARGET_UID,
b -> b.setSigningDetails(frameworkSigningDetails)
.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package"), DUMMY_CALLING_APPID,
pkg("com.some.other.package"), DUMMY_CALLING_UID,
b -> b.setSigningDetails(otherSigningDetails));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testForceQueryableByDevice_NonSystemCaller_Filters() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"},
false, null);
new AppsFilter(mFeatureConfigMock, new String[]{"com.some.package"}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkg("com.some.package"), DUMMY_TARGET_APPID);
pkg("com.some.package"), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package"), DUMMY_CALLING_APPID);
pkg("com.some.other.package"), DUMMY_CALLING_UID);
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testSystemQueryable_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{},
new AppsFilter(mFeatureConfigMock, new String[]{},
true /* system force queryable */, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkg("com.some.package"), DUMMY_TARGET_APPID,
pkg("com.some.package"), DUMMY_TARGET_UID,
setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package"), DUMMY_CALLING_APPID);
pkg("com.some.other.package"), DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testQueriesPackage_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkg("com.some.package"), DUMMY_TARGET_APPID);
pkg("com.some.package"), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package", "com.some.package"), DUMMY_CALLING_APPID);
pkg("com.some.other.package", "com.some.package"), DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
@@ -476,67 +445,63 @@ public class AppsFilterTest {
when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class)))
.thenReturn(false);
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(
appsFilter, pkg("com.some.package"), DUMMY_TARGET_APPID);
appsFilter, pkg("com.some.package"), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(
appsFilter, pkg("com.some.other.package"), DUMMY_CALLING_APPID);
appsFilter, pkg("com.some.other.package"), DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testSystemUid_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkg("com.some.package"), DUMMY_TARGET_APPID);
pkg("com.some.package"), DUMMY_TARGET_UID);
assertFalse(appsFilter.shouldFilterApplication(SYSTEM_USER, null, target, SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(0, null, target, 0));
assertFalse(appsFilter.shouldFilterApplication(Process.FIRST_APPLICATION_UID - 1,
null, target, SYSTEM_USER));
null, target, 0));
}
@Test
public void testNonSystemUid_NoCallingSetting_Filters() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
pkg("com.some.package"), DUMMY_TARGET_APPID);
pkg("com.some.package"), DUMMY_TARGET_UID);
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, null, target,
SYSTEM_USER));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, null, target, 0));
}
@Test
public void testNoTargetPackage_filters() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = new PackageSettingBuilder()
.setAppId(DUMMY_TARGET_APPID)
.setName("com.some.package")
.setCodePath("/")
.setResourcePath("/")
.setPVersionCode(1L)
.build();
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_APPID);
pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_UID);
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
@@ -551,11 +516,7 @@ public class AppsFilterTest {
.setOverlayTargetName("overlayableName");
ParsingPackage actor = pkg("com.some.package.actor");
final AppsFilter appsFilter = new AppsFilter(
mStateProvider,
mFeatureConfigMock,
new String[]{},
false,
final AppsFilter appsFilter = new AppsFilter(mFeatureConfigMock, new String[]{}, false,
new OverlayReferenceMapper.Provider() {
@Nullable
@Override
@@ -583,34 +544,31 @@ public class AppsFilterTest {
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting targetSetting = simulateAddPackage(appsFilter, target, DUMMY_TARGET_APPID);
PackageSetting overlaySetting =
simulateAddPackage(appsFilter, overlay, DUMMY_OVERLAY_APPID);
PackageSetting actorSetting = simulateAddPackage(appsFilter, actor, DUMMY_ACTOR_APPID);
PackageSetting targetSetting = simulateAddPackage(appsFilter, target, DUMMY_TARGET_UID);
PackageSetting overlaySetting = simulateAddPackage(appsFilter, overlay, DUMMY_OVERLAY_UID);
PackageSetting actorSetting = simulateAddPackage(appsFilter, actor, DUMMY_ACTOR_UID);
// Actor can see both target and overlay
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSetting,
targetSetting, SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSetting,
overlaySetting, SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_UID, actorSetting,
targetSetting, 0));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_UID, actorSetting,
overlaySetting, 0));
// But target/overlay can't see each other
assertTrue(appsFilter.shouldFilterApplication(DUMMY_TARGET_APPID, targetSetting,
overlaySetting, SYSTEM_USER));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_APPID, overlaySetting,
targetSetting, SYSTEM_USER));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_TARGET_UID, targetSetting,
overlaySetting, 0));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_UID, overlaySetting,
targetSetting, 0));
// And can't see the actor
assertTrue(appsFilter.shouldFilterApplication(DUMMY_TARGET_APPID, targetSetting,
actorSetting, SYSTEM_USER));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_APPID, overlaySetting,
actorSetting, SYSTEM_USER));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_TARGET_UID, targetSetting,
actorSetting, 0));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_UID, overlaySetting,
actorSetting, 0));
}
@Test
public void testActsOnTargetOfOverlayThroughSharedUser() throws Exception {
// Debug.waitForDebugger();
final String actorName = "overlay://test/actorName";
ParsingPackage target = pkg("com.some.package.target")
@@ -622,11 +580,7 @@ public class AppsFilterTest {
ParsingPackage actorOne = pkg("com.some.package.actor.one");
ParsingPackage actorTwo = pkg("com.some.package.actor.two");
final AppsFilter appsFilter = new AppsFilter(
mStateProvider,
mFeatureConfigMock,
new String[]{},
false,
final AppsFilter appsFilter = new AppsFilter(mFeatureConfigMock, new String[]{}, false,
new OverlayReferenceMapper.Provider() {
@Nullable
@Override
@@ -655,114 +609,108 @@ public class AppsFilterTest {
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting targetSetting = simulateAddPackage(appsFilter, target, DUMMY_TARGET_APPID);
SharedUserSetting actorSharedSetting = new SharedUserSetting("actorSharedUser",
targetSetting.pkgFlags, targetSetting.pkgPrivateFlags);
PackageSetting overlaySetting =
simulateAddPackage(appsFilter, overlay, DUMMY_OVERLAY_APPID);
simulateAddPackage(appsFilter, actorOne, DUMMY_ACTOR_APPID,
null /*settingBuilder*/, actorSharedSetting);
simulateAddPackage(appsFilter, actorTwo, DUMMY_ACTOR_APPID,
null /*settingBuilder*/, actorSharedSetting);
PackageSetting targetSetting = simulateAddPackage(appsFilter, target, DUMMY_TARGET_UID);
PackageSetting overlaySetting = simulateAddPackage(appsFilter, overlay, DUMMY_OVERLAY_UID);
PackageSetting actorOneSetting = simulateAddPackage(appsFilter, actorOne, DUMMY_ACTOR_UID);
PackageSetting actorTwoSetting = simulateAddPackage(appsFilter, actorTwo,
DUMMY_ACTOR_TWO_UID);
SharedUserSetting actorSharedSetting = new SharedUserSetting("actorSharedUser",
actorOneSetting.pkgFlags, actorOneSetting.pkgPrivateFlags);
actorSharedSetting.addPackage(actorOneSetting);
actorSharedSetting.addPackage(actorTwoSetting);
// actorTwo can see both target and overlay
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSharedSetting,
targetSetting, SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSharedSetting,
overlaySetting, SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_TWO_UID, actorSharedSetting,
targetSetting, 0));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_TWO_UID, actorSharedSetting,
overlaySetting, 0));
}
@Test
public void testInitiatingApp_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
DUMMY_TARGET_APPID);
DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
DUMMY_CALLING_APPID, withInstallSource(target.name, null, null, false));
DUMMY_CALLING_UID, withInstallSource(target.name, null, null, false));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testUninstalledInitiatingApp_Filters() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
DUMMY_TARGET_APPID);
DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
DUMMY_CALLING_APPID, withInstallSource(target.name, null, null, true));
DUMMY_CALLING_UID, withInstallSource(target.name, null, null, true));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testOriginatingApp_Filters() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
DUMMY_TARGET_APPID);
DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
DUMMY_CALLING_APPID, withInstallSource(null, target.name, null, false));
DUMMY_CALLING_UID, withInstallSource(null, target.name, null, false));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testInstallingApp_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
DUMMY_TARGET_APPID);
DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
DUMMY_CALLING_APPID, withInstallSource(null, null, target.name, false));
DUMMY_CALLING_UID, withInstallSource(null, null, target.name, false));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@Test
public void testInstrumentation_DoesntFilter() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
DUMMY_TARGET_APPID);
DUMMY_TARGET_UID);
PackageSetting instrumentation = simulateAddPackage(appsFilter,
pkgWithInstrumentation("com.some.other.package", "com.some.package"),
DUMMY_CALLING_APPID);
DUMMY_CALLING_UID);
assertFalse(
appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target,
SYSTEM_USER));
appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, instrumentation, target, 0));
assertFalse(
appsFilter.shouldFilterApplication(DUMMY_TARGET_APPID, target, instrumentation,
SYSTEM_USER));
appsFilter.shouldFilterApplication(DUMMY_TARGET_UID, target, instrumentation, 0));
}
@Test
public void testWhoCanSee() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady();
@@ -780,25 +728,21 @@ public class AppsFilterTest {
queriesProviderAppId);
final int[] systemFilter =
appsFilter.getVisibilityWhitelist(system, SINGLE_USER_ARRAY, mExisting)
.get(SYSTEM_USER);
appsFilter.getVisibilityWhitelist(system, new int[]{0}, mExisting).get(0);
assertThat(toList(systemFilter), empty());
final int[] seesNothingFilter =
appsFilter.getVisibilityWhitelist(seesNothing, SINGLE_USER_ARRAY, mExisting)
.get(SYSTEM_USER);
appsFilter.getVisibilityWhitelist(seesNothing, new int[]{0}, mExisting).get(0);
assertThat(toList(seesNothingFilter),
contains(seesNothingAppId));
final int[] hasProviderFilter =
appsFilter.getVisibilityWhitelist(hasProvider, SINGLE_USER_ARRAY, mExisting)
.get(SYSTEM_USER);
appsFilter.getVisibilityWhitelist(hasProvider, new int[]{0}, mExisting).get(0);
assertThat(toList(hasProviderFilter),
contains(hasProviderAppId, queriesProviderAppId));
int[] queriesProviderFilter =
appsFilter.getVisibilityWhitelist(queriesProvider, SINGLE_USER_ARRAY, mExisting)
.get(SYSTEM_USER);
appsFilter.getVisibilityWhitelist(queriesProvider, new int[]{0}, mExisting).get(0);
assertThat(toList(queriesProviderFilter),
contains(queriesProviderAppId));
@@ -807,8 +751,7 @@ public class AppsFilterTest {
// ensure implicit access is included in the filter
queriesProviderFilter =
appsFilter.getVisibilityWhitelist(queriesProvider, SINGLE_USER_ARRAY, mExisting)
.get(SYSTEM_USER);
appsFilter.getVisibilityWhitelist(queriesProvider, new int[]{0}, mExisting).get(0);
assertThat(toList(queriesProviderFilter),
contains(hasProviderAppId, queriesProviderAppId));
}
@@ -836,17 +779,11 @@ public class AppsFilterTest {
private PackageSetting simulateAddPackage(AppsFilter filter,
ParsingPackage newPkgBuilder, int appId) {
return simulateAddPackage(filter, newPkgBuilder, appId, null /*settingBuilder*/);
return simulateAddPackage(filter, newPkgBuilder, appId, null);
}
private PackageSetting simulateAddPackage(AppsFilter filter,
ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action) {
return simulateAddPackage(filter, newPkgBuilder, appId, action, null /*sharedUserSetting*/);
}
private PackageSetting simulateAddPackage(AppsFilter filter,
ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action,
@Nullable SharedUserSetting sharedUserSetting) {
AndroidPackage newPkg = ((ParsedPackage) newPkgBuilder.hideAsParsed()).hideAsFinal();
final PackageSettingBuilder settingBuilder = new PackageSettingBuilder()
@@ -858,12 +795,8 @@ public class AppsFilterTest {
.setPVersionCode(1L);
final PackageSetting setting =
(action == null ? settingBuilder : action.withBuilder(settingBuilder)).build();
filter.addPackage(setting, mExisting);
mExisting.put(newPkg.getPackageName(), setting);
if (sharedUserSetting != null) {
sharedUserSetting.addPackage(setting);
setting.sharedUser = sharedUserSetting;
}
filter.addPackage(setting);
return setting;
}
@@ -876,3 +809,4 @@ public class AppsFilterTest {
return setting -> setting.setInstallSource(installSource);
}
}