Add support for PackageManager to TestApp.

Test: atest TestAppTest
Fixes: 197231543
Change-Id: I21e7228151b3945267ed02cf64a1015db14aa77a
Merged-In: I21e7228151b3945267ed02cf64a1015db14aa77a
diff --git a/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Apis.java b/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Apis.java
index c7615d9..0c295dc 100644
--- a/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Apis.java
+++ b/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Apis.java
@@ -79,11 +79,13 @@
 
         String[] packageSplit = apiTxt.split("package " + packageName + " \\{", 2);
         if (packageSplit.length < 2) {
+            System.out.println("Package " + packageName + " not in file");
             // Package not in this file
             return new HashSet<>();
         }
         String[] classSplit = packageSplit[1].split("class " + simpleClassName + " \\{", 2);
         if (classSplit.length < 2) {
+            System.out.println("Class " + simpleClassName + " not in file");
             // Class not in this file
             return new HashSet<>();
         }
@@ -96,6 +98,11 @@
                 continue;
             }
 
+            if (methodLine.startsWith("ctor")) {
+                // Skip constructors
+                continue;
+            }
+
             if (!methodLine.startsWith("method")) {
                 return methodSignatures;
             }
diff --git a/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/MethodSignature.java b/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/MethodSignature.java
index b91adad..5fb7076 100644
--- a/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/MethodSignature.java
+++ b/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/MethodSignature.java
@@ -79,7 +79,17 @@
         Visibility visibility = Visibility.valueOf(parts[0].toUpperCase());
         string = parts[1];
         parts = string.split(" ", 2);
-        TypeMirror returnType = typeForString(parts[0], types, elements);
+
+        TypeMirror returnType;
+        if (parts[0].equals("abstract")) {
+            // Doesn't matter - we're wrapping anyway
+            string = parts[1];
+            parts = string.split(" ", 2);
+            returnType = typeForString(parts[0], types, elements);
+        } else {
+            returnType = typeForString(parts[0], types, elements);
+        }
+
         string = parts[1];
         parts = string.split("\\(", 2);
         String methodName = parts[0];
diff --git a/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Processor.java b/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Processor.java
index 14bd27f..236eca4 100644
--- a/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Processor.java
+++ b/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Processor.java
@@ -72,7 +72,8 @@
             "android.app.admin.DevicePolicyManager",
             "android.net.wifi.WifiManager",
             "android.os.HardwarePropertiesManager",
