diff options
3 files changed, 67 insertions, 55 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java index a58da81c6396..984105865f7d 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java @@ -90,6 +90,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.CompletableFuture; /** * Class responsible for setting, resolving, and enforcing policies set by multiple management @@ -1030,11 +1031,11 @@ final class DevicePolicyEngine { } } - private <V> void enforcePolicy(PolicyDefinition<V> policyDefinition, + private <V> CompletableFuture<Boolean> enforcePolicy(PolicyDefinition<V> policyDefinition, @Nullable PolicyValue<V> policyValue, int userId) { // null policyValue means remove any enforced policies, ensure callbacks handle this // properly - policyDefinition.enforcePolicy( + return policyDefinition.enforcePolicy( policyValue == null ? null : policyValue.getValue(), mContext, userId); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java index f271162bbfa4..6cb1756f93eb 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java @@ -53,6 +53,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.CompletableFuture; final class PolicyDefinition<V> { @@ -504,7 +505,8 @@ final class PolicyDefinition<V> { private final int mPolicyFlags; // A function that accepts policy to apply, context, userId, callback arguments, and returns // true if the policy has been enforced successfully. - private final QuadFunction<V, Context, Integer, PolicyKey, Boolean> mPolicyEnforcerCallback; + private final QuadFunction<V, Context, Integer, PolicyKey, CompletableFuture<Boolean>> + mPolicyEnforcerCallback; private final PolicySerializer<V> mPolicySerializer; private PolicyDefinition<V> createPolicyDefinition(PolicyKey key) { @@ -574,7 +576,7 @@ final class PolicyDefinition<V> { return mResolutionMechanism.resolve(adminsPolicy); } - boolean enforcePolicy(@Nullable V value, Context context, int userId) { + CompletableFuture<Boolean> enforcePolicy(@Nullable V value, Context context, int userId) { return mPolicyEnforcerCallback.apply(value, context, userId, mPolicyKey); } @@ -592,7 +594,6 @@ final class PolicyDefinition<V> { POLICY_DEFINITIONS.put(key.getIdentifier(), definition); } - /** * Callers must ensure that {@code policyType} have implemented an appropriate * {@link Object#equals} implementation. @@ -600,7 +601,8 @@ final class PolicyDefinition<V> { private PolicyDefinition( @NonNull PolicyKey key, ResolutionMechanism<V> resolutionMechanism, - QuadFunction<V, Context, Integer, PolicyKey, Boolean> policyEnforcerCallback, + QuadFunction<V, Context, Integer, PolicyKey, CompletableFuture<Boolean>> + policyEnforcerCallback, PolicySerializer<V> policySerializer) { this(key, resolutionMechanism, POLICY_FLAG_NONE, policyEnforcerCallback, policySerializer); } @@ -610,10 +612,11 @@ final class PolicyDefinition<V> { * {@link Object#equals} and {@link Object#hashCode()} implementation. */ private PolicyDefinition( - @NonNull PolicyKey policyKey, + @NonNull PolicyKey policyKey, ResolutionMechanism<V> resolutionMechanism, int policyFlags, - QuadFunction<V, Context, Integer, PolicyKey, Boolean> policyEnforcerCallback, + QuadFunction<V, Context, Integer, PolicyKey, CompletableFuture<Boolean>> + policyEnforcerCallback, PolicySerializer<V> policySerializer) { Objects.requireNonNull(policyKey); mPolicyKey = policyKey; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java index 4d9abf1d6be0..145416215cb0 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java @@ -55,6 +55,7 @@ import android.util.ArraySet; import android.util.Slog; import android.view.IWindowManager; +import com.android.internal.infra.AndroidFuture; import com.android.internal.os.BackgroundThread; import com.android.internal.util.ArrayUtils; import com.android.server.LocalServices; @@ -65,6 +66,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; @@ -73,33 +75,36 @@ final class PolicyEnforcerCallbacks { private static final String LOG_TAG = "PolicyEnforcerCallbacks"; - static <T> boolean noOp(T value, Context context, Integer userId, PolicyKey policyKey) { - return true; + static <T> CompletableFuture<Boolean> noOp(T value, Context context, Integer userId, + PolicyKey policyKey) { + return AndroidFuture.completedFuture(true); } - static boolean setAutoTimezoneEnabled(@Nullable Boolean enabled, @NonNull Context context) { + static CompletableFuture<Boolean> setAutoTimezoneEnabled(@Nullable Boolean enabled, + @NonNull Context context) { if (!Flags.setAutoTimeZoneEnabledCoexistence()) { Slogf.w(LOG_TAG, "Trying to enforce setAutoTimezoneEnabled while flag is off."); - return true; + return AndroidFuture.completedFuture(true); } return Binder.withCleanCallingIdentity(() -> { Objects.requireNonNull(context); int value = enabled != null && enabled ? 1 : 0; - return Settings.Global.putInt( - context.getContentResolver(), Settings.Global.AUTO_TIME_ZONE, - value); + return AndroidFuture.completedFuture( + Settings.Global.putInt( + context.getContentResolver(), Settings.Global.AUTO_TIME_ZONE, + value)); }); } - static boolean setPermissionGrantState( + static CompletableFuture<Boolean> setPermissionGrantState( @Nullable Integer grantState, @NonNull Context context, int userId, @NonNull PolicyKey policyKey) { if (!Flags.setPermissionGrantStateCoexistence()) { Slogf.w(LOG_TAG, "Trying to enforce setPermissionGrantState while flag is off."); - return true; + return AndroidFuture.completedFuture(true); } - return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> { + return Binder.withCleanCallingIdentity(() -> { if (!(policyKey instanceof PackagePermissionPolicyKey)) { throw new IllegalArgumentException("policyKey is not of type " + "PermissionGrantStatePolicyKey, passed in policyKey is: " + policyKey); @@ -125,12 +130,13 @@ final class PolicyEnforcerCallbacks { .setRuntimePermissionGrantStateByDeviceAdmin(context.getPackageName(), permissionParams, context.getMainExecutor(), callback::trigger); try { - return callback.await(20_000, TimeUnit.MILLISECONDS); + return AndroidFuture.completedFuture( + callback.await(20_000, TimeUnit.MILLISECONDS)); } catch (Exception e) { // TODO: add logging - return false; + return AndroidFuture.completedFuture(false); } - })); + }); } @NonNull @@ -149,23 +155,23 @@ final class PolicyEnforcerCallbacks { } } - static boolean enforceSecurityLogging( + static CompletableFuture<Boolean> enforceSecurityLogging( @Nullable Boolean value, @NonNull Context context, int userId, @NonNull PolicyKey policyKey) { final var dpmi = LocalServices.getService(DevicePolicyManagerInternal.class); dpmi.enforceSecurityLoggingPolicy(Boolean.TRUE.equals(value)); - return true; + return AndroidFuture.completedFuture(true); } - static boolean enforceAuditLogging( + static CompletableFuture<Boolean> enforceAuditLogging( @Nullable Boolean value, @NonNull Context context, int userId, @NonNull PolicyKey policyKey) { final var dpmi = LocalServices.getService(DevicePolicyManagerInternal.class); dpmi.enforceAuditLoggingPolicy(Boolean.TRUE.equals(value)); - return true; + return AndroidFuture.completedFuture(true); } - static boolean setLockTask( + static CompletableFuture<Boolean> setLockTask( @Nullable LockTaskPolicy policy, @NonNull Context context, int userId) { List<String> packages = Collections.emptyList(); int flags = LockTaskPolicy.DEFAULT_LOCK_TASK_FLAG; @@ -175,7 +181,7 @@ final class PolicyEnforcerCallbacks { } DevicePolicyManagerService.updateLockTaskPackagesLocked(context, packages, userId); DevicePolicyManagerService.updateLockTaskFeaturesLocked(flags, userId); - return true; + return AndroidFuture.completedFuture(true); } @@ -187,8 +193,8 @@ final class PolicyEnforcerCallbacks { * rely on the POLICY_FLAG_SKIP_ENFORCEMENT_IF_UNCHANGED flag so DPE only invokes this callback * when the policy is set, and not during system boot or other situations. */ - static boolean setApplicationRestrictions(Bundle bundle, Context context, Integer userId, - PolicyKey policyKey) { + static CompletableFuture<Boolean> setApplicationRestrictions(Bundle bundle, Context context, + Integer userId, PolicyKey policyKey) { Binder.withCleanCallingIdentity(() -> { PackagePolicyKey key = (PackagePolicyKey) policyKey; String packageName = key.getPackageName(); @@ -198,7 +204,7 @@ final class PolicyEnforcerCallbacks { changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); context.sendBroadcastAsUser(changeIntent, UserHandle.of(userId)); }); - return true; + return AndroidFuture.completedFuture(true); } private static class BlockingCallback { @@ -220,7 +226,7 @@ final class PolicyEnforcerCallbacks { // TODO: when a local policy exists for a user, this callback will be invoked for this user // individually as well as for USER_ALL. This can be optimized by separating local and global // enforcement in the policy engine. - static boolean setUserControlDisabledPackages( + static CompletableFuture<Boolean> setUserControlDisabledPackages( @Nullable Set<String> packages, Context context, int userId, PolicyKey policyKey) { Binder.withCleanCallingIdentity(() -> { PackageManagerInternal pmi = @@ -246,7 +252,7 @@ final class PolicyEnforcerCallbacks { } } }); - return true; + return AndroidFuture.completedFuture(true); } /** Handles USER_ALL expanding it into the list of all intact users. */ @@ -271,7 +277,7 @@ final class PolicyEnforcerCallbacks { } } - static boolean addPersistentPreferredActivity( + static CompletableFuture<Boolean> addPersistentPreferredActivity( @Nullable ComponentName preferredActivity, @NonNull Context context, int userId, @NonNull PolicyKey policyKey) { Binder.withCleanCallingIdentity(() -> { @@ -297,13 +303,13 @@ final class PolicyEnforcerCallbacks { Slog.wtf(LOG_TAG, "Error adding/removing persistent preferred activity", re); } }); - return true; + return AndroidFuture.completedFuture(true); } - static boolean setUninstallBlocked( + static CompletableFuture<Boolean> setUninstallBlocked( @Nullable Boolean uninstallBlocked, @NonNull Context context, int userId, @NonNull PolicyKey policyKey) { - return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> { + return Binder.withCleanCallingIdentity(() -> { if (!(policyKey instanceof PackagePolicyKey)) { throw new IllegalArgumentException("policyKey is not of type " + "PackagePolicyKey, passed in policyKey is: " + policyKey); @@ -314,14 +320,14 @@ final class PolicyEnforcerCallbacks { packageName, uninstallBlocked != null && uninstallBlocked, userId); - return true; - })); + return AndroidFuture.completedFuture(true); + }); } - static boolean setUserRestriction( + static CompletableFuture<Boolean> setUserRestriction( @Nullable Boolean enabled, @NonNull Context context, int userId, @NonNull PolicyKey policyKey) { - return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> { + return Binder.withCleanCallingIdentity(() -> { if (!(policyKey instanceof UserRestrictionPolicyKey)) { throw new IllegalArgumentException("policyKey is not of type " + "UserRestrictionPolicyKey, passed in policyKey is: " + policyKey); @@ -331,14 +337,14 @@ final class PolicyEnforcerCallbacks { UserManagerInternal userManager = LocalServices.getService(UserManagerInternal.class); userManager.setUserRestriction( userId, parsedKey.getRestriction(), enabled != null && enabled); - return true; - })); + return AndroidFuture.completedFuture(true); + }); } - static boolean setApplicationHidden( + static CompletableFuture<Boolean> setApplicationHidden( @Nullable Boolean hide, @NonNull Context context, int userId, @NonNull PolicyKey policyKey) { - return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> { + return Binder.withCleanCallingIdentity(() -> { if (!(policyKey instanceof PackagePolicyKey)) { throw new IllegalArgumentException("policyKey is not of type " + "PackagePolicyKey, passed in policyKey is: " + policyKey); @@ -346,12 +352,13 @@ final class PolicyEnforcerCallbacks { PackagePolicyKey parsedKey = (PackagePolicyKey) policyKey; String packageName = Objects.requireNonNull(parsedKey.getPackageName()); IPackageManager packageManager = AppGlobals.getPackageManager(); - return packageManager.setApplicationHiddenSettingAsUser( - packageName, hide != null && hide, userId); - })); + return AndroidFuture.completedFuture( + packageManager.setApplicationHiddenSettingAsUser( + packageName, hide != null && hide, userId)); + }); } - static boolean setScreenCaptureDisabled( + static CompletableFuture<Boolean> setScreenCaptureDisabled( @Nullable Boolean disabled, @NonNull Context context, int userId, @NonNull PolicyKey policyKey) { Binder.withCleanCallingIdentity(() -> { @@ -363,10 +370,10 @@ final class PolicyEnforcerCallbacks { updateScreenCaptureDisabled(); } }); - return true; + return AndroidFuture.completedFuture(true); } - static boolean setContentProtectionPolicy( + static CompletableFuture<Boolean> setContentProtectionPolicy( @Nullable Integer value, @NonNull Context context, @UserIdInt Integer userId, @@ -378,7 +385,7 @@ final class PolicyEnforcerCallbacks { cacheImpl.setContentProtectionPolicy(userId, value); } }); - return true; + return AndroidFuture.completedFuture(true); } private static void updateScreenCaptureDisabled() { @@ -393,7 +400,7 @@ final class PolicyEnforcerCallbacks { }); } - static boolean setPersonalAppsSuspended( + static CompletableFuture<Boolean> setPersonalAppsSuspended( @Nullable Boolean suspended, @NonNull Context context, int userId, @NonNull PolicyKey policyKey) { Binder.withCleanCallingIdentity(() -> { @@ -404,7 +411,7 @@ final class PolicyEnforcerCallbacks { .unsuspendAdminSuspendedPackages(userId); } }); - return true; + return AndroidFuture.completedFuture(true); } private static void suspendPersonalAppsInPackageManager(Context context, int userId) { @@ -418,13 +425,14 @@ final class PolicyEnforcerCallbacks { } } - static boolean setUsbDataSignalingEnabled(@Nullable Boolean value, @NonNull Context context) { + static CompletableFuture<Boolean> setUsbDataSignalingEnabled(@Nullable Boolean value, + @NonNull Context context) { return Binder.withCleanCallingIdentity(() -> { Objects.requireNonNull(context); boolean enabled = value == null || value; DevicePolicyManagerService.updateUsbDataSignal(context, enabled); - return true; + return AndroidFuture.completedFuture(true); }); } } |