Fix cross user package visibility leakage for queryInstrumentation

Returns false for querying instrumentation APIs if the target package
does not installed in the calling user.

Also adding a user id parameter to APIs for the system modules to
specify the correct user id when querying the instrumentation.

NoNonSdkCheck: The equivalent apis are available in PackageManager.
Bug: 229684723
Test: atest CrossUserPackageVisibilityTests
Change-Id: I0798e543705cb8866231ee376e07b853b419b6f3
diff --git a/cmds/am/src/com/android/commands/am/Instrument.java b/cmds/am/src/com/android/commands/am/Instrument.java
index 7ff4bc4..2604497 100644
--- a/cmds/am/src/com/android/commands/am/Instrument.java
+++ b/cmds/am/src/com/android/commands/am/Instrument.java
@@ -425,7 +425,8 @@
             if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg);
             return cn;
         } else {
-            List<InstrumentationInfo> infos = mPm.queryInstrumentation(null, 0).getList();
+            List<InstrumentationInfo> infos = mPm.queryInstrumentationAsUser(
+                    null, 0, userId).getList();
 
             final int numInfos = infos == null ? 0: infos.size();
             ArrayList<ComponentName> cns = new ArrayList<>();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 69868ab..c87f3c4 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -6863,9 +6863,12 @@
     private InstrumentationInfo prepareInstrumentation(AppBindData data) {
         final InstrumentationInfo ii;
         try {
-            ii = new ApplicationPackageManager(null, getPackageManager())
-                    .getInstrumentationInfo(data.instrumentationName, 0);
-        } catch (PackageManager.NameNotFoundException e) {
+            ii = getPackageManager().getInstrumentationInfoAsUser(data.instrumentationName,
+                    0 /* flags */, UserHandle.myUserId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        if (ii == null) {
             throw new RuntimeException(
                     "Unable to find instrumentation info for: " + data.instrumentationName);
         }
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index e9ebd72..fea3027 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1695,8 +1695,8 @@
         ComponentName className, int flags)
             throws NameNotFoundException {
         try {
-            InstrumentationInfo ii = mPM.getInstrumentationInfo(
-                className, flags);
+            InstrumentationInfo ii = mPM.getInstrumentationInfoAsUser(
+                    className, flags, getUserId());
             if (ii != null) {
                 return ii;
             }
@@ -1713,7 +1713,7 @@
         String targetPackage, int flags) {
         try {
             ParceledListSlice<InstrumentationInfo> parceledList =
-                    mPM.queryInstrumentation(targetPackage, flags);
+                    mPM.queryInstrumentationAsUser(targetPackage, flags, getUserId());
             if (parceledList == null) {
                 return Collections.emptyList();
             }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 6bb7e3e..1b1143a 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -201,13 +201,11 @@
     ParceledListSlice queryContentProviders(
             String processName, int uid, long flags, String metaDataKey);
 
-    @UnsupportedAppUsage
-    InstrumentationInfo getInstrumentationInfo(
-            in ComponentName className, int flags);
+    InstrumentationInfo getInstrumentationInfoAsUser(
+            in ComponentName className, int flags, int userId);
 
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    ParceledListSlice queryInstrumentation(
-            String targetPackage, int flags);
+    ParceledListSlice queryInstrumentationAsUser(
+            String targetPackage, int flags, int userId);
 
     void finishPackageInstall(int token, boolean didLaunch);
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b0ab89c..27f04f9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -14528,6 +14528,7 @@
         if (arguments != null && arguments.hasFileDescriptors()) {
             throw new IllegalArgumentException("File descriptors passed in Bundle");
         }
+        final IPackageManager pm = AppGlobals.getPackageManager();
 
         synchronized(this) {
             InstrumentationInfo ii = null;
@@ -14536,11 +14537,8 @@
             boolean noRestart = (flags & INSTR_FLAG_NO_RESTART) != 0;
 
             try {
-                ii = mContext.getPackageManager().getInstrumentationInfo(
-                        className, STOCK_PM_FLAGS);
-                ai = AppGlobals.getPackageManager().getApplicationInfo(
-                        ii.targetPackage, STOCK_PM_FLAGS, userId);
-            } catch (PackageManager.NameNotFoundException e) {
+                ii = pm.getInstrumentationInfoAsUser(className, STOCK_PM_FLAGS, userId);
+                ai = pm.getApplicationInfo(ii.targetPackage, STOCK_PM_FLAGS, userId);
             } catch (RemoteException e) {
             }
             if (ii == null) {
@@ -14568,8 +14566,7 @@
 
             int match = SIGNATURE_NO_MATCH;
             try {
-                match = AppGlobals.getPackageManager().checkSignatures(
-                        ii.targetPackage, ii.packageName, userId);
+                match = pm.checkSignatures(ii.targetPackage, ii.packageName, userId);
             } catch (RemoteException e) {
             }
             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index dfe06cf..33e9b2f 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -452,11 +452,12 @@
             @PackageManager.ComponentInfoFlagsBits long flags, @Nullable String metaDataKey);
 
     @Nullable
-    InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component, int flags);
+    InstrumentationInfo getInstrumentationInfoAsUser(@NonNull ComponentName component, int flags,
+            int userId);
 
     @NonNull
-    ParceledListSlice<InstrumentationInfo> queryInstrumentation(
-            @NonNull String targetPackage, int flags);
+    ParceledListSlice<InstrumentationInfo> queryInstrumentationAsUser(
+            @NonNull String targetPackage, int flags, int userId);
 
     @NonNull
     List<PackageStateInternal> findSharedNonSystemLibraries(
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 45a139d..ad0b455 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -4927,32 +4927,33 @@
 
     @Nullable
     @Override
-    public InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component, int flags) {
+    public InstrumentationInfo getInstrumentationInfoAsUser(@NonNull ComponentName component,
+            int flags, int userId) {
         final int callingUid = Binder.getCallingUid();
-        final int callingUserId = UserHandle.getUserId(callingUid);
+        enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
+                false /* checkShell */, "getInstrumentationInfoAsUser");
+        if (!mUserManager.exists(userId)) return null;
         String packageName = component.getPackageName();
         final PackageStateInternal ps = mSettings.getPackage(packageName);
         AndroidPackage pkg = mPackages.get(packageName);
         if (ps == null || pkg == null) return null;
         if (shouldFilterApplication(
-                ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
+                ps, callingUid, component, TYPE_UNKNOWN, userId)) {
             return null;
         }
         final ParsedInstrumentation i = mInstrumentation.get(component);
-        return PackageInfoUtils.generateInstrumentationInfo(i, pkg, flags, callingUserId, ps);
+        final PackageUserStateInternal state = ps.getUserStateOrDefault(userId);
+        return PackageInfoUtils.generateInstrumentationInfo(i, pkg, flags, state, userId, ps);
     }
 
     @NonNull
     @Override
-    public ParceledListSlice<InstrumentationInfo> queryInstrumentation(
-            @NonNull String targetPackage, int flags) {
+    public ParceledListSlice<InstrumentationInfo> queryInstrumentationAsUser(
+            @NonNull String targetPackage, int flags, int userId) {
         final int callingUid = Binder.getCallingUid();
-        final int callingUserId = UserHandle.getUserId(callingUid);
-        final PackageStateInternal ps = mSettings.getPackage(targetPackage);
-        if (shouldFilterApplication(ps, callingUid, callingUserId)) {
-            return ParceledListSlice.emptyList();
-        }
-
+        enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
+                false /* checkShell */, "queryInstrumentationAsUser");
+        if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
         ArrayList<InstrumentationInfo> finalList = new ArrayList<>();
 
         final int numInstrumentations = mInstrumentation.size();
@@ -4963,12 +4964,15 @@
                 String packageName = p.getPackageName();
                 AndroidPackage pkg = mPackages.get(packageName);
                 PackageStateInternal pkgSetting = getPackageStateInternal(packageName);
-                if (pkg != null) {
-                    InstrumentationInfo ii = PackageInfoUtils.generateInstrumentationInfo(p,
-                            pkg, flags, callingUserId, pkgSetting);
-                    if (ii != null) {
-                        finalList.add(ii);
-                    }
+                if (pkg == null || pkgSetting == null
+                        || shouldFilterApplication(pkgSetting, callingUid, userId)) {
+                    continue;
+                }
+                final PackageUserStateInternal state = pkgSetting.getUserStateOrDefault(userId);
+                InstrumentationInfo ii = PackageInfoUtils.generateInstrumentationInfo(p,
+                        pkg, flags, state, userId, pkgSetting);
+                if (ii != null) {
+                    finalList.add(ii);
                 }
             }
         }
diff --git a/services/core/java/com/android/server/pm/IPackageManagerBase.java b/services/core/java/com/android/server/pm/IPackageManagerBase.java
index 3754131..c16071d 100644
--- a/services/core/java/com/android/server/pm/IPackageManagerBase.java
+++ b/services/core/java/com/android/server/pm/IPackageManagerBase.java
@@ -533,9 +533,9 @@
     @Nullable
     @Override
     @Deprecated
-    public final InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component,
-            int flags) {
-        return snapshot().getInstrumentationInfo(component, flags);
+    public final InstrumentationInfo getInstrumentationInfoAsUser(@NonNull ComponentName component,
+            int flags, int userId) {
+        return snapshot().getInstrumentationInfoAsUser(component, flags, userId);
     }
 
     @Override
@@ -1017,9 +1017,9 @@
     @NonNull
     @Override
     @Deprecated
-    public final ParceledListSlice<InstrumentationInfo> queryInstrumentation(
-            @NonNull String targetPackage, int flags) {
-        return snapshot().queryInstrumentation(targetPackage, flags);
+    public final ParceledListSlice<InstrumentationInfo> queryInstrumentationAsUser(
+            @NonNull String targetPackage, int flags, int userId) {
+        return snapshot().queryInstrumentationAsUser(targetPackage, flags, userId);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index f5981e2..5906c3f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -788,7 +788,9 @@
         }
 
         final List<InstrumentationInfo> list =
-                mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList();
+                mInterface.queryInstrumentationAsUser(
+                        targetPackage, PackageManager.MATCH_KNOWN_PACKAGES, UserHandle.USER_SYSTEM)
+                        .getList();
 
         // sort by target package
         Collections.sort(list, new Comparator<InstrumentationInfo>() {
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index 4f0f2a8..9c620c4 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -204,7 +204,8 @@
                 info.instrumentation = new InstrumentationInfo[N];
                 for (int i = 0; i < N; i++) {
                     info.instrumentation[i] = generateInstrumentationInfo(
-                            pkg.getInstrumentations().get(i), pkg, flags, userId, pkgSetting);
+                            pkg.getInstrumentations().get(i), pkg, flags, state,
+                            userId, pkgSetting);
                 }
             }
         }
@@ -363,9 +364,12 @@
      */
     @Nullable
     public static InstrumentationInfo generateInstrumentationInfo(ParsedInstrumentation i,
-            AndroidPackage pkg, @PackageManager.ComponentInfoFlagsBits long flags, int userId,
-            @Nullable PackageStateInternal pkgSetting) {
+            AndroidPackage pkg, @PackageManager.ComponentInfoFlagsBits long flags,
+            PackageUserStateInternal state, int userId, @Nullable PackageStateInternal pkgSetting) {
         if (i == null) return null;
+        if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) {
+            return null;
+        }
 
         InstrumentationInfo info =
                 PackageInfoWithoutStateUtils.generateInstrumentationInfo(i, pkg, flags, userId,