-            "android.os.UserManager"
+            "android.os.UserManager",
+            "android.content.pm.PackageManager"
     };
 
     private static final Set<String> BLOCKLISTED_METHODS = ImmutableSet.of(
@@ -92,22 +93,17 @@
 
             // Uses Executor
             "public void addSuggestionConnectionStatusListener(java.util.concurrent.Executor, android.net.wifi.WifiManager.SuggestionConnectionStatusListener)",
-            // Uses Executor
             "public void addSuggestionUserApprovalStatusListener(java.util.concurrent.Executor, android.net.wifi.WifiManager.SuggestionUserApprovalStatusListener)",
-            // Uses Executor
             "public void clearApplicationUserData(android.content.ComponentName, @NonNull String, @NonNull java.util.concurrent.Executor, android.app.admin.DevicePolicyManager.OnClearApplicationUserDataListener)",
+            "public void registerScanResultsCallback(java.util.concurrent.Executor, android.net.wifi.WifiManager.ScanResultsCallback)",
+            "public void registerSubsystemRestartTrackingCallback(java.util.concurrent.Executor, android.net.wifi.WifiManager.SubsystemRestartTrackingCallback)",
             // Uses WpsCallback
             "public void cancelWps(android.net.wifi.WifiManager.WpsCallback)",
             // Uses MulticastLock
             "public android.net.wifi.WifiManager.MulticastLock createMulticastLock(String)",
             // Uses WifiLock
             "public android.net.wifi.WifiManager.WifiLock createWifiLock(int, String)",
-            // Uses WifiLock
             "public android.net.wifi.WifiManager.WifiLock createWifiLock(String)",
-            // Uses Executor
-            "public void registerScanResultsCallback(java.util.concurrent.Executor, android.net.wifi.WifiManager.ScanResultsCallback)",
-            // Uses Executor
-            "public void registerSubsystemRestartTrackingCallback(java.util.concurrent.Executor, android.net.wifi.WifiManager.SubsystemRestartTrackingCallback)",
             // Uses SuggestionConnectionStatusListener
             "public void removeSuggestionConnectionStatusListener(android.net.wifi.WifiManager.SuggestionConnectionStatusListener)",
             // Uses SuggestionUserApprovalStatusListener
@@ -119,7 +115,49 @@
             // Uses ScanResultsCallback
             "public void unregisterScanResultsCallback(@NonNull android.net.wifi.WifiManager.ScanResultsCallback)",
             // Uses SubsystemRestartTrackingCallback
-            "public void unregisterSubsystemRestartTrackingCallback(android.net.wifi.WifiManager.SubsystemRestartTrackingCallback)"
+            "public void unregisterSubsystemRestartTrackingCallback(android.net.wifi.WifiManager.SubsystemRestartTrackingCallback)",
+
+            // PackageManager
+
+            // Uses IBinder
+            "public android.os.IBinder getHoldLockToken()",
+            "public void holdLock(android.os.IBinder, int)",
+            // Uses Drawable
+            "public abstract android.graphics.drawable.Drawable getActivityBanner(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException",
+            "public abstract android.graphics.drawable.Drawable getActivityBanner(@NonNull android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException",
+            "public abstract android.graphics.drawable.Drawable getActivityIcon(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException",
+            "public abstract android.graphics.drawable.Drawable getActivityIcon(@NonNull android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException",
+            "public abstract android.graphics.drawable.Drawable getActivityLogo(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException",
+            "public abstract android.graphics.drawable.Drawable getActivityLogo(@NonNull android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException",
+            "public abstract android.graphics.drawable.Drawable getApplicationBanner(@NonNull android.content.pm.ApplicationInfo)",
+            "public abstract android.graphics.drawable.Drawable getApplicationBanner(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException",
+            "public abstract android.graphics.drawable.Drawable getApplicationIcon(@NonNull android.content.pm.ApplicationInfo)",
+            "public abstract android.graphics.drawable.Drawable getApplicationIcon(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException",
+            "public abstract android.graphics.drawable.Drawable getApplicationLogo(@NonNull android.content.pm.ApplicationInfo)",
+            "public abstract android.graphics.drawable.Drawable getApplicationLogo(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException",
+            "public abstract android.graphics.drawable.Drawable getDefaultActivityIcon()",
+            "public abstract android.graphics.drawable.Drawable getDrawable(@NonNull String, @DrawableRes int, @Nullable android.content.pm.ApplicationInfo)",
+            "public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle, @Nullable android.graphics.Rect, int)",
+            "public abstract android.graphics.drawable.Drawable getUserBadgedIcon(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle)",
+            "public boolean isDefaultApplicationIcon(@NonNull android.graphics.drawable.Drawable)",
+            // Uses Executor
+            "public void getGroupOfPlatformPermission(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.String>)",
+            "public void getPlatformPermissionsForGroup(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<java.lang.String>>)",
+            // Uses Resources
+            "public abstract android.content.res.Resources getResourcesForActivity(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException",
+            "public abstract android.content.res.Resources getResourcesForApplication(@NonNull android.content.pm.ApplicationInfo) throws android.content.pm.PackageManager.NameNotFoundException",
+            "public android.content.res.Resources getResourcesForApplication(@NonNull android.content.pm.ApplicationInfo, @Nullable android.content.res.Configuration) throws android.content.pm.PackageManager.NameNotFoundException",
+            "public abstract android.content.res.Resources getResourcesForApplication(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException",
+            // Uses PackageInstaller
+            "public abstract android.content.pm.PackageInstaller getPackageInstaller()",
+            // Uses XmlResourceParser
+            "public abstract android.content.res.XmlResourceParser getXml(@NonNull String, @XmlRes int, @Nullable android.content.pm.ApplicationInfo)",
+            // Uses OnChecksumsReadyListener
+            "public void requestChecksums(@NonNull String, boolean, int, @NonNull java.util.List<java.security.cert.Certificate>, @NonNull android.content.pm.PackageManager.OnChecksumsReadyListener) throws java.security.cert.CertificateEncodingException, android.content.pm.PackageManager.NameNotFoundException"
+
+
+
+
     );
 
     @Override
