Add more methods that take a userId to PackageManager.

Add methods installPackageAsUser and installExistingPackageAsUser
and deletePackageAsUser and getPackageInfoAsUser.

BUG:23516394
Change-Id: I15e30d2ec45ab18c7f8c0ac02cfc617c50fedb44
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 5544a71..0d53dbe 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -126,8 +126,14 @@
     @Override
     public PackageInfo getPackageInfo(String packageName, int flags)
             throws NameNotFoundException {
+        return getPackageInfoAsUser(packageName, flags, mContext.getUserId());
+    }
+
+    @Override
+    public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException {
         try {
-            PackageInfo pi = mPM.getPackageInfo(packageName, flags, mContext.getUserId());
+            PackageInfo pi = mPM.getPackageInfo(packageName, flags, userId);
             if (pi != null) {
                 return pi;
             }
@@ -1338,7 +1344,7 @@
         final VerificationParams verificationParams = new VerificationParams(null, null,
                 null, VerificationParams.NO_UID, null);
         installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
-                installerPackageName, verificationParams, null);
+                installerPackageName, verificationParams, null, UserHandle.myUserId());
     }
 
     @Override
@@ -1348,7 +1354,7 @@
         final VerificationParams verificationParams = new VerificationParams(verificationURI, null,
                 null, VerificationParams.NO_UID, manifestDigest);
         installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
-                installerPackageName, verificationParams, encryptionParams);
+                installerPackageName, verificationParams, encryptionParams, UserHandle.myUserId());
     }
 
     @Override
@@ -1356,15 +1362,23 @@
             IPackageInstallObserver observer, int flags, String installerPackageName,
             VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
         installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
-                installerPackageName, verificationParams, encryptionParams);
+                installerPackageName, verificationParams, encryptionParams, UserHandle.myUserId());
     }
 
     @Override
     public void installPackage(Uri packageURI, PackageInstallObserver observer,
             int flags, String installerPackageName) {
+        installPackageAsUser(packageURI, observer, flags, installerPackageName,
+                UserHandle.myUserId());
+    }
+
+    @Override
+    public void installPackageAsUser(Uri packageURI, PackageInstallObserver observer, int flags,
+               String installerPackageName, int userId) {
         final VerificationParams verificationParams = new VerificationParams(null, null,
                 null, VerificationParams.NO_UID, null);
-        installCommon(packageURI, observer, flags, installerPackageName, verificationParams, null);
+        installCommon(packageURI, observer, flags, installerPackageName, verificationParams, null,
+                userId);
     }
 
     @Override
@@ -1375,7 +1389,7 @@
         final VerificationParams verificationParams = new VerificationParams(verificationURI, null,
                 null, VerificationParams.NO_UID, manifestDigest);
         installCommon(packageURI, observer, flags, installerPackageName, verificationParams,
-                encryptionParams);
+                encryptionParams, UserHandle.myUserId());
     }
 
     @Override
@@ -1383,12 +1397,13 @@
             PackageInstallObserver observer, int flags, String installerPackageName,
             VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
         installCommon(packageURI, observer, flags, installerPackageName, verificationParams,
-                encryptionParams);
+                encryptionParams, UserHandle.myUserId());
     }
 
     private void installCommon(Uri packageURI,
             PackageInstallObserver observer, int flags, String installerPackageName,
-            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
+            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams,
+            int userId) {
         if (!"file".equals(packageURI.getScheme())) {
             throw new UnsupportedOperationException("Only file:// URIs are supported");
         }
@@ -1398,17 +1413,22 @@
 
         final String originPath = packageURI.getPath();
         try {
-            mPM.installPackage(originPath, observer.getBinder(), flags, installerPackageName,
-                    verificationParams, null);
+            mPM.installPackageAsUser(originPath, observer.getBinder(), flags, installerPackageName,
+                    verificationParams, null, userId);
         } catch (RemoteException ignored) {
         }
     }
 
     @Override
