Pre-cache filter results am: 0192f737ff am: 182b5f238a am: 1389bda829
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11817533 Change-Id: Iffb7147ff14208505acb5fce32a79ab6c1f109bf
This commit is contained in:
@@ -19,6 +19,8 @@ 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;
|
||||
@@ -27,6 +29,7 @@ import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManagerInternal;
|
||||
import android.content.pm.PackageParser;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.pm.parsing.component.ParsedComponent;
|
||||
import android.content.pm.parsing.component.ParsedInstrumentation;
|
||||
import android.content.pm.parsing.component.ParsedIntentInfo;
|
||||
@@ -108,12 +111,25 @@ public class AppsFilter {
|
||||
private final boolean mSystemAppsQueryable;
|
||||
|
||||
private final FeatureConfig mFeatureConfig;
|
||||
|
||||
private final OverlayReferenceMapper mOverlayReferenceMapper;
|
||||
private final StateProvider mStateProvider;
|
||||
|
||||
private PackageParser.SigningDetails mSystemSigningDetails;
|
||||
private Set<String> mProtectedBroadcasts = new ArraySet<>();
|
||||
|
||||
AppsFilter(FeatureConfig featureConfig, String[] forceQueryableWhitelist,
|
||||
/**
|
||||
* 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 scam and is null until {@link #onSystemReady()} is called.
|
||||
*/
|
||||
private volatile SparseArray<SparseBooleanArray> mShouldFilterCache;
|
||||
|
||||
@VisibleForTesting(visibility = PRIVATE)
|
||||
AppsFilter(StateProvider stateProvider,
|
||||
FeatureConfig featureConfig,
|
||||
String[] forceQueryableWhitelist,
|
||||
boolean systemAppsQueryable,
|
||||
@Nullable OverlayReferenceMapper.Provider overlayProvider) {
|
||||
mFeatureConfig = featureConfig;
|
||||
@@ -121,8 +137,23 @@ 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, UserInfo[] users);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting(visibility = PRIVATE)
|
||||
public interface FeatureConfig {
|
||||
|
||||
/** Called when the system is ready and components can be queried. */
|
||||
@@ -139,6 +170,7 @@ 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);
|
||||
@@ -146,6 +178,7 @@ 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);
|
||||
@@ -161,6 +194,7 @@ public class AppsFilter {
|
||||
|
||||
@Nullable
|
||||
private SparseBooleanArray mLoggingEnabled = null;
|
||||
private AppsFilter mAppsFilter;
|
||||
|
||||
private FeatureConfigImpl(
|
||||
PackageManagerInternal pmInternal, PackageManagerService.Injector injector) {
|
||||
@@ -168,6 +202,10 @@ public class AppsFilter {
|
||||
mInjector = injector;
|
||||
}
|
||||
|
||||
public void setAppsFilter(AppsFilter filter) {
|
||||
mAppsFilter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSystemReady() {
|
||||
mFeatureEnabled = DeviceConfig.getBoolean(
|
||||
@@ -235,11 +273,12 @@ public class AppsFilter {
|
||||
@Override
|
||||
public void onCompatChange(String packageName) {
|
||||
updateEnabledState(mPmInternal.getPackage(packageName));
|
||||
mAppsFilter.updateShouldFilterCacheForPackage(packageName);
|
||||
}
|
||||
|
||||
private void updateEnabledState(AndroidPackage pkg) {
|
||||
// TODO(b/135203078): Do not use toAppInfo
|
||||
final boolean enabled = mInjector.getCompatibility().isChangeEnabledInternal(
|
||||
final boolean enabled = mInjector.getCompatibility().isChangeEnabled(
|
||||
PackageManager.FILTER_APPLICATION_QUERY, pkg.toAppInfoWithoutState());
|
||||
if (enabled) {
|
||||
mDisabledPackages.remove(pkg.getPackageName());
|
||||
@@ -267,7 +306,7 @@ public class AppsFilter {
|
||||
final boolean forceSystemAppsQueryable =
|
||||
injector.getContext().getResources()
|
||||
.getBoolean(R.bool.config_forceSystemPackagesQueryable);
|
||||
final FeatureConfig featureConfig = new FeatureConfigImpl(pms, injector);
|
||||
final FeatureConfigImpl featureConfig = new FeatureConfigImpl(pms, injector);
|
||||
final String[] forcedQueryablePackageNames;
|
||||
if (forceSystemAppsQueryable) {
|
||||
// all system apps already queryable, no need to read and parse individual exceptions
|
||||
@@ -280,8 +319,16 @@ public class AppsFilter {
|
||||
forcedQueryablePackageNames[i] = forcedQueryablePackageNames[i].intern();
|
||||
}
|
||||
}
|
||||
return new AppsFilter(featureConfig, forcedQueryablePackageNames,
|
||||
forceSystemAppsQueryable, null);
|
||||
final StateProvider stateProvider = command -> {
|
||||
synchronized (injector.getLock()) {
|
||||
command.currentState(injector.getSettings().mPackages,
|
||||
injector.getUserManagerInternal().getUserInfos());
|
||||
}
|
||||
};
|
||||
AppsFilter appsFilter = new AppsFilter(stateProvider, featureConfig,
|
||||
forcedQueryablePackageNames, forceSystemAppsQueryable, null);
|
||||
featureConfig.setAppsFilter(appsFilter);
|
||||
return appsFilter;
|
||||
}
|
||||
|
||||
public FeatureConfig getFeatureConfig() {
|
||||
@@ -404,27 +451,59 @@ 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
|
||||
&& mImplicitlyQueryable.add(recipientUid, visibleUid) && DEBUG_LOGGING) {
|
||||
Slog.i(TAG, "implicit access granted: " + recipientUid + " -> " + 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onSystemReady() {
|
||||
mStateProvider.runWithState(new StateProvider.CurrentStateCallback() {
|
||||
@Override
|
||||
public void currentState(ArrayMap<String, PackageSetting> settings,
|
||||
UserInfo[] users) {
|
||||
mShouldFilterCache = new SparseArray<>(users.length * settings.size());
|
||||
}
|
||||
});
|
||||
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 existingSettings all other settings currently on the device.
|
||||
* @param newPkgSetting the new setting being added
|
||||
*/
|
||||
public void addPackage(PackageSetting newPkgSetting,
|
||||
public void addPackage(PackageSetting newPkgSetting) {
|
||||
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.addPackage");
|
||||
try {
|
||||
mStateProvider.runWithState((settings, users) -> {
|
||||
addPackageInternal(newPkgSetting, settings);
|
||||
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) {
|
||||
if (Objects.equals("android", newPkgSetting.name)) {
|
||||
// let's set aside the framework signatures
|
||||
@@ -438,79 +517,153 @@ public class AppsFilter {
|
||||
}
|
||||
}
|
||||
|
||||
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.addPackage");
|
||||
try {
|
||||
final AndroidPackage newPkg = newPkgSetting.pkg;
|
||||
if (newPkg == null) {
|
||||
// nothing to add
|
||||
return;
|
||||
}
|
||||
final AndroidPackage newPkg = newPkgSetting.pkg;
|
||||
if (newPkg == null) {
|
||||
// nothing to add
|
||||
return;
|
||||
}
|
||||
|
||||
if (!newPkg.getProtectedBroadcasts().isEmpty()) {
|
||||
mProtectedBroadcasts.addAll(newPkg.getProtectedBroadcasts());
|
||||
recomputeComponentVisibility(existingSettings, newPkg.getPackageName());
|
||||
}
|
||||
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);
|
||||
}
|
||||
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;
|
||||
for (int i = existingSettings.size() - 1; i >= 0; i--) {
|
||||
final PackageSetting existingSetting = existingSettings.valueAt(i);
|
||||
if (existingSetting.appId == newPkgSetting.appId || existingSetting.pkg == null) {
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
if (canQueryViaPackage(existingPkg, newPkg)
|
||||
|| canQueryAsInstaller(existingSetting, newPkg)) {
|
||||
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);
|
||||
// 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,
|
||||
UserInfo[] 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;
|
||||
}
|
||||
final int userCount = allUsers.length;
|
||||
final int appxUidCount = userCount * allSettings.size();
|
||||
for (int su = 0; su < userCount; su++) {
|
||||
int subjectUser = allUsers[su].id;
|
||||
for (int ou = su; ou < userCount; ou++) {
|
||||
int otherUser = allUsers[ou].id;
|
||||
int subjectUid = UserHandle.getUid(subjectUser, subjectSetting.appId);
|
||||
if (!mShouldFilterCache.contains(subjectUid)) {
|
||||
mShouldFilterCache.put(subjectUid, new SparseBooleanArray(appxUidCount));
|
||||
}
|
||||
int otherUid = UserHandle.getUid(otherUser, otherSetting.appId);
|
||||
if (!mShouldFilterCache.contains(otherUid)) {
|
||||
mShouldFilterCache.put(otherUid, new SparseBooleanArray(appxUidCount));
|
||||
}
|
||||
mShouldFilterCache.get(subjectUid).put(otherUid,
|
||||
shouldFilterApplicationInternal(
|
||||
subjectUid, subjectSetting, otherSetting, otherUser));
|
||||
mShouldFilterCache.get(otherUid).put(subjectUid,
|
||||
shouldFilterApplicationInternal(
|
||||
otherUid, otherSetting, subjectSetting, subjectUser));
|
||||
}
|
||||
}
|
||||
mOverlayReferenceMapper.addPkg(newPkgSetting.pkg, existingPkgs);
|
||||
mFeatureConfig.updatePackageState(newPkgSetting, false /*removed*/);
|
||||
} finally {
|
||||
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -561,6 +714,7 @@ 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
|
||||
@@ -569,11 +723,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,
|
||||
@@ -618,52 +772,61 @@ public class AppsFilter {
|
||||
/**
|
||||
* Removes a package for consideration when filtering visibility between apps.
|
||||
*
|
||||
* @param setting the setting of the package being removed.
|
||||
* @param allUsers array of all current users on device.
|
||||
* @param setting the setting of the package being removed.
|
||||
*/
|
||||
public void removePackage(PackageSetting setting, int[] allUsers,
|
||||
ArrayMap<String, PackageSetting> existingSettings) {
|
||||
public void removePackage(PackageSetting setting) {
|
||||
removeAppIdFromVisibilityCache(setting.appId);
|
||||
mStateProvider.runWithState((settings, users) -> {
|
||||
final int userCount = users.length;
|
||||
for (int u = 0; u < userCount; u++) {
|
||||
final int userId = users[u].id;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
});
|
||||
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*/);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -680,11 +843,32 @@ public class AppsFilter {
|
||||
PackageSetting targetPkgSetting, int userId) {
|
||||
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplication");
|
||||
try {
|
||||
|
||||
if (!shouldFilterApplicationInternal(
|
||||
callingUid, callingSetting, targetPkgSetting, userId)) {
|
||||
if (callingUid < Process.FIRST_APPLICATION_UID
|
||||
|| UserHandle.getAppId(callingUid) == targetPkgSetting.appId) {
|
||||
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");
|
||||
}
|
||||
@@ -695,7 +879,7 @@ public class AppsFilter {
|
||||
}
|
||||
|
||||
private boolean shouldFilterApplicationInternal(int callingUid, SettingBase callingSetting,
|
||||
PackageSetting targetPkgSetting, int userId) {
|
||||
PackageSetting targetPkgSetting, int targetUserId) {
|
||||
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplicationInternal");
|
||||
try {
|
||||
final boolean featureEnabled = mFeatureConfig.isGloballyEnabled();
|
||||
@@ -705,12 +889,6 @@ 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;
|
||||
@@ -719,8 +897,14 @@ public class AppsFilter {
|
||||
final ArraySet<PackageSetting> callingSharedPkgSettings;
|
||||
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "callingSetting instanceof");
|
||||
if (callingSetting instanceof PackageSetting) {
|
||||
callingPkgSetting = (PackageSetting) callingSetting;
|
||||
callingSharedPkgSettings = null;
|
||||
if (((PackageSetting) callingSetting).sharedUser == null) {
|
||||
callingPkgSetting = (PackageSetting) callingSetting;
|
||||
callingSharedPkgSettings = null;
|
||||
} else {
|
||||
callingPkgSetting = null;
|
||||
callingSharedPkgSettings =
|
||||
((PackageSetting) callingSetting).sharedUser.packages;
|
||||
}
|
||||
} else {
|
||||
callingPkgSetting = null;
|
||||
callingSharedPkgSettings = ((SharedUserSetting) callingSetting).packages;
|
||||
@@ -778,13 +962,17 @@ public class AppsFilter {
|
||||
}
|
||||
|
||||
try {
|
||||
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");
|
||||
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;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} finally {
|
||||
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
|
||||
@@ -825,7 +1013,7 @@ public class AppsFilter {
|
||||
|
||||
try {
|
||||
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mImplicitlyQueryable");
|
||||
final int targetUid = UserHandle.getUid(userId, targetAppId);
|
||||
final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
|
||||
if (mImplicitlyQueryable.contains(callingUid, targetUid)) {
|
||||
if (DEBUG_LOGGING) {
|
||||
log(callingSetting, targetPkgSetting, "implicitly queryable for user");
|
||||
@@ -863,13 +1051,20 @@ 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 {
|
||||
|
||||
@@ -12362,7 +12362,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
ksms.addScannedPackageLPw(pkg);
|
||||
|
||||
mComponentResolver.addAllComponents(pkg, chatty);
|
||||
mAppsFilter.addPackage(pkgSetting, mSettings.mPackages);
|
||||
mAppsFilter.addPackage(pkgSetting);
|
||||
|
||||
// Don't allow ephemeral applications to define new permissions groups.
|
||||
if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
|
||||
@@ -12536,8 +12536,6 @@ 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());
|
||||
@@ -14264,7 +14262,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
// Okay!
|
||||
targetPackageSetting.setInstallerPackageName(installerPackageName);
|
||||
mSettings.addInstallerPackageNames(targetPackageSetting.installSource);
|
||||
mAppsFilter.addPackage(targetPackageSetting, mSettings.mPackages);
|
||||
mAppsFilter.addPackage(targetPackageSetting);
|
||||
scheduleWriteSettingsLocked();
|
||||
}
|
||||
}
|
||||
@@ -18717,6 +18715,7 @@ 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;
|
||||
@@ -23474,6 +23473,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
scheduleWritePackageRestrictionsLocked(userId);
|
||||
scheduleWritePackageListLocked(userId);
|
||||
primeDomainVerificationsLPw(userId);
|
||||
mAppsFilter.onUsersChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ 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;
|
||||
|
||||
@@ -32,6 +33,7 @@ import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageParser;
|
||||
import android.content.pm.Signature;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.pm.parsing.ParsingPackage;
|
||||
import android.content.pm.parsing.component.ParsedActivity;
|
||||
import android.content.pm.parsing.component.ParsedInstrumentation;
|
||||
@@ -39,9 +41,11 @@ import android.content.pm.parsing.component.ParsedIntentInfo;
|
||||
import android.content.pm.parsing.component.ParsedProvider;
|
||||
import android.os.Build;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@@ -57,26 +61,36 @@ 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;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Presubmit
|
||||
@RunWith(JUnit4.class)
|
||||
public class AppsFilterTest {
|
||||
|
||||
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;
|
||||
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 SECONDARY_USER = 10;
|
||||
private static final int[] USER_ARRAY = {SYSTEM_USER, SECONDARY_USER};
|
||||
private static final UserInfo[] USER_INFO_LIST = Arrays.stream(USER_ARRAY).mapToObj(
|
||||
id -> new UserInfo(id, Integer.toString(id), 0)).toArray(UserInfo[]::new);
|
||||
|
||||
@Mock
|
||||
AppsFilter.FeatureConfig mFeatureConfigMock;
|
||||
@Mock
|
||||
AppsFilter.StateProvider mStateProvider;
|
||||
|
||||
private ArrayMap<String, PackageSetting> mExisting = new ArrayMap<>();
|
||||
|
||||
@@ -170,15 +184,24 @@ public class AppsFilterTest {
|
||||
mExisting = new ArrayMap<>();
|
||||
|
||||
MockitoAnnotations.initMocks(this);
|
||||
doAnswer(invocation -> {
|
||||
((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0))
|
||||
.currentState(mExisting, USER_INFO_LIST);
|
||||
return null;
|
||||
}).when(mStateProvider)
|
||||
.runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class));
|
||||
|
||||
when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true);
|
||||
when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class)))
|
||||
.thenReturn(true);
|
||||
when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))).thenAnswer(
|
||||
(Answer<Boolean>) invocation ->
|
||||
((AndroidPackage)invocation.getArgument(SYSTEM_USER)).getTargetSdkVersion()
|
||||
>= Build.VERSION_CODES.R);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSystemReadyPropogates() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
appsFilter.onSystemReady();
|
||||
verify(mFeatureConfigMock).onSystemReady();
|
||||
}
|
||||
@@ -186,22 +209,23 @@ public class AppsFilterTest {
|
||||
@Test
|
||||
public void testQueriesAction_FilterMatches() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.package", new IntentFilter("TEST_ACTION")), DUMMY_TARGET_UID);
|
||||
pkg("com.some.package", new IntentFilter("TEST_ACTION")), DUMMY_TARGET_APPID);
|
||||
PackageSetting calling = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_UID);
|
||||
pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_APPID);
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
final Signature frameworkSignature = Mockito.mock(Signature.class);
|
||||
final PackageParser.SigningDetails frameworkSigningDetails =
|
||||
new PackageParser.SigningDetails(new Signature[]{frameworkSignature}, 1);
|
||||
@@ -211,164 +235,174 @@ public class AppsFilterTest {
|
||||
b -> b.setSigningDetails(frameworkSigningDetails));
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
final int activityUid = DUMMY_TARGET_UID;
|
||||
final int activityUid = DUMMY_TARGET_APPID;
|
||||
PackageSetting targetActivity = simulateAddPackage(appsFilter,
|
||||
pkg("com.target.activity", new IntentFilter("TEST_ACTION")), activityUid);
|
||||
final int receiverUid = DUMMY_TARGET_UID + 1;
|
||||
final int receiverUid = DUMMY_TARGET_APPID + 1;
|
||||
PackageSetting targetReceiver = simulateAddPackage(appsFilter,
|
||||
pkgWithReceiver("com.target.receiver", new IntentFilter("TEST_ACTION")),
|
||||
receiverUid);
|
||||
final int callingUid = DUMMY_CALLING_UID;
|
||||
final int callingUid = DUMMY_CALLING_APPID;
|
||||
PackageSetting calling = simulateAddPackage(appsFilter,
|
||||
pkg("com.calling.action", new Intent("TEST_ACTION")), callingUid);
|
||||
final int wildcardUid = DUMMY_CALLING_UID + 1;
|
||||
final int wildcardUid = DUMMY_CALLING_APPID + 1;
|
||||
PackageSetting callingWildCard = simulateAddPackage(appsFilter,
|
||||
pkg("com.calling.wildcard", new Intent("*")), wildcardUid);
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(callingUid, calling, targetActivity, 0));
|
||||
assertTrue(appsFilter.shouldFilterApplication(callingUid, calling, targetReceiver, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(callingUid, calling, targetActivity,
|
||||
SYSTEM_USER));
|
||||
assertTrue(appsFilter.shouldFilterApplication(callingUid, calling, targetReceiver,
|
||||
SYSTEM_USER));
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(
|
||||
wildcardUid, callingWildCard, targetActivity, 0));
|
||||
wildcardUid, callingWildCard, targetActivity, SYSTEM_USER));
|
||||
assertTrue(appsFilter.shouldFilterApplication(
|
||||
wildcardUid, callingWildCard, targetReceiver, 0));
|
||||
wildcardUid, callingWildCard, targetReceiver, SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueriesProvider_FilterMatches() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter,
|
||||
pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_UID);
|
||||
pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_APPID);
|
||||
PackageSetting calling = simulateAddPackage(appsFilter,
|
||||
pkgQueriesProvider("com.some.other.package", "com.some.authority"),
|
||||
DUMMY_CALLING_UID);
|
||||
DUMMY_CALLING_APPID);
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueriesDifferentProvider_Filters() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter,
|
||||
pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_UID);
|
||||
pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_APPID);
|
||||
PackageSetting calling = simulateAddPackage(appsFilter,
|
||||
pkgQueriesProvider("com.some.other.package", "com.some.other.authority"),
|
||||
DUMMY_CALLING_UID);
|
||||
DUMMY_CALLING_APPID);
|
||||
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, 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_UID);
|
||||
DUMMY_TARGET_APPID);
|
||||
PackageSetting calling = simulateAddPackage(appsFilter,
|
||||
pkgQueriesProvider("com.some.other.package", "com.some.authority"),
|
||||
DUMMY_CALLING_UID);
|
||||
DUMMY_CALLING_APPID);
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueriesAction_NoMatchingAction_Filters() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.package"), DUMMY_TARGET_UID);
|
||||
pkg("com.some.package"), DUMMY_TARGET_APPID);
|
||||
PackageSetting calling = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_UID);
|
||||
pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_APPID);
|
||||
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter,
|
||||
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);
|
||||
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);
|
||||
|
||||
when(mFeatureConfigMock.packageIsEnabled(calling.pkg)).thenReturn(false);
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoQueries_Filters() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.package"), DUMMY_TARGET_UID);
|
||||
pkg("com.some.package"), DUMMY_TARGET_APPID);
|
||||
PackageSetting calling = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.other.package"), DUMMY_CALLING_UID);
|
||||
pkg("com.some.other.package"), DUMMY_CALLING_APPID);
|
||||
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForceQueryable_DoesntFilter() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_UID);
|
||||
pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_APPID);
|
||||
PackageSetting calling = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.other.package"), DUMMY_CALLING_UID);
|
||||
pkg("com.some.other.package"), DUMMY_CALLING_APPID);
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForceQueryableByDevice_SystemCaller_DoesntFilter() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{"com.some.package"}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"},
|
||||
false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.package"), DUMMY_TARGET_UID,
|
||||
pkg("com.some.package"), DUMMY_TARGET_APPID,
|
||||
setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
|
||||
PackageSetting calling = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.other.package"), DUMMY_CALLING_UID);
|
||||
pkg("com.some.other.package"), DUMMY_CALLING_APPID);
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSystemSignedTarget_DoesntFilter() throws CertificateException {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
final Signature frameworkSignature = Mockito.mock(Signature.class);
|
||||
@@ -382,62 +416,67 @@ public class AppsFilterTest {
|
||||
simulateAddPackage(appsFilter, pkg("android"), 1000,
|
||||
b -> b.setSigningDetails(frameworkSigningDetails));
|
||||
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
|
||||
DUMMY_TARGET_UID,
|
||||
DUMMY_TARGET_APPID,
|
||||
b -> b.setSigningDetails(frameworkSigningDetails)
|
||||
.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
|
||||
PackageSetting calling = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.other.package"), DUMMY_CALLING_UID,
|
||||
pkg("com.some.other.package"), DUMMY_CALLING_APPID,
|
||||
b -> b.setSigningDetails(otherSigningDetails));
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForceQueryableByDevice_NonSystemCaller_Filters() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{"com.some.package"}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"},
|
||||
false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.package"), DUMMY_TARGET_UID);
|
||||
pkg("com.some.package"), DUMMY_TARGET_APPID);
|
||||
PackageSetting calling = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.other.package"), DUMMY_CALLING_UID);
|
||||
pkg("com.some.other.package"), DUMMY_CALLING_APPID);
|
||||
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSystemQueryable_DoesntFilter() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{},
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{},
|
||||
true /* system force queryable */, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.package"), DUMMY_TARGET_UID,
|
||||
pkg("com.some.package"), DUMMY_TARGET_APPID,
|
||||
setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
|
||||
PackageSetting calling = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.other.package"), DUMMY_CALLING_UID);
|
||||
pkg("com.some.other.package"), DUMMY_CALLING_APPID);
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueriesPackage_DoesntFilter() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.package"), DUMMY_TARGET_UID);
|
||||
pkg("com.some.package"), DUMMY_TARGET_APPID);
|
||||
PackageSetting calling = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.other.package", "com.some.package"), DUMMY_CALLING_UID);
|
||||
pkg("com.some.other.package", "com.some.package"), DUMMY_CALLING_APPID);
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -445,63 +484,67 @@ public class AppsFilterTest {
|
||||
when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class)))
|
||||
.thenReturn(false);
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(
|
||||
appsFilter, pkg("com.some.package"), DUMMY_TARGET_UID);
|
||||
appsFilter, pkg("com.some.package"), DUMMY_TARGET_APPID);
|
||||
PackageSetting calling = simulateAddPackage(
|
||||
appsFilter, pkg("com.some.other.package"), DUMMY_CALLING_UID);
|
||||
appsFilter, pkg("com.some.other.package"), DUMMY_CALLING_APPID);
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSystemUid_DoesntFilter() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.package"), DUMMY_TARGET_UID);
|
||||
pkg("com.some.package"), DUMMY_TARGET_APPID);
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(0, null, target, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(SYSTEM_USER, null, target, SYSTEM_USER));
|
||||
assertFalse(appsFilter.shouldFilterApplication(Process.FIRST_APPLICATION_UID - 1,
|
||||
null, target, 0));
|
||||
null, target, SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonSystemUid_NoCallingSetting_Filters() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter,
|
||||
pkg("com.some.package"), DUMMY_TARGET_UID);
|
||||
pkg("com.some.package"), DUMMY_TARGET_APPID);
|
||||
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, null, target, 0));
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, null, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoTargetPackage_filters() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, 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_UID);
|
||||
pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_APPID);
|
||||
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -516,7 +559,11 @@ public class AppsFilterTest {
|
||||
.setOverlayTargetName("overlayableName");
|
||||
ParsingPackage actor = pkg("com.some.package.actor");
|
||||
|
||||
final AppsFilter appsFilter = new AppsFilter(mFeatureConfigMock, new String[]{}, false,
|
||||
final AppsFilter appsFilter = new AppsFilter(
|
||||
mStateProvider,
|
||||
mFeatureConfigMock,
|
||||
new String[]{},
|
||||
false,
|
||||
new OverlayReferenceMapper.Provider() {
|
||||
@Nullable
|
||||
@Override
|
||||
@@ -544,31 +591,34 @@ public class AppsFilterTest {
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting targetSetting = simulateAddPackage(appsFilter, target, DUMMY_TARGET_UID);
|
||||
PackageSetting overlaySetting = simulateAddPackage(appsFilter, overlay, DUMMY_OVERLAY_UID);
|
||||
PackageSetting actorSetting = simulateAddPackage(appsFilter, actor, DUMMY_ACTOR_UID);
|
||||
PackageSetting targetSetting = simulateAddPackage(appsFilter, target, DUMMY_TARGET_APPID);
|
||||
PackageSetting overlaySetting =
|
||||
simulateAddPackage(appsFilter, overlay, DUMMY_OVERLAY_APPID);
|
||||
PackageSetting actorSetting = simulateAddPackage(appsFilter, actor, DUMMY_ACTOR_APPID);
|
||||
|
||||
// Actor can see both target and overlay
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_UID, actorSetting,
|
||||
targetSetting, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_UID, actorSetting,
|
||||
overlaySetting, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSetting,
|
||||
targetSetting, SYSTEM_USER));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSetting,
|
||||
overlaySetting, SYSTEM_USER));
|
||||
|
||||
// But target/overlay can't see each other
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_TARGET_UID, targetSetting,
|
||||
overlaySetting, 0));
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_UID, overlaySetting,
|
||||
targetSetting, 0));
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_TARGET_APPID, targetSetting,
|
||||
overlaySetting, SYSTEM_USER));
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_APPID, overlaySetting,
|
||||
targetSetting, SYSTEM_USER));
|
||||
|
||||
// And can't see the actor
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_TARGET_UID, targetSetting,
|
||||
actorSetting, 0));
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_UID, overlaySetting,
|
||||
actorSetting, 0));
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_TARGET_APPID, targetSetting,
|
||||
actorSetting, SYSTEM_USER));
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_OVERLAY_APPID, overlaySetting,
|
||||
actorSetting, SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActsOnTargetOfOverlayThroughSharedUser() throws Exception {
|
||||
// Debug.waitForDebugger();
|
||||
|
||||
final String actorName = "overlay://test/actorName";
|
||||
|
||||
ParsingPackage target = pkg("com.some.package.target")
|
||||
@@ -580,7 +630,11 @@ public class AppsFilterTest {
|
||||
ParsingPackage actorOne = pkg("com.some.package.actor.one");
|
||||
ParsingPackage actorTwo = pkg("com.some.package.actor.two");
|
||||
|
||||
final AppsFilter appsFilter = new AppsFilter(mFeatureConfigMock, new String[]{}, false,
|
||||
final AppsFilter appsFilter = new AppsFilter(
|
||||
mStateProvider,
|
||||
mFeatureConfigMock,
|
||||
new String[]{},
|
||||
false,
|
||||
new OverlayReferenceMapper.Provider() {
|
||||
@Nullable
|
||||
@Override
|
||||
@@ -609,108 +663,114 @@ public class AppsFilterTest {
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
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);
|
||||
|
||||
PackageSetting targetSetting = simulateAddPackage(appsFilter, target, DUMMY_TARGET_APPID);
|
||||
SharedUserSetting actorSharedSetting = new SharedUserSetting("actorSharedUser",
|
||||
actorOneSetting.pkgFlags, actorOneSetting.pkgPrivateFlags);
|
||||
actorSharedSetting.addPackage(actorOneSetting);
|
||||
actorSharedSetting.addPackage(actorTwoSetting);
|
||||
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);
|
||||
|
||||
|
||||
// actorTwo can see both target and overlay
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_TWO_UID, actorSharedSetting,
|
||||
targetSetting, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_TWO_UID, actorSharedSetting,
|
||||
overlaySetting, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSharedSetting,
|
||||
targetSetting, SYSTEM_USER));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_ACTOR_APPID, actorSharedSetting,
|
||||
overlaySetting, SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitiatingApp_DoesntFilter() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
|
||||
DUMMY_TARGET_UID);
|
||||
DUMMY_TARGET_APPID);
|
||||
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
|
||||
DUMMY_CALLING_UID, withInstallSource(target.name, null, null, false));
|
||||
DUMMY_CALLING_APPID, withInstallSource(target.name, null, null, false));
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUninstalledInitiatingApp_Filters() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
|
||||
DUMMY_TARGET_UID);
|
||||
DUMMY_TARGET_APPID);
|
||||
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
|
||||
DUMMY_CALLING_UID, withInstallSource(target.name, null, null, true));
|
||||
DUMMY_CALLING_APPID, withInstallSource(target.name, null, null, true));
|
||||
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOriginatingApp_Filters() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
|
||||
DUMMY_TARGET_UID);
|
||||
DUMMY_TARGET_APPID);
|
||||
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
|
||||
DUMMY_CALLING_UID, withInstallSource(null, target.name, null, false));
|
||||
DUMMY_CALLING_APPID, withInstallSource(null, target.name, null, false));
|
||||
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInstallingApp_DoesntFilter() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
|
||||
DUMMY_TARGET_UID);
|
||||
DUMMY_TARGET_APPID);
|
||||
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
|
||||
DUMMY_CALLING_UID, withInstallSource(null, null, target.name, false));
|
||||
DUMMY_CALLING_APPID, withInstallSource(null, null, target.name, false));
|
||||
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
|
||||
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInstrumentation_DoesntFilter() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
|
||||
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
|
||||
DUMMY_TARGET_UID);
|
||||
DUMMY_TARGET_APPID);
|
||||
PackageSetting instrumentation = simulateAddPackage(appsFilter,
|
||||
pkgWithInstrumentation("com.some.other.package", "com.some.package"),
|
||||
DUMMY_CALLING_UID);
|
||||
DUMMY_CALLING_APPID);
|
||||
|
||||
assertFalse(
|
||||
appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, instrumentation, target, 0));
|
||||
appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target,
|
||||
SYSTEM_USER));
|
||||
assertFalse(
|
||||
appsFilter.shouldFilterApplication(DUMMY_TARGET_UID, target, instrumentation, 0));
|
||||
appsFilter.shouldFilterApplication(DUMMY_TARGET_APPID, target, instrumentation,
|
||||
SYSTEM_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWhoCanSee() throws Exception {
|
||||
final AppsFilter appsFilter =
|
||||
new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
|
||||
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
|
||||
simulateAddBasicAndroid(appsFilter);
|
||||
appsFilter.onSystemReady();
|
||||
|
||||
@@ -718,6 +778,7 @@ public class AppsFilterTest {
|
||||
final int seesNothingAppId = Process.FIRST_APPLICATION_UID;
|
||||
final int hasProviderAppId = Process.FIRST_APPLICATION_UID + 1;
|
||||
final int queriesProviderAppId = Process.FIRST_APPLICATION_UID + 2;
|
||||
|
||||
PackageSetting system = simulateAddPackage(appsFilter, pkg("some.system.pkg"), systemAppId);
|
||||
PackageSetting seesNothing = simulateAddPackage(appsFilter, pkg("com.some.package"),
|
||||
seesNothingAppId);
|
||||
@@ -727,23 +788,25 @@ public class AppsFilterTest {
|
||||
pkgQueriesProvider("com.yet.some.other.package", "com.some.authority"),
|
||||
queriesProviderAppId);
|
||||
|
||||
final int[] systemFilter =
|
||||
appsFilter.getVisibilityWhitelist(system, new int[]{0}, mExisting).get(0);
|
||||
assertThat(toList(systemFilter), empty());
|
||||
final SparseArray<int[]> systemFilter =
|
||||
appsFilter.getVisibilityWhitelist(system, USER_ARRAY, mExisting);
|
||||
assertThat(toList(systemFilter.get(SYSTEM_USER)), empty());
|
||||
|
||||
final int[] seesNothingFilter =
|
||||
appsFilter.getVisibilityWhitelist(seesNothing, new int[]{0}, mExisting).get(0);
|
||||
assertThat(toList(seesNothingFilter),
|
||||
final SparseArray<int[]> seesNothingFilter =
|
||||
appsFilter.getVisibilityWhitelist(seesNothing, USER_ARRAY, mExisting);
|
||||
assertThat(toList(seesNothingFilter.get(SYSTEM_USER)),
|
||||
contains(seesNothingAppId));
|
||||
assertThat(toList(seesNothingFilter.get(SECONDARY_USER)),
|
||||
contains(seesNothingAppId));
|
||||
|
||||
final int[] hasProviderFilter =
|
||||
appsFilter.getVisibilityWhitelist(hasProvider, new int[]{0}, mExisting).get(0);
|
||||
assertThat(toList(hasProviderFilter),
|
||||
final SparseArray<int[]> hasProviderFilter =
|
||||
appsFilter.getVisibilityWhitelist(hasProvider, USER_ARRAY, mExisting);
|
||||
assertThat(toList(hasProviderFilter.get(SYSTEM_USER)),
|
||||
contains(hasProviderAppId, queriesProviderAppId));
|
||||
|
||||
int[] queriesProviderFilter =
|
||||
appsFilter.getVisibilityWhitelist(queriesProvider, new int[]{0}, mExisting).get(0);
|
||||
assertThat(toList(queriesProviderFilter),
|
||||
SparseArray<int[]> queriesProviderFilter =
|
||||
appsFilter.getVisibilityWhitelist(queriesProvider, USER_ARRAY, mExisting);
|
||||
assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)),
|
||||
contains(queriesProviderAppId));
|
||||
|
||||
// provider read
|
||||
@@ -751,8 +814,8 @@ public class AppsFilterTest {
|
||||
|
||||
// ensure implicit access is included in the filter
|
||||
queriesProviderFilter =
|
||||
appsFilter.getVisibilityWhitelist(queriesProvider, new int[]{0}, mExisting).get(0);
|
||||
assertThat(toList(queriesProviderFilter),
|
||||
appsFilter.getVisibilityWhitelist(queriesProvider, USER_ARRAY, mExisting);
|
||||
assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)),
|
||||
contains(hasProviderAppId, queriesProviderAppId));
|
||||
}
|
||||
|
||||
@@ -779,11 +842,17 @@ public class AppsFilterTest {
|
||||
|
||||
private PackageSetting simulateAddPackage(AppsFilter filter,
|
||||
ParsingPackage newPkgBuilder, int appId) {
|
||||
return simulateAddPackage(filter, newPkgBuilder, appId, null);
|
||||
return simulateAddPackage(filter, newPkgBuilder, appId, null /*settingBuilder*/);
|
||||
}
|
||||
|
||||
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()
|
||||
@@ -795,8 +864,12 @@ 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;
|
||||
}
|
||||
|
||||
@@ -809,4 +882,3 @@ public class AppsFilterTest {
|
||||
return setting -> setting.setInstallSource(installSource);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user