diff --git a/common/device-side/bedstead/testapp/src/library/main/java/com/android/bedstead/testapp/TestAppInstanceReference.java b/common/device-side/bedstead/testapp/src/library/main/java/com/android/bedstead/testapp/TestAppInstanceReference.java
index 18f19cf..c6b7cb3a 100644
--- a/common/device-side/bedstead/testapp/src/library/main/java/com/android/bedstead/testapp/TestAppInstanceReference.java
+++ b/common/device-side/bedstead/testapp/src/library/main/java/com/android/bedstead/testapp/TestAppInstanceReference.java
@@ -16,17 +16,23 @@
 
 package com.android.bedstead.testapp;
 
+import android.app.admin.DevicePolicyManager;
 import android.app.admin.RemoteDevicePolicyManager;
 import android.app.admin.RemoteDevicePolicyManagerWrapper;
 import android.content.BroadcastReceiver;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.RemotePackageManager;
+import android.content.pm.RemotePackageManagerWrapper;
 import android.net.wifi.RemoteWifiManager;
 import android.net.wifi.RemoteWifiManagerWrapper;
+import android.net.wifi.WifiManager;
+import android.os.HardwarePropertiesManager;
 import android.os.RemoteHardwarePropertiesManager;
 import android.os.RemoteHardwarePropertiesManagerWrapper;
 import android.os.RemoteUserManager;
 import android.os.RemoteUserManagerWrapper;
-
+import android.os.UserManager;
 
 import com.android.bedstead.nene.TestApis;
 import com.android.bedstead.nene.exceptions.NeneException;
@@ -254,19 +260,48 @@
         }
     }
 
+    /**
+     * Access {@link DevicePolicyManager} using this test app.
+     *
+     * <p>Almost all methods are available. Those that are not will be missing from the interface.
+     */
     public RemoteDevicePolicyManager devicePolicyManager() {
         return new RemoteDevicePolicyManagerWrapper(mConnector);
     }
 
+    /**
+     * Access {@link UserManager} using this test app.
+     *
+     * <p>Almost all methods are available. Those that are not will be missing from the interface.
+     */
     public RemoteUserManager userManager() {
         return new RemoteUserManagerWrapper(mConnector);
     }
 
+    /**
+     * Access {@link WifiManager} using this test app.
+     *
+     * <p>Almost all methods are available. Those that are not will be missing from the interface.
+     */
     public RemoteWifiManager wifiManager() {
         return new RemoteWifiManagerWrapper(mConnector);
     }
 
+    /**
+     * Access {@link HardwarePropertiesManager} using this test app.
+     *
+     * <p>Almost all methods are available. Those that are not will be missing from the interface.
+     */
     public RemoteHardwarePropertiesManager hardwarePropertiesManager() {
         return new RemoteHardwarePropertiesManagerWrapper(mConnector);
     }
+
+    /**
+     * Access {@link PackageManager} using this test app.
+     *
+     * <p>Almost all methods are available. Those that are not will be missing from the interface.
+     */
+    public RemotePackageManager packageManager() {
+        return new RemotePackageManagerWrapper(mConnector);
+    }
 }
