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));