Merge "Map visibilty based on appId and uid"
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index bb5b04a..ec11a97 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -29,27 +29,24 @@
import android.content.pm.PackageParser;
import android.content.pm.ProviderInfo;
import android.net.Uri;
-import android.os.Build;
import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.Trace;
-import android.permission.IPermissionManager;
+import android.os.UserHandle;
import android.provider.DeviceConfig;
+import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseSetArray;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.server.FgThread;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -60,7 +57,7 @@
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public class AppsFilter {
- private static final String TAG = PackageManagerService.TAG;
+ private static final String TAG = "AppsFilter";
// Logs all filtering instead of enforcing
private static final boolean DEBUG_ALLOW_ALL = false;
@@ -69,52 +66,46 @@
private static final boolean DEBUG_LOGGING = false | DEBUG_ALLOW_ALL;
/**
- * This contains a list of packages that are implicitly queryable because another app explicitly
+ * This contains a list of app UIDs that are implicitly queryable because another app explicitly
* interacted with it. For example, if application A starts a service in application B,
* application B is implicitly allowed to query for application A; regardless of any manifest
* entries.
*/
- private final SparseArray<HashMap<String, Set<String>>> mImplicitlyQueryable =
- new SparseArray<>();
+ private final SparseSetArray<Integer> mImplicitlyQueryable = new SparseSetArray<>();
/**
- * A mapping from the set of packages that query other packages via package name to the
+ * A mapping from the set of App IDs that query other App IDs via package name to the
* list of packages that they can see.
*/
- private final HashMap<String, Set<String>> mQueriesViaPackage = new HashMap<>();
+ private final SparseSetArray<Integer> mQueriesViaPackage = new SparseSetArray<>();
/**
- * A mapping from the set of packages that query others via intent to the list
+ * A mapping from the set of App IDs that query others via intent to the list
* of packages that the intents resolve to.
*/
- private final HashMap<String, Set<String>> mQueriesViaIntent = new HashMap<>();
+ private final SparseSetArray<Integer> mQueriesViaIntent = new SparseSetArray<>();
/**
- * A set of packages that are always queryable by any package, regardless of their manifest
+ * A set of App IDs that are always queryable by any package, regardless of their manifest
* content.
*/
- private final HashSet<String> mForceQueryable;
+ private final ArraySet<Integer> mForceQueryable = new ArraySet<>();
+
/**
- * A set of packages that are always queryable by any package, regardless of their manifest
- * content.
+ * The set of package names provided by the device that should be force queryable regardless of
+ * their manifest contents.
*/
- private final Set<String> mForceQueryableByDevice;
+ private final String[] mForceQueryableByDevicePackageNames;
/** True if all system apps should be made queryable by default. */
private final boolean mSystemAppsQueryable;
- private final IPermissionManager mPermissionManager;
-
private final FeatureConfig mFeatureConfig;
- AppsFilter(FeatureConfig featureConfig, IPermissionManager permissionManager,
- String[] forceQueryableWhitelist, boolean systemAppsQueryable) {
+ AppsFilter(FeatureConfig featureConfig, String[] forceQueryableWhitelist,
+ boolean systemAppsQueryable) {
mFeatureConfig = featureConfig;
- final HashSet<String> forceQueryableByDeviceSet = new HashSet<>();
- Collections.addAll(forceQueryableByDeviceSet, forceQueryableWhitelist);
- this.mForceQueryableByDevice = Collections.unmodifiableSet(forceQueryableByDeviceSet);
- this.mForceQueryable = new HashSet<>();
- mPermissionManager = permissionManager;
+ mForceQueryableByDevicePackageNames = forceQueryableWhitelist;
mSystemAppsQueryable = systemAppsQueryable;
}
@@ -127,7 +118,6 @@
/** @return true if the feature is enabled for the given package. */
boolean packageIsEnabled(PackageParser.Package pkg);
-
}
private static class FeatureConfigImpl implements FeatureConfig {
@@ -174,7 +164,6 @@
}
}
-
public static AppsFilter create(PackageManagerService.Injector injector) {
final boolean forceSystemAppsQueryable =
injector.getContext().getResources()
@@ -192,15 +181,12 @@
forcedQueryablePackageNames[i] = forcedQueryablePackageNames[i].intern();
}
}
- IPermissionManager permissionmgr =
- (IPermissionManager) ServiceManager.getService("permissionmgr");
-
- return new AppsFilter(featureConfig, permissionmgr, forcedQueryablePackageNames,
+ return new AppsFilter(featureConfig, forcedQueryablePackageNames,
forceSystemAppsQueryable);
}
/** Returns true if the querying package may query for the potential target package */
- private static boolean canQuery(PackageParser.Package querying,
+ private static boolean canQueryViaIntent(PackageParser.Package querying,
PackageParser.Package potentialTarget) {
if (querying.mQueriesIntents == null) {
return false;
@@ -274,22 +260,14 @@
* Grants access based on an interaction between a calling and target package, granting
* visibility of the caller from the target.
*
- * @param callingPackage the package initiating the interaction
- * @param targetPackage the package being interacted with and thus gaining visibility of the
- * initiating package.
- * @param userId the user in which this interaction was taking place
+ * @param callingUid the uid initiating the interaction
+ * @param targetUid the uid being interacted with and thus gaining visibility of the
+ * initiating uid.
*/
- public void grantImplicitAccess(
- String callingPackage, String targetPackage, int userId) {
- HashMap<String, Set<String>> currentUser = mImplicitlyQueryable.get(userId);
- if (currentUser == null) {
- currentUser = new HashMap<>();
- mImplicitlyQueryable.put(userId, currentUser);
+ public void grantImplicitAccess(int callingUid, int targetUid) {
+ if (mImplicitlyQueryable.add(targetUid, callingUid) && DEBUG_LOGGING) {
+ Slog.wtf(TAG, "implicit access granted: " + callingUid + " -> " + targetUid);
}
- if (!currentUser.containsKey(targetPackage)) {
- currentUser.put(targetPackage, new HashSet<>());
- }
- currentUser.get(targetPackage).add(callingPackage);
}
public void onSystemReady() {
@@ -299,50 +277,57 @@
/**
* Adds a package that should be considered when filtering visibility between apps.
*
- * @param newPkg the new package being added
- * @param existing all other packages currently on the device.
+ * @param newPkgSetting the new setting being added
+ * @param existingSettings all other settings currently on the device.
*/
- public void addPackage(PackageParser.Package newPkg,
- Map<String, PackageParser.Package> existing) {
+ public void addPackage(PackageSetting newPkgSetting,
+ ArrayMap<String, PackageSetting> existingSettings) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.addPackage");
try {
- // let's re-evaluate the ability of already added packages to see this new package
- if (newPkg.mForceQueryable
- || (mSystemAppsQueryable && (newPkg.isSystem()
- || newPkg.isUpdatedSystemApp()))) {
- mForceQueryable.add(newPkg.packageName);
- } else {
- for (String packageName : mQueriesViaIntent.keySet()) {
- if (packageName == newPkg.packageName) {
- continue;
+ final PackageParser.Package newPkg = newPkgSetting.pkg;
+ if (newPkg == null) {
+ // nothing to add
+ return;
+ }
+
+ final boolean newIsForceQueryable =
+ mForceQueryable.contains(newPkgSetting.appId)
+ /* shared user that is already force queryable */
+ || newPkg.mForceQueryable
+ || (newPkgSetting.isSystem() && (mSystemAppsQueryable
+ || ArrayUtils.contains(mForceQueryableByDevicePackageNames,
+ newPkg.packageName)));
+ if (newIsForceQueryable) {
+ 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;
+ }
+ final PackageParser.Package existingPkg = existingSetting.pkg;
+ // let's evaluate the ability of already added packages to see this new package
+ if (!newIsForceQueryable) {
+ if (canQueryViaIntent(existingPkg, newPkg)) {
+ mQueriesViaIntent.add(existingSetting.appId, newPkgSetting.appId);
}
- final PackageParser.Package existingPackage = existing.get(packageName);
- if (canQuery(existingPackage, newPkg)) {
- mQueriesViaIntent.get(packageName).add(newPkg.packageName);
+ if (existingPkg.mQueriesPackages != null
+ && existingPkg.mQueriesPackages.contains(newPkg.packageName)) {
+ 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 (canQueryViaIntent(newPkg, existingPkg)) {
+ mQueriesViaIntent.add(newPkgSetting.appId, existingSetting.appId);
+ }
+ if (newPkg.mQueriesPackages != null
+ && newPkg.mQueriesPackages.contains(existingPkg.packageName)) {
+ mQueriesViaPackage.add(newPkgSetting.appId, existingSetting.appId);
}
}
}
- // if the new package declares them, let's evaluate its ability to see existing packages
- mQueriesViaIntent.put(newPkg.packageName, new HashSet<>());
- for (PackageParser.Package existingPackage : existing.values()) {
- if (existingPackage.packageName == newPkg.packageName) {
- continue;
- }
- if (existingPackage.mForceQueryable
- || (mSystemAppsQueryable
- && (newPkg.isSystem() || newPkg.isUpdatedSystemApp()))) {
- continue;
- }
- if (canQuery(newPkg, existingPackage)) {
- mQueriesViaIntent.get(newPkg.packageName).add(existingPackage.packageName);
- }
- }
- final HashSet<String> queriesPackages = new HashSet<>(
- newPkg.mQueriesPackages == null ? 0 : newPkg.mQueriesPackages.size());
- if (newPkg.mQueriesPackages != null) {
- queriesPackages.addAll(newPkg.mQueriesPackages);
- }
- mQueriesViaPackage.put(newPkg.packageName, queriesPackages);
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
@@ -351,24 +336,41 @@
/**
* Removes a package for consideration when filtering visibility between apps.
*
- * @param packageName the name 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(String packageName) {
- mForceQueryable.remove(packageName);
+ public void removePackage(PackageSetting setting, int[] allUsers,
+ ArrayMap<String, PackageSetting> existingSettings) {
+ mForceQueryable.remove(setting.appId);
- for (int i = 0; i < mImplicitlyQueryable.size(); i++) {
- mImplicitlyQueryable.valueAt(i).remove(packageName);
- for (Set<String> initiators : mImplicitlyQueryable.valueAt(i).values()) {
- initiators.remove(packageName);
+ 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);
}
}
- mQueriesViaIntent.remove(packageName);
- for (Set<String> declarators : mQueriesViaIntent.values()) {
- declarators.remove(packageName);
+ mQueriesViaIntent.remove(setting.appId);
+ for (int i = mQueriesViaIntent.size() - 1; i >= 0; i--) {
+ mQueriesViaIntent.remove(mQueriesViaIntent.keyAt(i), setting.appId);
+ }
+ mQueriesViaPackage.remove(setting.appId);
+ for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) {
+ mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), setting.appId);
}
- mQueriesViaPackage.remove(packageName);
+ // 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);
+ }
+ }
}
/**
@@ -385,6 +387,25 @@
PackageSetting targetPkgSetting, int userId) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplication");
try {
+ if (!shouldFilterApplicationInternal(callingUid, callingSetting,
+ targetPkgSetting,
+ userId)) {
+ return false;
+ }
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting,
+ DEBUG_ALLOW_ALL ? "ALLOWED" : "BLOCKED", new RuntimeException());
+ }
+ return !DEBUG_ALLOW_ALL;
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ private boolean shouldFilterApplicationInternal(int callingUid,
+ SettingBase callingSetting, PackageSetting targetPkgSetting, int userId) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplicationInternal");
+ try {
final boolean featureEnabled = mFeatureConfig.isGloballyEnabled();
if (!featureEnabled) {
if (DEBUG_LOGGING) {
@@ -402,85 +423,37 @@
Slog.wtf(TAG, "No setting found for non system uid " + callingUid);
return true;
}
- PackageSetting callingPkgSetting = null;
+ final PackageSetting callingPkgSetting;
+ final ArraySet<PackageSetting> callingSharedPkgSettings;
if (callingSetting instanceof PackageSetting) {
callingPkgSetting = (PackageSetting) callingSetting;
- if (!shouldFilterApplicationInternal(callingPkgSetting, targetPkgSetting,
- userId)) {
+ callingSharedPkgSettings = null;
+ } else {
+ callingPkgSetting = null;
+ callingSharedPkgSettings = ((SharedUserSetting) callingSetting).packages;
+ }
+
+ if (callingPkgSetting != null) {
+ if (!mFeatureConfig.packageIsEnabled(callingPkgSetting.pkg)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "DISABLED");
+ }
return false;
}
- } else if (callingSetting instanceof SharedUserSetting) {
- final ArraySet<PackageSetting> packageSettings =
- ((SharedUserSetting) callingSetting).packages;
- if (packageSettings != null && packageSettings.size() > 0) {
- for (int i = 0, max = packageSettings.size(); i < max; i++) {
- final PackageSetting packageSetting = packageSettings.valueAt(i);
- if (!shouldFilterApplicationInternal(packageSetting, targetPkgSetting,
- userId)) {
- return false;
+ } else {
+ for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
+ if (!mFeatureConfig.packageIsEnabled(callingSharedPkgSettings.valueAt(i).pkg)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "DISABLED");
}
- if (callingPkgSetting == null && packageSetting.pkg != null) {
- callingPkgSetting = packageSetting;
- }
- }
- if (callingPkgSetting == null) {
- Slog.wtf(TAG, callingSetting + " does not have any non-null packages!");
- return true;
- }
- } else {
- Slog.wtf(TAG, callingSetting + " has no packages!");
- return true;
- }
- }
-
- if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting,
- DEBUG_ALLOW_ALL ? "ALLOWED" : "BLOCKED");
- }
- return !DEBUG_ALLOW_ALL;
- } finally {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
-
- private boolean shouldFilterApplicationInternal(
- PackageSetting callingPkgSetting, PackageSetting targetPkgSetting, int userId) {
- return shouldFilterApplicationInternal(callingPkgSetting, targetPkgSetting, userId,
- true /*expandSharedUser*/);
- }
-
- /**
- * @param expandSharedUser true if all members of the shared user a target may belong to should
- * be considered
- */
- private boolean shouldFilterApplicationInternal(
- PackageSetting callingPkgSetting, PackageSetting targetPkgSetting, int userId,
- boolean expandSharedUser) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplicationInternal");
- try {
- // special case shared user targets
- if (expandSharedUser && targetPkgSetting.sharedUser != null) {
- for (PackageSetting sharedMemberSetting : targetPkgSetting.sharedUser.packages) {
- if (!shouldFilterApplicationInternal(
- callingPkgSetting, sharedMemberSetting, userId,
- false /*expandSharedUser*/)) {
return false;
}
}
- return true;
}
- final String callingName = callingPkgSetting.pkg.packageName;
- final PackageParser.Package targetPkg = targetPkgSetting.pkg;
-
- if (!mFeatureConfig.packageIsEnabled(callingPkgSetting.pkg)) {
- if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting, "DISABLED");
- }
- return false;
- }
// This package isn't technically installed and won't be written to settings, so we can
// treat it as filtered until it's available again.
+ final PackageParser.Package targetPkg = targetPkgSetting.pkg;
if (targetPkg == null) {
if (DEBUG_LOGGING) {
Slog.wtf(TAG, "shouldFilterApplication: " + "targetPkg is null");
@@ -488,149 +461,180 @@
return true;
}
final String targetName = targetPkg.packageName;
- if (callingPkgSetting.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.R) {
+ final int callingAppId;
+ if (callingPkgSetting != null) {
+ callingAppId = callingPkgSetting.appId;
+ } else {
+ callingAppId = callingSharedPkgSettings.valueAt(0).appId; // all should be the same
+ }
+ final int targetAppId = targetPkgSetting.appId;
+ if (callingAppId == targetAppId) {
if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting, "caller pre-R");
+ log(callingSetting, targetPkgSetting, "same app id");
}
return false;
}
- if (callingPkgSetting.appId == targetPkgSetting.appId) {
+
+ if (callingSetting.getPermissionsState().hasPermission(
+ Manifest.permission.QUERY_ALL_PACKAGES, UserHandle.getUserId(callingUid))) {
if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting, "same app id");
+ log(callingSetting, targetPkgSetting, "has query-all permission");
}
return false;
}
- if (isImplicitlyQueryableSystemApp(targetPkgSetting)) {
+ if (mForceQueryable.contains(targetAppId)) {
if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting, "implicitly queryable sys");
+ log(callingSetting, targetPkgSetting, "force queryable");
}
return false;
}
- if (targetPkg.mForceQueryable) {
- if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting, "manifest forceQueryable");
- }
- return false;
- }
- if (mForceQueryable.contains(targetName)) {
- if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting, "whitelist forceQueryable");
- }
- return false;
- }
- if (mQueriesViaPackage.containsKey(callingName)
- && mQueriesViaPackage.get(callingName).contains(
- targetName)) {
+ if (mQueriesViaPackage.contains(callingAppId, targetAppId)) {
// the calling package has explicitly declared the target package; allow
if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting, "queries package");
+ log(callingSetting, targetPkgSetting, "queries package");
}
return false;
- } else if (mQueriesViaIntent.containsKey(callingName)
- && mQueriesViaIntent.get(callingName).contains(targetName)) {
+ } else if (mQueriesViaIntent.contains(callingAppId, targetAppId)) {
if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting, "queries intent");
+ log(callingSetting, targetPkgSetting, "queries intent");
}
return false;
}
- if (mImplicitlyQueryable.get(userId) != null
- && mImplicitlyQueryable.get(userId).containsKey(callingName)
- && mImplicitlyQueryable.get(userId).get(callingName).contains(targetName)) {
+
+ final int targetUid = UserHandle.getUid(userId, targetAppId);
+ if (mImplicitlyQueryable.contains(callingUid, targetUid)) {
if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting, "implicitly queryable for user");
+ log(callingSetting, targetPkgSetting, "implicitly queryable for user");
}
return false;
}
- final ArrayList<PackageParser.Instrumentation> inst =
- callingPkgSetting.pkg.instrumentation;
- if (inst.size() > 0) {
- for (int i = 0, max = inst.size(); i < max; i++) {
- if (inst.get(i).info.targetPackage == targetName) {
- if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting, "instrumentation");
- }
+ if (callingPkgSetting != null) {
+ if (callingPkgInstruments(callingPkgSetting, targetPkgSetting, targetName)) {
+ return false;
+ }
+ } else {
+ for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
+ if (callingPkgInstruments(callingSharedPkgSettings.valueAt(i),
+ targetPkgSetting, targetName)) {
return false;
}
}
}
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.checkPermission");
- try {
- if (mPermissionManager.checkPermission(
- Manifest.permission.QUERY_ALL_PACKAGES, callingName, userId)
- == PackageManager.PERMISSION_GRANTED) {
- if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting, "permission");
- }
- return false;
- }
- } catch (RemoteException e) {
- return true;
- } finally {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
return true;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
- private static void log(PackageSetting callingPkgSetting, PackageSetting targetPkgSetting,
- String description) {
- Slog.wtf(TAG,
- "interaction: " + callingPkgSetting.name + " -> " + targetPkgSetting.name + " "
- + description);
+ private static boolean callingPkgInstruments(PackageSetting callingPkgSetting,
+ PackageSetting targetPkgSetting,
+ String targetName) {
+ final ArrayList<PackageParser.Instrumentation> inst = callingPkgSetting.pkg.instrumentation;
+ for (int i = inst.size() - 1; i >= 0; i--) {
+ if (inst.get(i).info.targetPackage == targetName) {
+ if (DEBUG_LOGGING) {
+ log(callingPkgSetting, targetPkgSetting, "instrumentation");
+ }
+ return true;
+ }
+ }
+ return false;
}
- private boolean isImplicitlyQueryableSystemApp(PackageSetting targetPkgSetting) {
- return targetPkgSetting.isSystem() && (mSystemAppsQueryable
- || mForceQueryableByDevice.contains(targetPkgSetting.pkg.packageName));
+ private static void log(SettingBase callingPkgSetting, PackageSetting targetPkgSetting,
+ String description) {
+ log(callingPkgSetting, targetPkgSetting, description, null);
+ }
+
+ private static void log(SettingBase callingPkgSetting, PackageSetting targetPkgSetting,
+ String description, Throwable throwable) {
+ Slog.wtf(TAG,
+ "interaction: " + callingPkgSetting.toString()
+ + " -> " + targetPkgSetting.name + " "
+ + description, throwable);
}
public void dumpQueries(
- PrintWriter pw, @Nullable String filteringPackageName, DumpState dumpState,
+ PrintWriter pw, PackageManagerService pms, @Nullable Integer filteringAppId,
+ DumpState dumpState,
int[] users) {
+ final SparseArray<String> cache = new SparseArray<>();
+ ToString<Integer> expandPackages = input -> {
+ String cachedValue = cache.get(input);
+ if (cachedValue == null) {
+ final String[] packagesForUid = pms.getPackagesForUid(input);
+ if (packagesForUid == null) {
+ cachedValue = "[unknown app id " + input + "]";
+ } else {
+ cachedValue = packagesForUid.length == 1 ? packagesForUid[0]
+ : "[" + TextUtils.join(",", packagesForUid) + "]";
+ }
+ cache.put(input, cachedValue);
+ }
+ return cachedValue;
+ };
pw.println();
pw.println("Queries:");
dumpState.onTitlePrinted();
+ if (!mFeatureConfig.isGloballyEnabled()) {
+ pw.println(" DISABLED");
+ if (!DEBUG_LOGGING) {
+ return;
+ }
+ }
pw.println(" system apps queryable: " + mSystemAppsQueryable);
- dumpPackageSet(pw, filteringPackageName, mForceQueryableByDevice, "System whitelist", " ");
- dumpPackageSet(pw, filteringPackageName, mForceQueryable, "forceQueryable", " ");
+ dumpPackageSet(pw, filteringAppId, mForceQueryable, "forceQueryable", " ", expandPackages);
pw.println(" queries via package name:");
- dumpQueriesMap(pw, filteringPackageName, mQueriesViaPackage, " ");
+ dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, " ", expandPackages);
pw.println(" queries via intent:");
- dumpQueriesMap(pw, filteringPackageName, mQueriesViaIntent, " ");
+ dumpQueriesMap(pw, filteringAppId, mQueriesViaIntent, " ", expandPackages);
pw.println(" queryable via interaction:");
for (int user : users) {
pw.append(" User ").append(Integer.toString(user)).println(":");
- final HashMap<String, Set<String>> queryMapForUser = mImplicitlyQueryable.get(user);
- if (queryMapForUser != null) {
- dumpQueriesMap(pw, filteringPackageName, queryMapForUser, " ");
- }
+ dumpQueriesMap(pw,
+ filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId),
+ mImplicitlyQueryable, " ", expandPackages);
}
}
- private static void dumpQueriesMap(PrintWriter pw, @Nullable String filteringPackageName,
- HashMap<String, Set<String>> queriesMap, String spacing) {
- for (String callingPkg : queriesMap.keySet()) {
- if (Objects.equals(callingPkg, filteringPackageName)) {
- // don't filter target package names if the calling is filteringPackageName
- dumpPackageSet(pw, null /*filteringPackageName*/, queriesMap.get(callingPkg),
- callingPkg, spacing);
+ private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId,
+ SparseSetArray<Integer> queriesMap, String spacing,
+ @Nullable ToString<Integer> toString) {
+ for (int i = 0; i < queriesMap.size(); i++) {
+ Integer callingId = queriesMap.keyAt(i);
+ if (Objects.equals(callingId, filteringId)) {
+ // don't filter target package names if the calling is filteringId
+ dumpPackageSet(
+ pw, null /*filteringId*/, queriesMap.get(callingId),
+ toString == null
+ ? callingId.toString()
+ : toString.toString(callingId),
+ spacing, toString);
} else {
- dumpPackageSet(pw, filteringPackageName, queriesMap.get(callingPkg), callingPkg,
- spacing);
+ dumpPackageSet(
+ pw, filteringId, queriesMap.get(callingId),
+ toString == null
+ ? callingId.toString()
+ : toString.toString(callingId),
+ spacing, toString);
}
}
}
- private static void dumpPackageSet(PrintWriter pw, @Nullable String filteringPackageName,
- Set<String> targetPkgSet, String subTitle, String spacing) {
+ private interface ToString<T> {
+ String toString(T input);
+ }
+
+ private static <T> void dumpPackageSet(PrintWriter pw, @Nullable T filteringId,
+ Set<T> targetPkgSet, String subTitle, String spacing,
+ @Nullable ToString<T> toString) {
if (targetPkgSet != null && targetPkgSet.size() > 0
- && (filteringPackageName == null || targetPkgSet.contains(filteringPackageName))) {
+ && (filteringId == null || targetPkgSet.contains(filteringId))) {
pw.append(spacing).append(subTitle).println(":");
- for (String pkgName : targetPkgSet) {
- if (filteringPackageName == null || Objects.equals(filteringPackageName, pkgName)) {
- pw.append(spacing).append(" ").println(pkgName);
+ for (T item : targetPkgSet) {
+ if (filteringId == null || Objects.equals(filteringId, item)) {
+ pw.append(spacing).append(" ")
+ .println(toString == null ? item : toString.toString(item));
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index fe82f7c..fa98c96 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -11701,7 +11701,7 @@
ksms.addScannedPackageLPw(pkg);
mComponentResolver.addAllComponents(pkg, chatty);
- mAppsFilter.addPackage(pkg, mPackages);
+ mAppsFilter.addPackage(pkgSetting, mSettings.mPackages);
// Don't allow ephemeral applications to define new permissions groups.
if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
@@ -11889,31 +11889,10 @@
}
}
- void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
- if (DEBUG_INSTALL) {
- if (chatty)
- Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
- }
-
- // writer
- synchronized (mLock) {
- // Remove the parent package
- mPackages.remove(pkg.applicationInfo.packageName);
- cleanPackageDataStructuresLILPw(pkg, chatty);
-
- // Remove the child packages
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = pkg.childPackages.get(i);
- mPackages.remove(childPkg.applicationInfo.packageName);
- cleanPackageDataStructuresLILPw(childPkg, chatty);
- }
- }
- }
-
void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
mComponentResolver.removeAllComponents(pkg, chatty);
- mAppsFilter.removePackage(pkg.packageName);
+ mAppsFilter.removePackage((PackageSetting) pkg.mExtras,
+ mInjector.getUserManagerInternal().getUserIds(), mSettings.mPackages);
mPermissionManager.removeAllPermissions(pkg, chatty);
final int instrumentationSize = pkg.instrumentation.size();
@@ -20861,7 +20840,11 @@
}
if (dumpState.isDumping(DumpState.DUMP_QUERIES)) {
- mAppsFilter.dumpQueries(pw, packageName, dumpState, mUserManager.getUserIds());
+ final PackageSetting setting = mSettings.getPackageLPr(packageName);
+ Integer filteringAppId = setting == null ? null : setting.appId;
+ mAppsFilter.dumpQueries(
+ pw, this, filteringAppId, dumpState,
+ mUserManager.getUserIds());
}
if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
@@ -23195,8 +23178,9 @@
int callingUid, int targetAppId) {
synchronized (mLock) {
final PackageParser.Package callingPackage = getPackage(callingUid);
+ final int targetUid = UserHandle.getUid(userId, targetAppId);
final PackageParser.Package targetPackage =
- getPackage(UserHandle.getUid(userId, targetAppId));
+ getPackage(targetUid);
if (callingPackage == null || targetPackage == null) {
return;
}
@@ -23207,8 +23191,7 @@
mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
UserHandle.getAppId(callingUid), targetAppId);
} else {
- mAppsFilter.grantImplicitAccess(
- callingPackage.packageName, targetPackage.packageName, userId);
+ mAppsFilter.grantImplicitAccess(callingUid, targetUid);
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
index 819091c..f6fb6e2 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
@@ -20,20 +20,17 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.annotation.Nullable;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.os.Build;
import android.os.Process;
-import android.permission.IPermissionManager;
import android.util.ArrayMap;
import org.junit.Before;
@@ -43,20 +40,16 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.util.Map;
-
@RunWith(JUnit4.class)
public class AppsFilterTest {
private static final int DUMMY_CALLING_UID = 10345;
-
- @Mock
- IPermissionManager mPermissionManagerMock;
+ private static final int DUMMY_TARGET_UID = 10556;
@Mock
AppsFilter.FeatureConfig mFeatureConfigMock;
- private Map<String, PackageParser.Package> mExisting = new ArrayMap<>();
+ private ArrayMap<String, PackageSetting> mExisting = new ArrayMap<>();
private static PackageBuilder pkg(String packageName) {
return new PackageBuilder(packageName)
@@ -72,9 +65,10 @@
}
private static PackageBuilder pkg(String packageName, IntentFilter... filters) {
+ final ActivityInfo activityInfo = new ActivityInfo();
final PackageBuilder packageBuilder = pkg(packageName).addActivity(
pkg -> new PackageParser.ParseComponentArgs(pkg, new String[1], 0, 0, 0, 0, 0, 0,
- new String[]{packageName}, 0, 0, 0), new ActivityInfo());
+ new String[]{packageName}, 0, 0, 0), activityInfo);
for (IntentFilter filter : filters) {
packageBuilder.addActivityIntentInfo(0 /* index */, activity -> {
final PackageParser.ActivityIntentInfo info =
@@ -83,7 +77,7 @@
filter.actionsIterator().forEachRemaining(info::addAction);
}
if (filter.countCategories() > 0) {
- filter.actionsIterator().forEachRemaining(info::addAction);
+ filter.actionsIterator().forEachRemaining(info::addCategory);
}
if (filter.countDataAuthorities() > 0) {
filter.authoritiesIterator().forEachRemaining(info::addDataAuthority);
@@ -91,6 +85,7 @@
if (filter.countDataSchemes() > 0) {
filter.schemesIterator().forEachRemaining(info::addDataScheme);
}
+ activityInfo.exported = true;
return info;
});
}
@@ -102,9 +97,6 @@
mExisting = new ArrayMap<>();
MockitoAnnotations.initMocks(this);
- when(mPermissionManagerMock
- .checkPermission(anyString(), anyString(), anyInt()))
- .thenReturn(PackageManager.PERMISSION_DENIED);
when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true);
when(mFeatureConfigMock.packageIsEnabled(any(PackageParser.Package.class)))
.thenReturn(true);
@@ -113,7 +105,7 @@
@Test
public void testSystemReadyPropogates() throws Exception {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, mPermissionManagerMock, new String[]{}, false);
+ new AppsFilter(mFeatureConfigMock, new String[]{}, false);
appsFilter.onSystemReady();
verify(mFeatureConfigMock).onSystemReady();
}
@@ -121,12 +113,12 @@
@Test
public void testQueriesAction_FilterMatches() {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, mPermissionManagerMock, new String[]{}, false);
+ new AppsFilter(mFeatureConfigMock, new String[]{}, false);
PackageSetting target = simulateAddPackage(appsFilter,
- pkg("com.some.package", new IntentFilter("TEST_ACTION"))).build();
+ pkg("com.some.package", new IntentFilter("TEST_ACTION")), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package", new Intent("TEST_ACTION"))).build();
+ pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@@ -134,12 +126,12 @@
@Test
public void testQueriesAction_NoMatchingAction_Filters() {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, mPermissionManagerMock, new String[]{}, false);
+ new AppsFilter(mFeatureConfigMock, new String[]{}, false);
PackageSetting target = simulateAddPackage(appsFilter,
- pkg("com.some.package")).build();
+ pkg("com.some.package"), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package", new Intent("TEST_ACTION"))).build();
+ pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_UID);
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@@ -147,13 +139,17 @@
@Test
public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
- new String[]{}, false);
+ new AppsFilter(mFeatureConfigMock, new String[]{}, false);
- PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
- PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package",
- new Intent("TEST_ACTION")).setApplicationInfoTargetSdkVersion(
- Build.VERSION_CODES.P)).build();
+ PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.package"), DUMMY_TARGET_UID);
+ PackageSetting calling = simulateAddPackage(appsFilter,
+ pkg("com.some.other.package",
+ new Intent("TEST_ACTION"))
+ .setApplicationInfoTargetSdkVersion(Build.VERSION_CODES.P),
+ DUMMY_CALLING_UID);
+
+ when(mFeatureConfigMock.packageIsEnabled(calling.pkg)).thenReturn(false);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@@ -161,12 +157,12 @@
@Test
public void testNoQueries_Filters() {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
- new String[]{}, false);
+ new AppsFilter(mFeatureConfigMock, new String[]{}, false);
- PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
+ PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.package"), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package")).build();
+ pkg("com.some.other.package"), DUMMY_CALLING_UID);
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@@ -174,14 +170,12 @@
@Test
public void testForceQueryable_DoesntFilter() {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
- new String[]{}, false);
+ new AppsFilter(mFeatureConfigMock, new String[]{}, false);
- PackageSetting target =
- simulateAddPackage(appsFilter, pkg("com.some.package").setForceQueryable(true))
- .build();
+ PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package")).build();
+ pkg("com.some.other.package"), DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@@ -189,14 +183,13 @@
@Test
public void testForceQueryableByDevice_SystemCaller_DoesntFilter() {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
- new String[]{"com.some.package"}, false);
+ new AppsFilter(mFeatureConfigMock, new String[]{"com.some.package"}, false);
- PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"))
- .setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
- .build();
+ PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.package"), DUMMY_TARGET_UID,
+ setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package")).build();
+ pkg("com.some.other.package"), DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@@ -204,12 +197,12 @@
@Test
public void testForceQueryableByDevice_NonSystemCaller_Filters() {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
- new String[]{"com.some.package"}, false);
+ new AppsFilter(mFeatureConfigMock, new String[]{"com.some.package"}, false);
- PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
+ PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.package"), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package")).build();
+ pkg("com.some.other.package"), DUMMY_CALLING_UID);
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@@ -218,14 +211,14 @@
@Test
public void testSystemQueryable_DoesntFilter() {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
- new String[]{}, true /* system force queryable */);
+ new AppsFilter(mFeatureConfigMock, new String[]{},
+ true /* system force queryable */);
- PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"))
- .setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
- .build();
+ PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.package"), DUMMY_TARGET_UID,
+ setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package")).build();
+ pkg("com.some.other.package"), DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@@ -233,12 +226,12 @@
@Test
public void testQueriesPackage_DoesntFilter() {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
- new String[]{}, false);
+ new AppsFilter(mFeatureConfigMock, new String[]{}, false);
- PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
+ PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.package"), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package", "com.some.package")).build();
+ pkg("com.some.other.package", "com.some.package"), DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@@ -248,12 +241,12 @@
when(mFeatureConfigMock.packageIsEnabled(any(PackageParser.Package.class)))
.thenReturn(false);
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
- new String[]{}, false);
+ new AppsFilter(mFeatureConfigMock, new String[]{}, false);
- PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
- PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package")).build();
+ PackageSetting target = simulateAddPackage(
+ appsFilter, pkg("com.some.package"), DUMMY_TARGET_UID);
+ PackageSetting calling = simulateAddPackage(
+ appsFilter, pkg("com.some.other.package"), DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
@@ -261,10 +254,10 @@
@Test
public void testSystemUid_DoesntFilter() {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
- new String[]{}, false);
+ new AppsFilter(mFeatureConfigMock, new String[]{}, false);
- PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
+ PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.package"), DUMMY_TARGET_UID);
assertFalse(appsFilter.shouldFilterApplication(0, null, target, 0));
assertFalse(appsFilter.shouldFilterApplication(
@@ -274,10 +267,10 @@
@Test
public void testNonSystemUid_NoCallingSetting_Filters() {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
- new String[]{}, false);
+ new AppsFilter(mFeatureConfigMock, new String[]{}, false);
- PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
+ PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.package"), DUMMY_TARGET_UID);
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, null, target, 0));
}
@@ -285,8 +278,7 @@
@Test
public void testNoTargetPackage_filters() {
final AppsFilter appsFilter =
- new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
- new String[]{}, false);
+ new AppsFilter(mFeatureConfigMock, new String[]{}, false);
PackageSetting target = new PackageSettingBuilder()
.setName("com.some.package")
@@ -295,22 +287,36 @@
.setPVersionCode(1L)
.build();
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package", new Intent("TEST_ACTION"))).build();
+ pkg("com.some.other.package", new Intent("TEST_ACTION")), DUMMY_CALLING_UID);
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
}
- private PackageSettingBuilder simulateAddPackage(AppsFilter filter,
- PackageBuilder newPkgBuilder) {
+ private interface WithSettingBuilder {
+ PackageSettingBuilder withBuilder(PackageSettingBuilder builder);
+ }
+
+ private PackageSetting simulateAddPackage(AppsFilter filter,
+ PackageBuilder newPkgBuilder, int appId) {
+ return simulateAddPackage(filter, newPkgBuilder, appId, null);
+ }
+
+ private PackageSetting simulateAddPackage(AppsFilter filter,
+ PackageBuilder newPkgBuilder, int appId, @Nullable WithSettingBuilder action) {
PackageParser.Package newPkg = newPkgBuilder.build();
- filter.addPackage(newPkg, mExisting);
- mExisting.put(newPkg.packageName, newPkg);
- return new PackageSettingBuilder()
+
+ final PackageSettingBuilder settingBuilder = new PackageSettingBuilder()
.setPackage(newPkg)
+ .setAppId(appId)
.setName(newPkg.packageName)
.setCodePath("/")
.setResourcePath("/")
.setPVersionCode(1L);
+ final PackageSetting setting =
+ (action == null ? settingBuilder : action.withBuilder(settingBuilder)).build();
+ filter.addPackage(setting, mExisting);
+ mExisting.put(newPkg.packageName, setting);
+ return setting;
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
index 06c6314..8d476f6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
@@ -43,6 +43,7 @@
private String mVolumeUuid;
private SparseArray<PackageUserState> mUserStates = new SparseArray<>();
private PackageParser.Package mPkg;
+ private int mAppId;
public PackageSettingBuilder setPackage(PackageParser.Package pkg) {
this.mPkg = pkg;
@@ -54,6 +55,11 @@
return this;
}
+ public PackageSettingBuilder setAppId(int appId) {
+ this.mAppId = appId;
+ return this;
+ }
+
public PackageSettingBuilder setRealName(String realName) {
this.mRealName = realName;
return this;
@@ -152,6 +158,7 @@
mChildPackageNames, mSharedUserId, mUsesStaticLibraries,
mUsesStaticLibrariesVersions);
packageSetting.pkg = mPkg;
+ packageSetting.appId = mAppId;
packageSetting.volumeUuid = this.mVolumeUuid;
for (int i = 0; i < mUserStates.size(); i++) {
packageSetting.setUserState(mUserStates.keyAt(i), mUserStates.valueAt(i));