-    public int installExistingPackage(String packageName)
+    public int installExistingPackage(String packageName) throws NameNotFoundException {
+        return installExistingPackageAsUser(packageName, UserHandle.myUserId());
+    }
+
+    @Override
+    public int installExistingPackageAsUser(String packageName, int userId)
             throws NameNotFoundException {
         try {
-            int res = mPM.installExistingPackageAsUser(packageName, UserHandle.myUserId());
+            int res = mPM.installExistingPackageAsUser(packageName, userId);
             if (res == INSTALL_FAILED_INVALID_URI) {
                 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
             }
@@ -1706,8 +1726,14 @@
 
     @Override
     public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
+        deletePackageAsUser(packageName, observer, flags, UserHandle.myUserId());
+    }
+
+    @Override
+    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags,
+            int userId) {
         try {
-            mPM.deletePackageAsUser(packageName, observer, UserHandle.myUserId(), flags);
+            mPM.deletePackageAsUser(packageName, observer, userId, flags);
         } catch (RemoteException e) {
             // Should never happen!
         }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index c8e9402..697b946 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2010,7 +2010,7 @@
      *            {@link #GET_RECEIVERS}, {@link #GET_SERVICES},
      *            {@link #GET_SIGNATURES}, {@link #GET_UNINSTALLED_PACKAGES} to
      *            modify the data returned.
-     * @return Returns a PackageInfo object containing information about the
+     * @return A PackageInfo object containing information about the
      *         package. If flag GET_UNINSTALLED_PACKAGES is set and if the
      *         package is not found in the list of installed applications, the
      *         package information is retrieved from the list of uninstalled
@@ -2032,6 +2032,46 @@
             throws NameNotFoundException;
 
     /**
+     * @hide
+     * Retrieve overall information about an application package that is
+     * installed on the system.
+     * <p>
+     * Throws {@link NameNotFoundException} if a package with the given name can
+     * not be found on the system.
+     *
+     * @param packageName The full name (i.e. com.google.apps.contacts) of the
+     *            desired package.
+     * @param flags Additional option flags. Use any combination of
+     *            {@link #GET_ACTIVITIES}, {@link #GET_GIDS},
+     *            {@link #GET_CONFIGURATIONS}, {@link #GET_INSTRUMENTATION},
+     *            {@link #GET_PERMISSIONS}, {@link #GET_PROVIDERS},
+     *            {@link #GET_RECEIVERS}, {@link #GET_SERVICES},
+     *            {@link #GET_SIGNATURES}, {@link #GET_UNINSTALLED_PACKAGES} to
+     *            modify the data returned.
+     * @param userId The user id.
+     * @return A PackageInfo object containing information about the
+     *         package. If flag GET_UNINSTALLED_PACKAGES is set and if the
+     *         package is not found in the list of installed applications, the
+     *         package information is retrieved from the list of uninstalled
+     *         applications (which includes installed applications as well as
+     *         applications with data directory i.e. applications which had been
+     *         deleted with {@code DONT_DELETE_DATA} flag set).
+     * @see #GET_ACTIVITIES
+     * @see #GET_GIDS
+     * @see #GET_CONFIGURATIONS
+     * @see #GET_INSTRUMENTATION
+     * @see #GET_PERMISSIONS
+     * @see #GET_PROVIDERS
+     * @see #GET_RECEIVERS
+     * @see #GET_SERVICES
+     * @see #GET_SIGNATURES
+     * @see #GET_UNINSTALLED_PACKAGES
+     */
+    @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
+    public abstract PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException;
+
+    /**
      * Map from the current package names in use on the device to whatever
      * the current canonical name of that package is.
      * @param names Array of current names to be mapped.
@@ -3689,6 +3729,31 @@
             Uri packageURI, PackageInstallObserver observer,
             int flags, String installerPackageName);
 
+
+    /**
+     * @hide
+     * Install a package. Since this may take a little while, the result will be
+     * posted back to the given observer. An installation will fail if the package named
+     * in the package file's manifest is already installed, or if there's no space
+     * available on the device.
+     * @param packageURI The location of the package file to install. This can be a 'file:' or a
+     * 'content:' URI.
+     * @param observer An observer callback to get notified when the package installation is
+     * complete. {@link PackageInstallObserver#packageInstalled(String, Bundle, int)} will be
+     * called when that happens. This parameter must not be null.
+     * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
+     * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
+     * @param installerPackageName Optional package name of the application that is performing the
+     * installation. This identifies which market the package came from.
+     * @param userId The user id.
+     */
+     @RequiresPermission(anyOf = {
+            Manifest.permission.INSTALL_PACKAGES,
+            Manifest.permission.INTERACT_ACROSS_USERS_FULL})
+    public abstract void installPackageAsUser(
+            Uri packageURI, PackageInstallObserver observer, int flags,
+            String installerPackageName, int userId);
+
     /**
      * Similar to
      * {@link #installPackage(Uri, IPackageInstallObserver, int, String)} but
@@ -3752,7 +3817,17 @@
      * @hide
      */
     // @SystemApi
-    public abstract int installExistingPackage(String packageName)
+    public abstract int installExistingPackage(String packageName) throws NameNotFoundException;
+
+    /**
+     * If there is already an application with the given package name installed
+     * on the system for other users, also install it for the specified user.
+     * @hide
+     */
+     @RequiresPermission(anyOf = {
+            Manifest.permission.INSTALL_PACKAGES,
+            Manifest.permission.INTERACT_ACROSS_USERS_FULL})
+    public abstract int installExistingPackageAsUser(String packageName, int userId)
             throws NameNotFoundException;
 
     /**
@@ -3958,7 +4033,7 @@
      * @param observer An observer callback to get notified when the package deletion is
      * complete. {@link android.content.pm.IPackageDeleteObserver#packageDeleted(boolean)} will be
      * called when that happens.  observer may be null to indicate that no callback is desired.
-     * @param flags - possible values: {@link #DELETE_KEEP_DATA},
+     * @param flags Possible values: {@link #DELETE_KEEP_DATA},
      * {@link #DELETE_ALL_USERS}.
      *
      * @hide
@@ -3968,6 +4043,27 @@
             String packageName, IPackageDeleteObserver observer, int flags);
 
     /**
+     * Attempts to delete a package.  Since this may take a little while, the result will
+     * be posted back to the given observer. A deletion will fail if the named package cannot be
+     * found, or if the named package is a "system package".
+     * (TODO: include pointer to documentation on "system packages")
+     *
+     * @param packageName The name of the package to delete
+     * @param observer An observer callback to get notified when the package deletion is
+     * complete. {@link android.content.pm.IPackageDeleteObserver#packageDeleted(boolean)} will be
+     * called when that happens.  observer may be null to indicate that no callback is desired.
+     * @param flags Possible values: {@link #DELETE_KEEP_DATA}, {@link #DELETE_ALL_USERS}.
+     * @param userId The user Id
+     *
+     * @hide
+     */
+     @RequiresPermission(anyOf = {
+            Manifest.permission.DELETE_PACKAGES,
+            Manifest.permission.INTERACT_ACROSS_USERS_FULL})
+    public abstract void deletePackageAsUser(
+            String packageName, IPackageDeleteObserver observer, int flags, int userId);
+
+    /**
      * Retrieve the package name of the application that installed a package. This identifies
      * which market the package came from.
      *
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 1ff621a..17c24af 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -63,8 +63,14 @@
 public class MockPackageManager extends PackageManager {
 
     @Override
-    public PackageInfo getPackageInfo(String packageName, int flags)
-    throws NameNotFoundException {
+    public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException {
         throw new UnsupportedOperationException();
     }
 
@@ -524,6 +530,14 @@
         throw new UnsupportedOperationException();
     }
 
+    /** @hide */
+    @Override
+    public void installPackageAsUser(Uri packageURI, PackageInstallObserver observer,
+            int flags, String installerPackageName, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+
     @Override
     public void setInstallerPackageName(String targetPackage,
             String installerPackageName) {
@@ -629,6 +643,15 @@
         throw new UnsupportedOperationException();
     }
 
+    /**
+     * @hide - to match hiding in superclass
+     */
+    @Override
+    public void deletePackageAsUser(
+            String packageName, IPackageDeleteObserver observer, int flags, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public void addPackageToPreferred(String packageName) {
         throw new UnsupportedOperationException();
@@ -792,7 +815,15 @@
      * @hide
      */
     @Override
-    public int installExistingPackage(String packageName)
+    public int installExistingPackage(String packageName) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int installExistingPackageAsUser(String packageName, int userId)
             throws NameNotFoundException {
         throw new UnsupportedOperationException();
     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
index f04654e..e3a19e7 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
@@ -65,6 +65,12 @@
     }
 
     @Override
+    public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
     public String[] currentToCanonicalPackageNames(String[] names) {
         return new String[0];
     }
@@ -499,6 +505,11 @@
     }
 
     @Override
+    public void installPackageAsUser(Uri packageURI, PackageInstallObserver observer,int flags,
+            String installerPackageName, int userId) {
+    }
+
+    @Override
     public void installPackageWithVerification(Uri packageURI, PackageInstallObserver observer,
             int flags, String installerPackageName, Uri verificationURI,
             ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
@@ -516,6 +527,12 @@
     }
 
     @Override
+    public int installExistingPackageAsUser(String packageName, int userId)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
     public void verifyPendingInstall(int id, int verificationCode) {
     }
 
@@ -568,6 +585,11 @@
     }
 
     @Override
+    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags,
+            int userId) {
+    }
+
+    @Override
     public String getInstallerPackageName(String packageName) {
         return null;
     }