diff options
| author | 2024-11-13 01:59:33 +0000 | |
|---|---|---|
| committer | 2024-11-13 01:59:33 +0000 | |
| commit | 63099c37a6ac645f05462b12787b0f5394b2a0e8 (patch) | |
| tree | fa8cc330ef91ee48ceee7ab11e2225f7dde87ac9 | |
| parent | 6e63bbbb3f19ac96dbcada179d4d4eaeb20d0616 (diff) | |
| parent | 9aae1c069ae960b27f664cb44dd1a67ced1bfd8a (diff) | |
Merge "Add new DPM.setAutoTimePolicy coexistable API." into main
6 files changed, 206 insertions, 36 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index faa24bc602ef..4526de4de6e0 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -8075,6 +8075,7 @@ package android.app.admin { method @NonNull @WorkerThread public android.os.Bundle getApplicationRestrictions(@Nullable android.content.ComponentName, String); method @Deprecated @Nullable public String getApplicationRestrictionsManagingPackage(@NonNull android.content.ComponentName); method @RequiresPermission(anyOf={android.Manifest.permission.SET_TIME, "android.permission.QUERY_ADMIN_POLICY"}, conditional=true) public boolean getAutoTimeEnabled(@Nullable android.content.ComponentName); + method @FlaggedApi("android.app.admin.flags.set_auto_time_enabled_coexistence") @RequiresPermission(anyOf={android.Manifest.permission.SET_TIME, "android.permission.QUERY_ADMIN_POLICY"}, conditional=true) public int getAutoTimePolicy(); method @Deprecated public boolean getAutoTimeRequired(); method @RequiresPermission(anyOf={android.Manifest.permission.SET_TIME_ZONE, "android.permission.QUERY_ADMIN_POLICY"}, conditional=true) public boolean getAutoTimeZoneEnabled(@Nullable android.content.ComponentName); method @FlaggedApi("android.app.admin.flags.set_auto_time_zone_enabled_coexistence") @RequiresPermission(anyOf={android.Manifest.permission.SET_TIME_ZONE, "android.permission.QUERY_ADMIN_POLICY"}, conditional=true) public int getAutoTimeZonePolicy(); @@ -8233,6 +8234,7 @@ package android.app.admin { 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(@Nullable android.content.ComponentName, boolean); + method @FlaggedApi("android.app.admin.flags.set_auto_time_enabled_coexistence") @RequiresPermission(value=android.Manifest.permission.SET_TIME, conditional=true) public void setAutoTimePolicy(int); method @Deprecated public void setAutoTimeRequired(@NonNull android.content.ComponentName, boolean); method @RequiresPermission(value=android.Manifest.permission.SET_TIME_ZONE, conditional=true) public void setAutoTimeZoneEnabled(@Nullable android.content.ComponentName, boolean); method @FlaggedApi("android.app.admin.flags.set_auto_time_zone_enabled_coexistence") @RequiresPermission(value=android.Manifest.permission.SET_TIME_ZONE, conditional=true) public void setAutoTimeZonePolicy(int); @@ -8354,6 +8356,9 @@ package android.app.admin { field public static final String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD"; field public static final String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION"; field public static final String ACTION_SYSTEM_UPDATE_POLICY_CHANGED = "android.app.action.SYSTEM_UPDATE_POLICY_CHANGED"; + field @FlaggedApi("android.app.admin.flags.set_auto_time_enabled_coexistence") public static final int AUTO_TIME_DISABLED = 1; // 0x1 + field @FlaggedApi("android.app.admin.flags.set_auto_time_enabled_coexistence") public static final int AUTO_TIME_ENABLED = 2; // 0x2 + field @FlaggedApi("android.app.admin.flags.set_auto_time_enabled_coexistence") public static final int AUTO_TIME_NOT_CONTROLLED_BY_POLICY = 0; // 0x0 field @FlaggedApi("android.app.admin.flags.set_auto_time_zone_enabled_coexistence") public static final int AUTO_TIME_ZONE_DISABLED = 1; // 0x1 field @FlaggedApi("android.app.admin.flags.set_auto_time_zone_enabled_coexistence") public static final int AUTO_TIME_ZONE_ENABLED = 2; // 0x2 field @FlaggedApi("android.app.admin.flags.set_auto_time_zone_enabled_coexistence") public static final int AUTO_TIME_ZONE_NOT_CONTROLLED_BY_POLICY = 0; // 0x0 diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index bff77f951b9f..c789c41ec431 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -8920,12 +8920,9 @@ public class DevicePolicyManager { /** * Called by a device owner, a profile owner for the primary user or a profile * owner of an organization-owned managed profile to turn auto time on and off. - * Callers are recommended to use {@link UserManager#DISALLOW_CONFIG_DATE_TIME} - * to prevent the user from changing this setting. * <p> - * If user restriction {@link UserManager#DISALLOW_CONFIG_DATE_TIME} is used, - * no user will be able set the date and time. Instead, the network date - * and time will be used. + * Callers are recommended to use {@link UserManager#DISALLOW_CONFIG_DATE_TIME} to prevent the + * user from changing this setting, that way no user will be able set the date and time zone. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the * caller is not a device admin. @@ -8938,7 +8935,13 @@ public class DevicePolicyManager { throwIfParentInstance("setAutoTimeEnabled"); if (mService != null) { try { - mService.setAutoTimeEnabled(admin, mContext.getPackageName(), enabled); + if (Flags.setAutoTimeEnabledCoexistence()) { + mService.setAutoTimePolicy(mContext.getPackageName(), + enabled ? DevicePolicyManager.AUTO_TIME_ENABLED + : DevicePolicyManager.AUTO_TIME_DISABLED); + } else { + mService.setAutoTimeEnabled(admin, mContext.getPackageName(), enabled); + } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -8968,6 +8971,97 @@ public class DevicePolicyManager { } /** + * Specifies that the auto time state is not controlled by device policy. + * + * @see #setAutoTimePolicy(ComponentName, int) + */ + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ENABLED_COEXISTENCE) + public static final int AUTO_TIME_NOT_CONTROLLED_BY_POLICY = 0; + + /** + * Specifies the "disabled" auto time state. + * + * @see #setAutoTimePolicy(ComponentName, int) + */ + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ENABLED_COEXISTENCE) + public static final int AUTO_TIME_DISABLED = 1; + + /** + * Specifies the "enabled" auto time state. + * + * @see #setAutoTimePolicy(ComponentName, int) + */ + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ENABLED_COEXISTENCE) + public static final int AUTO_TIME_ENABLED = 2; + + /** + * Flags supplied to {@link #setAutoTimePolicy}(ComponentName, int)}. + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "AUTO_TIME_" }, value = { + AUTO_TIME_NOT_CONTROLLED_BY_POLICY, + AUTO_TIME_DISABLED, + AUTO_TIME_ENABLED + }) + public @interface AutoTimePolicy {} + + /** + * Called by a device owner, a profile owner for the primary user or a profile owner of an + * organization-owned managed profile to turn auto time on and off i.e. Whether time should be + * obtained automatically from the network or not. + * <p> + * Callers are recommended to use {@link UserManager#DISALLOW_CONFIG_DATE_TIME} to prevent the + * user from changing this setting, that way no user will be able set the date and time zone. + * + * @param policy The desired state among {@link #AUTO_TIME_ENABLED} to enable, + * {@link #AUTO_TIME_DISABLED} to disable and + * {@link #AUTO_TIME_NOT_CONTROLLED_BY_POLICY} to unset the policy. + * @throws SecurityException if caller is not a device owner, a profile owner for the + * primary user, or a profile owner of an organization-owned managed profile, or if the caller + * does not hold the required permission. + */ + @SupportsCoexistence + @RequiresPermission(value = SET_TIME, conditional = true) + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ENABLED_COEXISTENCE) + public void setAutoTimePolicy(@AutoTimePolicy int policy) { + throwIfParentInstance("setAutoTimePolicy"); + if (mService != null) { + try { + mService.setAutoTimePolicy(mContext.getPackageName(), policy); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Returns current auto time policy's state. + * + * @return One of {@link #AUTO_TIME_ENABLED} if enabled, {@link #AUTO_TIME_DISABLED} if disabled + * and {@link #AUTO_TIME_NOT_CONTROLLED_BY_POLICY} if it's not controlled by + * policy. + * @throws SecurityException if caller is not a device owner, a profile owner for the + * primary user, or a profile owner of an organization-owned managed profile, or if the caller + * does not hold the required permission. + */ + @SupportsCoexistence + @RequiresPermission(anyOf = {SET_TIME, QUERY_ADMIN_POLICY}, conditional = true) + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ENABLED_COEXISTENCE) + public @AutoTimePolicy int getAutoTimePolicy() { + throwIfParentInstance("getAutoTimePolicy"); + if (mService != null) { + try { + return mService.getAutoTimePolicy(mContext.getPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + return DevicePolicyManager.AUTO_TIME_NOT_CONTROLLED_BY_POLICY; + } + + /** * Called by a device owner, a profile owner for the primary user or a profile * owner of an organization-owned managed profile to turn auto time zone on and off. * <p> diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 0b8f53881d07..a40680218039 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -375,6 +375,9 @@ interface IDevicePolicyManager { void setAutoTimeEnabled(in ComponentName who, String callerPackageName, boolean enabled); boolean getAutoTimeEnabled(in ComponentName who, String callerPackageName); + void setAutoTimePolicy(String callerPackageName, int policy); + int getAutoTimePolicy(String callerPackageName); + void setAutoTimeZoneEnabled(in ComponentName who, String callerPackageName, boolean enabled); boolean getAutoTimeZoneEnabled(in ComponentName who, String callerPackageName); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index d221e8ccb9b7..8ad878627804 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -9004,26 +9004,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } - - CallerIdentity caller; - if (Flags.setAutoTimeEnabledCoexistence()) { - caller = getCallerIdentity(who, callerPackageName); - } else { - caller = getCallerIdentity(who); - } - - if (Flags.setAutoTimeEnabledCoexistence()) { - // The effect of this policy is device-wide. - enforcePermission(SET_TIME, caller.getPackageName(), UserHandle.USER_ALL); - } else { - Objects.requireNonNull(who, "ComponentName is null"); - Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller) - || isProfileOwnerOfOrganizationOwnedDevice(caller) || isDefaultDeviceOwner( - caller)); - } + CallerIdentity caller = getCallerIdentity(who); + Objects.requireNonNull(who, "ComponentName is null"); + Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller) + || isProfileOwnerOfOrganizationOwnedDevice(caller) || isDefaultDeviceOwner( + caller)); mInjector.binderWithCleanCallingIdentity(() -> mInjector.settingsGlobalPutInt(Settings.Global.AUTO_TIME, enabled ? 1 : 0)); - DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_AUTO_TIME) .setAdmin(caller.getPackageName()) @@ -9039,23 +9026,74 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return false; } - CallerIdentity caller; - if (Flags.setAutoTimeEnabledCoexistence()) { - caller = getCallerIdentity(who, callerPackageName); - } else { - caller = getCallerIdentity(who); + CallerIdentity caller = getCallerIdentity(who); + + Objects.requireNonNull(who, "ComponentName is null"); + Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller) + || isProfileOwnerOfOrganizationOwnedDevice(caller) || isDefaultDeviceOwner(caller)); + + return mInjector.settingsGlobalGetInt(Global.AUTO_TIME, 0) > 0; + } + + /** + * Set whether auto time is enabled on the device. + */ + @Override + public void setAutoTimePolicy(String callerPackageName, int policy) { + if (!mHasFeature) { + return; } - if (Flags.setAutoTimeEnabledCoexistence()) { - enforceCanQuery(SET_TIME, caller.getPackageName(), UserHandle.USER_ALL); + final Set<Integer> allowedValues = + Set.of( + DevicePolicyManager.AUTO_TIME_ENABLED, + DevicePolicyManager.AUTO_TIME_DISABLED, + DevicePolicyManager.AUTO_TIME_NOT_CONTROLLED_BY_POLICY); + Preconditions.checkArgument( + allowedValues.contains(policy), "Provided mode is not one of the allowed values."); + + CallerIdentity caller = getCallerIdentity(callerPackageName); + // The effect of this policy is device-wide. + EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( + /* who */ null, + SET_TIME, + caller.getPackageName(), + UserHandle.USER_ALL + ); + if (policy == DevicePolicyManager.AUTO_TIME_NOT_CONTROLLED_BY_POLICY) { + mDevicePolicyEngine.removeGlobalPolicy(PolicyDefinition.AUTO_TIME, enforcingAdmin); } else { - Objects.requireNonNull(who, "ComponentName is null"); - Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller) - || isProfileOwnerOfOrganizationOwnedDevice(caller) || isDefaultDeviceOwner( - caller)); + mDevicePolicyEngine.setGlobalPolicy( + PolicyDefinition.AUTO_TIME, + enforcingAdmin, + new IntegerPolicyValue(policy)); + DevicePolicyEventLogger + .createEvent(DevicePolicyEnums.SET_AUTO_TIME) + .setAdmin(caller.getPackageName()) + .setBoolean(policy == DevicePolicyManager.AUTO_TIME_ENABLED) + .write(); } + } - return mInjector.settingsGlobalGetInt(Global.AUTO_TIME, 0) > 0; + /** + * Returns whether auto time is used on the device or not. + */ + @Override + public int getAutoTimePolicy(String callerPackageName) { + if (!mHasFeature) { + return DevicePolicyManager.AUTO_TIME_NOT_CONTROLLED_BY_POLICY; + } + CallerIdentity caller = getCallerIdentity(callerPackageName); + // The effect of this policy is device-wide. + EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( + /* who */ null, + SET_TIME, + caller.getPackageName(), + UserHandle.USER_ALL + ); + Integer state = mDevicePolicyEngine.getGlobalPolicySetByAdmin( + PolicyDefinition.AUTO_TIME, enforcingAdmin); + return state != null ? state : DevicePolicyManager.AUTO_TIME_NOT_CONTROLLED_BY_POLICY; } /** diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java index a5aeaace94bc..24b16b7c2c60 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java @@ -349,6 +349,16 @@ final class PolicyDefinition<V> { PolicyEnforcerCallbacks::setMtePolicy, new IntegerPolicySerializer()); + static PolicyDefinition<Integer> AUTO_TIME = new PolicyDefinition<>( + new NoArgsPolicyKey(DevicePolicyIdentifiers.AUTO_TIME_POLICY), + new TopPriority<>(List.of( + EnforcingAdmin.getRoleAuthorityOf(SYSTEM_SUPERVISION_ROLE), + EnforcingAdmin.getRoleAuthorityOf(DEVICE_LOCK_CONTROLLER_ROLE), + EnforcingAdmin.DPC_AUTHORITY)), + POLICY_FLAG_GLOBAL_ONLY_POLICY, + PolicyEnforcerCallbacks::setAutoTimePolicy, + new IntegerPolicySerializer()); + private static final Map<String, PolicyDefinition<?>> POLICY_DEFINITIONS = new HashMap<>(); private static Map<String, Integer> USER_RESTRICTION_FLAGS = new HashMap<>(); @@ -397,6 +407,7 @@ final class PolicyDefinition<V> { PACKAGES_SUSPENDED); POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.MEMORY_TAGGING_POLICY, MEMORY_TAGGING); + POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.AUTO_TIME_POLICY, AUTO_TIME); // User Restriction Policies USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_MODIFY_ACCOUNTS, /* flags= */ 0); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java index 40d8dae41dcf..8f80004a7ea5 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java @@ -212,6 +212,25 @@ final class PolicyEnforcerCallbacks { return AndroidFuture.completedFuture(true); } + public static CompletableFuture<Boolean> setAutoTimePolicy( + Integer policy, Context context, Integer userId, PolicyKey policyKey) { + if (!Flags.setAutoTimeEnabledCoexistence()) { + Slogf.w(LOG_TAG, "Trying to enforce setAutoTimePolicy while flag is off."); + return AndroidFuture.completedFuture(true); + } + return Binder.withCleanCallingIdentity(() -> { + Objects.requireNonNull(context); + if (policy != null + && policy == DevicePolicyManager.AUTO_TIME_NOT_CONTROLLED_BY_POLICY) { + return AndroidFuture.completedFuture(false); + } + int enabled = policy != null && policy == DevicePolicyManager.AUTO_TIME_ENABLED ? 1 : 0; + return AndroidFuture.completedFuture( + Settings.Global.putInt( + context.getContentResolver(), Settings.Global.AUTO_TIME, enabled)); + }); + } + private static class BlockingCallback { private final CountDownLatch mLatch = new CountDownLatch(1); private final AtomicReference<Boolean> mValue = new AtomicReference<>(); |