summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2017-12-11 22:21:12 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-12-11 22:21:12 +0000
commit8c919fd93cc35db80d77a68092458e1405ba8ccf (patch)
tree151d6cc6a99a5647edd81c01d96bf53831baa494
parentf413d90f0db3838659e7461c50e1da8907ac2d11 (diff)
parent5343fcb77df55d01655c9f7bad074c9c7b75ea72 (diff)
Merge "Introduce API to enable existing packages on shared users"
-rw-r--r--api/current.txt5
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java41
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl1
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java38
4 files changed, 81 insertions, 4 deletions
diff --git a/api/current.txt b/api/current.txt
index eec7b5387886..05b2a0c6a4fb 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6344,6 +6344,7 @@ package android.app.admin {
method public java.util.List<java.lang.String> getDelegatedScopes(android.content.ComponentName, java.lang.String);
method public java.lang.CharSequence getDeviceOwnerLockScreenInfo();
method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName);
+ method public java.util.List<java.lang.String> getKeepUninstalledPackages(android.content.ComponentName);
method public int getKeyguardDisabledFeatures(android.content.ComponentName);
method public int getLockTaskFeatures(android.content.ComponentName);
method public java.lang.String[] getLockTaskPackages(android.content.ComponentName);
@@ -6384,6 +6385,7 @@ package android.app.admin {
method public boolean hasCaCertInstalled(android.content.ComponentName, byte[]);
method public boolean hasGrantedPolicy(android.content.ComponentName, int);
method public boolean installCaCert(android.content.ComponentName, byte[]);
+ method public boolean installExistingPackage(android.content.ComponentName, java.lang.String);
method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String);
method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean);
method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean, boolean);
@@ -6434,6 +6436,7 @@ package android.app.admin {
method public void setDelegatedScopes(android.content.ComponentName, java.lang.String, java.util.List<java.lang.String>);
method public void setDeviceOwnerLockScreenInfo(android.content.ComponentName, java.lang.CharSequence);
method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
+ method public void setKeepUninstalledPackages(android.content.ComponentName, java.util.List<java.lang.String>);
method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
method public void setLockTaskFeatures(android.content.ComponentName, int);
@@ -6503,6 +6506,8 @@ package android.app.admin {
field public static final java.lang.String DELEGATION_BLOCK_UNINSTALL = "delegation-block-uninstall";
field public static final java.lang.String DELEGATION_CERT_INSTALL = "delegation-cert-install";
field public static final java.lang.String DELEGATION_ENABLE_SYSTEM_APP = "delegation-enable-system-app";
+ field public static final java.lang.String DELEGATION_INSTALL_EXISTING_PACKAGE = "delegation-install-existing-package";
+ field public static final java.lang.String DELEGATION_KEEP_UNINSTALLED_PACKAGES = "delegation-keep-uninstalled-packages";
field public static final java.lang.String DELEGATION_PACKAGE_ACCESS = "delegation-package-access";
field public static final java.lang.String DELEGATION_PERMISSION_GRANT = "delegation-permission-grant";
field public static final int ENCRYPTION_STATUS_ACTIVATING = 2; // 0x2
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ad219837fdf5..34cd67e455ce 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1321,9 +1321,15 @@ public class DevicePolicyManager {
public static final String DELEGATION_ENABLE_SYSTEM_APP = "delegation-enable-system-app";
/**
+ * Delegation for installing existing packages. This scope grants access to the
+ * {@link #installExistingPackage} API.
+ */
+ public static final String DELEGATION_INSTALL_EXISTING_PACKAGE =
+ "delegation-install-existing-package";
+
+ /**
* Delegation of management of uninstalled packages. This scope grants access to the
* {@code #setKeepUninstalledPackages} and {@code #getKeepUninstalledPackages} APIs.
- * @hide
*/
public static final String DELEGATION_KEEP_UNINSTALLED_PACKAGES =
"delegation-keep-uninstalled-packages";
@@ -6085,7 +6091,6 @@ public class DevicePolicyManager {
* @return List of package names to keep cached.
* @see #setDelegatedScopes
* @see #DELEGATION_KEEP_UNINSTALLED_PACKAGES
- * @hide
*/
public @Nullable List<String> getKeepUninstalledPackages(@Nullable ComponentName admin) {
throwIfParentInstance("getKeepUninstalledPackages");
@@ -6113,7 +6118,6 @@ public class DevicePolicyManager {
* @throws SecurityException if {@code admin} is not a device owner.
* @see #setDelegatedScopes
* @see #DELEGATION_KEEP_UNINSTALLED_PACKAGES
- * @hide
*/
public void setKeepUninstalledPackages(@Nullable ComponentName admin,
@NonNull List<String> packageNames) {
@@ -6591,6 +6595,37 @@ public class DevicePolicyManager {
}
/**
+ * Install an existing package that has been installed in another user, or has been kept after
+ * removal via {@link #setKeepUninstalledPackages}.
+ * This function can be called by a device owner, profile owner or a delegate given
+ * the {@link #DELEGATION_INSTALL_EXISTING_PACKAGE} scope via {@link #setDelegatedScopes}.
+ * When called in a secondary user or managed profile, the user/profile must be affiliated with
+ * the device owner. See {@link #setAffiliationIds}.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param packageName The package to be installed in the calling profile.
+ * @return {@code true} if the app is installed; {@code false} otherwise.
+ * @throws SecurityException if {@code admin} is not the device owner, or the profile owner of
+ * an affiliated user or profile.
+ * @see #setKeepUninstalledPackages
+ * @see #setDelegatedScopes
+ * @see #setAffiliationIds
+ * @see #DELEGATION_PACKAGE_ACCESS
+ */
+ public boolean installExistingPackage(@NonNull ComponentName admin, String packageName) {
+ throwIfParentInstance("installExistingPackage");
+ if (mService != null) {
+ try {
+ return mService.installExistingPackage(admin, mContext.getPackageName(),
+ packageName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ return false;
+ }
+
+ /**
* Called by a device owner or profile owner to disable account management for a specific type
* of account.
* <p>
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index ff869d247d9a..81da197f2129 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -223,6 +223,7 @@ interface IDevicePolicyManager {
void enableSystemApp(in ComponentName admin, in String callerPackage, in String packageName);
int enableSystemAppWithIntent(in ComponentName admin, in String callerPackage, in Intent intent);
+ boolean installExistingPackage(in ComponentName admin, in String callerPackage, in String packageName);
void setAccountManagementDisabled(in ComponentName who, in String accountType, in boolean disabled);
String[] getAccountTypesWithManagementDisabled();
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 91ba87e84005..b946122019f9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -40,6 +40,7 @@ import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS;
import static android.app.admin.DevicePolicyManager.DELEGATION_BLOCK_UNINSTALL;
import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL;
import static android.app.admin.DevicePolicyManager.DELEGATION_ENABLE_SYSTEM_APP;
+import static android.app.admin.DevicePolicyManager.DELEGATION_INSTALL_EXISTING_PACKAGE;
import static android.app.admin.DevicePolicyManager.DELEGATION_KEEP_UNINSTALLED_PACKAGES;
import static android.app.admin.DevicePolicyManager.DELEGATION_PACKAGE_ACCESS;
import static android.app.admin.DevicePolicyManager.DELEGATION_PERMISSION_GRANT;
@@ -296,7 +297,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
DELEGATION_ENABLE_SYSTEM_APP,
DELEGATION_KEEP_UNINSTALLED_PACKAGES,
DELEGATION_PACKAGE_ACCESS,
- DELEGATION_PERMISSION_GRANT
+ DELEGATION_PERMISSION_GRANT,
+ DELEGATION_INSTALL_EXISTING_PACKAGE,
+ DELEGATION_KEEP_UNINSTALLED_PACKAGES
};
/**
@@ -8843,6 +8846,39 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
@Override
+ public boolean installExistingPackage(ComponentName who, String callerPackage,
+ String packageName) {
+ synchronized (this) {
+ // Ensure the caller is a PO or an install existing package delegate
+ enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER,
+ DELEGATION_INSTALL_EXISTING_PACKAGE);
+ final int callingUserId = mInjector.userHandleGetCallingUserId();
+ if (!isUserAffiliatedWithDeviceLocked(callingUserId)) {
+ throw new SecurityException("Admin " + who +
+ " is neither the device owner or affiliated user's profile owner.");
+ }
+
+ final long id = mInjector.binderClearCallingIdentity();
+ try {
+ if (VERBOSE_LOG) {
+ Slog.v(LOG_TAG, "installing " + packageName + " for "
+ + callingUserId);
+ }
+
+ // Install the package.
+ return mIPackageManager.installExistingPackageAsUser(packageName, callingUserId,
+ 0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY)
+ == PackageManager.INSTALL_SUCCEEDED;
+ } catch (RemoteException re) {
+ // shouldn't happen
+ return false;
+ } finally {
+ mInjector.binderRestoreCallingIdentity(id);
+ }
+ }
+ }
+
+ @Override
public void setAccountManagementDisabled(ComponentName who, String accountType,
boolean disabled) {
if (!mHasFeature) {