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