From aff477466eb4b215c0ef9814873e3966341e1818 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 24 Feb 2021 09:45:49 -0800 Subject: [PATCH] Fixed notifyUnsafeOperationStateChanged. It was always sending the notification to the DO, even when it wasn't set. Test: atest com.android.cts.devicepolicy.ProfileOwnerTest#testDevicePolicySafetyCheckerIntegration_unsafeStateException,testDevicePolicySafetyCheckerIntegration_allOperations,testDevicePolicySafetyCheckerIntegration_isSafeOperation,testAdminActionBookkeeping,testDevicePolicySafetyCheckerIntegration_onOperationSafetyStateChanged Fixes: 180922138 Change-Id: I474a1026999296ccff1e64d5cc302af4178ce201 --- .../DevicePolicyManagerService.java | 9 ++++--- .../devicepolicy/OneTimeSafetyChecker.java | 26 ++++++++++++++++++- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 7260732bbcb62..1b6bc667bd82f 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -7560,8 +7560,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } private void sendProfileOwnerCommand(String action, Bundle extras, @UserIdInt int userId) { - sendActiveAdminCommand(action, extras, userId, - mOwners.getProfileOwnerComponent(userId)); + sendActiveAdminCommand(action, extras, userId, mOwners.getProfileOwnerComponent(userId)); } private void sendActiveAdminCommand(String action, Bundle extras, @@ -12351,8 +12350,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { extras.putInt(DeviceAdminReceiver.EXTRA_OPERATION_SAFETY_REASON, reason); extras.putBoolean(DeviceAdminReceiver.EXTRA_OPERATION_SAFETY_STATE, isSafe); - sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_OPERATION_SAFETY_STATE_CHANGED, - extras); + if (mOwners.hasDeviceOwner()) { + sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_OPERATION_SAFETY_STATE_CHANGED, + extras); + } for (int profileOwnerId : mOwners.getProfileOwnerKeys()) { sendProfileOwnerCommand(DeviceAdminReceiver.ACTION_OPERATION_SAFETY_STATE_CHANGED, extras, profileOwnerId); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OneTimeSafetyChecker.java b/services/devicepolicy/java/com/android/server/devicepolicy/OneTimeSafetyChecker.java index 776b444456787..257fc640f93c7 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/OneTimeSafetyChecker.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/OneTimeSafetyChecker.java @@ -23,6 +23,8 @@ import android.app.admin.DevicePolicyManager.DevicePolicyOperation; import android.app.admin.DevicePolicyManager.OperationSafetyReason; import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.DevicePolicySafetyChecker; +import android.os.Handler; +import android.os.Looper; import android.util.Slog; import com.android.internal.os.IResultReceiver; @@ -42,10 +44,15 @@ final class OneTimeSafetyChecker implements DevicePolicySafetyChecker { private static final String TAG = OneTimeSafetyChecker.class.getSimpleName(); + private static final long SELF_DESTRUCT_TIMEOUT_MS = 10_000; + private final DevicePolicyManagerService mService; private final DevicePolicySafetyChecker mRealSafetyChecker; private final @DevicePolicyOperation int mOperation; private final @OperationSafetyReason int mReason; + private final Handler mHandler = new Handler(Looper.getMainLooper()); + + private boolean mDone; OneTimeSafetyChecker(DevicePolicyManagerService service, @DevicePolicyOperation int operation, @OperationSafetyReason int reason) { @@ -53,7 +60,11 @@ final class OneTimeSafetyChecker implements DevicePolicySafetyChecker { mOperation = operation; mReason = reason; mRealSafetyChecker = service.getDevicePolicySafetyChecker(); - Slog.i(TAG, "Saving real DevicePolicySafetyChecker as " + mRealSafetyChecker); + Slog.i(TAG, "OneTimeSafetyChecker constructor: operation= " + operationToString(operation) + + ", reason=" + operationSafetyReasonToString(reason) + + ", realChecker=" + mRealSafetyChecker + + ", maxDuration=" + SELF_DESTRUCT_TIMEOUT_MS + "ms"); + mHandler.postDelayed(() -> selfDestruct(), SELF_DESTRUCT_TIMEOUT_MS); } @Override @@ -99,8 +110,21 @@ final class OneTimeSafetyChecker implements DevicePolicySafetyChecker { } private void disableSelf() { + if (mDone) { + Slog.w(TAG, "disableSelf(): already disabled"); + return; + } Slog.i(TAG, "restoring DevicePolicySafetyChecker to " + mRealSafetyChecker); mService.setDevicePolicySafetyCheckerUnchecked(mRealSafetyChecker); + mDone = true; + } + + private void selfDestruct() { + if (mDone) return; + + // Usually happens when a CTS failed before calling the DPM method that would clear it + Slog.e(TAG, "Self destructing " + this + ", as it was not automatically disabled"); + disableSelf(); } @Override