diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index dcd80ff7e96c0..b856a5e7b25cc 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1214,7 +1214,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { sendDeviceOwnerUserCommand(DeviceAdminReceiver.ACTION_USER_STOPPED, userHandle); if (isManagedProfile(userHandle)) { Slogf.d(LOG_TAG, "Managed profile was stopped"); - updatePersonalAppsSuspension(userHandle, false /* unlocked */); + updatePersonalAppsSuspension(userHandle); } } else if (Intent.ACTION_USER_SWITCHED.equals(action)) { sendDeviceOwnerUserCommand(DeviceAdminReceiver.ACTION_USER_SWITCHED, userHandle); @@ -1224,8 +1224,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } if (isManagedProfile(userHandle)) { Slogf.d(LOG_TAG, "Managed profile became unlocked"); - final boolean suspended = - updatePersonalAppsSuspension(userHandle, true /* unlocked */); + final boolean suspended = updatePersonalAppsSuspension(userHandle); triggerPolicyComplianceCheckIfNeeded(userHandle, suspended); } } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { @@ -1252,13 +1251,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { updateSystemUpdateFreezePeriodsRecord(/* saveIfChanged */ true); final int userId = getManagedUserId(getMainUserId()); if (userId >= 0) { - updatePersonalAppsSuspension(userId, mUserManager.isUserUnlocked(userId)); + updatePersonalAppsSuspension(userId); } } else if (ACTION_PROFILE_OFF_DEADLINE.equals(action)) { Slogf.i(LOG_TAG, "Profile off deadline alarm was triggered"); final int userId = getManagedUserId(getMainUserId()); if (userId >= 0) { - updatePersonalAppsSuspension(userId, mUserManager.isUserUnlocked(userId)); + updatePersonalAppsSuspension(userId); } else { Slogf.wtf(LOG_TAG, "Got deadline alarm for nonexistent profile"); } @@ -1268,9 +1267,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } else if (ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action)) { notifyIfManagedSubscriptionsAreUnavailable( UserHandle.of(userHandle), /* managedProfileAvailable= */ false); + updatePersonalAppsSuspension(userHandle); } else if (ACTION_MANAGED_PROFILE_AVAILABLE.equals(action)) { notifyIfManagedSubscriptionsAreUnavailable( UserHandle.of(userHandle), /* managedProfileAvailable= */ true); + final boolean suspended = updatePersonalAppsSuspension(userHandle); + triggerPolicyComplianceCheckIfNeeded(userHandle, suspended); } else if (LOGIN_ACCOUNTS_CHANGED_ACTION.equals(action)) { calculateHasIncompatibleAccounts(); } @@ -3433,7 +3435,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final int profileUserHandle = getManagedUserId(userHandle); if (profileUserHandle >= 0) { // Given that the parent user has just started, profile should be locked. - updatePersonalAppsSuspension(profileUserHandle, false /* unlocked */); + updatePersonalAppsSuspension(profileUserHandle); } else { suspendPersonalAppsInternal(userHandle, profileUserHandle, false); } @@ -20786,7 +20788,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } mInjector.binderWithCleanCallingIdentity(() -> updatePersonalAppsSuspension( - callingUserId, mUserManager.isUserUnlocked(callingUserId))); + callingUserId)); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_PERSONAL_APPS_SUSPENDED) @@ -20820,16 +20822,19 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { /** * Checks whether personal apps should be suspended according to the policy and applies the * change if needed. - * - * @param unlocked whether the profile is currently running unlocked. */ - private boolean updatePersonalAppsSuspension(int profileUserId, boolean unlocked) { + private boolean updatePersonalAppsSuspension(int profileUserId) { final boolean shouldSuspend; synchronized (getLockObject()) { final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(profileUserId); if (profileOwner != null) { - final int notificationState = - updateProfileOffDeadlineLocked(profileUserId, profileOwner, unlocked); + // Profile is considered "off" when it is either not running or is running locked + // or is in quiet mode, i.e. when the admin cannot sync policies or show UI. + boolean profileUserOff = + !mUserManagerInternal.isUserUnlockingOrUnlocked(profileUserId) + || mUserManager.isQuietModeEnabled(UserHandle.of(profileUserId)); + final int notificationState = updateProfileOffDeadlineLocked( + profileUserId, profileOwner, profileUserOff); final boolean suspendedExplicitly = profileOwner.mSuspendPersonalApps; final boolean suspendedByTimeout = profileOwner.mProfileOffDeadline == -1; Slogf.d(LOG_TAG, @@ -20854,16 +20859,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * @return notification state */ private int updateProfileOffDeadlineLocked( - int profileUserId, ActiveAdmin profileOwner, boolean unlocked) { + int profileUserId, ActiveAdmin profileOwner, boolean off) { final long now = mInjector.systemCurrentTimeMillis(); if (profileOwner.mProfileOffDeadline != 0 && now > profileOwner.mProfileOffDeadline) { - Slogf.i(LOG_TAG, "Profile off deadline has been reached, unlocked: " + unlocked); + Slogf.i(LOG_TAG, "Profile off deadline has been reached, off: " + off); if (profileOwner.mProfileOffDeadline != -1) { // Move the deadline far to the past so that it cannot be rolled back by TZ change. profileOwner.mProfileOffDeadline = -1; saveSettingsLocked(profileUserId); } - return unlocked ? PROFILE_OFF_NOTIFICATION_NONE : PROFILE_OFF_NOTIFICATION_SUSPENDED; + return off ? PROFILE_OFF_NOTIFICATION_SUSPENDED : PROFILE_OFF_NOTIFICATION_NONE; } boolean shouldSaveSettings = false; if (profileOwner.mSuspendPersonalApps) { @@ -20880,7 +20885,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { profileOwner.mProfileOffDeadline = 0; shouldSaveSettings = true; } else if (profileOwner.mProfileOffDeadline == 0 - && (profileOwner.mProfileMaximumTimeOffMillis != 0 && !unlocked)) { + && (profileOwner.mProfileMaximumTimeOffMillis != 0 && off)) { // There profile is locked and there is a policy, but the deadline is not set -> set the // deadline. Slogf.i(LOG_TAG, "Profile off deadline is set."); @@ -20894,7 +20899,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final long alarmTime; final int notificationState; - if (unlocked || profileOwner.mProfileOffDeadline == 0) { + if (!off || profileOwner.mProfileOffDeadline == 0) { alarmTime = 0; notificationState = PROFILE_OFF_NOTIFICATION_NONE; } else if (profileOwner.mProfileOffDeadline - now < MANAGED_PROFILE_OFF_WARNING_PERIOD) { @@ -21168,7 +21173,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } mInjector.binderWithCleanCallingIdentity( - () -> updatePersonalAppsSuspension(userId, mUserManager.isUserUnlocked())); + () -> updatePersonalAppsSuspension(userId)); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_MANAGED_PROFILE_MAXIMUM_TIME_OFF) diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 2ea56f659297e..39de2cf86a6cb 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -8600,6 +8600,8 @@ public class DevicePolicyManagerTest extends DpmTestBase { private void setUserUnlocked(int userHandle, boolean unlocked) { when(getServices().userManager.isUserUnlocked(eq(userHandle))).thenReturn(unlocked); + when(getServices().userManagerInternal.isUserUnlockingOrUnlocked(eq(userHandle))) + .thenReturn(unlocked); } private void prepareMocksForSetMaximumProfileTimeOff() throws Exception {