diff options
| -rw-r--r-- | api/current.txt | 3 | ||||
| -rw-r--r-- | api/system-current.txt | 3 | ||||
| -rw-r--r-- | api/test-current.txt | 3 | ||||
| -rw-r--r-- | core/java/android/app/admin/DevicePolicyManager.java | 170 | ||||
| -rw-r--r-- | core/java/android/app/admin/IDevicePolicyManager.aidl | 22 | ||||
| -rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 104 |
6 files changed, 211 insertions, 94 deletions
diff --git a/api/current.txt b/api/current.txt index c1cb89a23c15..95382530e933 100644 --- a/api/current.txt +++ b/api/current.txt @@ -6274,6 +6274,9 @@ package android.app.admin { field public static final java.lang.String DELEGATION_APP_RESTRICTIONS = "delegation-app-restrictions"; 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_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 field public static final int ENCRYPTION_STATUS_ACTIVE = 3; // 0x3 field public static final int ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY = 4; // 0x4 diff --git a/api/system-current.txt b/api/system-current.txt index cd579650bdea..c649c237df1a 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -6492,6 +6492,9 @@ package android.app.admin { field public static final java.lang.String DELEGATION_APP_RESTRICTIONS = "delegation-app-restrictions"; 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_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 field public static final int ENCRYPTION_STATUS_ACTIVE = 3; // 0x3 field public static final int ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY = 4; // 0x4 diff --git a/api/test-current.txt b/api/test-current.txt index a4218c6a6333..ab421ceca1f8 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -6296,6 +6296,9 @@ package android.app.admin { field public static final java.lang.String DELEGATION_APP_RESTRICTIONS = "delegation-app-restrictions"; 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_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 field public static final int ENCRYPTION_STATUS_ACTIVE = 3; // 0x3 field public static final int ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY = 4; // 0x4 diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index abab6bf0eb14..72daade21441 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -1230,6 +1230,34 @@ public class DevicePolicyManager { public static final String DELEGATION_BLOCK_UNINSTALL = "delegation-block-uninstall"; /** + * Delegation of permission policy and permission grant state. This scope grants access to the + * {@link #setPermissionPolicy}, {@link #getPermissionGrantState}, + * and {@link #setPermissionGrantState} APIs. + */ + public static final String DELEGATION_PERMISSION_GRANT = "delegation-permission-grant"; + + /** + * Delegation of package access state. This scope grants access to the + * {@link #isApplicationHidden}, {@link #setApplicationHidden}, {@link #isPackageSuspended}, and + * {@link #setPackagesSuspended} APIs. + */ + public static final String DELEGATION_PACKAGE_ACCESS = "delegation-package-access"; + + /** + * Delegation for enabling system apps. This scope grants access to the {@link #enableSystemApp} + * API. + */ + public static final String DELEGATION_ENABLE_SYSTEM_APP = "delegation-enable-system-app"; + + /** + * 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"; + + /** * No management for current user in-effect. This is the default. * @hide */ @@ -4573,7 +4601,9 @@ public class DevicePolicyManager { } /** - * Called by device or profile owners to suspend packages for this user. + * Called by device or profile owners to suspend packages for this user. This function can be + * called by a device owner, profile owner, or by a delegate given the + * {@link #DELEGATION_PACKAGE_ACCESS} scope via {@link #setDelegatedScopes}. * <p> * A suspended package will not be able to start activities. Its notifications will be hidden, * it will not show up in recents, will not be able to show toasts or dialogs or ring the @@ -4583,20 +4613,24 @@ public class DevicePolicyManager { * package will no longer be suspended. The admin can block this by using * {@link #setUninstallBlocked}. * - * @param admin The name of the admin component to check. + * @param admin The name of the admin component to check, or {@code null} if the caller is a + * package access delegate. * @param packageNames The package names to suspend or unsuspend. * @param suspended If set to {@code true} than the packages will be suspended, if set to * {@code false} the packages will be unsuspended. * @return an array of package names for which the suspended status is not set as requested in * this method. * @throws SecurityException if {@code admin} is not a device or profile owner. + * @see #setDelegatedScopes + * @see #DELEGATION_PACKAGE_ACCESS */ public @NonNull String[] setPackagesSuspended(@NonNull ComponentName admin, @NonNull String[] packageNames, boolean suspended) { throwIfParentInstance("setPackagesSuspended"); if (mService != null) { try { - return mService.setPackagesSuspended(admin, packageNames, suspended); + return mService.setPackagesSuspended(admin, mContext.getPackageName(), packageNames, + suspended); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } @@ -4605,21 +4639,26 @@ public class DevicePolicyManager { } /** - * Called by device or profile owners to determine if a package is suspended. + * Determine if a package is suspended. This function can be called by a device owner, profile + * owner, or by a delegate given the {@link #DELEGATION_PACKAGE_ACCESS} scope via + * {@link #setDelegatedScopes}. * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or + * {@code null} if the caller is a package access delegate. * @param packageName The name of the package to retrieve the suspended status of. * @return {@code true} if the package is suspended or {@code false} if the package is not * suspended, could not be found or an error occurred. * @throws SecurityException if {@code admin} is not a device or profile owner. * @throws NameNotFoundException if the package could not be found. + * @see #setDelegatedScopes + * @see #DELEGATION_PACKAGE_ACCESS */ public boolean isPackageSuspended(@NonNull ComponentName admin, String packageName) throws NameNotFoundException { throwIfParentInstance("isPackageSuspended"); if (mService != null) { try { - return mService.isPackageSuspended(admin, packageName); + return mService.isPackageSuspended(admin, mContext.getPackageName(), packageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } catch (IllegalArgumentException ex) { @@ -5489,19 +5528,24 @@ public class DevicePolicyManager { } /** - * Called by a device owner to get the list of apps to keep around as APKs even if no user has - * currently installed it. - * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * Get the list of apps to keep around as APKs even if no user has currently installed it. This + * function can be called by a device owner or by a delegate given the + * {@link #DELEGATION_KEEP_UNINSTALLED_PACKAGES} scope via {@link #setDelegatedScopes}. + * <p> + * Please note that packages returned in this method are not automatically pre-cached. * + * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or + * {@code null} if the caller is a keep uninstalled packages delegate. * @return List of package names to keep cached. + * @see #setDelegatedScopes + * @see #DELEGATION_KEEP_UNINSTALLED_PACKAGES * @hide */ - public @Nullable List<String> getKeepUninstalledPackages(@NonNull ComponentName admin) { + public @Nullable List<String> getKeepUninstalledPackages(@Nullable ComponentName admin) { throwIfParentInstance("getKeepUninstalledPackages"); if (mService != null) { try { - return mService.getKeepUninstalledPackages(admin); + return mService.getKeepUninstalledPackages(admin, mContext.getPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5510,23 +5554,27 @@ public class DevicePolicyManager { } /** - * Called by a device owner to set a list of apps to keep around as APKs even if no user has - * currently installed it. + * Set a list of apps to keep around as APKs even if no user has currently installed it. This + * function can be called by a device owner or by a delegate given the + * {@link #DELEGATION_KEEP_UNINSTALLED_PACKAGES} scope via {@link #setDelegatedScopes}. * * <p>Please note that setting this policy does not imply that specified apps will be * automatically pre-cached.</p> * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or + * {@code null} if the caller is a keep uninstalled packages delegate. * @param packageNames List of package names to keep cached. * @throws SecurityException if {@code admin} is not a device owner. + * @see #setDelegatedScopes + * @see #DELEGATION_KEEP_UNINSTALLED_PACKAGES * @hide */ - public void setKeepUninstalledPackages(@NonNull ComponentName admin, + public void setKeepUninstalledPackages(@Nullable ComponentName admin, @NonNull List<String> packageNames) { throwIfParentInstance("setKeepUninstalledPackages"); if (mService != null) { try { - mService.setKeepUninstalledPackages(admin, packageNames); + mService.setKeepUninstalledPackages(admin, mContext.getPackageName(), packageNames); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5779,22 +5827,28 @@ public class DevicePolicyManager { } /** - * Called by profile or device owners to hide or unhide packages. When a package is hidden it is - * unavailable for use, but the data and actual package file remain. + * Hide or unhide packages. When a package is hidden it is unavailable for use, but the data and + * actual package file remain. This function can be called by a device owner, profile owner, or + * by a delegate given the {@link #DELEGATION_PACKAGE_ACCESS} scope via + * {@link #setDelegatedScopes}. * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or + * {@code null} if the caller is a package access delegate. * @param packageName The name of the package to hide or unhide. * @param hidden {@code true} if the package should be hidden, {@code false} if it should be * unhidden. * @return boolean Whether the hidden setting of the package was successfully updated. * @throws SecurityException if {@code admin} is not a device or profile owner. + * @see #setDelegatedScopes + * @see #DELEGATION_PACKAGE_ACCESS */ public boolean setApplicationHidden(@NonNull ComponentName admin, String packageName, boolean hidden) { throwIfParentInstance("setApplicationHidden"); if (mService != null) { try { - return mService.setApplicationHidden(admin, packageName, hidden); + return mService.setApplicationHidden(admin, mContext.getPackageName(), packageName, + hidden); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5803,18 +5857,23 @@ public class DevicePolicyManager { } /** - * Called by profile or device owners to determine if a package is hidden. + * Determine if a package is hidden. This function can be called by a device owner, profile + * owner, or by a delegate given the {@link #DELEGATION_PACKAGE_ACCESS} scope via + * {@link #setDelegatedScopes}. * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or + * {@code null} if the caller is a package access delegate. * @param packageName The name of the package to retrieve the hidden status of. * @return boolean {@code true} if the package is hidden, {@code false} otherwise. * @throws SecurityException if {@code admin} is not a device or profile owner. + * @see #setDelegatedScopes + * @see #DELEGATION_PACKAGE_ACCESS */ public boolean isApplicationHidden(@NonNull ComponentName admin, String packageName) { throwIfParentInstance("isApplicationHidden"); if (mService != null) { try { - return mService.isApplicationHidden(admin, packageName); + return mService.isApplicationHidden(admin, mContext.getPackageName(), packageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5823,18 +5882,22 @@ public class DevicePolicyManager { } /** - * Called by profile or device owners to re-enable a system app that was disabled by default - * when the user was initialized. + * Re-enable a system app that was disabled by default when the user was initialized. This + * function can be called by a device owner, profile owner, or by a delegate given the + * {@link #DELEGATION_ENABLE_SYSTEM_APP} scope via {@link #setDelegatedScopes}. * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or + * {@code null} if the caller is an enable system app delegate. * @param packageName The package to be re-enabled in the calling profile. * @throws SecurityException if {@code admin} is not a device or profile owner. + * @see #setDelegatedScopes + * @see #DELEGATION_PACKAGE_ACCESS */ public void enableSystemApp(@NonNull ComponentName admin, String packageName) { throwIfParentInstance("enableSystemApp"); if (mService != null) { try { - mService.enableSystemApp(admin, packageName); + mService.enableSystemApp(admin, mContext.getPackageName(), packageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5842,20 +5905,24 @@ public class DevicePolicyManager { } /** - * Called by profile or device owners to re-enable system apps by intent that were disabled by - * default when the user was initialized. + * Re-enable system apps by intent that were disabled by default when the user was initialized. + * This function can be called by a device owner, profile owner, or by a delegate given the + * {@link #DELEGATION_ENABLE_SYSTEM_APP} scope via {@link #setDelegatedScopes}. * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or + * {@code null} if the caller is an enable system app delegate. * @param intent An intent matching the app(s) to be installed. All apps that resolve for this * intent will be re-enabled in the calling profile. * @return int The number of activities that matched the intent and were installed. * @throws SecurityException if {@code admin} is not a device or profile owner. + * @see #setDelegatedScopes + * @see #DELEGATION_PACKAGE_ACCESS */ public int enableSystemApp(@NonNull ComponentName admin, Intent intent) { throwIfParentInstance("enableSystemApp"); if (mService != null) { try { - return mService.enableSystemAppWithIntent(admin, intent); + return mService.enableSystemAppWithIntent(admin, mContext.getPackageName(), intent); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -6437,12 +6504,14 @@ public class DevicePolicyManager { } /** - * Called by profile or device owners to set the default response for future runtime permission - * requests by applications. The policy can allow for normal operation which prompts the user to - * grant a permission, or can allow automatic granting or denying of runtime permission requests - * by an application. This also applies to new permissions declared by app updates. When a - * permission is denied or granted this way, the effect is equivalent to setting the permission - * grant state via {@link #setPermissionGrantState}. + * Set the default response for future runtime permission requests by applications. This + * function can be called by a device owner, profile owner, or by a delegate given the + * {@link #DELEGATION_PERMISSION_GRANT} scope via {@link #setDelegatedScopes}. + * The policy can allow for normal operation which prompts the user to grant a permission, or + * can allow automatic granting or denying of runtime permission requests by an application. + * This also applies to new permissions declared by app updates. When a permission is denied or + * granted this way, the effect is equivalent to setting the permission * grant state via + * {@link #setPermissionGrantState}. * <p/> * As this policy only acts on runtime permission requests, it only applies to applications * built with a {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#M} or later. @@ -6452,11 +6521,13 @@ public class DevicePolicyManager { * {@link #PERMISSION_POLICY_AUTO_GRANT} and {@link #PERMISSION_POLICY_AUTO_DENY}. * @throws SecurityException if {@code admin} is not a device or profile owner. * @see #setPermissionGrantState + * @see #setDelegatedScopes + * @see #DELEGATION_PERMISSION_GRANT */ public void setPermissionPolicy(@NonNull ComponentName admin, int policy) { throwIfParentInstance("setPermissionPolicy"); try { - mService.setPermissionPolicy(admin, policy); + mService.setPermissionPolicy(admin, mContext.getPackageName(), policy); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } @@ -6465,6 +6536,7 @@ public class DevicePolicyManager { /** * Returns the current runtime permission policy set by the device or profile owner. The * default is {@link #PERMISSION_POLICY_PROMPT}. + * * @param admin Which profile or device owner this request is associated with. * @return the current policy for future permission requests. */ @@ -6484,7 +6556,8 @@ public class DevicePolicyManager { * cannot manage it through the UI, and {@link #PERMISSION_GRANT_STATE_GRANTED granted} in which * the permission is granted and the user cannot manage it through the UI. This might affect all * permissions in a group that the runtime permission belongs to. This method can only be called - * by a profile or device owner. + * by a profile owner, device owner, or a delegate given the + * {@link #DELEGATION_PERMISSION_GRANT} scope via {@link #setDelegatedScopes}. * <p/> * Setting the grant state to {@link #PERMISSION_GRANT_STATE_DEFAULT default} does not revoke * the permission. It retains the previous grant, if any. @@ -6503,21 +6576,27 @@ public class DevicePolicyManager { * @see #PERMISSION_GRANT_STATE_DENIED * @see #PERMISSION_GRANT_STATE_DEFAULT * @see #PERMISSION_GRANT_STATE_GRANTED + * @see #setDelegatedScopes + * @see #DELEGATION_PERMISSION_GRANT */ public boolean setPermissionGrantState(@NonNull ComponentName admin, String packageName, String permission, int grantState) { throwIfParentInstance("setPermissionGrantState"); try { - return mService.setPermissionGrantState(admin, packageName, permission, grantState); + return mService.setPermissionGrantState(admin, mContext.getPackageName(), packageName, + permission, grantState); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } /** - * Returns the current grant state of a runtime permission for a specific application. + * Returns the current grant state of a runtime permission for a specific application. This + * function can be called by a device owner, profile owner, or by a delegate given the + * {@link #DELEGATION_PERMISSION_GRANT} scope via {@link #setDelegatedScopes}. * - * @param admin Which profile or device owner this request is associated with. + * @param admin Which profile or device owner this request is associated with, or {@code null} + * if the caller is a permission grant delegate. * @param packageName The application to check the grant state for. * @param permission The permission to check for. * @return the current grant state specified by device policy. If the profile or device owner @@ -6532,12 +6611,15 @@ public class DevicePolicyManager { * @throws SecurityException if {@code admin} is not a device or profile owner. * @see #setPermissionGrantState(ComponentName, String, String, int) * @see PackageManager#checkPermission(String, String) + * @see #setDelegatedScopes + * @see #DELEGATION_PERMISSION_GRANT */ public int getPermissionGrantState(@Nullable ComponentName admin, String packageName, String permission) { throwIfParentInstance("getPermissionGrantState"); try { - return mService.getPermissionGrantState(admin, packageName, permission); + return mService.getPermissionGrantState(admin, mContext.getPackageName(), packageName, + permission); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 7e04016d9c21..7604af83e089 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -150,8 +150,8 @@ interface IDevicePolicyManager { void setDeviceOwnerLockScreenInfo(in ComponentName who, CharSequence deviceOwnerInfo); CharSequence getDeviceOwnerLockScreenInfo(); - String[] setPackagesSuspended(in ComponentName admin, in String[] packageNames, boolean suspended); - boolean isPackageSuspended(in ComponentName admin, String packageName); + String[] setPackagesSuspended(in ComponentName admin, in String callerPackage, in String[] packageNames, boolean suspended); + boolean isPackageSuspended(in ComponentName admin, in String callerPackage, String packageName); boolean installCaCert(in ComponentName admin, String callerPackage, in byte[] certBuffer); void uninstallCaCerts(in ComponentName admin, String callerPackage, in String[] aliases); @@ -201,15 +201,15 @@ interface IDevicePolicyManager { List getPermittedInputMethodsForCurrentUser(); boolean isInputMethodPermittedByAdmin(in ComponentName admin, String packageName, int userId); - boolean setApplicationHidden(in ComponentName admin, in String packageName, boolean hidden); - boolean isApplicationHidden(in ComponentName admin, in String packageName); + boolean setApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName, boolean hidden); + boolean isApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName); UserHandle createAndManageUser(in ComponentName who, in String name, in ComponentName profileOwner, in PersistableBundle adminExtras, in int flags); boolean removeUser(in ComponentName who, in UserHandle userHandle); boolean switchUser(in ComponentName who, in UserHandle userHandle); - void enableSystemApp(in ComponentName admin, in String packageName); - int enableSystemAppWithIntent(in ComponentName admin, in Intent intent); + void enableSystemApp(in ComponentName admin, in String callerPackage, in String packageName); + int enableSystemAppWithIntent(in ComponentName admin, in String callerPackage, in Intent intent); void setAccountManagementDisabled(in ComponentName who, in String accountType, in boolean disabled); String[] getAccountTypesWithManagementDisabled(); @@ -271,15 +271,15 @@ interface IDevicePolicyManager { void notifyPendingSystemUpdate(in SystemUpdateInfo info); SystemUpdateInfo getPendingSystemUpdate(in ComponentName admin); - void setPermissionPolicy(in ComponentName admin, int policy); + void setPermissionPolicy(in ComponentName admin, in String callerPackage, int policy); int getPermissionPolicy(in ComponentName admin); - boolean setPermissionGrantState(in ComponentName admin, String packageName, + boolean setPermissionGrantState(in ComponentName admin, in String callerPackage, String packageName, String permission, int grantState); - int getPermissionGrantState(in ComponentName admin, String packageName, String permission); + int getPermissionGrantState(in ComponentName admin, in String callerPackage, String packageName, String permission); boolean isProvisioningAllowed(String action, String packageName); int checkProvisioningPreCondition(String action, String packageName); - void setKeepUninstalledPackages(in ComponentName admin,in List<String> packageList); - List<String> getKeepUninstalledPackages(in ComponentName admin); + void setKeepUninstalledPackages(in ComponentName admin, in String callerPackage, in List<String> packageList); + List<String> getKeepUninstalledPackages(in ComponentName admin, in String callerPackage); boolean isManagedProfile(in ComponentName admin); boolean isSystemOnlyUser(in ComponentName admin); String getWifiMacAddress(in ComponentName admin); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 587b032cc17b..3082e8bf51b5 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -36,6 +36,10 @@ import static android.app.admin.DevicePolicyManager.CODE_USER_SETUP_COMPLETED; 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_KEEP_UNINSTALLED_PACKAGES; +import static android.app.admin.DevicePolicyManager.DELEGATION_PACKAGE_ACCESS; +import static android.app.admin.DevicePolicyManager.DELEGATION_PERMISSION_GRANT; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE; import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA; @@ -266,7 +270,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final String DELEGATIONS[] = { DELEGATION_CERT_INSTALL, DELEGATION_APP_RESTRICTIONS, - DELEGATION_BLOCK_UNINSTALL + DELEGATION_BLOCK_UNINSTALL, + DELEGATION_ENABLE_SYSTEM_APP, + DELEGATION_KEEP_UNINSTALLED_PACKAGES, + DELEGATION_PACKAGE_ACCESS, + DELEGATION_PERMISSION_GRANT }; /** @@ -6287,32 +6295,38 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public void setKeepUninstalledPackages(ComponentName who, List<String> packageList) { + public void setKeepUninstalledPackages(ComponentName who, String callerPackage, + List<String> packageList) { if (!mHasFeature) { return; } - Preconditions.checkNotNull(who, "ComponentName is null"); Preconditions.checkNotNull(packageList, "packageList is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - ActiveAdmin admin = getActiveAdminForCallerLocked(who, - DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); - admin.keepUninstalledPackages = packageList; + // Ensure the caller is a DO or a keep uninstalled packages delegate. + enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER, + DELEGATION_KEEP_UNINSTALLED_PACKAGES); + // Get the device owner + ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); + // Set list of packages to be kept even if uninstalled. + deviceOwner.keepUninstalledPackages = packageList; + // Save settings. saveSettingsLocked(userHandle); + // Notify package manager. mInjector.getPackageManagerInternal().setKeepUninstalledPackages(packageList); } } @Override - public List<String> getKeepUninstalledPackages(ComponentName who) { - Preconditions.checkNotNull(who, "ComponentName is null"); + public List<String> getKeepUninstalledPackages(ComponentName who, String callerPackage) { if (!mHasFeature) { return null; } // TODO In split system user mode, allow apps on user 0 to query the list synchronized (this) { - // Check if this is the device owner who is calling - getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); + // Ensure the caller is a DO or a keep uninstalled packages delegate. + enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER, + DELEGATION_KEEP_UNINSTALLED_PACKAGES); return getKeepUninstalledPackagesLocked(); } } @@ -7987,12 +8001,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public String[] setPackagesSuspended(ComponentName who, String[] packageNames, - boolean suspended) { - Preconditions.checkNotNull(who, "ComponentName is null"); + public String[] setPackagesSuspended(ComponentName who, String callerPackage, + String[] packageNames, boolean suspended) { int callingUserId = UserHandle.getCallingUserId(); synchronized (this) { - getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + // Ensure the caller is a DO/PO or a package access delegate. + enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, + DELEGATION_PACKAGE_ACCESS); long id = mInjector.binderClearCallingIdentity(); try { @@ -8009,10 +8024,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public boolean isPackageSuspended(ComponentName who, String packageName) { - Preconditions.checkNotNull(who, "ComponentName is null"); + public boolean isPackageSuspended(ComponentName who, String callerPackage, String packageName) { int callingUserId = UserHandle.getCallingUserId(); synchronized (this) { + // Ensure the caller is a DO/PO or a package access delegate. + enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, + DELEGATION_PACKAGE_ACCESS); getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); long id = mInjector.binderClearCallingIdentity(); @@ -8124,12 +8141,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public boolean setApplicationHidden(ComponentName who, String packageName, + public boolean setApplicationHidden(ComponentName who, String callerPackage, String packageName, boolean hidden) { - Preconditions.checkNotNull(who, "ComponentName is null"); int callingUserId = UserHandle.getCallingUserId(); synchronized (this) { - getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + // Ensure the caller is a DO/PO or a package access delegate. + enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, + DELEGATION_PACKAGE_ACCESS); long id = mInjector.binderClearCallingIdentity(); try { @@ -8146,11 +8164,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public boolean isApplicationHidden(ComponentName who, String packageName) { - Preconditions.checkNotNull(who, "ComponentName is null"); + public boolean isApplicationHidden(ComponentName who, String callerPackage, + String packageName) { int callingUserId = UserHandle.getCallingUserId(); synchronized (this) { - getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + // Ensure the caller is a DO/PO or a package access delegate. + enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, + DELEGATION_PACKAGE_ACCESS); long id = mInjector.binderClearCallingIdentity(); try { @@ -8167,12 +8187,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public void enableSystemApp(ComponentName who, String packageName) { - Preconditions.checkNotNull(who, "ComponentName is null"); + public void enableSystemApp(ComponentName who, String callerPackage, String packageName) { synchronized (this) { - // This API can only be called by an active device admin, - // so try to retrieve it to check that the caller is one. - getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + // Ensure the caller is a DO/PO or an enable system app delegate. + enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, + DELEGATION_ENABLE_SYSTEM_APP); int userId = UserHandle.getCallingUserId(); long id = mInjector.binderClearCallingIdentity(); @@ -8202,12 +8221,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public int enableSystemAppWithIntent(ComponentName who, Intent intent) { - Preconditions.checkNotNull(who, "ComponentName is null"); + public int enableSystemAppWithIntent(ComponentName who, String callerPackage, Intent intent) { synchronized (this) { - // This API can only be called by an active device admin, - // so try to retrieve it to check that the caller is one. - getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + // Ensure the caller is a DO/PO or an enable system app delegate. + enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, + DELEGATION_ENABLE_SYSTEM_APP); int userId = UserHandle.getCallingUserId(); long id = mInjector.binderClearCallingIdentity(); @@ -9139,10 +9157,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public void setPermissionPolicy(ComponentName admin, int policy) throws RemoteException { + public void setPermissionPolicy(ComponentName admin, String callerPackage, int policy) + throws RemoteException { int userId = UserHandle.getCallingUserId(); synchronized (this) { - getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + // Ensure the caller is a DO/PO or a permission grant state delegate. + enforceCanManageScope(admin, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, + DELEGATION_PERMISSION_GRANT); DevicePolicyData userPolicy = getUserData(userId); if (userPolicy.mPermissionPolicy != policy) { userPolicy.mPermissionPolicy = policy; @@ -9161,11 +9182,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public boolean setPermissionGrantState(ComponentName admin, String packageName, - String permission, int grantState) throws RemoteException { + public boolean setPermissionGrantState(ComponentName admin, String callerPackage, + String packageName, String permission, int grantState) throws RemoteException { UserHandle user = mInjector.binderGetCallingUserHandle(); synchronized (this) { - getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + // Ensure the caller is a DO/PO or a permission grant state delegate. + enforceCanManageScope(admin, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, + DELEGATION_PERMISSION_GRANT); long ident = mInjector.binderClearCallingIdentity(); try { if (getTargetSdk(packageName, user.getIdentifier()) @@ -9205,13 +9228,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public int getPermissionGrantState(ComponentName admin, String packageName, - String permission) throws RemoteException { + public int getPermissionGrantState(ComponentName admin, String callerPackage, + String packageName, String permission) throws RemoteException { PackageManager packageManager = mInjector.getPackageManager(); UserHandle user = mInjector.binderGetCallingUserHandle(); enforceProfileOwnerOrSystemUser(admin); synchronized (this) { + // Ensure the caller is a DO/PO or a permission grant state delegate. + enforceCanManageScope(admin, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, + DELEGATION_PERMISSION_GRANT); long ident = mInjector.binderClearCallingIdentity(); try { int granted = mIPackageManager.checkPermission(permission, |