Add native bindings for getNamesForUids

A new API [getNamesForUids] was recently added to the PackageManager
and this API needs to be accessible to native code. However, there
were two constraints:
1) Instead of hand-rolling the binder, we wanted to auto generate
the bindings directly from the AIDL compiler.
2) We didn't want to expose/annotate all 180+ PackageManager APIs
when only a single API is needed.
So, we chose to create a parallel API that can be used explicitly
for native bindings without exposing the entirety of the
PackageManager.

Bug: 62805090
Test: Manual
Test: Create a native application that calls into the new service
Test: See the call works and data and returned
Change-Id: Ia571ab1607c6c88fef44eb0de6a313a28906c732
diff --git a/Android.mk b/Android.mk
index 2b16c02..6903905 100644
--- a/Android.mk
+++ b/Android.mk
@@ -172,6 +172,7 @@
 	core/java/android/content/pm/IPackageInstallerCallback.aidl \
 	core/java/android/content/pm/IPackageInstallerSession.aidl \
 	core/java/android/content/pm/IPackageManager.aidl \
+	../native/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl \
 	core/java/android/content/pm/IPackageMoveObserver.aidl \
 	core/java/android/content/pm/IPackageStatsObserver.aidl \
 	core/java/android/content/pm/IPinItemRequest.aidl \
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 1921b2a..0e70645 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -61,12 +61,6 @@
  *  {@hide}
  */
 interface IPackageManager {
-    // Since these transactions are also called from native code, these must be kept in sync with
-    // the ones in frameworks/native/include/binder/IPackageManager.h
-    // =============== Beginning of transactions used on native side as well ======================
-    String[] getNamesForUids(in int[] uids);
-    // =============== End of transactions used on native side as well ============================
-
     void checkPackageStartable(String packageName, int userId);
     boolean isPackageAvailable(String packageName, int userId);
     PackageInfo getPackageInfo(String packageName, int flags, int userId);
@@ -134,6 +128,7 @@
     String[] getPackagesForUid(int uid);
 
     String getNameForUid(int uid);
+    String[] getNamesForUids(in int[] uids);
 
     int getUidForSharedUser(String sharedUserName);
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ebd8ef0..a8344b1 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -143,6 +143,7 @@
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageManager;
+import android.content.pm.IPackageManagerNative;
 import android.content.pm.IPackageMoveObserver;
 import android.content.pm.IPackageStatsObserver;
 import android.content.pm.InstantAppInfo;
@@ -2304,6 +2305,8 @@
                 factoryTest, onlyCore);
         m.enableSystemUserPackages();
         ServiceManager.addService("package", m);
+        final PackageManagerNative pmn = m.new PackageManagerNative();
+        ServiceManager.addService("package_native", pmn);
         return m;
     }
 
@@ -6402,7 +6405,18 @@
             return null;
         }
         synchronized (mPackages) {
-            return getNameForUidLocked(callingUid, uid);
+            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
+            if (obj instanceof SharedUserSetting) {
+                final SharedUserSetting sus = (SharedUserSetting) obj;
+                return sus.name + ":" + sus.userId;
+            } else if (obj instanceof PackageSetting) {
+                final PackageSetting ps = (PackageSetting) obj;
+                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
+                    return null;
+                }
+                return ps.name;
+            }
+            return null;
         }
     }
 
@@ -6419,27 +6433,25 @@
         synchronized (mPackages) {
             for (int i = uids.length - 1; i >= 0; i--) {
                 final int uid = uids[i];
-                names[i] = getNameForUidLocked(callingUid, uid);
+                Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
+                if (obj instanceof SharedUserSetting) {
+                    final SharedUserSetting sus = (SharedUserSetting) obj;
+                    names[i] = "shared:" + sus.name;
+                } else if (obj instanceof PackageSetting) {
+                    final PackageSetting ps = (PackageSetting) obj;
+                    if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
+                        names[i] = null;
+                    } else {
+                        names[i] = ps.name;
+                    }
+                } else {
+                    names[i] = null;
+                }
             }
         }
         return names;
     }
 
-    private String getNameForUidLocked(int callingUid, int uid) {
-        Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
-        if (obj instanceof SharedUserSetting) {
-            final SharedUserSetting sus = (SharedUserSetting) obj;
-            return sus.name + ":" + sus.userId;
-        } else if (obj instanceof PackageSetting) {
-            final PackageSetting ps = (PackageSetting) obj;
-            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
-                return null;
-            }
-            return ps.name;
-        }
-        return null;
-    }
-
     @Override
     public int getUidForSharedUser(String sharedUserName) {
         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
@@ -24781,6 +24793,20 @@
         }
     }
 
+    private class PackageManagerNative extends IPackageManagerNative.Stub {
+        @Override
+        public String[] getNamesForUids(int[] uids) throws RemoteException {
+            final String[] results = PackageManagerService.this.getNamesForUids(uids);
+            // massage results so they can be parsed by the native binder
+            for (int i = results.length - 1; i >= 0; --i) {
+                if (results[i] == null) {
+                    results[i] = "";
+                }
+            }
+            return results;
+        }
+    }
+
     private class PackageManagerInternalImpl extends PackageManagerInternal {
         @Override
         public void setLocationPackagesProvider(PackagesProvider provider) {