From dd1a75b57dc2423203a67976dfdc7ff2a71aca82 Mon Sep 17 00:00:00 2001 From: Jonathan Scott Date: Mon, 13 Feb 2023 15:50:29 +0000 Subject: [PATCH] Add DPM Permissions 3. Test: btest a.d.c.PermitInputMethodsTest Test: btest a.d.c.KeyguardTest Test: btest a.d.c.LockTest Test: btest a.d.c.FactoryResetTest Bug: 234609037 Change-Id: Id6a35acb9e88fcff44772011e41d63baa8ec8e31 --- core/api/current.txt | 18 +- .../app/admin/DevicePolicyManager.java | 137 ++++++--- .../app/admin/IDevicePolicyManager.aidl | 14 +- .../DevicePolicyManagerService.java | 290 +++++++++++++----- 4 files changed, 320 insertions(+), 139 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index d7460b326160e..e350f565d8112 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -7825,7 +7825,7 @@ package android.app.admin { method @Nullable public String getDevicePolicyManagementRoleHolderPackage(); method public CharSequence getEndUserSessionMessage(@NonNull android.content.ComponentName); method @NonNull public String getEnrollmentSpecificId(); - method @Nullable public android.app.admin.FactoryResetProtectionPolicy getFactoryResetProtectionPolicy(@Nullable android.content.ComponentName); + method @Nullable @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_FACTORY_RESET, conditional=true) public android.app.admin.FactoryResetProtectionPolicy getFactoryResetProtectionPolicy(@Nullable android.content.ComponentName); method @Nullable public String getGlobalPrivateDnsHost(@NonNull android.content.ComponentName); method public int getGlobalPrivateDnsMode(@NonNull android.content.ComponentName); method @NonNull public java.util.List getInstalledCaCerts(@Nullable android.content.ComponentName); @@ -7868,7 +7868,7 @@ package android.app.admin { method public int getPermissionPolicy(android.content.ComponentName); method @Nullable public java.util.List getPermittedAccessibilityServices(@NonNull android.content.ComponentName); method @Nullable public java.util.List getPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName); - method @Nullable public java.util.List getPermittedInputMethods(@NonNull android.content.ComponentName); + method @Nullable @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_INPUT_METHODS, conditional=true) public java.util.List getPermittedInputMethods(@Nullable android.content.ComponentName); method public int getPersonalAppsSuspendedReasons(@NonNull android.content.ComponentName); method @NonNull public java.util.List getPreferentialNetworkServiceConfigs(); method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional=true) public int getRequiredPasswordComplexity(); @@ -7934,8 +7934,8 @@ package android.app.admin { method public boolean isUsbDataSignalingEnabled(); method public boolean isUsingUnifiedPassword(@NonNull android.content.ComponentName); method @NonNull public java.util.List listForegroundAffiliatedUsers(); - method public void lockNow(); - method public void lockNow(int); + method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK, conditional=true) public void lockNow(); + method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK, conditional=true) public void lockNow(int); method public int logoutUser(@NonNull android.content.ComponentName); method public void reboot(@NonNull android.content.ComponentName); method public void removeActiveAdmin(@NonNull android.content.ComponentName); @@ -7976,14 +7976,14 @@ package android.app.admin { method public void setDelegatedScopes(@NonNull android.content.ComponentName, @NonNull String, @NonNull java.util.List); method public void setDeviceOwnerLockScreenInfo(@NonNull android.content.ComponentName, CharSequence); method public void setEndUserSessionMessage(@NonNull android.content.ComponentName, @Nullable CharSequence); - method public void setFactoryResetProtectionPolicy(@NonNull android.content.ComponentName, @Nullable android.app.admin.FactoryResetProtectionPolicy); + method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_FACTORY_RESET, conditional=true) public void setFactoryResetProtectionPolicy(@Nullable android.content.ComponentName, @Nullable android.app.admin.FactoryResetProtectionPolicy); method public int setGlobalPrivateDnsModeOpportunistic(@NonNull android.content.ComponentName); method @WorkerThread public int setGlobalPrivateDnsModeSpecifiedHost(@NonNull android.content.ComponentName, @NonNull String); method public void setGlobalSetting(@NonNull android.content.ComponentName, String, String); method public void setKeepUninstalledPackages(@Nullable android.content.ComponentName, @NonNull java.util.List); method public boolean setKeyPairCertificate(@Nullable android.content.ComponentName, @NonNull String, @NonNull java.util.List, boolean); method public boolean setKeyguardDisabled(@NonNull android.content.ComponentName, boolean); - method public void setKeyguardDisabledFeatures(@NonNull android.content.ComponentName, int); + method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_KEYGUARD, conditional=true) public void setKeyguardDisabledFeatures(@Nullable android.content.ComponentName, int); method public void setLocationEnabled(@NonNull android.content.ComponentName, boolean); method public void setLockTaskFeatures(@NonNull android.content.ComponentName, int); method public void setLockTaskPackages(@NonNull android.content.ComponentName, @NonNull String[]) throws java.lang.SecurityException; @@ -7995,7 +7995,7 @@ package android.app.admin { method public void setManagedSubscriptionsPolicy(@Nullable android.app.admin.ManagedSubscriptionsPolicy); method public void setMasterVolumeMuted(@NonNull android.content.ComponentName, boolean); method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_WIPE_DATA, conditional=true) public void setMaximumFailedPasswordsForWipe(@Nullable android.content.ComponentName, int); - method public void setMaximumTimeToLock(@NonNull android.content.ComponentName, long); + method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK, conditional=true) public void setMaximumTimeToLock(@Nullable android.content.ComponentName, long); method @NonNull public java.util.List setMeteredDataDisabledPackages(@NonNull android.content.ComponentName, @NonNull java.util.List); method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_WIFI, conditional=true) public void setMinimumRequiredWifiSecurityLevel(int); method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_MTE, conditional=true) public void setMtePolicy(int); @@ -8021,7 +8021,7 @@ package android.app.admin { method public void setPermissionPolicy(@NonNull android.content.ComponentName, int); method public boolean setPermittedAccessibilityServices(@NonNull android.content.ComponentName, java.util.List); method public boolean setPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName, @Nullable java.util.List); - method public boolean setPermittedInputMethods(@NonNull android.content.ComponentName, java.util.List); + method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_INPUT_METHODS, conditional=true) public boolean setPermittedInputMethods(@Nullable android.content.ComponentName, java.util.List); method public void setPersonalAppsSuspended(@NonNull android.content.ComponentName, boolean); method public void setPreferentialNetworkServiceConfigs(@NonNull java.util.List); method public void setPreferentialNetworkServiceEnabled(boolean); @@ -8043,7 +8043,7 @@ package android.app.admin { method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_SYSTEM_UPDATES, conditional=true) public void setSystemUpdatePolicy(@NonNull android.content.ComponentName, android.app.admin.SystemUpdatePolicy); method @RequiresPermission(value=android.Manifest.permission.SET_TIME, conditional=true) public boolean setTime(@NonNull android.content.ComponentName, long); method @RequiresPermission(value=android.Manifest.permission.SET_TIME_ZONE, conditional=true) public boolean setTimeZone(@NonNull android.content.ComponentName, String); - method public void setTrustAgentConfiguration(@NonNull android.content.ComponentName, @NonNull android.content.ComponentName, android.os.PersistableBundle); + method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_KEYGUARD, conditional=true) public void setTrustAgentConfiguration(@Nullable android.content.ComponentName, @NonNull android.content.ComponentName, android.os.PersistableBundle); method public void setUninstallBlocked(@Nullable android.content.ComponentName, String, boolean); method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING, conditional=true) public void setUsbDataSignalingEnabled(boolean); method public void setUserControlDisabledPackages(@NonNull android.content.ComponentName, @NonNull java.util.List); diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index d4d5aac23d7f2..f3717d3ed3e37 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -20,6 +20,10 @@ import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CAMERA; import static android.Manifest.permission.MANAGE_DEVICE_ADMINS; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_FACTORY_RESET; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_INPUT_METHODS; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_KEYGUARD; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_MTE; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY; @@ -6095,23 +6099,26 @@ public class DevicePolicyManager { * activity until the device will lock. This limits the length that the user can set. It takes * effect immediately. *

- * The calling device admin must have requested {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} + * A calling device admin must have requested {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} * to be able to call this method; if it has not, a security exception will be thrown. *

* This method can be called on the {@link DevicePolicyManager} instance returned by * {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent * profile. * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the + * caller is not a device admin * @param timeMs The new desired maximum time to lock in milliseconds. A value of 0 means there * is no restriction. * @throws SecurityException if {@code admin} is not an active administrator or it does not use - * {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} + * {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} and the caller does not hold the + * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK} permission */ - public void setMaximumTimeToLock(@NonNull ComponentName admin, long timeMs) { + @RequiresPermission(value = MANAGE_DEVICE_POLICY_LOCK, conditional = true) + public void setMaximumTimeToLock(@Nullable ComponentName admin, long timeMs) { if (mService != null) { try { - mService.setMaximumTimeToLock(admin, timeMs, mParentInstance); + mService.setMaximumTimeToLock(admin, mContext.getPackageName(), timeMs, mParentInstance); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -6261,7 +6268,8 @@ public class DevicePolicyManager { *

* This method secures the device in response to an urgent situation, such as a lost or stolen * device. After this method is called, the device must be unlocked using strong authentication - * (PIN, pattern, or password). This API is intended for use only by device admins. + * (PIN, pattern, or password). This API is for use only by device admins and holders of the + * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK} permission. *

* From version {@link android.os.Build.VERSION_CODES#R} onwards, the caller must either have * the LOCK_DEVICE permission or the device must have the device admin feature; if neither is @@ -6285,8 +6293,10 @@ public class DevicePolicyManager { * Equivalent to calling {@link #lockNow(int)} with no flags. * * @throws SecurityException if the calling application does not own an active administrator - * that uses {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} + * that uses {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} and does not hold the + * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK} permission */ + @RequiresPermission(value = MANAGE_DEVICE_POLICY_LOCK, conditional = true) public void lockNow() { lockNow(0); } @@ -6297,7 +6307,8 @@ public class DevicePolicyManager { *

* This method secures the device in response to an urgent situation, such as a lost or stolen * device. After this method is called, the device must be unlocked using strong authentication - * (PIN, pattern, or password). This API is intended for use only by device admins. + * (PIN, pattern, or password). This API is for use only by device admins and holders of the + * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK} permission. *

* From version {@link android.os.Build.VERSION_CODES#R} onwards, the caller must either have * the LOCK_DEVICE permission or the device must have the device admin feature; if neither is @@ -6305,7 +6316,7 @@ public class DevicePolicyManager { * {@link android.os.Build.VERSION_CODES#R}, the device needed the device admin feature, * regardless of the caller's permissions. *

- * The calling device admin must have requested {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} + * A calling device admin must have requested {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} * to be able to call this method; if it has not, a security exception will be thrown. *

* If there's no lock type set, this method forces the device to go to sleep but doesn't lock @@ -6331,16 +6342,17 @@ public class DevicePolicyManager { * * @param flags May be 0 or {@link #FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY}. * @throws SecurityException if the calling application does not own an active administrator - * that uses {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} or the - * {@link #FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY} flag is passed by an application - * that is not a profile - * owner of a managed profile. + * that uses {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} and the does not hold + * the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK} permission, or + * the {@link #FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY} flag is passed by an + * application that is not a profile owner of a managed profile. * @throws IllegalArgumentException if the {@link #FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY} flag is * passed when locking the parent profile. * @throws UnsupportedOperationException if the {@link #FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY} * flag is passed when {@link #getStorageEncryptionStatus} does not return * {@link #ENCRYPTION_STATUS_ACTIVE_PER_USER}. */ + @RequiresPermission(value = MANAGE_DEVICE_POLICY_LOCK, conditional = true) public void lockNow(@LockNowFlag int flags) { if (mService != null) { try { @@ -6485,24 +6497,28 @@ public class DevicePolicyManager { } /** - * Callable by device owner or profile owner of an organization-owned device, to set a + * Callable by device owner, profile owner of an organization-owned device, or a holder of the + * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_FACTORY_RESET} permission to set a * factory reset protection (FRP) policy. When a new policy is set, the system * notifies the FRP management agent of a policy change by broadcasting * {@code ACTION_RESET_PROTECTION_POLICY_CHANGED}. * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the + * caller is not a device admin * @param policy the new FRP policy, or {@code null} to clear the current policy. - * @throws SecurityException if {@code admin} is not a device owner or a profile owner of - * an organization-owned device. + * @throws SecurityException if {@code admin} is not a device owner, profile owner of + * an organization-owned device, or holder of the + * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_FACTORY_RESET} permission * @throws UnsupportedOperationException if factory reset protection is not * supported on the device. */ - public void setFactoryResetProtectionPolicy(@NonNull ComponentName admin, + @RequiresPermission(value = MANAGE_DEVICE_POLICY_FACTORY_RESET, conditional = true) + public void setFactoryResetProtectionPolicy(@Nullable ComponentName admin, @Nullable FactoryResetProtectionPolicy policy) { throwIfParentInstance("setFactoryResetProtectionPolicy"); if (mService != null) { try { - mService.setFactoryResetProtectionPolicy(admin, policy); + mService.setFactoryResetProtectionPolicy(admin, mContext.getPackageName(), policy); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -6510,23 +6526,26 @@ public class DevicePolicyManager { } /** - * Callable by device owner or profile owner of an organization-owned device, to retrieve - * the current factory reset protection (FRP) policy set previously by - * {@link #setFactoryResetProtectionPolicy}. + * Callable by device owner, profile owner of an organization-owned device, or + * holder of the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_FACTORY_RESET} + * permission to retrieve the current factory reset protection (FRP) + * policy set previously by {@link #setFactoryResetProtectionPolicy}. *

* This method can also be called by the FRP management agent on device or with the permission * {@link android.Manifest.permission#MASTER_CLEAR}, in which case, it can pass {@code null} * as the ComponentName. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with or - * {@code null} if called by the FRP management agent on device or with the - * permission {@link android.Manifest.permission#MASTER_CLEAR}. + * {@code null} if the caller is not a device admin * @return The current FRP policy object or {@code null} if no policy is set. * @throws SecurityException if {@code admin} is not a device owner, a profile owner of - * an organization-owned device or the FRP management agent. + * an organization-owned device, a holder of the + * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_FACTORY_RESET} + * permission, or the FRP management agent. * @throws UnsupportedOperationException if factory reset protection is not * supported on the device. */ + @RequiresPermission(value = MANAGE_DEVICE_POLICY_FACTORY_RESET, conditional = true) public @Nullable FactoryResetProtectionPolicy getFactoryResetProtectionPolicy( @Nullable ComponentName admin) { throwIfParentInstance("getFactoryResetProtectionPolicy"); @@ -8725,7 +8744,7 @@ public class DevicePolicyManager { * such as widgets. After setting this, keyguard features will be disabled according to the * provided feature list. *

- * The calling device admin must have requested + * A calling device admin must have requested * {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} to be able to call this method; * if it has not, a security exception will be thrown. *

@@ -8764,7 +8783,8 @@ public class DevicePolicyManager { * The admin can check which features have been disabled by calling * {@link #getKeyguardDisabledFeatures(ComponentName)} * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the + * caller is not a device admin * @param which The disabled features flag which can be either * {@link #KEYGUARD_DISABLE_FEATURES_NONE} (default), * {@link #KEYGUARD_DISABLE_FEATURES_ALL}, or a combination of @@ -8776,13 +8796,16 @@ public class DevicePolicyManager { * {@link #KEYGUARD_DISABLE_FACE}, * {@link #KEYGUARD_DISABLE_IRIS}, * {@link #KEYGUARD_DISABLE_SHORTCUTS_ALL}. - * @throws SecurityException if {@code admin} is not an active administrator or does not user - * {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} + * @throws SecurityException if {@code admin} is not an active administrator or does not use + * {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} and does not hold + * the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_KEYGUARD} permission */ - public void setKeyguardDisabledFeatures(@NonNull ComponentName admin, int which) { + @RequiresPermission(value = MANAGE_DEVICE_POLICY_KEYGUARD, conditional = true) + public void setKeyguardDisabledFeatures(@Nullable ComponentName admin, int which) { if (mService != null) { try { - mService.setKeyguardDisabledFeatures(admin, which, mParentInstance); + mService.setKeyguardDisabledFeatures( + admin, mContext.getPackageName(), which, mParentInstance); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -9934,7 +9957,7 @@ public class DevicePolicyManager { * {@link #KEYGUARD_DISABLE_TRUST_AGENTS} and aggregate the configurations to determine its * behavior. The exact meaning of aggregation is trust-agent-specific. *

- * The calling device admin must have requested + * A calling device admin must have requested * {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} to be able to call this method; * if not, a security exception will be thrown. *

@@ -9945,20 +9968,24 @@ public class DevicePolicyManager { * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, calling * this method has no effect - no trust agent configuration will be set. * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the + * caller is not a device admin * @param target Component name of the agent to be configured. * @param configuration Trust-agent-specific feature configuration bundle. Please consult * documentation of the specific trust agent to determine the interpretation of this * bundle. * @throws SecurityException if {@code admin} is not an active administrator or does not use - * {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} + * {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} and does not have + * the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_KEYGUARD} permission */ @RequiresFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN) - public void setTrustAgentConfiguration(@NonNull ComponentName admin, + @RequiresPermission(value = MANAGE_DEVICE_POLICY_KEYGUARD, conditional = true) + public void setTrustAgentConfiguration(@Nullable ComponentName admin, @NonNull ComponentName target, PersistableBundle configuration) { if (mService != null) { try { - mService.setTrustAgentConfiguration(admin, target, configuration, mParentInstance); + mService.setTrustAgentConfiguration( + admin, mContext.getPackageName(), target, configuration, mParentInstance); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -10639,8 +10666,10 @@ public class DevicePolicyManager { } /** - * Called by a profile or device owner to set the permitted input methods services for this - * user. By default, the user can use any input method. + * Called by a profile or device owner or holder of the + * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_INPUT_METHODS} permission to set + * the permitted input methods services for this user. By default, the user can use any input + * method. *

* This method can be called on the {@link DevicePolicyManager} instance, * returned by {@link #getParentProfileInstance(ComponentName)}, where the caller must be @@ -10665,23 +10694,28 @@ public class DevicePolicyManager { *

* System input methods are always available to the user - this method can't modify this. * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the + * caller is not a device admin * @param packageNames List of input method package names. * @return {@code true} if the operation succeeded, or {@code false} if the list didn't * contain every enabled non-system input method service. - * @throws SecurityException if {@code admin} is not a device, profile owner or if called on - * the parent profile and the {@code admin} is not a profile owner - * of an organization-owned managed profile. + * @throws SecurityException if {@code admin} is not a device or profile owner and does not + * hold the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_INPUT_METHODS} + * permission, or if called on the parent profile and the + * {@code admin} is not a profile owner of an organization-owned + * managed profile. * @throws IllegalArgumentException if called on the parent profile, the {@code admin} is a * profile owner of an organization-owned managed profile and the * list of permitted input method package names is not null or empty. */ @SupportsCoexistence + @RequiresPermission(value = MANAGE_DEVICE_POLICY_INPUT_METHODS, conditional = true) public boolean setPermittedInputMethods( - @NonNull ComponentName admin, List packageNames) { + @Nullable ComponentName admin, List packageNames) { if (mService != null) { try { - return mService.setPermittedInputMethods(admin, packageNames, mParentInstance); + return mService.setPermittedInputMethods( + admin, mContext.getPackageName(), packageNames, mParentInstance); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -10702,16 +10736,19 @@ public class DevicePolicyManager { * An empty list means no input methods except system input methods are allowed. Null means all * input methods are allowed. * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the + * caller is not a device admin * @return List of input method package names. - * @throws SecurityException if {@code admin} is not a device, profile owner or if called on - * the parent profile and the {@code admin} is not a profile owner - * of an organization-owned managed profile. + * @throws SecurityException if {@code admin} is not a device or profile owner and does not + * hold the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_INPUT_METHODS} + * permission or if called on the parent profile and the {@code admin} + * is not a profile owner of an organization-owned managed profile. */ - public @Nullable List getPermittedInputMethods(@NonNull ComponentName admin) { + @RequiresPermission(value = MANAGE_DEVICE_POLICY_INPUT_METHODS, conditional = true) + public @Nullable List getPermittedInputMethods(@Nullable ComponentName admin) { if (mService != null) { try { - return mService.getPermittedInputMethods(admin, mParentInstance); + return mService.getPermittedInputMethods(admin, mContext.getPackageName(), mParentInstance); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 23871c313db7d..14c6ecd414337 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -113,7 +113,7 @@ interface IDevicePolicyManager { boolean resetPassword(String password, int flags); - void setMaximumTimeToLock(in ComponentName who, long timeMs, boolean parent); + void setMaximumTimeToLock(in ComponentName who, String callerPackageName, long timeMs, boolean parent); long getMaximumTimeToLock(in ComponentName who, int userHandle, boolean parent); void setRequiredStrongAuthTimeout(in ComponentName who, String callerPackageName, long timeMs, boolean parent); @@ -126,7 +126,7 @@ interface IDevicePolicyManager { **/ void wipeDataWithReason(int flags, String wipeReasonForUser, boolean parent, boolean factoryReset); - void setFactoryResetProtectionPolicy(in ComponentName who, in FactoryResetProtectionPolicy policy); + void setFactoryResetProtectionPolicy(in ComponentName who, String callerPackageName, in FactoryResetProtectionPolicy policy); FactoryResetProtectionPolicy getFactoryResetProtectionPolicy(in ComponentName who); boolean isFactoryResetProtectionPolicySupported(); @@ -155,7 +155,7 @@ interface IDevicePolicyManager { void setNearbyAppStreamingPolicy(int policy); int getNearbyAppStreamingPolicy(int userId); - void setKeyguardDisabledFeatures(in ComponentName who, int which, boolean parent); + void setKeyguardDisabledFeatures(in ComponentName who, String callerPackageName, int which, boolean parent); int getKeyguardDisabledFeatures(in ComponentName who, int userHandle, boolean parent); void setActiveAdmin(in ComponentName policyReceiver, boolean refreshing, int userHandle); @@ -262,8 +262,8 @@ interface IDevicePolicyManager { List getPermittedAccessibilityServicesForUser(int userId); boolean isAccessibilityServicePermittedByAdmin(in ComponentName admin, String packageName, int userId); - boolean setPermittedInputMethods(in ComponentName admin,in List packageList, boolean parent); - List getPermittedInputMethods(in ComponentName admin, boolean parent); + boolean setPermittedInputMethods(in ComponentName admin, String callerPackageName, in List packageList, boolean parent); + List getPermittedInputMethods(in ComponentName admin, String callerPackageName, boolean parent); List getPermittedInputMethodsAsUser(int userId); boolean isInputMethodPermittedByAdmin(in ComponentName admin, String packageName, int userId, boolean parent); @@ -353,8 +353,8 @@ interface IDevicePolicyManager { boolean getBluetoothContactSharingDisabled(in ComponentName who); boolean getBluetoothContactSharingDisabledForUser(int userId); - void setTrustAgentConfiguration(in ComponentName admin, in ComponentName agent, - in PersistableBundle args, boolean parent); + void setTrustAgentConfiguration(in ComponentName admin, String callerPackageName, + in ComponentName agent, in PersistableBundle args, boolean parent); List getTrustAgentConfiguration(in ComponentName admin, in ComponentName agent, int userId, boolean parent); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index d5612ada6a441..e9860f6f0b7e2 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -17,11 +17,16 @@ package com.android.server.devicepolicy; import static android.Manifest.permission.BIND_DEVICE_ADMIN; +import static android.Manifest.permission.LOCK_DEVICE; import static android.Manifest.permission.MANAGE_CA_CERTIFICATES; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CAMERA; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_FACTORY_RESET; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_INPUT_METHODS; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_KEYGUARD; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_MTE; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY; @@ -2800,14 +2805,34 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ComponentName who, int reqPolicy, @Nullable String permission) throws SecurityException { + return getActiveAdminOrCheckPermissionsForCallerLocked( + who, reqPolicy, permission == null ? Set.of() : Set.of(permission)); + } + + /** + * Finds an active admin for the caller then checks {@code permissions} if admin check failed. + * + * @return an active admin or {@code null} if there is no active admin but + * one of {@code permissions} is granted + * @throws SecurityException if caller neither has an active admin nor {@code permission} + */ + @Nullable + ActiveAdmin getActiveAdminOrCheckPermissionsForCallerLocked( + ComponentName who, + int reqPolicy, + Set permissions) throws SecurityException { ensureLocked(); final CallerIdentity caller = getCallerIdentity(); ActiveAdmin result = getActiveAdminWithPolicyForUidLocked(who, reqPolicy, caller.getUid()); if (result != null) { return result; - } else if (permission != null && hasCallingPermission(permission)) { - return null; + } else { + for (String permission : permissions) { + if (hasCallingPermission(permission)) { + return null; + } + } } // Code for handling failure from getActiveAdminWithPolicyForUidLocked to find an admin @@ -2831,8 +2856,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { + admin.info.getTagForPolicy(reqPolicy)); } else { throw new SecurityException("No active admin owned by uid " - + caller.getUid() + " for policy #" + reqPolicy + (permission == null ? "" - : ", which doesn't have " + permission)); + + caller.getUid() + " for policy #" + reqPolicy + (permissions.isEmpty() ? "" + : ", which doesn't have " + permissions)); } } @@ -2855,12 +2880,29 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { int reqPolicy, boolean parent, @Nullable String permission) throws SecurityException { + return getActiveAdminOrCheckPermissionsForCallerLocked( + who, reqPolicy, parent, permission == null ? Set.of() : Set.of(permission)); + } + + /** + * Finds an active admin for the caller then checks {@code permission} if admin check failed. + * + * @return an active admin or {@code null} if there is no active admin but + * {@code permission} is granted + * @throws SecurityException if caller neither has an active admin nor {@code permission} + */ + @Nullable + ActiveAdmin getActiveAdminOrCheckPermissionsForCallerLocked( + @Nullable ComponentName who, + int reqPolicy, + boolean parent, + Set permissions) throws SecurityException { ensureLocked(); if (parent) { Preconditions.checkCallingUser(isManagedProfile(getCallerIdentity().getUserId())); } - ActiveAdmin admin = getActiveAdminOrCheckPermissionForCallerLocked( - who, reqPolicy, permission); + ActiveAdmin admin = getActiveAdminOrCheckPermissionsForCallerLocked( + who, reqPolicy, permissions); return parent ? admin.getParentActiveAdmin() : admin; } @@ -5512,15 +5554,29 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public void setMaximumTimeToLock(ComponentName who, long timeMs, boolean parent) { + public void setMaximumTimeToLock(ComponentName who, String callerPackageName, + long timeMs, boolean parent) { + CallerIdentity caller = getCallerIdentity(who, callerPackageName); if (!mHasFeature) { return; } - Objects.requireNonNull(who, "ComponentName is null"); - final int userHandle = mInjector.userHandleGetCallingUserId(); + if (!isPermissionCheckFlagEnabled()) { + Objects.requireNonNull(who, "ComponentName is null"); + } + int userHandle = mInjector.userHandleGetCallingUserId(); + int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle; synchronized (getLockObject()) { - final ActiveAdmin ap = getActiveAdminForCallerLocked( - who, DeviceAdminInfo.USES_POLICY_FORCE_LOCK, parent); + ActiveAdmin ap; + if (isPermissionCheckFlagEnabled()) { + // TODO: Allow use of USES_POLICY_FORCE_LOCK + ap = enforcePermissionAndGetEnforcingAdmin( + who, MANAGE_DEVICE_POLICY_LOCK, caller.getPackageName(), + affectedUserId).getActiveAdmin(); + } else { + ap = getActiveAdminForCallerLocked( + who, DeviceAdminInfo.USES_POLICY_FORCE_LOCK, parent); + } + if (ap.maximumTimeToUnlock != timeMs) { ap.maximumTimeToUnlock = timeMs; saveSettingsLocked(userHandle); @@ -5528,9 +5584,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } if (SecurityLog.isLoggingEnabled()) { - final int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle; SecurityLog.writeEvent(SecurityLog.TAG_MAX_SCREEN_LOCK_TIMEOUT_SET, - who.getPackageName(), userHandle, affectedUserId, timeMs); + caller.getPackageName(), userHandle, affectedUserId, timeMs); } } @@ -5733,13 +5788,22 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final int callingUserId = caller.getUserId(); ComponentName adminComponent = null; synchronized (getLockObject()) { + ActiveAdmin admin; // Make sure the caller has any active admin with the right policy or // the required permission. - final ActiveAdmin admin = getActiveAdminOrCheckPermissionForCallerLocked( - null, - DeviceAdminInfo.USES_POLICY_FORCE_LOCK, - parent, - android.Manifest.permission.LOCK_DEVICE); + if (isPermissionCheckFlagEnabled()) { + admin = getActiveAdminOrCheckPermissionsForCallerLocked( + null, + DeviceAdminInfo.USES_POLICY_FORCE_LOCK, + parent, + Set.of(MANAGE_DEVICE_POLICY_LOCK, LOCK_DEVICE)); + } else { + admin = getActiveAdminOrCheckPermissionForCallerLocked( + null, + DeviceAdminInfo.USES_POLICY_FORCE_LOCK, + parent, + LOCK_DEVICE); + } checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_LOCK_NOW); final long ident = mInjector.binderClearCallingIdentity(); try { @@ -7433,21 +7497,34 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public void setFactoryResetProtectionPolicy(ComponentName who, + public void setFactoryResetProtectionPolicy(ComponentName who, String callerPackageName, @Nullable FactoryResetProtectionPolicy policy) { if (!mHasFeature) { return; } - Preconditions.checkNotNull(who, "ComponentName is null"); - CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallAuthorization( - isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller)); + if (!isPermissionCheckFlagEnabled()) { + Preconditions.checkNotNull(who, "ComponentName is null"); + } + CallerIdentity caller = getCallerIdentity(who, callerPackageName); + if (!isPermissionCheckFlagEnabled()) { + Preconditions.checkCallAuthorization( + isDefaultDeviceOwner(caller) + || isProfileOwnerOfOrganizationOwnedDevice(caller)); + } checkCanExecuteOrThrowUnsafe(DevicePolicyManager .OPERATION_SET_FACTORY_RESET_PROTECTION_POLICY); final int frpManagementAgentUid = getFrpManagementAgentUidOrThrow(); synchronized (getLockObject()) { - ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()); + ActiveAdmin admin; + if (isPermissionCheckFlagEnabled()) { + admin = enforcePermissionAndGetEnforcingAdmin( + who, MANAGE_DEVICE_POLICY_FACTORY_RESET, caller.getPackageName(), + UserHandle.USER_ALL) + .getActiveAdmin(); + } else { + admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()); + } admin.mFactoryResetProtectionPolicy = policy; saveSettingsLocked(caller.getUserId()); } @@ -7457,7 +7534,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_FACTORY_RESET_PROTECTION) - .setAdmin(who) + .setAdmin(caller.getPackageName()) .write(); } @@ -7484,7 +7561,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { synchronized (getLockObject()) { if (who == null) { Preconditions.checkCallAuthorization(frpManagementAgentUid == caller.getUid() - || hasCallingPermission(permission.MASTER_CLEAR), + || hasCallingPermission(permission.MASTER_CLEAR) + || hasCallingPermission(MANAGE_DEVICE_POLICY_FACTORY_RESET), "Must be called by the FRP management agent on device"); // TODO(b/261999445): Remove if (isHeadlessFlagEnabled()) { @@ -8770,18 +8848,30 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public void setKeyguardDisabledFeatures(ComponentName who, int which, boolean parent) { + public void setKeyguardDisabledFeatures( + ComponentName who, String callerPackageName, int which, boolean parent) { if (!mHasFeature) { return; } - Objects.requireNonNull(who, "ComponentName is null"); + if (!isPermissionCheckFlagEnabled()) { + Objects.requireNonNull(who, "ComponentName is null"); + } - final CallerIdentity caller = getCallerIdentity(who); + final CallerIdentity caller = getCallerIdentity(who, callerPackageName); final int userHandle = caller.getUserId(); + int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle; synchronized (getLockObject()) { - ActiveAdmin ap = getActiveAdminForCallerLocked( - who, DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES, parent); + ActiveAdmin ap; + if (isPermissionCheckFlagEnabled()) { + // SUPPORT USES_POLICY_DISABLE_KEYGUARD_FEATURES + ap = enforcePermissionAndGetEnforcingAdmin( + who, MANAGE_DEVICE_POLICY_KEYGUARD, caller.getPackageName(), + affectedUserId).getActiveAdmin(); + } else { + ap = getActiveAdminForCallerLocked( + who, DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES, parent); + } if (isManagedProfile(userHandle)) { if (parent) { if (isProfileOwnerOfOrganizationOwnedDevice(caller)) { @@ -8799,13 +8889,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } if (SecurityLog.isLoggingEnabled()) { - final int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle; SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISABLED_FEATURES_SET, - who.getPackageName(), userHandle, affectedUserId, which); + caller.getPackageName(), userHandle, affectedUserId, which); } DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_KEYGUARD_DISABLED_FEATURES) - .setAdmin(caller.getComponentName()) + .setAdmin(caller.getPackageName()) .setInt(which) .setStrings(parent ? CALLED_FROM_PARENT : NOT_CALLED_FROM_PARENT) .write(); @@ -10829,17 +10918,31 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public void setTrustAgentConfiguration(ComponentName admin, ComponentName agent, + public void setTrustAgentConfiguration( + ComponentName admin, String callerPackageName, ComponentName agent, PersistableBundle args, boolean parent) { if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) { return; } - Objects.requireNonNull(admin, "admin is null"); + if (!isPermissionCheckFlagEnabled()) { + Objects.requireNonNull(admin, "admin is null"); + } + CallerIdentity caller = getCallerIdentity(admin, callerPackageName); + Objects.requireNonNull(agent, "agent is null"); - final int userHandle = UserHandle.getCallingUserId(); + int userHandle = UserHandle.getCallingUserId(); synchronized (getLockObject()) { - ActiveAdmin ap = getActiveAdminForCallerLocked(admin, - DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES, parent); + ActiveAdmin ap; + if (isPermissionCheckFlagEnabled()) { + int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle; + // TODO: Support USES_POLICY_DISABLE_KEYGUARD_FEATURES + ap = enforcePermissionAndGetEnforcingAdmin( + admin, MANAGE_DEVICE_POLICY_KEYGUARD, + caller.getPackageName(), affectedUserId).getActiveAdmin(); + } else { + ap = getActiveAdminForCallerLocked(admin, + DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES, parent); + } checkCanExecuteOrThrowUnsafe( DevicePolicyManager.OPERATION_SET_TRUST_AGENT_CONFIGURATION); @@ -11233,23 +11336,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public boolean setPermittedInputMethods(ComponentName who, List packageList, - boolean calledOnParentInstance) { + public boolean setPermittedInputMethods(ComponentName who, String callerPackageName, + List packageList, boolean calledOnParentInstance) { if (!mHasFeature) { return false; } - Objects.requireNonNull(who, "ComponentName is null"); + if (!isPermissionCheckFlagEnabled()) { + Objects.requireNonNull(who, "ComponentName is null"); + } - final CallerIdentity caller = getCallerIdentity(who); - final int userId = getProfileParentUserIfRequested( + CallerIdentity caller = getCallerIdentity(who, callerPackageName); + int userId = getProfileParentUserIfRequested( caller.getUserId(), calledOnParentInstance); if (calledOnParentInstance) { - Preconditions.checkCallAuthorization(isProfileOwnerOfOrganizationOwnedDevice(caller)); + if (!isPermissionCheckFlagEnabled()) { + Preconditions.checkCallAuthorization( + isProfileOwnerOfOrganizationOwnedDevice(caller)); + } Preconditions.checkArgument(packageList == null || packageList.isEmpty(), "Permitted input methods must allow all input methods or only " + "system input methods when called on the parent instance of an " + "organization-owned device"); - } else { + } else if (!isPermissionCheckFlagEnabled()) { Preconditions.checkCallAuthorization( isDefaultDeviceOwner(caller) || isProfileOwner(caller)); } @@ -11272,15 +11380,22 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } synchronized (getLockObject()) { - final ActiveAdmin admin = getParentOfAdminIfRequired( - getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), calledOnParentInstance); + ActiveAdmin admin; + if (isPermissionCheckFlagEnabled()) { + admin = enforcePermissionAndGetEnforcingAdmin( + who, MANAGE_DEVICE_POLICY_INPUT_METHODS, + caller.getPackageName(), userId).getActiveAdmin(); + } else { + admin = getParentOfAdminIfRequired( + getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), calledOnParentInstance); + } admin.permittedInputMethods = packageList; saveSettingsLocked(caller.getUserId()); } DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_PERMITTED_INPUT_METHODS) - .setAdmin(who) + .setAdmin(caller.getPackageName()) .setStrings(getStringArrayForLogging(packageList, calledOnParentInstance)) .write(); return true; @@ -11298,24 +11413,39 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public List getPermittedInputMethods(ComponentName who, + public List getPermittedInputMethods(ComponentName who, String callerPackageName, boolean calledOnParentInstance) { if (!mHasFeature) { return null; } - Objects.requireNonNull(who, "ComponentName is null"); + if (!isPermissionCheckFlagEnabled()) { + Objects.requireNonNull(who, "ComponentName is null"); + } - final CallerIdentity caller = getCallerIdentity(who); - if (calledOnParentInstance) { - Preconditions.checkCallAuthorization(isProfileOwnerOfOrganizationOwnedDevice(caller)); - } else { - Preconditions.checkCallAuthorization( - isDefaultDeviceOwner(caller) || isProfileOwner(caller)); + final CallerIdentity caller = getCallerIdentity(who, callerPackageName); + if (!isPermissionCheckFlagEnabled()) { + if (calledOnParentInstance) { + Preconditions.checkCallAuthorization( + isProfileOwnerOfOrganizationOwnedDevice(caller)); + } else { + Preconditions.checkCallAuthorization( + isDefaultDeviceOwner(caller) || isProfileOwner(caller)); + } } synchronized (getLockObject()) { - final ActiveAdmin admin = getParentOfAdminIfRequired( - getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), calledOnParentInstance); + ActiveAdmin admin; + if (isPermissionCheckFlagEnabled()) { + int affectedUser = calledOnParentInstance ? getProfileParentId( + caller.getUserId()) : caller.getUserId(); + admin = enforcePermissionAndGetEnforcingAdmin( + who, MANAGE_DEVICE_POLICY_INPUT_METHODS, caller.getPackageName(), + affectedUser).getActiveAdmin(); + } else { + admin = getParentOfAdminIfRequired( + getProfileOwnerOrDeviceOwnerLocked( + caller.getUserId()), calledOnParentInstance); + } return admin.permittedInputMethods; } } @@ -18693,11 +18823,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { for (int i = 0; i < exemptions.length; i++) { appOpExemptions[i] = APPLICATION_EXEMPTION_CONSTANTS_TO_APP_OPS.get(exemptions[i]); } - DevicePolicyEventLogger - .createEvent(DevicePolicyEnums.SET_APPLICATION_EXEMPTIONS) - .setAdmin(caller.getPackageName()) - .setStrings(packageName, appOpExemptions) - .write(); +// DevicePolicyEventLogger +// .createEvent(DevicePolicyEnums.SET_APPLICATION_EXEMPTIONS) +// .setAdmin(caller.getPackageName()) +// .setStrings(packageName, appOpExemptions) +// .write(); } @Override @@ -20942,12 +21072,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING, MANAGE_DEVICE_POLICY_MTE, MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, - MANAGE_DEVICE_POLICY_PACKAGE_STATE); + MANAGE_DEVICE_POLICY_PACKAGE_STATE, + MANAGE_DEVICE_POLICY_LOCK, + MANAGE_DEVICE_POLICY_FACTORY_RESET, + MANAGE_DEVICE_POLICY_KEYGUARD); private static final List FINANCED_DEVICE_OWNER_PERMISSIONS = List.of( MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL, MANAGE_DEVICE_POLICY_ACROSS_USERS, MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL, - MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY); + MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY, + MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS, + MANAGE_DEVICE_POLICY_FACTORY_RESET, + MANAGE_DEVICE_POLICY_KEYGUARD); private static final List PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE_PERMISSIONS = List.of( MANAGE_DEVICE_POLICY_ACROSS_USERS, @@ -20964,7 +21100,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING, MANAGE_DEVICE_POLICY_MTE, MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, - MANAGE_DEVICE_POLICY_PACKAGE_STATE); + MANAGE_DEVICE_POLICY_PACKAGE_STATE, + MANAGE_DEVICE_POLICY_LOCK, + MANAGE_DEVICE_POLICY_FACTORY_RESET, + MANAGE_DEVICE_POLICY_KEYGUARD); private static final List PROFILE_OWNER_ON_USER_0_PERMISSIONS = List.of( SET_TIME, SET_TIME_ZONE, @@ -20972,7 +21111,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { MANAGE_DEVICE_POLICY_WIPE_DATA, MANAGE_DEVICE_POLICY_SCREEN_CAPTURE, MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, - MANAGE_DEVICE_POLICY_PACKAGE_STATE); + MANAGE_DEVICE_POLICY_PACKAGE_STATE, + MANAGE_DEVICE_POLICY_LOCK, + MANAGE_DEVICE_POLICY_KEYGUARD); private static final List PROFILE_OWNER_PERMISSIONS = List.of( MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL, MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY, @@ -20980,7 +21121,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { MANAGE_DEVICE_POLICY_WIPE_DATA, MANAGE_DEVICE_POLICY_SCREEN_CAPTURE, MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, - MANAGE_DEVICE_POLICY_PACKAGE_STATE); + MANAGE_DEVICE_POLICY_PACKAGE_STATE, + MANAGE_DEVICE_POLICY_LOCK, + MANAGE_DEVICE_POLICY_KEYGUARD); private static final HashMap> DPC_PERMISSIONS = new HashMap<>(); { @@ -20993,10 +21136,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } //TODO(b/254253251) Fill this map in as new permissions are added for policies. - // TODO: Add USES_POLICY_WIPE_DATA -> MANAGE_DEVICE_POLICY_WIPE_DATA - // TODO: Add USES_POLICY_EXPIRE_PASSWORD -> MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS - // TODO: Consider USES_POLICY_WATCH_LOGIN -> MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS - - // is this opening up too much? maybe we need to special case device admin in the checker private static final HashMap ACTIVE_ADMIN_POLICIES = new HashMap<>(); private static final HashMap CROSS_USER_PERMISSIONS = @@ -21013,6 +21152,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING, null); // mte is intrinsically global so there is no cross-user permission CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_MTE, null); + CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_FACTORY_RESET, null); // Organisation identity policy will involve data of other organisations on the device and // therefore the FULL cross-user permission is required. CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY, @@ -21027,6 +21167,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL); CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_PACKAGE_STATE, MANAGE_DEVICE_POLICY_ACROSS_USERS); + CROSS_USER_PERMISSIONS.put( + MANAGE_DEVICE_POLICY_LOCK, MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL); + CROSS_USER_PERMISSIONS.put( + MANAGE_DEVICE_POLICY_KEYGUARD, MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL); } /**