Merge changes from topics "dpmapis1", "dpmapis2"
* changes:
Add DPM Permissions 3.
Add permissions to DPM 2.
Add permission access to DPM Apis.
diff --git a/core/api/current.txt b/core/api/current.txt
index fb79e08..95729da 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -7818,14 +7818,14 @@
method @Deprecated public boolean getCrossProfileContactsSearchDisabled(@NonNull android.content.ComponentName);
method @NonNull public java.util.Set<java.lang.String> getCrossProfilePackages(@NonNull android.content.ComponentName);
method @NonNull public java.util.List<java.lang.String> getCrossProfileWidgetProviders(@NonNull android.content.ComponentName);
- method public int getCurrentFailedPasswordAttempts();
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional=true) public int getCurrentFailedPasswordAttempts();
method @Nullable public java.util.List<java.lang.String> getDelegatePackages(@NonNull android.content.ComponentName, @NonNull String);
method @NonNull public java.util.List<java.lang.String> getDelegatedScopes(@Nullable android.content.ComponentName, @NonNull String);
method public CharSequence getDeviceOwnerLockScreenInfo();
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);
@@ -7843,14 +7843,14 @@
method public long getMaximumTimeToLock(@Nullable android.content.ComponentName);
method @NonNull public java.util.List<java.lang.String> getMeteredDataDisabledPackages(@NonNull android.content.ComponentName);
method public int getMinimumRequiredWifiSecurityLevel();
- method public int getMtePolicy();
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_MTE, conditional=true) public int getMtePolicy();
method @RequiresPermission(value=android.Manifest.permission.READ_NEARBY_STREAMING_POLICY, conditional=true) public int getNearbyAppStreamingPolicy();
method @RequiresPermission(value=android.Manifest.permission.READ_NEARBY_STREAMING_POLICY, conditional=true) public int getNearbyNotificationStreamingPolicy();
method @Deprecated @ColorInt public int getOrganizationColor(@NonNull android.content.ComponentName);
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY) public CharSequence getOrganizationName(@Nullable android.content.ComponentName);
method public java.util.List<android.telephony.data.ApnSetting> getOverrideApns(@NonNull android.content.ComponentName);
method @NonNull public android.app.admin.DevicePolicyManager getParentProfileInstance(@NonNull android.content.ComponentName);
- method @RequiresPermission(android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY) public int getPasswordComplexity();
+ method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY}, conditional=true) public int getPasswordComplexity();
method public long getPasswordExpiration(@Nullable android.content.ComponentName);
method public long getPasswordExpirationTimeout(@Nullable android.content.ComponentName);
method public int getPasswordHistoryLength(@Nullable android.content.ComponentName);
@@ -7868,10 +7868,10 @@
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 public int getRequiredPasswordComplexity();
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional=true) public int getRequiredPasswordComplexity();
method public long getRequiredStrongAuthTimeout(@Nullable android.content.ComponentName);
method @NonNull public android.app.admin.DevicePolicyResourcesManager getResources();
method public boolean getScreenCaptureDisabled(@Nullable android.content.ComponentName);
@@ -7886,26 +7886,26 @@
method @NonNull public java.util.List<java.lang.String> getUserControlDisabledPackages(@NonNull android.content.ComponentName);
method @NonNull public android.os.Bundle getUserRestrictions(@NonNull android.content.ComponentName);
method @NonNull public android.os.Bundle getUserRestrictionsGlobally();
- method @Nullable public String getWifiMacAddress(@NonNull android.content.ComponentName);
- method @Nullable public android.app.admin.WifiSsidPolicy getWifiSsidPolicy();
+ method @Nullable public String getWifiMacAddress(@Nullable android.content.ComponentName);
+ method @Nullable @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_WIFI, conditional=true) public android.app.admin.WifiSsidPolicy getWifiSsidPolicy();
method public boolean grantKeyPairToApp(@Nullable android.content.ComponentName, @NonNull String, @NonNull String);
method public boolean grantKeyPairToWifiAuth(@NonNull String);
method public boolean hasCaCertInstalled(@Nullable android.content.ComponentName, byte[]);
method public boolean hasGrantedPolicy(@NonNull android.content.ComponentName, int);
method public boolean hasKeyPair(@NonNull String);
- method public boolean hasLockdownAdminConfiguredNetworks(@NonNull android.content.ComponentName);
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_WIFI, conditional=true) public boolean hasLockdownAdminConfiguredNetworks(@Nullable android.content.ComponentName);
method public boolean installCaCert(@Nullable android.content.ComponentName, byte[]);
method public boolean installExistingPackage(@NonNull android.content.ComponentName, String);
method public boolean installKeyPair(@Nullable android.content.ComponentName, @NonNull java.security.PrivateKey, @NonNull java.security.cert.Certificate, @NonNull String);
method public boolean installKeyPair(@Nullable android.content.ComponentName, @NonNull java.security.PrivateKey, @NonNull java.security.cert.Certificate[], @NonNull String, boolean);
method public boolean installKeyPair(@Nullable android.content.ComponentName, @NonNull java.security.PrivateKey, @NonNull java.security.cert.Certificate[], @NonNull String, int);
- method public void installSystemUpdate(@NonNull android.content.ComponentName, @NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback);
- method public boolean isActivePasswordSufficient();
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_SYSTEM_UPDATES, conditional=true) public void installSystemUpdate(@Nullable android.content.ComponentName, @NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback);
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional=true) public boolean isActivePasswordSufficient();
method public boolean isActivePasswordSufficientForDeviceRequirement();
method public boolean isAdminActive(@NonNull android.content.ComponentName);
method public boolean isAffiliatedUser();
method public boolean isAlwaysOnVpnLockdownEnabled(@NonNull android.content.ComponentName);
- method public boolean isApplicationHidden(@NonNull android.content.ComponentName, String);
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_PACKAGE_STATE, conditional=true) public boolean isApplicationHidden(@Nullable android.content.ComponentName, String);
method public boolean isBackupServiceEnabled(@NonNull android.content.ComponentName);
method @Deprecated public boolean isCallerApplicationRestrictionsManagingPackage();
method public boolean isCommonCriteriaModeEnabled(@Nullable android.content.ComponentName);
@@ -7927,15 +7927,15 @@
method public boolean isProvisioningAllowed(@NonNull String);
method public boolean isResetPasswordTokenActive(android.content.ComponentName);
method public boolean isSafeOperation(int);
- method public boolean isSecurityLoggingEnabled(@Nullable android.content.ComponentName);
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_SECURITY_LOGGING, conditional=true) public boolean isSecurityLoggingEnabled(@Nullable android.content.ComponentName);
method public boolean isStatusBarDisabled();
method public boolean isUninstallBlocked(@Nullable android.content.ComponentName, String);
method public boolean isUniqueDeviceAttestationSupported();
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);
@@ -7947,15 +7947,15 @@
method @Deprecated public boolean resetPassword(String, int);
method public boolean resetPasswordWithToken(@NonNull android.content.ComponentName, String, byte[], int);
method @Nullable public java.util.List<android.app.admin.NetworkEvent> retrieveNetworkLogs(@Nullable android.content.ComponentName, long);
- method @Nullable public java.util.List<android.app.admin.SecurityLog.SecurityEvent> retrievePreRebootSecurityLogs(@NonNull android.content.ComponentName);
- method @Nullable public java.util.List<android.app.admin.SecurityLog.SecurityEvent> retrieveSecurityLogs(@NonNull android.content.ComponentName);
+ method @Nullable @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_SECURITY_LOGGING, conditional=true) public java.util.List<android.app.admin.SecurityLog.SecurityEvent> retrievePreRebootSecurityLogs(@Nullable android.content.ComponentName);
+ method @Nullable @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_SECURITY_LOGGING, conditional=true) public java.util.List<android.app.admin.SecurityLog.SecurityEvent> retrieveSecurityLogs(@Nullable android.content.ComponentName);
method public boolean revokeKeyPairFromApp(@Nullable android.content.ComponentName, @NonNull String, @NonNull String);
method public boolean revokeKeyPairFromWifiAuth(@NonNull String);
method public void setAccountManagementDisabled(@NonNull android.content.ComponentName, String, boolean);
method public void setAffiliationIds(@NonNull android.content.ComponentName, @NonNull java.util.Set<java.lang.String>);
method public void setAlwaysOnVpnPackage(@NonNull android.content.ComponentName, @Nullable String, boolean) throws android.content.pm.PackageManager.NameNotFoundException;
method public void setAlwaysOnVpnPackage(@NonNull android.content.ComponentName, @Nullable String, boolean, @Nullable java.util.Set<java.lang.String>) throws android.content.pm.PackageManager.NameNotFoundException;
- method public boolean setApplicationHidden(@NonNull android.content.ComponentName, String, boolean);
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_PACKAGE_STATE, conditional=true) public boolean setApplicationHidden(@Nullable android.content.ComponentName, String, boolean);
method @WorkerThread public void setApplicationRestrictions(@Nullable android.content.ComponentName, String, android.os.Bundle);
method @Deprecated public void setApplicationRestrictionsManagingPackage(@NonNull android.content.ComponentName, @Nullable String) throws android.content.pm.PackageManager.NameNotFoundException;
method @RequiresPermission(value=android.Manifest.permission.SET_TIME, conditional=true) public void setAutoTimeEnabled(@NonNull android.content.ComponentName, boolean);
@@ -7966,7 +7966,7 @@
method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_CAMERA, conditional=true) public void setCameraDisabled(@Nullable android.content.ComponentName, boolean);
method @Deprecated public void setCertInstallerPackage(@NonNull android.content.ComponentName, @Nullable String) throws java.lang.SecurityException;
method public void setCommonCriteriaModeEnabled(@NonNull android.content.ComponentName, boolean);
- method public void setConfiguredNetworksLockdownState(@NonNull android.content.ComponentName, boolean);
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_WIFI, conditional=true) public void setConfiguredNetworksLockdownState(@Nullable android.content.ComponentName, boolean);
method public void setCredentialManagerPolicy(@Nullable android.app.admin.PackagePolicy);
method @Deprecated public void setCrossProfileCalendarPackages(@NonNull android.content.ComponentName, @Nullable java.util.Set<java.lang.String>);
method @Deprecated public void setCrossProfileCallerIdDisabled(@NonNull android.content.ComponentName, boolean);
@@ -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;
@@ -7994,11 +7994,11 @@
method public void setManagedProfileMaximumTimeOff(@NonNull android.content.ComponentName, long);
method public void setManagedSubscriptionsPolicy(@Nullable android.app.admin.ManagedSubscriptionsPolicy);
method public void setMasterVolumeMuted(@NonNull android.content.ComponentName, boolean);
- method public void setMaximumFailedPasswordsForWipe(@NonNull android.content.ComponentName, int);
- method public void setMaximumTimeToLock(@NonNull android.content.ComponentName, long);
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_WIPE_DATA, conditional=true) public void setMaximumFailedPasswordsForWipe(@Nullable android.content.ComponentName, int);
+ 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 public void setMinimumRequiredWifiSecurityLevel(int);
- method public void setMtePolicy(int);
+ 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);
method public void setNearbyAppStreamingPolicy(int);
method public void setNearbyNotificationStreamingPolicy(int);
method public void setNetworkLoggingEnabled(@Nullable android.content.ComponentName, boolean);
@@ -8007,7 +8007,7 @@
method @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY) public void setOrganizationName(@Nullable android.content.ComponentName, @Nullable CharSequence);
method public void setOverrideApnsEnabled(@NonNull android.content.ComponentName, boolean);
method @NonNull public String[] setPackagesSuspended(@NonNull android.content.ComponentName, @NonNull String[], boolean);
- method public void setPasswordExpirationTimeout(@NonNull android.content.ComponentName, long);
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional=true) public void setPasswordExpirationTimeout(@Nullable android.content.ComponentName, long);
method public void setPasswordHistoryLength(@NonNull android.content.ComponentName, int);
method @Deprecated public void setPasswordMinimumLength(@NonNull android.content.ComponentName, int);
method @Deprecated public void setPasswordMinimumLetters(@NonNull android.content.ComponentName, int);
@@ -8021,34 +8021,34 @@
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);
method public void setProfileEnabled(@NonNull android.content.ComponentName);
method public void setProfileName(@NonNull android.content.ComponentName, String);
method public void setRecommendedGlobalProxy(@NonNull android.content.ComponentName, @Nullable android.net.ProxyInfo);
- method public void setRequiredPasswordComplexity(int);
- method public void setRequiredStrongAuthTimeout(@NonNull android.content.ComponentName, long);
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional=true) public void setRequiredPasswordComplexity(int);
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional=true) public void setRequiredStrongAuthTimeout(@Nullable android.content.ComponentName, long);
method public boolean setResetPasswordToken(android.content.ComponentName, byte[]);
method public void setRestrictionsProvider(@NonNull android.content.ComponentName, @Nullable android.content.ComponentName);
- method public void setScreenCaptureDisabled(@NonNull android.content.ComponentName, boolean);
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_SCREEN_CAPTURE, conditional=true) public void setScreenCaptureDisabled(@Nullable android.content.ComponentName, boolean);
method public void setSecureSetting(@NonNull android.content.ComponentName, String, String);
- method public void setSecurityLoggingEnabled(@NonNull android.content.ComponentName, boolean);
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_SECURITY_LOGGING, conditional=true) public void setSecurityLoggingEnabled(@Nullable android.content.ComponentName, boolean);
method public void setShortSupportMessage(@NonNull android.content.ComponentName, @Nullable CharSequence);
method public void setStartUserSessionMessage(@NonNull android.content.ComponentName, @Nullable CharSequence);
method public boolean setStatusBarDisabled(@NonNull android.content.ComponentName, boolean);
method @Deprecated public int setStorageEncryption(@NonNull android.content.ComponentName, boolean);
method public void setSystemSetting(@NonNull android.content.ComponentName, @NonNull String, String);
- method public void setSystemUpdatePolicy(@NonNull android.content.ComponentName, android.app.admin.SystemUpdatePolicy);
+ 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 public void setUsbDataSignalingEnabled(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>);
method public void setUserIcon(@NonNull android.content.ComponentName, android.graphics.Bitmap);
- method public void setWifiSsidPolicy(@Nullable android.app.admin.WifiSsidPolicy);
+ method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_WIFI, conditional=true) public void setWifiSsidPolicy(@Nullable android.app.admin.WifiSsidPolicy);
method public int startUserInBackground(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle);
method public int stopUser(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle);
method public boolean switchUser(@NonNull android.content.ComponentName, @Nullable android.os.UserHandle);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index f8941c06..f3717d3 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -19,8 +19,24 @@
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;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_PACKAGE_STATE;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SCREEN_CAPTURE;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SECURITY_LOGGING;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SYSTEM_UPDATES;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WIFI;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WIPE_DATA;
import static android.Manifest.permission.QUERY_ADMIN_POLICY;
+import static android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY;
import static android.Manifest.permission.SET_TIME;
import static android.Manifest.permission.SET_TIME_ZONE;
import static android.content.Intent.LOCAL_FLAG_FROM_SYSTEM;
@@ -2218,7 +2234,7 @@
*
* <p>If an invalid value is used, it will be treated as {@link #PASSWORD_COMPLEXITY_NONE}.
*/
- @RequiresPermission(android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY)
+ @RequiresPermission(REQUEST_PASSWORD_COMPLEXITY)
public static final String EXTRA_PASSWORD_COMPLEXITY =
"android.app.extra.PASSWORD_COMPLEXITY";
@@ -3992,7 +4008,8 @@
public static @interface MtePolicy {}
/**
- * Called by a device owner or profile owner of an organization-owned device to set the Memory
+ * Called by a device owner, profile owner of an organization-owned device, or holder of the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_MTE} permission to set the Memory
* Tagging Extension (MTE) policy. MTE is a CPU extension that allows to protect against certain
* classes of security problems at a small runtime performance cost overhead.
*
@@ -4001,16 +4018,16 @@
*
* <p>The device needs to be rebooted to apply changes to the MTE policy.
*
- * @throws SecurityException if caller is not device owner or profile owner of org-owned device
- * or if called on a parent instance
+ * @throws SecurityException if caller is not permitted to set Mte policy
* @throws UnsupportedOperationException if the device does not support MTE
* @param policy the MTE policy to be set
*/
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_MTE, conditional = true)
public void setMtePolicy(@MtePolicy int policy) {
throwIfParentInstance("setMtePolicy");
if (mService != null) {
try {
- mService.setMtePolicy(policy);
+ mService.setMtePolicy(policy, mContext.getPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4018,21 +4035,22 @@
}
/**
- * Called by a device owner, a profile owner of an organization-owned device or the system to
+ * Called by a device owner, profile owner of an organization-owned device, or a holder of the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_MTE} permission to
* get the Memory Tagging Extension (MTE) policy
*
* <a href="https://source.android.com/docs/security/test/memory-safety/arm-mte">
* Learn more about MTE</a>
*
- * @throws SecurityException if caller is not device owner or profile owner of org-owned device
- * or system uid, or if called on a parent instance
+ * @throws SecurityException if caller is not permitted to set Mte policy
* @return the currently set MTE policy
*/
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_MTE, conditional = true)
public @MtePolicy int getMtePolicy() {
throwIfParentInstance("setMtePolicy");
if (mService != null) {
try {
- return mService.getMtePolicy();
+ return mService.getMtePolicy(mContext.getPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -5228,7 +5246,9 @@
}
/**
- * Called by a device admin to set the password expiration timeout. Calling this method will
+ * Called by a device admin or holder of the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS} permission to set
+ * the password expiration timeout. Calling this method will
* restart the countdown for password expiration for the given admin, as will changing the
* device password (for all admins).
* <p>
@@ -5241,7 +5261,7 @@
* On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
* password expiration is always disabled.
* <p>
- * The calling device admin must have requested
+ * A calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD} to be able to call this method; if it has
* not, a security exception will be thrown.
* <p>
@@ -5252,17 +5272,23 @@
* {@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 timeout The limit (in ms) that a password can remain in effect. A value of 0 means
* there is no restriction (unlimited).
* @throws SecurityException if {@code admin} is not an active administrator or {@code admin}
- * does not use {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD}
+ * does not use {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD} and the caller
+ * does not hold the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS}
+ * permission
*/
@RequiresFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN)
- public void setPasswordExpirationTimeout(@NonNull ComponentName admin, long timeout) {
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional = true)
+ public void setPasswordExpirationTimeout(@Nullable ComponentName admin, long timeout) {
if (mService != null) {
try {
- mService.setPasswordExpirationTimeout(admin, timeout, mParentInstance);
+ mService.setPasswordExpirationTimeout(
+ admin, mContext.getPackageName(), timeout, mParentInstance);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -5418,9 +5444,11 @@
*
* @return {@code true} if the password meets the policy requirements, {@code false} otherwise
* @throws SecurityException if the calling application isn't an active admin that uses
- * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD}
+ * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} and does not hold the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS} permission
* @throws IllegalStateException if the user isn't unlocked
*/
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional = true)
public boolean isActivePasswordSufficient() {
if (mService != null) {
try {
@@ -5484,7 +5512,8 @@
* <p>Note that when called from a profile which uses an unified challenge with its parent, the
* screen lock complexity of the parent will be returned.
*
- * <p>Apps need the {@link permission#REQUEST_PASSWORD_COMPLEXITY} permission to call this
+ * <p>Apps need the {@link permission#REQUEST_PASSWORD_COMPLEXITY} or
+ * {@link permission#MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS} permissions to call this
* method. On Android {@link android.os.Build.VERSION_CODES#S} and above, the calling
* application does not need this permission if it is a device owner or a profile owner.
*
@@ -5494,11 +5523,12 @@
*
* @throws IllegalStateException if the user is not unlocked.
* @throws SecurityException if the calling application does not have the permission
- * {@link permission#REQUEST_PASSWORD_COMPLEXITY}, and is not a
- * device owner or a profile owner.
+ * {@link permission#REQUEST_PASSWORD_COMPLEXITY} or
+ * {@link permission#MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS}, and
+ * is not a device owner or a profile owner.
*/
@PasswordComplexity
- @RequiresPermission(android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY)
+ @RequiresPermission(anyOf={MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, REQUEST_PASSWORD_COMPLEXITY}, conditional = true)
public int getPasswordComplexity() {
if (mService == null) {
return PASSWORD_COMPLEXITY_NONE;
@@ -5532,20 +5562,23 @@
* with {@link #PASSWORD_QUALITY_UNSPECIFIED} on that instance prior to setting complexity
* requirement for the managed profile.
*
- * @throws SecurityException if the calling application is not a device owner or a profile
- * owner.
+ * @throws SecurityException if the calling application is not a device owner, a profile
+ * owner, or a holder of the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS} permission.
* @throws IllegalArgumentException if the complexity level is not one of the four above.
* @throws IllegalStateException if the caller is trying to set password complexity while there
* are password requirements specified using {@link #setPasswordQuality(ComponentName, int)}
* on the parent {@code DevicePolicyManager} instance.
*/
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional = true)
public void setRequiredPasswordComplexity(@PasswordComplexity int passwordComplexity) {
if (mService == null) {
return;
}
try {
- mService.setRequiredPasswordComplexity(passwordComplexity, mParentInstance);
+ mService.setRequiredPasswordComplexity(
+ mContext.getPackageName(), passwordComplexity, mParentInstance);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -5565,9 +5598,11 @@
* restrictions on the parent profile.
*
* @throws SecurityException if the calling application is not a device owner or a profile
- * owner.
+ * owner and does not hold the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS} permission.
*/
@PasswordComplexity
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional = true)
public int getRequiredPasswordComplexity() {
if (mService == null) {
return PASSWORD_COMPLEXITY_NONE;
@@ -5675,9 +5710,11 @@
* @return The number of times user has entered an incorrect password since the last correct
* password entry.
* @throws SecurityException if the calling application does not own an active administrator
- * that uses {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN}
+ * that uses {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} and does not hold the
+ * @link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS} permission.
*/
@RequiresFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN)
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional = true)
public int getCurrentFailedPasswordAttempts() {
return getCurrentFailedPasswordAttempts(myUserId());
}
@@ -5722,16 +5759,16 @@
}
/**
- * Setting this to a value greater than zero enables a built-in policy that will perform a
+ * Setting this to a value greater than zero enables a policy that will perform a
* device or profile wipe after too many incorrect device-unlock passwords have been entered.
- * This built-in policy combines watching for failed passwords and wiping the device, and
- * requires that you request both {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} and
+ * This policy combines watching for failed passwords and wiping the device, and
+ * requires that calling Device Admins request both
+ * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} and
* {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA}}.
* <p>
- * When this policy is set by a device owner, profile owner of an organization-owned device or
- * an admin on the primary user, the device will be factory reset after too many incorrect
- * password attempts. When set by a profile owner or an admin on a secondary user or a managed
- * profile, only the corresponding user or profile will be wiped.
+ * When this policy is set on the system or the main user, the device will be factory reset
+ * after too many incorrect password attempts. When set on any other user, only the
+ * corresponding user or profile will be wiped.
* <p>
* To implement any other policy (e.g. wiping data for a particular application only, erasing or
* revoking credentials, or reporting the failure to a server), you should implement
@@ -5744,19 +5781,27 @@
* profile.
* <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
* password is always empty and this method has no effect - i.e. the policy is not set.
+ * <p>
+ * This policy can be set by holders of the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_WIPE_DATA} permission.
*
- * @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 num The number of failed password attempts at which point the device or profile will
* be wiped.
- * @throws SecurityException if {@code admin} is not an active administrator or does not use
- * both {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} and
- * {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA}.
+ * @throws SecurityException if {@code admin} is not null, and {@code admin} is not an active
+ * administrator or does not use both
+ * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} and
+ * {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA}, or if {@code admin} is null and the
+ * caller does not have permission to wipe the device.
*/
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_WIPE_DATA, conditional = true)
@RequiresFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN)
- public void setMaximumFailedPasswordsForWipe(@NonNull ComponentName admin, int num) {
+ public void setMaximumFailedPasswordsForWipe(@Nullable ComponentName admin, int num) {
if (mService != null) {
try {
- mService.setMaximumFailedPasswordsForWipe(admin, num, mParentInstance);
+ mService.setMaximumFailedPasswordsForWipe(
+ admin, mContext.getPackageName(), num, mParentInstance);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -6054,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();
}
@@ -6109,7 +6157,9 @@
}
/**
- * Called by a device/profile owner to set the timeout after which unlocking with secondary, non
+ * Called by a device owner, profile owner, or holder of the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS} permission to set
+ * the timeout after which unlocking with secondary, non
* strong auth (e.g. fingerprint, face, trust agents) times out, i.e. the user has to use a
* strong authentication method like password, pin or pattern.
*
@@ -6120,10 +6170,7 @@
*
* <p>Trust agents can also be disabled altogether using {@link #KEYGUARD_DISABLE_TRUST_AGENTS}.
*
- * <p>The calling device admin must be a device or profile owner. If it is not,
- * a {@link SecurityException} will be thrown.
- *
- * <p>The calling device admin can verify the value it has set by calling
+ * <p>A calling device admin can verify the value it has set by calling
* {@link #getRequiredStrongAuthTimeout(ComponentName)} and passing in its instance.
*
* <p>This method can be called on the {@link DevicePolicyManager} instance returned by
@@ -6133,7 +6180,8 @@
* <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature,
* calling this methods has no effect - i.e. the timeout is not 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 timeoutMs The new timeout in milliseconds, after which the user will have to unlock
* with strong authentication method. A value of 0 means the admin is not participating
* in controlling the timeout.
@@ -6142,14 +6190,17 @@
* auth at all times using {@link #KEYGUARD_DISABLE_FINGERPRINT} and/or
* {@link #KEYGUARD_DISABLE_TRUST_AGENTS}.
*
- * @throws SecurityException if {@code admin} is not a device or profile owner.
+ * @throws SecurityException if {@code admin} is not permitted to set this policy.
+ *
*/
@RequiresFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN)
- public void setRequiredStrongAuthTimeout(@NonNull ComponentName admin,
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, conditional = true)
+ public void setRequiredStrongAuthTimeout(@Nullable ComponentName admin,
long timeoutMs) {
if (mService != null) {
try {
- mService.setRequiredStrongAuthTimeout(admin, timeoutMs, mParentInstance);
+ mService.setRequiredStrongAuthTimeout(
+ admin, mContext.getPackageName(), timeoutMs, mParentInstance);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -6217,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
@@ -6241,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);
}
@@ -6253,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
@@ -6261,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
@@ -6287,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 {
@@ -6441,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();
}
@@ -6466,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");
@@ -8318,9 +8381,11 @@
}
/**
- * Called by a device/profile owner to set whether the screen capture is disabled. Disabling
- * screen capture also prevents the content from being shown on display devices that do not have
- * a secure video output. See {@link android.view.Display#FLAG_SECURE} for more details about
+ * Called by a device owner, profile owner, or holder of the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_SCREEN_CAPTURE} permission to set
+ * whether the screen capture is disabled. Disabling screen capture also prevents the
+ * content from being shown on display devices that do not have a secure video output.
+ * See {@link android.view.Display#FLAG_SECURE} for more details about
* secure surfaces and secure displays.
* <p>
* This method can be called on the {@link DevicePolicyManager} instance, returned by
@@ -8334,16 +8399,17 @@
* From version {@link android.os.Build.VERSION_CODES#M} disabling screen capture also blocks
* assist requests for all activities of the relevant user.
*
- * @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 disabled Whether screen capture is disabled or not.
- * @throws SecurityException if {@code admin} is not a device or 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 the caller is not permitted to control screen capture policy.
*/
- public void setScreenCaptureDisabled(@NonNull ComponentName admin, boolean disabled) {
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_SCREEN_CAPTURE, conditional = true)
+ public void setScreenCaptureDisabled(@Nullable ComponentName admin, boolean disabled) {
if (mService != null) {
try {
- mService.setScreenCaptureDisabled(admin, disabled, mParentInstance);
+ mService.setScreenCaptureDisabled(
+ admin, mContext.getPackageName(), disabled, mParentInstance);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -8678,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>
@@ -8717,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
@@ -8729,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();
}
@@ -8781,7 +8851,7 @@
@TestApi
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@RequiresPermission(allOf = {
- android.Manifest.permission.MANAGE_DEVICE_ADMINS,
+ MANAGE_DEVICE_ADMINS,
INTERACT_ACROSS_USERS_FULL
})
public void setActiveAdmin(@NonNull ComponentName policyReceiver, boolean refreshing,
@@ -9209,7 +9279,7 @@
*/
@Deprecated
@SystemApi
- @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS)
+ @RequiresPermission(MANAGE_DEVICE_ADMINS)
public boolean setActiveProfileOwner(@NonNull ComponentName admin, @Deprecated String ownerName)
throws IllegalArgumentException {
throwIfParentInstance("setActiveProfileOwner");
@@ -9887,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>
@@ -9898,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();
}
@@ -10592,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
@@ -10618,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();
}
@@ -10655,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();
}
@@ -11477,9 +11561,10 @@
/**
* Hide or unhide packages. When a package is hidden it is unavailable for use, but the data and
- * actual package file remain. This function can be called by a device owner, profile owner, or
- * by a delegate given the {@link #DELEGATION_PACKAGE_ACCESS} scope via
- * {@link #setDelegatedScopes}.
+ * actual package file remain. This function can be called by a device owner, profile owner,
+ * delegate given the {@link #DELEGATION_PACKAGE_ACCESS} scope via
+ * {@link #setDelegatedScopes}, or a holder of the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_PACKAGE_STATE} permission.
* <p>
* This method can be called on the {@link DevicePolicyManager} instance, returned by
* {@link #getParentProfileInstance(ComponentName)}, where the caller must be the profile owner
@@ -11487,7 +11572,7 @@
* on the parent instance, then the package is hidden or unhidden in the personal profile.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
- * {@code null} if the caller is a package access delegate.
+ * {@code null} if the caller is not a device admin.
* @param packageName The name of the package to hide or unhide.
* @param hidden {@code true} if the package should be hidden, {@code false} if it should be
* unhidden.
@@ -11500,7 +11585,8 @@
* @see #setDelegatedScopes
* @see #DELEGATION_PACKAGE_ACCESS
*/
- public boolean setApplicationHidden(@NonNull ComponentName admin, String packageName,
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_PACKAGE_STATE, conditional = true)
+ public boolean setApplicationHidden(@Nullable ComponentName admin, String packageName,
boolean hidden) {
if (mService != null) {
try {
@@ -11515,8 +11601,9 @@
/**
* Determine if a package is hidden. This function can be called by a device owner, profile
- * owner, or by a delegate given the {@link #DELEGATION_PACKAGE_ACCESS} scope via
- * {@link #setDelegatedScopes}.
+ * owner, delegate given the {@link #DELEGATION_PACKAGE_ACCESS} scope via
+ * {@link #setDelegatedScopes}, or a holder of the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_PACKAGE_STATE} permission.
* <p>
* This method can be called on the {@link DevicePolicyManager} instance, returned by
* {@link #getParentProfileInstance(ComponentName)}, where the caller must be the profile owner
@@ -11525,7 +11612,7 @@
* personal profile.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
- * {@code null} if the caller is a package access delegate.
+ * {@code null} if the caller is not a device admin.
* @param packageName The name of the package to retrieve the hidden status of.
* @return boolean {@code true} if the package is hidden, {@code false} otherwise.
* @throws SecurityException if {@code admin} is not a device or profile owner or if called on
@@ -11536,7 +11623,8 @@
* @see #setDelegatedScopes
* @see #DELEGATION_PACKAGE_ACCESS
*/
- public boolean isApplicationHidden(@NonNull ComponentName admin, String packageName) {
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_PACKAGE_STATE, conditional = true)
+ public boolean isApplicationHidden(@Nullable ComponentName admin, String packageName) {
if (mService != null) {
try {
return mService.isApplicationHidden(admin, mContext.getPackageName(), packageName,
@@ -12095,7 +12183,8 @@
}
/**
- * Called by a device owner or a profile owner of an organization-owned managed profile to
+ * Called by a device owner, profile owner of an organization-owned managed profile, or holder
+ * of the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_WIFI} permission to
* control whether the user can change networks configured by the admin. When this lockdown is
* enabled, the user can still configure and connect to other Wi-Fi networks, or use other Wi-Fi
* capabilities such as tethering.
@@ -12107,17 +12196,19 @@
* to this API.
*
* @param admin admin Which {@link DeviceAdminReceiver} this request is associated
- * with.
+ * with. Null if the caller is not a device admin.
* @param lockdown Whether the admin configured networks should be unmodifiable by the
* user.
- * @throws SecurityException if caller is not a device owner or a profile owner of an
- * organization-owned managed profile.
+ * @throws SecurityException if caller is not permitted to modify this policy
*/
- public void setConfiguredNetworksLockdownState(@NonNull ComponentName admin, boolean lockdown) {
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_WIFI, conditional = true)
+ public void setConfiguredNetworksLockdownState(
+ @Nullable ComponentName admin, boolean lockdown) {
throwIfParentInstance("setConfiguredNetworksLockdownState");
if (mService != null) {
try {
- mService.setConfiguredNetworksLockdownState(admin, lockdown);
+ mService.setConfiguredNetworksLockdownState(
+ admin, mContext.getPackageName(), lockdown);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -12125,15 +12216,19 @@
}
/**
- * Called by a device owner or a profile owner of an organization-owned managed profile to
+ * Called by a device owner, profile owner of an organization-owned managed profile, or holder
+ * of the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_WIFI} permission to
* determine whether the user is prevented from modifying networks configured by the admin.
*
* @param admin admin Which {@link DeviceAdminReceiver} this request is associated
- * with.
- * @throws SecurityException if caller is not a device owner or a profile owner of an
- * organization-owned managed profile.
+ * with. Null if the caller is not a device admin.
+ * @throws SecurityException if caller is not a device owner, a profile owner of an
+ * organization-owned managed profile, or holder of the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_WIFI}
+ * permission.
*/
- public boolean hasLockdownAdminConfiguredNetworks(@NonNull ComponentName admin) {
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_WIFI, conditional = true)
+ public boolean hasLockdownAdminConfiguredNetworks(@Nullable ComponentName admin) {
throwIfParentInstance("hasLockdownAdminConfiguredNetworks");
if (mService != null) {
try {
@@ -12500,9 +12595,10 @@
}
/**
- * Called by device owners or profile owners of an organization-owned managed profile to to set
- * a local system update policy. When a new policy is set,
- * {@link #ACTION_SYSTEM_UPDATE_POLICY_CHANGED} is broadcasted.
+ * Called by a device owner, profile owners of an organization-owned managed profile, or a
+ * holder of the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_SYSTEM_UPDATES}
+ * permission to set a local system update policy. When a new policy is set,
+ * {@link #ACTION_SYSTEM_UPDATE_POLICY_CHANGED} is broadcast.
* <p>
* If the supplied system update policy has freeze periods set but the freeze periods do not
* meet 90-day maximum length or 60-day minimum separation requirement set out in
@@ -12516,22 +12612,24 @@
* {@code adb shell dpm clear-freeze-period-record} can be used to clear the record.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with. All
- * components in the device owner package can set system update policies and the most
- * recent policy takes effect.
+ * components in the package can set system update policies and the most
+ * recent policy takes effect. This should be null if the caller is not a device
+ * admin.
* @param policy the new 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 managed profile.
+ * organization-owned managed profile, or the caller is not permitted to set this policy
* @throws IllegalArgumentException if the policy type or maintenance window is not valid.
* @throws SystemUpdatePolicy.ValidationFailedException if the policy's freeze period does not
* meet the requirement.
* @see SystemUpdatePolicy
* @see SystemUpdatePolicy#setFreezePeriods(List)
*/
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_SYSTEM_UPDATES, conditional = true)
public void setSystemUpdatePolicy(@NonNull ComponentName admin, SystemUpdatePolicy policy) {
throwIfParentInstance("setSystemUpdatePolicy");
if (mService != null) {
try {
- mService.setSystemUpdatePolicy(admin, policy);
+ mService.setSystemUpdatePolicy(admin, mContext.getPackageName(), policy);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -12989,7 +13087,7 @@
}
/**
- * Called by device owner, or profile owner on organization-owned device, to get the MAC
+ * Called by a device owner or profile owner on organization-owned device to get the MAC
* address of the Wi-Fi device.
*
* NOTE: The MAC address returned here should only be used for inventory management and is
@@ -12998,17 +13096,19 @@
* To get the randomized MAC address used, call
* {@link android.net.wifi.WifiConfiguration#getRandomizedMacAddress}.
*
- * @param admin Which device owner this request is associated with.
+ * @param admin Which admin this request is associated with. Null if the caller is not a device
+ * admin
* @return the MAC address of the Wi-Fi device, or null when the information is not available.
* (For example, Wi-Fi hasn't been enabled, or the device doesn't support Wi-Fi.)
* <p>
* The address will be in the {@code XX:XX:XX:XX:XX:XX} format.
- * @throws SecurityException if {@code admin} is not a device owner.
+ * @throws SecurityException if {@code admin} is not permitted to get wifi mac addresses
*/
- public @Nullable String getWifiMacAddress(@NonNull ComponentName admin) {
+// @RequiresPermission(value = MANAGE_DEVICE_POLICY_WIFI, conditional = true)
+ public @Nullable String getWifiMacAddress(@Nullable ComponentName admin) {
throwIfParentInstance("getWifiMacAddress");
try {
- return mService.getWifiMacAddress(admin);
+ return mService.getWifiMacAddress(admin, mContext.getPackageName());
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -13249,31 +13349,34 @@
}
/**
- * Called by device owner or a profile owner of an organization-owned managed profile to
- * control the security logging feature.
+ * Called by a device owner, profile owner of an organization-owned managed profile, or holder
+ * of the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_SECURITY_LOGGING} permission
+ * to control the security logging feature.
*
* <p> Security logs contain various information intended for security auditing purposes.
- * When security logging is enabled by a profile owner of
- * an organization-owned managed profile, certain security logs are not visible (for example
- * personal app launch events) or they will be redacted (for example, details of the physical
- * volume mount events). Please see {@link SecurityEvent} for details.
+ * When security logging is enabled by any app other than the device owner, certain security
+ * logs are not visible (for example personal app launch events) or they will be redacted
+ * (for example, details of the physical volume mount events).
+ * Please see {@link SecurityEvent} for details.
*
* <p><strong>Note:</strong> The device owner won't be able to retrieve security logs if there
* are unaffiliated secondary users or profiles on the device, regardless of whether the
* feature is enabled. Logs will be discarded if the internal buffer fills up while waiting for
* all users to become affiliated. Therefore it's recommended that affiliation ids are set for
- * new users as soon as possible after provisioning via {@link #setAffiliationIds}. Profile
- * owner of organization-owned managed profile is not subject to this restriction since all
+ * new users as soon as possible after provisioning via {@link #setAffiliationIds}. Non device
+ * owners are not subject to this restriction since all
* privacy-sensitive events happening outside the managed profile would have been redacted
* already.
*
- * @param admin Which device admin this request is associated with.
+ * @param admin Which device admin this request is associated with. Null if the caller is not
+ * a device admin
* @param enabled whether security logging should be enabled or not.
- * @throws SecurityException if {@code admin} is not allowed to control security logging.
+ * @throws SecurityException if the caller is not permitted to control security logging.
* @see #setAffiliationIds
* @see #retrieveSecurityLogs
*/
- public void setSecurityLoggingEnabled(@NonNull ComponentName admin, boolean enabled) {
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_SECURITY_LOGGING, conditional = true)
+ public void setSecurityLoggingEnabled(@Nullable ComponentName admin, boolean enabled) {
throwIfParentInstance("setSecurityLoggingEnabled");
try {
mService.setSecurityLoggingEnabled(admin, mContext.getPackageName(), enabled);
@@ -13285,13 +13388,17 @@
/**
* Return whether security logging is enabled or not by the admin.
*
- * <p>Can only be called by the device owner or a profile owner of an organization-owned
- * managed profile, otherwise a {@link SecurityException} will be thrown.
+ * <p>Can only be called by a device owner, a profile owner of an organization-owned
+ * managed profile, or a holder of the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_SECURITY_LOGGING} permission
+ * otherwise a {@link SecurityException} will be thrown.
*
- * @param admin Which device admin this request is associated with.
- * @return {@code true} if security logging is enabled by device owner, {@code false} otherwise.
- * @throws SecurityException if {@code admin} is not allowed to control security logging.
+ * @param admin Which device admin this request is associated with. Null if the caller is not
+ * a device admin
+ * @return {@code true} if security logging is enabled, {@code false} otherwise.
+ * @throws SecurityException if the caller is not allowed to control security logging.
*/
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_SECURITY_LOGGING, conditional = true)
public boolean isSecurityLoggingEnabled(@Nullable ComponentName admin) {
throwIfParentInstance("isSecurityLoggingEnabled");
try {
@@ -13302,26 +13409,30 @@
}
/**
- * Called by device owner or profile owner of an organization-owned managed profile to retrieve
- * all new security logging entries since the last call to this API after device boots.
+ * Called by a device owner, profile owner of an organization-owned managed profile, or holder
+ * of the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_SECURITY_LOGGING} permission
+ * to retrieve all new security logging entries since the last call to this API after device
+ * boots.
*
- * <p> Access to the logs is rate limited and it will only return new logs after the device
- * owner has been notified via {@link DeviceAdminReceiver#onSecurityLogsAvailable}.
+ * <p> Access to the logs is rate limited and it will only return new logs after the admin has
+ * been notified via {@link DeviceAdminReceiver#onSecurityLogsAvailable}.
*
* <p> When called by a device owner, if there is any other user or profile on the device,
* it must be affiliated with the device. Otherwise a {@link SecurityException} will be thrown.
* See {@link #isAffiliatedUser}.
*
- * @param admin Which device admin this request is associated with.
+ * @param admin Which device admin this request is associated with. Null if the caller is not
+ * a device admin.
* @return the new batch of security logs which is a list of {@link SecurityEvent},
* or {@code null} if rate limitation is exceeded or if logging is currently disabled.
- * @throws SecurityException if {@code admin} is not allowed to access security logging,
+ * @throws SecurityException if the caller is not allowed to access security logging,
* or there is at least one profile or secondary user that is not affiliated with the device.
* @see #isAffiliatedUser
* @see DeviceAdminReceiver#onSecurityLogsAvailable
*/
@SuppressLint("NullableCollection")
- public @Nullable List<SecurityEvent> retrieveSecurityLogs(@NonNull ComponentName admin) {
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_SECURITY_LOGGING, conditional = true)
+ public @Nullable List<SecurityEvent> retrieveSecurityLogs(@Nullable ComponentName admin) {
throwIfParentInstance("retrieveSecurityLogs");
try {
ParceledListSlice<SecurityEvent> list = mService.retrieveSecurityLogs(
@@ -13455,8 +13566,9 @@
}
/**
- * Called by device owner or profile owner of an organization-owned managed profile to retrieve
- * device logs from before the device's last reboot.
+ * Called by a device owner, profile owner of an organization-owned managed profile, or holder
+ * of the {@link android.Manfiest.permission#MANAGE_DEVICE_POLICY_SECURITY_LOGGING} permission
+ * to retrieve device logs from before the device's last reboot.
* <p>
* <strong> This API is not supported on all devices. Calling this API on unsupported devices
* will result in {@code null} being returned. The device logs are retrieved from a RAM region
@@ -13467,17 +13579,19 @@
* it must be affiliated with the device. Otherwise a {@link SecurityException} will be thrown.
* See {@link #isAffiliatedUser}.
*
- * @param admin Which device admin this request is associated with.
+ * @param admin Which device admin this request is associated with. Null if the caller is not
+ * a device admin.
* @return Device logs from before the latest reboot of the system, or {@code null} if this API
* is not supported on the device.
- * @throws SecurityException if {@code admin} is not allowed to access security logging, or
+ * @throws SecurityException if the caller is not allowed to access security logging, or
* there is at least one profile or secondary user that is not affiliated with the device.
* @see #isAffiliatedUser
* @see #retrieveSecurityLogs
*/
@SuppressLint("NullableCollection")
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_SECURITY_LOGGING, conditional = true)
public @Nullable List<SecurityEvent> retrievePreRebootSecurityLogs(
- @NonNull ComponentName admin) {
+ @Nullable ComponentName admin) {
throwIfParentInstance("retrievePreRebootSecurityLogs");
try {
ParceledListSlice<SecurityEvent> list = mService.retrievePreRebootSecurityLogs(
@@ -14837,8 +14951,9 @@
}
/**
- * Called by device owner or profile owner of an organization-owned managed profile to install
- * a system update from the given file. The device will be
+ * Called by a device owner, profile owner of an organization-owned managed profile, or a holder
+ * of the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_SYSTEM_UPDATES} permission to
+ * install a system update from the given file. The device will be
* rebooted in order to finish installing the update. Note that if the device is rebooted, this
* doesn't necessarily mean that the update has been applied successfully. The caller should
* additionally check the system version with {@link android.os.Build#FINGERPRINT} or {@link
@@ -14847,15 +14962,17 @@
* sufficient battery level, the installation will fail with error {@link
* InstallSystemUpdateCallback#UPDATE_ERROR_BATTERY_LOW}.
*
- * @param admin The {@link DeviceAdminReceiver} that this request is associated with.
- * @param updateFilePath An Uri of the file that contains the update. The file should be
+ * @param admin The {@link DeviceAdminReceiver} that this request is associated with. Null if
+ * the caller is not a device admin
+ * @param updateFilePath A Uri of the file that contains the update. The file should be
* readable by the calling app.
* @param executor The executor through which the callback should be invoked.
* @param callback A callback object that will inform the caller when installing an update
* fails.
*/
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_SYSTEM_UPDATES, conditional = true)
public void installSystemUpdate(
- @NonNull ComponentName admin, @NonNull Uri updateFilePath,
+ @Nullable ComponentName admin, @NonNull Uri updateFilePath,
@NonNull @CallbackExecutor Executor executor,
@NonNull InstallSystemUpdateCallback callback) {
throwIfParentInstance("installUpdate");
@@ -14865,7 +14982,8 @@
try (ParcelFileDescriptor fileDescriptor = mContext.getContentResolver()
.openFileDescriptor(updateFilePath, "r")) {
mService.installUpdateFromFile(
- admin, fileDescriptor, new StartInstallingUpdateCallback.Stub() {
+ admin, mContext.getPackageName(), fileDescriptor,
+ new StartInstallingUpdateCallback.Stub() {
@Override
public void onStartInstallingUpdateError(
int errorCode, String errorMessage) {
@@ -15691,7 +15809,7 @@
* @hide
*/
@TestApi
- @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS)
+ @RequiresPermission(MANAGE_DEVICE_ADMINS)
public void setNextOperationSafety(@DevicePolicyOperation int operation,
@OperationSafetyReason int reason) {
if (mService != null) {
@@ -16007,20 +16125,21 @@
}
/**
- * Called by device owner or profile owner of an organization-owned managed profile to
- * enable or disable USB data signaling for the device. When disabled, USB data connections
- * (except from charging functions) are prohibited.
+ * Called by a device owner, profile owner of an organization-owned managed profile, or holder
+ * of the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING}
+ * permission to enable or disable USB data signaling for the device. When disabled, USB data
+ * connections (except from charging functions) are prohibited.
*
* <p> This API is not supported on all devices, the caller should call
* {@link #canUsbDataSignalingBeDisabled()} to check whether enabling or disabling USB data
* signaling is supported on the device.
*
* @param enabled whether USB data signaling should be enabled or not.
- * @throws SecurityException if the caller is not a device owner or a profile owner on
- * an organization-owned managed profile.
+ * @throws SecurityException if the caller is not permitted to set this policy
* @throws IllegalStateException if disabling USB data signaling is not supported or
* if USB data signaling fails to be enabled/disabled.
*/
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING, conditional = true)
public void setUsbDataSignalingEnabled(boolean enabled) {
throwIfParentInstance("setUsbDataSignalingEnabled");
if (mService != null) {
@@ -16114,7 +16233,7 @@
* @hide
*/
@TestApi
- @RequiresPermission(value = android.Manifest.permission.MANAGE_DEVICE_ADMINS)
+ @RequiresPermission(value = MANAGE_DEVICE_ADMINS)
public @NonNull Set<String> getPolicyExemptApps() {
if (mService == null) return Collections.emptySet();
@@ -16155,7 +16274,8 @@
}
/**
- * Called by device owner or profile owner of an organization-owned managed profile to
+ * Called by a device owner, profile owner of an organization-owned managed profile, or holder
+ * of the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_WIFI} permission to
* specify the minimum security level required for Wi-Fi networks.
* The device may not connect to networks that do not meet the minimum security level.
* If the current network does not meet the minimum security level set, it will be disconnected.
@@ -16167,14 +16287,14 @@
* {@link #WIFI_SECURITY_ENTERPRISE_192}
*
* @param level minimum security level
- * @throws SecurityException if the caller is not a device owner or a profile owner on
- * an organization-owned managed profile.
+ * @throws SecurityException if the caller is not permitted to set this policy
*/
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_WIFI, conditional = true)
public void setMinimumRequiredWifiSecurityLevel(@WifiSecurity int level) {
throwIfParentInstance("setMinimumRequiredWifiSecurityLevel");
if (mService != null) {
try {
- mService.setMinimumRequiredWifiSecurityLevel(level);
+ mService.setMinimumRequiredWifiSecurityLevel(mContext.getPackageName(), level);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -16199,23 +16319,24 @@
}
/**
- * Called by device owner or profile owner of an organization-owned managed profile to
+ * Called by device owner, profile owner of an organization-owned managed profile, or holder of
+ * the {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_WIFI} permission to
* specify the Wi-Fi SSID policy ({@link WifiSsidPolicy}).
* Wi-Fi SSID policy specifies the SSID restriction the network must satisfy
* in order to be eligible for a connection. Providing a null policy results in the
* deactivation of the SSID restriction
*
* @param policy Wi-Fi SSID policy
- * @throws SecurityException if the caller is not a device owner or a profile owner on
- * an organization-owned managed profile.
+ * @throws SecurityException if the caller is not permitted to manage wifi policy
*/
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_WIFI, conditional = true)
public void setWifiSsidPolicy(@Nullable WifiSsidPolicy policy) {
throwIfParentInstance("setWifiSsidPolicy");
if (mService == null) {
return;
}
try {
- mService.setWifiSsidPolicy(policy);
+ mService.setWifiSsidPolicy(mContext.getPackageName(), policy);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -16227,9 +16348,9 @@
* If the policy has not been set, it will return NULL.
*
* @see #setWifiSsidPolicy(WifiSsidPolicy)
- * @throws SecurityException if the caller is not a device owner or a profile owner on
- * an organization-owned managed profile.
+ * @throws SecurityException if the caller is not permitted to manage wifi policy
*/
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_WIFI, conditional = true)
@Nullable
public WifiSsidPolicy getWifiSsidPolicy() {
throwIfParentInstance("getWifiSsidPolicy");
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 132d616..14c6ecd 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -91,7 +91,7 @@
void setPasswordHistoryLength(in ComponentName who, int length, boolean parent);
int getPasswordHistoryLength(in ComponentName who, int userHandle, boolean parent);
- void setPasswordExpirationTimeout(in ComponentName who, long expiration, boolean parent);
+ void setPasswordExpirationTimeout(in ComponentName who, String callerPackageName, long expiration, boolean parent);
long getPasswordExpirationTimeout(in ComponentName who, int userHandle, boolean parent);
long getPasswordExpiration(in ComponentName who, int userHandle, boolean parent);
@@ -100,22 +100,23 @@
boolean isActivePasswordSufficientForDeviceRequirement();
boolean isPasswordSufficientAfterProfileUnification(int userHandle, int profileUser);
int getPasswordComplexity(boolean parent);
- void setRequiredPasswordComplexity(int passwordComplexity, boolean parent);
+ void setRequiredPasswordComplexity(String callerPackageName, int passwordComplexity, boolean parent);
int getRequiredPasswordComplexity(boolean parent);
int getAggregatedPasswordComplexityForUser(int userId, boolean deviceWideOnly);
boolean isUsingUnifiedPassword(in ComponentName admin);
int getCurrentFailedPasswordAttempts(int userHandle, boolean parent);
int getProfileWithMinimumFailedPasswordsForWipe(int userHandle, boolean parent);
- void setMaximumFailedPasswordsForWipe(in ComponentName admin, int num, boolean parent);
+ void setMaximumFailedPasswordsForWipe(
+ in ComponentName admin, String callerPackageName, int num, boolean parent);
int getMaximumFailedPasswordsForWipe(in ComponentName admin, int userHandle, boolean parent);
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, long timeMs, boolean parent);
+ void setRequiredStrongAuthTimeout(in ComponentName who, String callerPackageName, long timeMs, boolean parent);
long getRequiredStrongAuthTimeout(in ComponentName who, int userId, boolean parent);
void lockNow(int flags, boolean parent);
@@ -125,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();
@@ -144,7 +145,8 @@
void setCameraDisabled(in ComponentName who, String callerPackageName, boolean disabled, boolean parent);
boolean getCameraDisabled(in ComponentName who, int userHandle, boolean parent);
- void setScreenCaptureDisabled(in ComponentName who, boolean disabled, boolean parent);
+ void setScreenCaptureDisabled(
+ in ComponentName who, String callerPackageName, boolean disabled, boolean parent);
boolean getScreenCaptureDisabled(in ComponentName who, int userHandle, boolean parent);
void setNearbyNotificationStreamingPolicy(int policy);
@@ -153,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);
@@ -260,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);
@@ -312,7 +314,7 @@
void setSystemSetting(in ComponentName who, in String setting, in String value);
void setSecureSetting(in ComponentName who, in String setting, in String value);
- void setConfiguredNetworksLockdownState(in ComponentName who, boolean lockdown);
+ void setConfiguredNetworksLockdownState(in ComponentName who, String callerPackageName, boolean lockdown);
boolean hasLockdownAdminConfiguredNetworks(in ComponentName who);
void setLocationEnabled(in ComponentName who, boolean locationEnabled);
@@ -351,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);
@@ -376,7 +378,7 @@
void setUserIcon(in ComponentName admin, in Bitmap icon);
- void setSystemUpdatePolicy(in ComponentName who, in SystemUpdatePolicy policy);
+ void setSystemUpdatePolicy(in ComponentName who, String callerPackageName, in SystemUpdatePolicy policy);
SystemUpdatePolicy getSystemUpdatePolicy();
void clearSystemUpdatePolicyFreezePeriodRecord();
@@ -398,7 +400,7 @@
void setKeepUninstalledPackages(in ComponentName admin, in String callerPackage, in List<String> packageList);
List<String> getKeepUninstalledPackages(in ComponentName admin, in String callerPackage);
boolean isManagedProfile(in ComponentName admin);
- String getWifiMacAddress(in ComponentName admin);
+ String getWifiMacAddress(in ComponentName admin, String callerPackageName);
void reboot(in ComponentName admin);
void setShortSupportMessage(in ComponentName admin, in CharSequence message);
@@ -502,7 +504,7 @@
void setProfileOwnerOnOrganizationOwnedDevice(in ComponentName who, int userId, boolean isProfileOwnerOnOrganizationOwnedDevice);
- void installUpdateFromFile(in ComponentName admin, in ParcelFileDescriptor updateFileDescriptor, in StartInstallingUpdateCallback listener);
+ void installUpdateFromFile(in ComponentName admin, String callerPackageName, in ParcelFileDescriptor updateFileDescriptor, in StartInstallingUpdateCallback listener);
void setCrossProfileCalendarPackages(in ComponentName admin, in List<String> packageNames);
List<String> getCrossProfileCalendarPackages(in ComponentName admin);
@@ -565,10 +567,10 @@
boolean isUsbDataSignalingEnabledForUser(int userId);
boolean canUsbDataSignalingBeDisabled();
- void setMinimumRequiredWifiSecurityLevel(int level);
+ void setMinimumRequiredWifiSecurityLevel(String callerPackageName, int level);
int getMinimumRequiredWifiSecurityLevel();
- void setWifiSsidPolicy(in WifiSsidPolicy policy);
+ void setWifiSsidPolicy(String callerPackageName, in WifiSsidPolicy policy);
WifiSsidPolicy getWifiSsidPolicy();
List<UserHandle> listForegroundAffiliatedUsers();
@@ -591,8 +593,8 @@
void setApplicationExemptions(String packageName, in int[]exemptions);
int[] getApplicationExemptions(String packageName);
- void setMtePolicy(int flag);
- int getMtePolicy();
+ void setMtePolicy(int flag, String callerPackageName);
+ int getMtePolicy(String callerPackageName);
void setManagedSubscriptionsPolicy(in ManagedSubscriptionsPolicy policy);
ManagedSubscriptionsPolicy getManagedSubscriptionsPolicy();
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index dd9791b..e9860f6 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -17,12 +17,27 @@
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;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_PACKAGE_STATE;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SCREEN_CAPTURE;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SECURITY_LOGGING;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SYSTEM_UPDATES;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WIFI;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WIPE_DATA;
import static android.Manifest.permission.QUERY_ADMIN_POLICY;
import static android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY;
import static android.Manifest.permission.SET_TIME;
@@ -2790,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
@@ -2821,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));
}
}
@@ -2845,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;
}
@@ -4364,16 +4416,31 @@
}
@Override
- public void setPasswordExpirationTimeout(ComponentName who, long timeout, boolean parent) {
+ public void setPasswordExpirationTimeout(ComponentName who, String callerPackageName,
+ long timeout, boolean parent) {
if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
return;
}
- Objects.requireNonNull(who, "ComponentName is null");
+ if (!isPermissionCheckFlagEnabled()) {
+ Objects.requireNonNull(who, "ComponentName is null");
+ }
+
+ CallerIdentity caller = getCallerIdentity(who, callerPackageName);
+
Preconditions.checkArgumentNonnegative(timeout, "Timeout must be >= 0 ms");
- final int userHandle = mInjector.userHandleGetCallingUserId();
+ int userHandle = mInjector.userHandleGetCallingUserId();
+ int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle;
synchronized (getLockObject()) {
- ActiveAdmin ap = getActiveAdminForCallerLocked(
- who, DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD, parent);
+ ActiveAdmin ap;
+ if (isPermissionCheckFlagEnabled()) {
+ ap = enforcePermissionAndGetEnforcingAdmin(
+ who, MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
+ caller.getPackageName(), affectedUserId)
+ .getActiveAdmin();
+ } else {
+ ap = getActiveAdminForCallerLocked(
+ who, DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD, parent);
+ }
// Calling this API automatically bumps the expiration date
final long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
ap.passwordExpirationDate = expiration;
@@ -4389,8 +4456,7 @@
setExpirationAlarmCheckLocked(mContext, userHandle, parent);
}
if (SecurityLog.isLoggingEnabled()) {
- final int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle;
- SecurityLog.writeEvent(SecurityLog.TAG_PASSWORD_EXPIRATION_SET, who.getPackageName(),
+ SecurityLog.writeEvent(SecurityLog.TAG_PASSWORD_EXPIRATION_SET, caller.getPackageName(),
userHandle, affectedUserId, timeout);
}
}
@@ -4851,9 +4917,16 @@
enforceUserUnlocked(userHandle, parent);
synchronized (getLockObject()) {
- // This API can only be called by an active device admin,
- // so try to retrieve it to check that the caller is one.
- getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
+ if (isPermissionCheckFlagEnabled()) {
+ int affectedUser = parent ? getProfileParentId(userHandle) : userHandle;
+ enforcePermission(MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, affectedUser);
+ } else {
+ // This API can only be called by an active device admin,
+ // so try to retrieve it to check that the caller is one.
+ getActiveAdminForCallerLocked(
+ null, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
+ }
+
int credentialOwner = getCredentialOwner(userHandle, parent);
DevicePolicyData policy = getUserDataUnchecked(credentialOwner);
PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(credentialOwner);
@@ -4999,11 +5072,21 @@
isDefaultDeviceOwner(caller) || isProfileOwner(caller) || isSystemUid(caller),
"Only profile owner, device owner and system may call this method on parent.");
} else {
- Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(REQUEST_PASSWORD_COMPLEXITY)
- || isDefaultDeviceOwner(caller) || isProfileOwner(caller),
- "Must have " + REQUEST_PASSWORD_COMPLEXITY
- + " permission, or be a profile owner or device owner.");
+ if (isPermissionCheckFlagEnabled()) {
+ Preconditions.checkCallAuthorization(
+ hasCallingOrSelfPermission(REQUEST_PASSWORD_COMPLEXITY)
+ || hasCallingOrSelfPermission(MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS)
+ || isDefaultDeviceOwner(caller) || isProfileOwner(caller),
+ "Must have " + REQUEST_PASSWORD_COMPLEXITY + " or " +
+ MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS
+ + " permissions, or be a profile owner or device owner.");
+ } else {
+ Preconditions.checkCallAuthorization(
+ hasCallingOrSelfPermission(REQUEST_PASSWORD_COMPLEXITY)
+ || isDefaultDeviceOwner(caller) || isProfileOwner(caller),
+ "Must have " + REQUEST_PASSWORD_COMPLEXITY
+ + " permission, or be a profile owner or device owner.");
+ }
}
synchronized (getLockObject()) {
@@ -5014,7 +5097,8 @@
}
@Override
- public void setRequiredPasswordComplexity(int passwordComplexity, boolean calledOnParent) {
+ public void setRequiredPasswordComplexity(
+ String callerPackageName, int passwordComplexity, boolean calledOnParent) {
if (!mHasFeature) {
return;
}
@@ -5023,14 +5107,28 @@
Preconditions.checkArgument(allowedModes.contains(passwordComplexity),
"Provided complexity is not one of the allowed values.");
- final CallerIdentity caller = getCallerIdentity();
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwner(caller));
- Preconditions.checkArgument(!calledOnParent || isProfileOwner(caller));
+ final CallerIdentity caller = getCallerIdentity(callerPackageName);
+ if (!isPermissionCheckFlagEnabled()) {
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller) || isProfileOwner(caller));
+ Preconditions.checkArgument(!calledOnParent || isProfileOwner(caller));
+ }
synchronized (getLockObject()) {
- final ActiveAdmin admin = getParentOfAdminIfRequired(
- getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), calledOnParent);
+ ActiveAdmin admin;
+ if (isPermissionCheckFlagEnabled()) {
+ // TODO: Make sure this returns the parent of the fake admin
+ // TODO: Deal with null componentname
+ int affectedUser = calledOnParent
+ ? getProfileParentId(caller.getUserId()) : caller.getUserId();
+ admin = enforcePermissionAndGetEnforcingAdmin(
+ null, MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
+ caller.getPackageName(), affectedUser).getActiveAdmin();
+ } else {
+ admin = getParentOfAdminIfRequired(
+ getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), calledOnParent);
+ }
+
if (admin.mPasswordComplexity != passwordComplexity) {
// We require the caller to explicitly clear any password quality requirements set
// on the parent DPM instance, to avoid the case where password requirements are
@@ -5057,22 +5155,23 @@
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_PASSWORD_COMPLEXITY)
- .setAdmin(admin.info.getPackageName())
+ .setAdmin(caller.getPackageName())
.setInt(passwordComplexity)
.setBoolean(calledOnParent)
.write();
}
- logPasswordComplexityRequiredIfSecurityLogEnabled(admin.info.getComponent(),
+ logPasswordComplexityRequiredIfSecurityLogEnabled(caller.getPackageName(),
caller.getUserId(), calledOnParent, passwordComplexity);
}
}
- private void logPasswordComplexityRequiredIfSecurityLogEnabled(ComponentName who, int userId,
+ private void logPasswordComplexityRequiredIfSecurityLogEnabled(String adminPackageName,
+ int userId,
boolean parent, int complexity) {
if (SecurityLog.isLoggingEnabled()) {
final int affectedUserId = parent ? getProfileParentId(userId) : userId;
SecurityLog.writeEvent(SecurityLog.TAG_PASSWORD_COMPLEXITY_REQUIRED,
- who.getPackageName(), userId, affectedUserId, complexity);
+ adminPackageName, userId, affectedUserId, complexity);
}
}
@@ -5104,10 +5203,17 @@
}
final CallerIdentity caller = getCallerIdentity();
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwner(caller));
- Preconditions.checkArgument(!calledOnParent || isProfileOwner(caller));
+ if (isPermissionCheckFlagEnabled()) {
+ int affectedUser = calledOnParent ? getProfileParentId(caller.getUserId())
+ : caller.getUserId();
+ enforcePermission(MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, affectedUser);
+ } else {
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller) || isProfileOwner(caller));
+
+ Preconditions.checkArgument(!calledOnParent || isProfileOwner(caller));
+ }
synchronized (getLockObject()) {
final ActiveAdmin requiredAdmin = getParentOfAdminIfRequired(
@@ -5145,8 +5251,13 @@
if (!isSystemUid(caller)) {
// This API can be called by an active device admin or by keyguard code.
if (!hasCallingPermission(permission.ACCESS_KEYGUARD_SECURE_STORAGE)) {
- getActiveAdminForCallerLocked(
- null, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
+ if (isPermissionCheckFlagEnabled()) {
+ int affectedUser = parent ? getProfileParentId(userHandle) : userHandle;
+ enforcePermission(MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS, affectedUser);
+ } else {
+ getActiveAdminForCallerLocked(
+ null, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
+ }
}
}
@@ -5157,27 +5268,43 @@
}
@Override
- public void setMaximumFailedPasswordsForWipe(ComponentName who, int num, boolean parent) {
+ public void setMaximumFailedPasswordsForWipe(
+ ComponentName who, String callerPackageName, int num, boolean parent) {
if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
return;
}
- Objects.requireNonNull(who, "ComponentName is null");
- final int userId = mInjector.userHandleGetCallingUserId();
+
+ if (!isPermissionCheckFlagEnabled()) {
+ Objects.requireNonNull(who, "ComponentName is null");
+ }
+
+ CallerIdentity caller = getCallerIdentity(who, callerPackageName);
+
+ int userId = mInjector.userHandleGetCallingUserId();
+ int affectedUserId = parent ? getProfileParentId(userId) : userId;
+
synchronized (getLockObject()) {
- // This API can only be called by an active device admin,
- // so try to retrieve it to check that the caller is one.
- getActiveAdminForCallerLocked(
- who, DeviceAdminInfo.USES_POLICY_WIPE_DATA, parent);
- ActiveAdmin ap = getActiveAdminForCallerLocked(
- who, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
+ ActiveAdmin ap;
+ if (isPermissionCheckFlagEnabled()) {
+ ap = enforcePermissionAndGetEnforcingAdmin(
+ who, MANAGE_DEVICE_POLICY_WIPE_DATA,
+ caller.getPackageName(), affectedUserId).getActiveAdmin();
+ } else {
+ // This API can only be called by an active device admin,
+ // so try to retrieve it to check that the caller is one.
+ getActiveAdminForCallerLocked(
+ who, DeviceAdminInfo.USES_POLICY_WIPE_DATA, parent);
+ ap = getActiveAdminForCallerLocked(
+ who, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
+ }
+
if (ap.maximumFailedPasswordsForWipe != num) {
ap.maximumFailedPasswordsForWipe = num;
saveSettingsLocked(userId);
}
}
if (SecurityLog.isLoggingEnabled()) {
- final int affectedUserId = parent ? getProfileParentId(userId) : userId;
- SecurityLog.writeEvent(SecurityLog.TAG_MAX_PASSWORD_ATTEMPTS_SET, who.getPackageName(),
+ SecurityLog.writeEvent(SecurityLog.TAG_MAX_PASSWORD_ATTEMPTS_SET, callerPackageName,
userId, affectedUserId, num);
}
}
@@ -5427,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);
@@ -5443,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);
}
}
@@ -5535,16 +5675,20 @@
}
@Override
- public void setRequiredStrongAuthTimeout(ComponentName who, long timeoutMs,
+ public void setRequiredStrongAuthTimeout(ComponentName who, String callerPackageName, long timeoutMs,
boolean parent) {
if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
return;
}
- Objects.requireNonNull(who, "ComponentName is null");
+ if (!isPermissionCheckFlagEnabled()) {
+ Objects.requireNonNull(who, "ComponentName is null");
+ }
Preconditions.checkArgument(timeoutMs >= 0, "Timeout must not be a negative number.");
- final CallerIdentity caller = getCallerIdentity(who);
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwner(caller));
+ final CallerIdentity caller = getCallerIdentity(who, callerPackageName);
+ if (!isPermissionCheckFlagEnabled()) {
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller) || isProfileOwner(caller));
+ }
// timeoutMs with value 0 means that the admin doesn't participate
// timeoutMs is clamped to the interval in case the internal constants change in the future
final long minimumStrongAuthTimeout = getMinimumStrongAuthTimeoutMs();
@@ -5558,8 +5702,17 @@
final int userHandle = caller.getUserId();
boolean changed = false;
synchronized (getLockObject()) {
- ActiveAdmin ap = getParentOfAdminIfRequired(
- getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), parent);
+ ActiveAdmin ap;
+ if (isPermissionCheckFlagEnabled()) {
+ int affectedUser = parent
+ ? getProfileParentId(caller.getUserId()) : caller.getUserId();
+ ap = enforcePermissionAndGetEnforcingAdmin(
+ who, MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
+ caller.getPackageName(), affectedUser).getActiveAdmin();
+ } else {
+ ap = getParentOfAdminIfRequired(
+ getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), parent);
+ }
if (ap.strongAuthUnlockTimeout != timeoutMs) {
ap.strongAuthUnlockTimeout = timeoutMs;
saveSettingsLocked(userHandle);
@@ -5635,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 {
@@ -7335,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());
}
@@ -7359,7 +7534,7 @@
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_FACTORY_RESET_PROTECTION)
- .setAdmin(who)
+ .setAdmin(caller.getPackageName())
.write();
}
@@ -7386,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()) {
@@ -8042,23 +8218,37 @@
* Set whether the screen capture is disabled for the user managed by the specified admin.
*/
@Override
- public void setScreenCaptureDisabled(ComponentName who, boolean disabled, boolean parent) {
+ public void setScreenCaptureDisabled(
+ ComponentName who, String callerPackage, boolean disabled, boolean parent) {
if (!mHasFeature) {
return;
}
- Objects.requireNonNull(who, "ComponentName is null");
- final CallerIdentity caller = getCallerIdentity(who);
- if (parent) {
- Preconditions.checkCallAuthorization(isProfileOwnerOfOrganizationOwnedDevice(caller));
- } else {
- Preconditions.checkCallAuthorization(isProfileOwner(caller)
- || isDeviceOwner(caller));
+ CallerIdentity caller = getCallerIdentity(who, callerPackage);
+ if (!isPermissionCheckFlagEnabled()) {
+ Objects.requireNonNull(who, "ComponentName is null");
+ if (parent) {
+ Preconditions.checkCallAuthorization(
+ isProfileOwnerOfOrganizationOwnedDevice(caller));
+ } else {
+ Preconditions.checkCallAuthorization(isProfileOwner(caller)
+ || isDeviceOwner(caller));
+ }
}
synchronized (getLockObject()) {
- ActiveAdmin ap = getParentOfAdminIfRequired(
- getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), parent);
+ ActiveAdmin ap;
+ if (isPermissionCheckFlagEnabled()) {
+ int callerUserId = Binder.getCallingUserHandle().getIdentifier();
+ int targetUserId = parent ? getProfileParentId(callerUserId) : callerUserId;
+ ap = enforcePermissionAndGetEnforcingAdmin(
+ who, MANAGE_DEVICE_POLICY_SCREEN_CAPTURE, caller.getPackageName(),
+ targetUserId).getActiveAdmin();
+ } else {
+ ap = getParentOfAdminIfRequired(
+ getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), parent);
+ }
+
if (ap.disableScreenCapture != disabled) {
ap.disableScreenCapture = disabled;
saveSettingsLocked(caller.getUserId());
@@ -8067,7 +8257,7 @@
}
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_SCREEN_CAPTURE_DISABLED)
- .setAdmin(caller.getComponentName())
+ .setAdmin(caller.getPackageName())
.setBoolean(disabled)
.write();
}
@@ -8566,7 +8756,7 @@
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
who,
MANAGE_DEVICE_POLICY_CAMERA,
- callerPackageName,
+ caller.getPackageName(),
getProfileParentUserIfRequested(userHandle, parent));
admin = enforcingAdmin.getActiveAdmin();
} else {
@@ -8658,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)) {
@@ -8687,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();
@@ -9915,6 +10116,15 @@
return UserHandle.USER_NULL;
}
+ private @UserIdInt int getManagedProfileUserId() {
+ for (UserInfo ui : mUserManagerInternal.getUserInfos()) {
+ if (ui.isManagedProfile()) {
+ return ui.id;
+ }
+ }
+ return UserHandle.USER_NULL;
+ }
+
/**
* This API is cached: invalidate with invalidateBinderCaches().
*/
@@ -10708,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);
@@ -11112,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));
}
@@ -11151,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;
@@ -11177,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;
}
}
@@ -12405,10 +12656,16 @@
@Override
public boolean setApplicationHidden(ComponentName who, String callerPackage, String packageName,
boolean hidden, boolean parent) {
- final CallerIdentity caller = getCallerIdentity(who, callerPackage);
- Preconditions.checkCallAuthorization((caller.hasAdminComponent()
- && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
- || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_PACKAGE_ACCESS)));
+ CallerIdentity caller = getCallerIdentity(who, callerPackage);
+ int userId = parent ? getProfileParentId(caller.getUserId()) : caller.getUserId();
+ if (isPermissionCheckFlagEnabled()) {
+ // TODO: We need to ensure the delegate with DELEGATION_PACKAGE_ACCESS can do this
+ enforcePermission(MANAGE_DEVICE_POLICY_PACKAGE_STATE, userId);
+ } else {
+ Preconditions.checkCallAuthorization((caller.hasAdminComponent()
+ && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
+ || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_PACKAGE_ACCESS)));
+ }
List<String> exemptApps = listPolicyExemptAppsUnchecked(mContext);
if (exemptApps.contains(packageName)) {
@@ -12417,12 +12674,14 @@
return false;
}
- final int userId = parent ? getProfileParentId(caller.getUserId()) : caller.getUserId();
boolean result;
synchronized (getLockObject()) {
if (parent) {
- Preconditions.checkCallAuthorization(isProfileOwnerOfOrganizationOwnedDevice(
- caller.getUserId()) && isManagedProfile(caller.getUserId()));
+ if (!isPermissionCheckFlagEnabled()) {
+ Preconditions.checkCallAuthorization(
+ isProfileOwnerOfOrganizationOwnedDevice(
+ caller.getUserId()) && isManagedProfile(caller.getUserId()));
+ }
// Ensure the package provided is a system package, this is to ensure that this
// API cannot be used to leak if certain non-system package exists in the person
// profile.
@@ -12451,17 +12710,25 @@
@Override
public boolean isApplicationHidden(ComponentName who, String callerPackage,
String packageName, boolean parent) {
- final CallerIdentity caller = getCallerIdentity(who, callerPackage);
- Preconditions.checkCallAuthorization((caller.hasAdminComponent()
- && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
- || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_PACKAGE_ACCESS)));
+ CallerIdentity caller = getCallerIdentity(who, callerPackage);
+ int userId = parent ? getProfileParentId(caller.getUserId()) : caller.getUserId();
+ if (isPermissionCheckFlagEnabled()) {
+ // TODO: Also support DELEGATION_PACKAGE_ACCESS
+ enforcePermission(MANAGE_DEVICE_POLICY_PACKAGE_STATE, userId);
+ } else {
+ Preconditions.checkCallAuthorization((caller.hasAdminComponent()
+ && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
+ || (caller.hasPackage() && isCallerDelegate(
+ caller, DELEGATION_PACKAGE_ACCESS)));
+ }
- final int userId = parent ? getProfileParentId(caller.getUserId()) : caller.getUserId();
synchronized (getLockObject()) {
if (parent) {
- Preconditions.checkCallAuthorization(
- isProfileOwnerOfOrganizationOwnedDevice(caller.getUserId())
- && isManagedProfile(caller.getUserId()));
+ if (!isPermissionCheckFlagEnabled()) {
+ Preconditions.checkCallAuthorization(
+ isProfileOwnerOfOrganizationOwnedDevice(caller.getUserId())
+ && isManagedProfile(caller.getUserId()));
+ }
// Ensure the package provided is a system package.
mInjector.binderWithCleanCallingIdentity(() ->
enforcePackageIsSystemPackage(packageName, userId));
@@ -13600,15 +13867,21 @@
}
@Override
- public void setConfiguredNetworksLockdownState(ComponentName who, boolean lockdown) {
+ public void setConfiguredNetworksLockdownState(
+ ComponentName who, String callerPackageName, boolean lockdown) {
if (!mHasFeature) {
return;
}
- Preconditions.checkNotNull(who, "ComponentName is null");
+ CallerIdentity caller = getCallerIdentity(who, callerPackageName);
- final CallerIdentity caller = getCallerIdentity(who);
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller));
+ if (isPermissionCheckFlagEnabled()) {
+ enforcePermission(MANAGE_DEVICE_POLICY_WIFI, UserHandle.USER_ALL);
+ } else {
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller));
+ }
mInjector.binderWithCleanCallingIdentity(() ->
mInjector.settingsGlobalPutInt(Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN,
@@ -13616,7 +13889,7 @@
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.ALLOW_MODIFICATION_OF_ADMIN_CONFIGURED_NETWORKS)
- .setAdmin(caller.getComponentName())
+ .setAdmin(caller.getPackageName())
.setBoolean(lockdown)
.write();
}
@@ -13626,11 +13899,16 @@
if (!mHasFeature) {
return false;
}
- Preconditions.checkNotNull(who, "ComponentName is null");
+ CallerIdentity caller = getCallerIdentity(who);
+ if (isPermissionCheckFlagEnabled()) {
+ enforcePermission(MANAGE_DEVICE_POLICY_WIFI, UserHandle.USER_ALL);
+ } else {
+ Preconditions.checkNotNull(who, "ComponentName is null");
- final CallerIdentity caller = getCallerIdentity(who);
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller));
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller));
+ }
return mInjector.binderWithCleanCallingIdentity(() ->
mInjector.settingsGlobalGetInt(Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0) > 0);
@@ -14909,7 +15187,8 @@
}
@Override
- public void setSystemUpdatePolicy(ComponentName who, SystemUpdatePolicy policy) {
+ public void setSystemUpdatePolicy(
+ ComponentName who, String callerPackageName, SystemUpdatePolicy policy) {
if (policy != null) {
// throws exception if policy type is invalid
policy.validateType();
@@ -14920,11 +15199,17 @@
policy.validateAgainstPreviousFreezePeriod(record.first, record.second,
LocalDate.now());
}
- final CallerIdentity caller = getCallerIdentity(who);
+ final CallerIdentity caller = getCallerIdentity(who, callerPackageName);
synchronized (getLockObject()) {
- Preconditions.checkCallAuthorization(isProfileOwnerOfOrganizationOwnedDevice(caller)
- || isDefaultDeviceOwner(caller));
+ if (isPermissionCheckFlagEnabled()) {
+ enforcePermission(MANAGE_DEVICE_POLICY_SYSTEM_UPDATES, UserHandle.USER_ALL);
+ } else {
+ Preconditions.checkCallAuthorization(
+ isProfileOwnerOfOrganizationOwnedDevice(caller)
+ || isDefaultDeviceOwner(caller));
+ }
+
checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_SYSTEM_UPDATE_POLICY);
if (policy == null) {
@@ -14939,7 +15224,7 @@
new Intent(ACTION_SYSTEM_UPDATE_POLICY_CHANGED), UserHandle.SYSTEM));
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_SYSTEM_UPDATE_POLICY)
- .setAdmin(who)
+ .setAdmin(caller.getPackageName())
.setInt(policy != null ? policy.getPolicyType() : 0)
.write();
}
@@ -15618,12 +15903,19 @@
}
@Override
- public String getWifiMacAddress(ComponentName admin) {
- Objects.requireNonNull(admin, "ComponentName is null");
+ public String getWifiMacAddress(ComponentName admin, String callerPackageName) {
+// if (!isPermissionCheckFlagEnabled()) {
+ Objects.requireNonNull(admin, "ComponentName is null");
+// }
- final CallerIdentity caller = getCallerIdentity(admin);
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller));
+ final CallerIdentity caller = getCallerIdentity(admin, callerPackageName);
+// if (isPermissionCheckFlagEnabled()) {
+// enforcePermission(MANAGE_DEVICE_POLICY_WIFI, UserHandle.USER_ALL);
+// } else {
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller));
+// }
return mInjector.binderWithCleanCallingIdentity(() -> {
String[] macAddresses = mInjector.getWifiManager().getFactoryMacAddresses();
@@ -15632,7 +15924,7 @@
}
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.GET_WIFI_MAC_ADDRESS)
- .setAdmin(caller.getComponentName())
+ .setAdmin(caller.getPackageName())
.write();
return macAddresses.length > 0 ? macAddresses[0] : null;
});
@@ -16288,6 +16580,7 @@
return UserHandle.USER_ALL;
}
}
+ // TODO: Add check for permission-based
return getOrganizationOwnedProfileUserId();
}
@@ -16300,14 +16593,19 @@
final CallerIdentity caller = getCallerIdentity(admin, packageName);
synchronized (getLockObject()) {
- if (admin != null) {
- Preconditions.checkCallAuthorization(
- isProfileOwnerOfOrganizationOwnedDevice(caller)
- || isDefaultDeviceOwner(caller));
+ if (isPermissionCheckFlagEnabled()) {
+ // TODO: add support for DELEGATION_SECURITY_LOGGING
+ enforcePermission(MANAGE_DEVICE_POLICY_SECURITY_LOGGING, UserHandle.USER_ALL);
} else {
- // A delegate app passes a null admin component, which is expected
- Preconditions.checkCallAuthorization(
- isCallerDelegate(caller, DELEGATION_SECURITY_LOGGING));
+ if (admin != null) {
+ Preconditions.checkCallAuthorization(
+ isProfileOwnerOfOrganizationOwnedDevice(caller)
+ || isDefaultDeviceOwner(caller));
+ } else {
+ // A delegate app passes a null admin component, which is expected
+ Preconditions.checkCallAuthorization(
+ isCallerDelegate(caller, DELEGATION_SECURITY_LOGGING));
+ }
}
if (enabled == mInjector.securityLogGetLoggingEnabledProperty()) {
@@ -16323,7 +16621,7 @@
}
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_SECURITY_LOGGING_ENABLED)
- .setAdmin(admin)
+ .setAdmin(caller.getPackageName())
.setBoolean(enabled)
.write();
}
@@ -16337,14 +16635,18 @@
synchronized (getLockObject()) {
if (!isSystemUid(getCallerIdentity())) {
final CallerIdentity caller = getCallerIdentity(admin, packageName);
- if (admin != null) {
- Preconditions.checkCallAuthorization(
- isProfileOwnerOfOrganizationOwnedDevice(caller)
- || isDefaultDeviceOwner(caller));
+ if (isPermissionCheckFlagEnabled()) {
+ enforcePermission(MANAGE_DEVICE_POLICY_SECURITY_LOGGING, UserHandle.USER_ALL);
} else {
- // A delegate app passes a null admin component, which is expected
- Preconditions.checkCallAuthorization(
- isCallerDelegate(caller, DELEGATION_SECURITY_LOGGING));
+ if (admin != null) {
+ Preconditions.checkCallAuthorization(
+ isProfileOwnerOfOrganizationOwnedDevice(caller)
+ || isDefaultDeviceOwner(caller));
+ } else {
+ // A delegate app passes a null admin component, which is expected
+ Preconditions.checkCallAuthorization(
+ isCallerDelegate(caller, DELEGATION_SECURITY_LOGGING));
+ }
}
}
return mInjector.securityLogGetLoggingEnabledProperty();
@@ -16370,22 +16672,27 @@
}
final CallerIdentity caller = getCallerIdentity(admin, packageName);
- if (admin != null) {
- Preconditions.checkCallAuthorization(
- isProfileOwnerOfOrganizationOwnedDevice(caller)
- || isDefaultDeviceOwner(caller));
+ if (isPermissionCheckFlagEnabled()) {
+ // TODO: Restore the "affiliated users" check
+ enforcePermission(MANAGE_DEVICE_POLICY_SECURITY_LOGGING, UserHandle.USER_ALL);
} else {
- // A delegate app passes a null admin component, which is expected
- Preconditions.checkCallAuthorization(
- isCallerDelegate(caller, DELEGATION_SECURITY_LOGGING));
- }
+ if (admin != null) {
+ Preconditions.checkCallAuthorization(
+ isProfileOwnerOfOrganizationOwnedDevice(caller)
+ || isDefaultDeviceOwner(caller));
+ } else {
+ // A delegate app passes a null admin component, which is expected
+ Preconditions.checkCallAuthorization(
+ isCallerDelegate(caller, DELEGATION_SECURITY_LOGGING));
+ }
- Preconditions.checkCallAuthorization(isOrganizationOwnedDeviceWithManagedProfile()
- || areAllUsersAffiliatedWithDeviceLocked());
+ Preconditions.checkCallAuthorization(isOrganizationOwnedDeviceWithManagedProfile()
+ || areAllUsersAffiliatedWithDeviceLocked());
+ }
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.RETRIEVE_PRE_REBOOT_SECURITY_LOGS)
- .setAdmin(caller.getComponentName())
+ .setAdmin(caller.getPackageName())
.write();
if (!mContext.getResources().getBoolean(R.bool.config_supportPreRebootSecurityLogs)
@@ -16416,17 +16723,22 @@
}
final CallerIdentity caller = getCallerIdentity(admin, packageName);
- if (admin != null) {
- Preconditions.checkCallAuthorization(
- isProfileOwnerOfOrganizationOwnedDevice(caller)
- || isDefaultDeviceOwner(caller));
+ if (isPermissionCheckFlagEnabled()) {
+ // TODO: Restore the "affiliated users" check
+ enforcePermission(MANAGE_DEVICE_POLICY_SECURITY_LOGGING, UserHandle.USER_ALL);
} else {
- // A delegate app passes a null admin component, which is expected
- Preconditions.checkCallAuthorization(
- isCallerDelegate(caller, DELEGATION_SECURITY_LOGGING));
+ if (admin != null) {
+ Preconditions.checkCallAuthorization(
+ isProfileOwnerOfOrganizationOwnedDevice(caller)
+ || isDefaultDeviceOwner(caller));
+ } else {
+ // A delegate app passes a null admin component, which is expected
+ Preconditions.checkCallAuthorization(
+ isCallerDelegate(caller, DELEGATION_SECURITY_LOGGING));
+ }
+ Preconditions.checkCallAuthorization(isOrganizationOwnedDeviceWithManagedProfile()
+ || areAllUsersAffiliatedWithDeviceLocked());
}
- Preconditions.checkCallAuthorization(isOrganizationOwnedDeviceWithManagedProfile()
- || areAllUsersAffiliatedWithDeviceLocked());
if (!mInjector.securityLogGetLoggingEnabledProperty()) {
return null;
@@ -16437,7 +16749,7 @@
List<SecurityEvent> logs = mSecurityLogMonitor.retrieveLogs();
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.RETRIEVE_SECURITY_LOGS)
- .setAdmin(caller.getComponentName())
+ .setAdmin(caller.getPackageName())
.write();
return logs != null ? new ParceledListSlice<SecurityEvent>(logs) : null;
}
@@ -17004,9 +17316,11 @@
mNetworkLogger.pause();
}
}
+ // TODO: We need to also enable this when someone is managing using permission
if (!isOrganizationOwnedDeviceWithManagedProfile()) {
- Slogf.i(LOG_TAG, "Not org-owned managed profile device, security logging will be "
- + "paused if enabled.");
+ Slogf.i(LOG_TAG,
+ "Not org-owned managed profile device, security logging will be "
+ + "paused if enabled.");
mSecurityLogMonitor.pause();
}
}
@@ -18104,18 +18418,25 @@
}
@Override
- public void installUpdateFromFile(ComponentName admin,
+ public void installUpdateFromFile(ComponentName admin, String callerPackageName,
ParcelFileDescriptor updateFileDescriptor, StartInstallingUpdateCallback callback) {
- Objects.requireNonNull(admin, "ComponentName is null");
+ if (!isPermissionCheckFlagEnabled()) {
+ Objects.requireNonNull(admin, "ComponentName is null");
+ }
- final CallerIdentity caller = getCallerIdentity(admin);
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller));
+ final CallerIdentity caller = getCallerIdentity(admin, callerPackageName);
+ if (isPermissionCheckFlagEnabled()) {
+ enforcePermission(MANAGE_DEVICE_POLICY_SYSTEM_UPDATES, UserHandle.USER_ALL);
+ } else {
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller));
+ }
checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_INSTALL_SYSTEM_UPDATE);
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.INSTALL_SYSTEM_UPDATE)
- .setAdmin(caller.getComponentName())
+ .setAdmin(caller.getPackageName())
.setBoolean(isDeviceAB())
.write();
@@ -18502,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
@@ -20164,15 +20485,27 @@
public void setUsbDataSignalingEnabled(String packageName, boolean enabled) {
Objects.requireNonNull(packageName, "Admin package name must be provided");
final CallerIdentity caller = getCallerIdentity(packageName);
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
- "USB data signaling can only be controlled by a device owner or "
- + "a profile owner on an organization-owned device.");
- Preconditions.checkState(canUsbDataSignalingBeDisabled(),
- "USB data signaling cannot be disabled.");
+ if (!isPermissionCheckFlagEnabled()) {
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
+ "USB data signaling can only be controlled by a device owner or "
+ + "a profile owner on an organization-owned device.");
+ Preconditions.checkState(canUsbDataSignalingBeDisabled(),
+ "USB data signaling cannot be disabled.");
+ }
+
synchronized (getLockObject()) {
- final ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
+ ActiveAdmin admin;
+ if (isPermissionCheckFlagEnabled()) {
+ admin = enforcePermissionAndGetEnforcingAdmin(
+ /* admin= */ null, MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING,
+ caller.getPackageName(),
+ caller.getUserId()).getActiveAdmin();
+ } else {
+ admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
+ }
+
if (admin.mUsbDataSignalingEnabled != enabled) {
admin.mUsbDataSignalingEnabled = enabled;
saveSettingsLocked(caller.getUserId());
@@ -20261,16 +20594,25 @@
}
@Override
- public void setMinimumRequiredWifiSecurityLevel(int level) {
+ public void setMinimumRequiredWifiSecurityLevel(String callerPackageName, int level) {
final CallerIdentity caller = getCallerIdentity();
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
- "Wi-Fi minimum security level can only be controlled by a device owner or "
- + "a profile owner on an organization-owned device.");
+ if (!isPermissionCheckFlagEnabled()) {
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
+ "Wi-Fi minimum security level can only be controlled by a device owner or "
+ + "a profile owner on an organization-owned device.");
+ }
boolean valueChanged = false;
synchronized (getLockObject()) {
- final ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
+ ActiveAdmin admin;
+ if (isPermissionCheckFlagEnabled()) {
+ admin = enforcePermissionAndGetEnforcingAdmin(/* admin= */ null,
+ MANAGE_DEVICE_POLICY_WIFI, caller.getPackageName(), caller.getUserId())
+ .getActiveAdmin();
+ } else {
+ admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
+ }
if (admin.mWifiMinimumSecurityLevel != level) {
admin.mWifiMinimumSecurityLevel = level;
saveSettingsLocked(caller.getUserId());
@@ -20299,12 +20641,17 @@
@Override
public WifiSsidPolicy getWifiSsidPolicy() {
final CallerIdentity caller = getCallerIdentity();
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller)
- || canQueryAdminPolicy(caller),
- "SSID policy can only be retrieved by a device owner or "
- + "a profile owner on an organization-owned device or "
- + "an app with the QUERY_ADMIN_POLICY permission.");
+ if (isPermissionCheckFlagEnabled()) {
+ enforcePermission(MANAGE_DEVICE_POLICY_WIFI, caller.getUserId());
+ } else {
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller)
+ || canQueryAdminPolicy(caller),
+ "SSID policy can only be retrieved by a device owner or "
+ + "a profile owner on an organization-owned device or "
+ + "an app with the QUERY_ADMIN_POLICY permission.");
+ }
synchronized (getLockObject()) {
ActiveAdmin admin;
// TODO(b/261999445): remove
@@ -20319,16 +20666,27 @@
}
@Override
- public void setWifiSsidPolicy(WifiSsidPolicy policy) {
- final CallerIdentity caller = getCallerIdentity();
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
- "SSID denylist can only be controlled by a device owner or "
- + "a profile owner on an organization-owned device.");
+ public void setWifiSsidPolicy(String callerPackageName, WifiSsidPolicy policy) {
+ final CallerIdentity caller = getCallerIdentity(callerPackageName);
+
+ if (!isPermissionCheckFlagEnabled()) {
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
+ "SSID denylist can only be controlled by a device owner or "
+ + "a profile owner on an organization-owned device.");
+ }
boolean changed = false;
synchronized (getLockObject()) {
- final ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
+ ActiveAdmin admin;
+ if (isPermissionCheckFlagEnabled()) {
+ admin = enforcePermissionAndGetEnforcingAdmin(
+ /* admin= */ null, MANAGE_DEVICE_POLICY_WIFI,
+ caller.getPackageName(),
+ caller.getUserId()).getActiveAdmin();
+ } else {
+ admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
+ }
if (!Objects.equals(policy, admin.mWifiSsidPolicy)) {
admin.mWifiSsidPolicy = policy;
changed = true;
@@ -20704,25 +21062,68 @@
MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL,
SET_TIME,
SET_TIME_ZONE,
- MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY);
+ MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY,
+ MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS,
+ MANAGE_DEVICE_POLICY_WIFI,
+ MANAGE_DEVICE_POLICY_WIPE_DATA,
+ MANAGE_DEVICE_POLICY_SCREEN_CAPTURE,
+ MANAGE_DEVICE_POLICY_SYSTEM_UPDATES,
+ MANAGE_DEVICE_POLICY_SECURITY_LOGGING,
+ MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING,
+ MANAGE_DEVICE_POLICY_MTE,
+ MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
+ 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,
MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL,
SET_TIME,
SET_TIME_ZONE,
- MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY);
+ MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY,
+ MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS,
+ MANAGE_DEVICE_POLICY_WIFI,
+ MANAGE_DEVICE_POLICY_WIPE_DATA,
+ MANAGE_DEVICE_POLICY_SCREEN_CAPTURE,
+ MANAGE_DEVICE_POLICY_SYSTEM_UPDATES,
+ MANAGE_DEVICE_POLICY_SECURITY_LOGGING,
+ MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING,
+ MANAGE_DEVICE_POLICY_MTE,
+ MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
+ 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);
+ SET_TIME_ZONE,
+ MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS,
+ MANAGE_DEVICE_POLICY_WIPE_DATA,
+ MANAGE_DEVICE_POLICY_SCREEN_CAPTURE,
+ MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
+ 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);
+ MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY,
+ MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS,
+ MANAGE_DEVICE_POLICY_WIPE_DATA,
+ MANAGE_DEVICE_POLICY_SCREEN_CAPTURE,
+ MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
+ MANAGE_DEVICE_POLICY_PACKAGE_STATE,
+ MANAGE_DEVICE_POLICY_LOCK,
+ MANAGE_DEVICE_POLICY_KEYGUARD);
private static final HashMap<Integer, List<String>> DPC_PERMISSIONS = new HashMap<>();
{
@@ -20743,10 +21144,33 @@
// Time and Timezone is intrinsically global so there is no cross-user permission.
CROSS_USER_PERMISSIONS.put(SET_TIME, null);
CROSS_USER_PERMISSIONS.put(SET_TIME_ZONE, null);
+ // system updates are intrinsically global so there is no cross-user permission
+ CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_SYSTEM_UPDATES, null);
+ // security logs are intrinsically global so there is no cross-user permission
+ CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_SECURITY_LOGGING, null);
+ // usb signalling is intrinsically global so there is no cross-user permission
+ 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,
MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
+ CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_WIFI,
+ MANAGE_DEVICE_POLICY_ACROSS_USERS);
+ CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_WIPE_DATA,
+ MANAGE_DEVICE_POLICY_ACROSS_USERS);
+ CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_SCREEN_CAPTURE,
+ MANAGE_DEVICE_POLICY_ACROSS_USERS);
+ CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
+ 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);
}
/**
@@ -20973,8 +21397,7 @@
Slog.i(LOG_TAG, "Keep profiles running overridden to: " + enabled);
}
- @Override
- public void setMtePolicy(int flags) {
+ public void setMtePolicy(int flags, String callerPackageName) {
final Set<Integer> allowedModes =
Set.of(
DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY,
@@ -20993,9 +21416,15 @@
"ro.arm64.memtag.bootctl_settings_toggle", false))) {
throw new UnsupportedOperationException("device does not support MTE");
}
- final CallerIdentity caller = getCallerIdentity();
+ final CallerIdentity caller = getCallerIdentity(callerPackageName);
+ // For now we continue to restrict the DISABLED setting to device owner - we might need
+ // another permission for this in future.
if (flags == DevicePolicyManager.MTE_DISABLED) {
Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller));
+ }
+
+ if (isPermissionCheckFlagEnabled()) {
+ enforcePermission(MANAGE_DEVICE_POLICY_MTE, UserHandle.USER_ALL);
} else {
Preconditions.checkCallAuthorization(
isDefaultDeviceOwner(caller)
@@ -21025,19 +21454,23 @@
DevicePolicyEventLogger.createEvent(DevicePolicyEnums.SET_MTE_POLICY)
.setInt(flags)
- .setAdmin(admin.info.getPackageName())
+ .setAdmin(caller.getPackageName())
.write();
}
}
}
@Override
- public int getMtePolicy() {
- final CallerIdentity caller = getCallerIdentity();
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller)
- || isProfileOwnerOfOrganizationOwnedDevice(caller)
- || isSystemUid(caller));
+ public int getMtePolicy(String callerPackageName) {
+ final CallerIdentity caller = getCallerIdentity(callerPackageName);
+ if (isPermissionCheckFlagEnabled()) {
+ enforcePermission(MANAGE_DEVICE_POLICY_MTE, UserHandle.USER_ALL);
+ } else {
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller)
+ || isSystemUid(caller));
+ }
synchronized (getLockObject()) {
// TODO(b/261999445): Remove
ActiveAdmin admin;