diff --git a/common/device-side/bedstead/testapp/src/processor/main/java/com/android/bedstead/testapp/processor/Processor.java b/common/device-side/bedstead/testapp/src/processor/main/java/com/android/bedstead/testapp/processor/Processor.java
index ee768d8..bb8524c 100644
--- a/common/device-side/bedstead/testapp/src/processor/main/java/com/android/bedstead/testapp/processor/Processor.java
+++ b/common/device-side/bedstead/testapp/src/processor/main/java/com/android/bedstead/testapp/processor/Processor.java
@@ -28,6 +28,7 @@
 import com.google.auto.service.AutoService;
 import com.squareup.javapoet.AnnotationSpec;
 import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.CodeBlock;
 import com.squareup.javapoet.FieldSpec;
 import com.squareup.javapoet.JavaFile;
 import com.squareup.javapoet.MethodSpec;
@@ -521,14 +522,23 @@
             ClassName implClassName = ClassName.get(
                     originalClassName.packageName(), interfaceClassName.simpleName() + "Impl");
 
+            CodeBlock systemServiceGetterCode = CodeBlock.of(
+                    "context.getSystemService($T.class)", originalClassName);
+
+            if (systemServiceClass.asType().toString().equals(
+                    "android.content.pm.PackageManager")) {
+                // Special case - getSystemService will return null
+                systemServiceGetterCode = CodeBlock.of("context.getPackageManager()");
+            }
+
             classBuilder.addMethod(
                     MethodSpec.methodBuilder("provide" + interfaceClassName.simpleName())
                             .returns(interfaceClassName)
                             .addModifiers(Modifier.PUBLIC)
                             .addAnnotation(CrossProfileProvider.class)
                             .addParameter(CONTEXT_CLASSNAME, "context")
-                            .addCode("return new $T(context.getSystemService($T.class));",
-                                    implClassName, originalClassName)
+                            .addCode("return new $T($L);",
+                                    implClassName, systemServiceGetterCode)
                             .build());
         }
 
diff --git a/common/device-side/bedstead/testapp/src/test/java/com/android/bedstead/testapp/TestAppInstanceReferenceTest.java b/common/device-side/bedstead/testapp/src/test/java/com/android/bedstead/testapp/TestAppInstanceReferenceTest.java
index e03b961..cb89c34 100644
--- a/common/device-side/bedstead/testapp/src/test/java/com/android/bedstead/testapp/TestAppInstanceReferenceTest.java
+++ b/common/device-side/bedstead/testapp/src/test/java/com/android/bedstead/testapp/TestAppInstanceReferenceTest.java
@@ -61,6 +61,8 @@
     private static final IntentFilter INTENT_FILTER_2 = new IntentFilter(INTENT_ACTION_2);
     private static final Intent INTENT_2 = new Intent(INTENT_ACTION_2);
 
+    private static final int NON_EXISTING_UID = -1;
+
     @Before
     public void setup() {
         mTestAppProvider = new TestAppProvider();
@@ -350,4 +352,13 @@
             });
         }
     }
+
+    @Test
+    public void packageManager_returnsUsableInstance() {
+        TestApp testApp = mTestAppProvider.any();
+        try (TestAppInstanceReference testAppInstance = testApp.install(sUser)) {
+            assertThat(testAppInstance.packageManager().getPackagesForUid(NON_EXISTING_UID))
+                    .isNull();
+        }
+    }
 }
diff --git a/common/device-side/bedstead/testapp/src/testapps/main/java/com/android/bedstead/testapp/TestAppAppComponentFactory.java b/common/device-side/bedstead/testapp/src/testapps/main/java/com/android/bedstead/testapp/TestAppAppComponentFactory.java
index 18638de..8f1f2aa 100644
--- a/common/device-side/bedstead/testapp/src/testapps/main/java/com/android/bedstead/testapp/TestAppAppComponentFactory.java
+++ b/common/device-side/bedstead/testapp/src/testapps/main/java/com/android/bedstead/testapp/TestAppAppComponentFactory.java
@@ -21,6 +21,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.net.wifi.WifiManager;
 import android.os.HardwarePropertiesManager;
 import android.os.UserManager;
@@ -36,7 +37,8 @@
                 DevicePolicyManager.class,
                 HardwarePropertiesManager.class,
                 UserManager.class,
-                WifiManager.class
+                WifiManager.class,
+                PackageManager.class
         }
 )public final class TestAppAppComponentFactory extends AppComponentFactory {