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
diff --git a/core/api/current.txt b/core/api/current.txt
index d7460b3..e350f56 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -7825,7 +7825,7 @@
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<byte[]> getInstalledCaCerts(@Nullable android.content.ComponentName);
@@ -7868,7 +7868,7 @@
method public int getPermissionPolicy(android.content.ComponentName);
method @Nullable public java.util.List<java.lang.String> getPermittedAccessibilityServices(@NonNull android.content.ComponentName);
method @Nullable public java.util.List<java.lang.String> getPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName);
- method @Nullable public java.util.List<java.lang.String> getPermittedInputMethods(@NonNull android.content.ComponentName);
+ method @Nullable @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_INPUT_METHODS, conditional=true) public java.util.List<java.lang.String> getPermittedInputMethods(@Nullable android.content.ComponentName);
method public int getPersonalAppsSuspendedReasons(@NonNull android.content.ComponentName);
method @NonNull public java.util.List<android.app.admin.PreferentialNetworkServiceConfig> getPreferentialNetworkServiceConfigs();
method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional=true) public int getRequiredPasswordComplexity();
@@ -7934,8 +7934,8 @@
method public boolean isUsbDataSignalingEnabled();
method public boolean isUsingUnifiedPassword(@NonNull android.content.ComponentName);
method @NonNull public java.util.List<android.os.UserHandle> 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 @@
method public void setDelegatedScopes(@NonNull android.content.ComponentName, @NonNull String, @NonNull java.util.List<java.lang.String>);
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<java.lang.String>);
method public boolean setKeyPairCertificate(@Nullable android.content.ComponentName, @NonNull String, @NonNull java.util.List<java.security.cert.Certificate>, 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 @@
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<java.lang.String> setMeteredDataDisabledPackages(@NonNull android.content.ComponentName, @NonNull java.util.List<java.lang.String>);
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 @@
method public void setPermissionPolicy(@NonNull android.content.ComponentName, int);
method public boolean setPermittedAccessibilityServices(@NonNull android.content.ComponentName, java.util.List<java.lang.String>);
method public boolean setPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName, @Nullable java.util.List<java.lang.String>);
- method public boolean setPermittedInputMethods(@NonNull android.content.ComponentName, java.util.List<java.lang.String>);
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_INPUT_METHODS, conditional=true) public boolean setPermittedInputMethods(@Nullable android.content.ComponentName, java.util.List<java.lang.String>);
method public void setPersonalAppsSuspended(@NonNull android.content.ComponentName, boolean);
method public void setPreferentialNetworkServiceConfigs(@NonNull java.util.List<android.app.admin.PreferentialNetworkServiceConfig>);
method public void setPreferentialNetworkServiceEnabled(boolean);
@@ -8043,7 +8043,7 @@
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<java.lang.String>);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index d4d5aac..f3717d3 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_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 @@
* activity until the device will lock. This limits the length that the user can set. It takes
* effect immediately.
* <p>
- * 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.
* <p>
* 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 @@
* <p>
* 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.
* <p>
* 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 @@
* 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 @@
* <p>
* 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.
* <p>
* 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 @@
* {@link android.os.Build.VERSION_CODES#R}, the device needed the device admin feature,
* regardless of the caller's permissions.
* <p>
- * 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.
* <p>
* If there's no lock type set, this method forces the device to go to sleep but doesn't lock
@@ -6331,16 +6342,17 @@
*
* @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 @@
}
/**
- * 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 @@
}
/**
- * 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}.
* <p>
* 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 @@
* such as widgets. After setting this, keyguard features will be disabled according to the
* provided feature list.
* <p>
- * 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.
* <p>
@@ -8764,7 +8783,8 @@
* 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 @@
* {@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 @@
* {@link #KEYGUARD_DISABLE_TRUST_AGENTS} and aggregate the configurations to determine its
* behavior. The exact meaning of aggregation is trust-agent-specific.
* <p>
- * 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.
* <p>
@@ -9945,20 +9968,24 @@
* 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 @@
}
/**
- * 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.
* <p>
* This method can be called on the {@link DevicePolicyManager} instance,
* returned by {@link #getParentProfileInstance(ComponentName)}, where the caller must be
@@ -10665,23 +10694,28 @@
* <p>
* 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<String> packageNames) {
+ @Nullable ComponentName admin, List<String> 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 @@
* 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<String> getPermittedInputMethods(@NonNull ComponentName admin) {
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_INPUT_METHODS, conditional = true)
+ public @Nullable List<String> 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 23871c3..14c6ecd 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -113,7 +113,7 @@
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 @@
**/
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 @@
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 @@
List<String> getPermittedAccessibilityServicesForUser(int userId);
boolean isAccessibilityServicePermittedByAdmin(in ComponentName admin, String packageName, int userId);
- boolean setPermittedInputMethods(in ComponentName admin,in List<String> packageList, boolean parent);
- List<String> getPermittedInputMethods(in ComponentName admin, boolean parent);
+ boolean setPermittedInputMethods(in ComponentName admin, String callerPackageName, in List<String> packageList, boolean parent);
+ List<String> getPermittedInputMethods(in ComponentName admin, String callerPackageName, boolean parent);
List<String> getPermittedInputMethodsAsUser(int userId);
boolean isInputMethodPermittedByAdmin(in ComponentName admin, String packageName, int userId, boolean parent);
@@ -353,8 +353,8 @@
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<PersistableBundle> 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 d5612ad..e9860f6 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 @@
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<String> 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 @@
+ 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 @@
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<String> 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 @@
}
@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 @@
}
}
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 @@
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 @@
}
@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 @@
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_FACTORY_RESET_PROTECTION)
- .setAdmin(who)
+ .setAdmin(caller.getPackageName())
.write();
}
@@ -7484,7 +7561,8 @@
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 @@
}
@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 @@
}
}
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 @@
}
@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 @@
}
@Override
- public boolean setPermittedInputMethods(ComponentName who, List<String> packageList,
- boolean calledOnParentInstance) {
+ public boolean setPermittedInputMethods(ComponentName who, String callerPackageName,
+ List<String> 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 @@
}
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 @@
}
@Override
- public List<String> getPermittedInputMethods(ComponentName who,
+ public List<String> 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 @@
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 @@
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<String> 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<String> PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE_PERMISSIONS =
List.of(
MANAGE_DEVICE_POLICY_ACROSS_USERS,
@@ -20964,7 +21100,10 @@
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<String> PROFILE_OWNER_ON_USER_0_PERMISSIONS = List.of(
SET_TIME,
SET_TIME_ZONE,
@@ -20972,7 +21111,9 @@
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<String> PROFILE_OWNER_PERMISSIONS = List.of(
MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL,
MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY,
@@ -20980,7 +21121,9 @@
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<Integer, List<String>> DPC_PERMISSIONS = new HashMap<>();
{
@@ -20993,10 +21136,6 @@
}
//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<String, Integer> ACTIVE_ADMIN_POLICIES = new HashMap<>();
private static final HashMap<String, String> CROSS_USER_PERMISSIONS =
@@ -21013,6 +21152,7 @@
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 @@
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);
}
/**