Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractorTest.kt +65 −3 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.keyguard.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.widget.lockPatternUtils import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues import com.android.systemui.keyguard.data.repository.biometricSettingsRepository Loading @@ -33,6 +34,8 @@ import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) Loading @@ -52,14 +55,21 @@ class KeyguardLockWhileAwakeInteractorTest : SysuiTestCase() { testScope.runTest { val values by collectValues(underTest.lockWhileAwakeEvents) underTest.onKeyguardServiceDoKeyguardTimeout(options = null) kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(true) runCurrent() kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout( options = null ) runCurrent() assertThat(values) .containsExactly(LockWhileAwakeReason.KEYGUARD_TIMEOUT_WHILE_SCREEN_ON) advanceTimeBy(1000) underTest.onKeyguardServiceDoKeyguardTimeout(options = null) kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout( options = null ) runCurrent() assertThat(values) Loading @@ -69,8 +79,15 @@ class KeyguardLockWhileAwakeInteractorTest : SysuiTestCase() { ) } /** * We re-show keyguard when it's re-enabled, but only if it was originally showing when we * disabled it. * * If it wasn't showing when originally disabled it, re-enabling it should do nothing (the * keyguard will re-show next time we're locked). */ @Test fun emitsWhenKeyguardEnabled_onlyIfShowingWhenDisabled() = fun emitsWhenKeyguardReenabled_onlyIfShowingWhenDisabled() = testScope.runTest { val values by collectValues(underTest.lockWhileAwakeEvents) Loading Loading @@ -98,4 +115,49 @@ class KeyguardLockWhileAwakeInteractorTest : SysuiTestCase() { assertThat(values).containsExactly(LockWhileAwakeReason.KEYGUARD_REENABLED) } /** * Un-suppressing keyguard should never cause us to re-show. We'll re-show when we're next * locked, even if we were showing when originally suppressed. */ @Test fun doesNotEmit_keyguardNoLongerSuppressed() = testScope.runTest { val values by collectValues(underTest.lockWhileAwakeEvents) // Enable keyguard and then suppress it. kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(true) whenever(kosmos.lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true) runCurrent() assertEquals(0, values.size) // Un-suppress keyguard. whenever(kosmos.lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false) runCurrent() assertEquals(0, values.size) } /** * Lockdown and lockNow() should not cause us to lock while awake if we are suppressed via adb. */ @Test fun doesNotEmit_fromLockdown_orFromLockNow_ifEnabledButSuppressed() = testScope.runTest { val values by collectValues(underTest.lockWhileAwakeEvents) // Set keyguard enabled, but then disable lockscreen (suppress it). kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(true) whenever(kosmos.lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true) runCurrent() kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(null) runCurrent() kosmos.biometricSettingsRepository.setIsUserInLockdown(true) runCurrent() assertEquals(0, values.size) } } packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt +77 −48 Original line number Diff line number Diff line Loading @@ -87,9 +87,9 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { assertEquals( listOf( false, // Defaults to false. false // Defaults to false. ), canWake canWake, ) repository.setKeyguardEnabled(false) Loading @@ -100,33 +100,26 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { false, // Default to false. true, // True now that keyguard service is disabled ), canWake canWake, ) repository.setKeyguardEnabled(true) runCurrent() assertEquals( listOf( false, true, false, ), canWake ) assertEquals(listOf(false, true, false), canWake) } @Test @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testCanWakeDirectlyToGone_lockscreenDisabledThenEnabled() = fun testCanWakeDirectlyToGone_lockscreenDisabledThenEnabled_onlyAfterWakefulnessChange() = testScope.runTest { val canWake by collectValues(underTest.canWakeDirectlyToGone) assertEquals( listOf( false, // Defaults to false. false // Defaults to false. ), canWake canWake, ) whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true) Loading @@ -136,9 +129,9 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { listOf( // Still false - isLockScreenDisabled only causes canWakeDirectlyToGone to // update on the next wake/sleep event. false, false ), canWake canWake, ) kosmos.powerInteractor.setAsleepForTest() Loading @@ -150,7 +143,7 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { // True since we slept after setting isLockScreenDisabled=true true, ), canWake canWake, ) kosmos.powerInteractor.setAwakeForTest() Loading @@ -159,25 +152,75 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { kosmos.powerInteractor.setAsleepForTest() runCurrent() assertEquals(listOf(false, true), canWake) whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false) kosmos.powerInteractor.setAwakeForTest() runCurrent() assertEquals(listOf(false, true, false), canWake) } @Test @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testCanWakeDirectlyToGone_lockscreenDisabledThenEnabled_lockNowEvent() = testScope.runTest { val canWake by collectValues(underTest.canWakeDirectlyToGone) assertEquals( listOf( false // Defaults to false. ), canWake, ) whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true) runCurrent() assertEquals( listOf( // Still false - isLockScreenDisabled only causes canWakeDirectlyToGone to // update on the next wakefulness or lockNow event. false ), canWake, ) kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(null) runCurrent() assertEquals( listOf( false, // True when lockNow() called after setting isLockScreenDisabled=true true, ), canWake canWake, ) whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false) kosmos.powerInteractor.setAwakeForTest() runCurrent() assertEquals( listOf( false, // Still true since no lockNow() calls made. true, ), canWake, ) kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(null) runCurrent() assertEquals( listOf( false, true, // False again after the lockNow() call. false, ), canWake canWake, ) } Loading @@ -189,9 +232,9 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { assertEquals( listOf( false, // Defaults to false. false // Defaults to false. ), canWake canWake, ) repository.setBiometricUnlockState(BiometricUnlockMode.WAKE_AND_UNLOCK) Loading @@ -213,9 +256,9 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { assertEquals( listOf( false, // Defaults to false. false // Defaults to false. ), canWake canWake, ) repository.setCanIgnoreAuthAndReturnToGone(true) Loading @@ -237,9 +280,9 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { assertEquals( listOf( false, // Defaults to false. false // Defaults to false. ), canWake canWake, ) whenever(kosmos.devicePolicyManager.getMaximumTimeToLock(eq(null), anyInt())) Loading @@ -257,13 +300,7 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { ) runCurrent() assertEquals( listOf( false, true, ), canWake ) assertEquals(listOf(false, true), canWake) verify(kosmos.alarmManager) .setExactAndAllowWhileIdle( Loading @@ -281,9 +318,9 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { assertEquals( listOf( false, // Defaults to false. false // Defaults to false. ), canWake canWake, ) whenever(kosmos.devicePolicyManager.getMaximumTimeToLock(eq(null), anyInt())) Loading Loading @@ -312,7 +349,7 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { // Timed out, so we can ignore auth/return to GONE. true, ), canWake canWake, ) verify(kosmos.alarmManager) Loading @@ -338,7 +375,7 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { // alarm in flight that should be canceled. false, ), canWake canWake, ) kosmos.powerInteractor.setAsleepForTest( Loading @@ -354,25 +391,17 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { // Back to sleep. true, ), canWake canWake, ) // Simulate the first sleep's alarm coming in. lastRegisteredBroadcastReceiver?.onReceive( kosmos.mockedContext, Intent("com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD") Intent("com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD"), ) runCurrent() // It should not have any effect. assertEquals( listOf( false, true, false, true, ), canWake ) assertEquals(listOf(false, true, false, true), canWake) } } packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +5 −6 Original line number Diff line number Diff line Loading @@ -81,7 +81,7 @@ import com.android.systemui.flags.FeatureFlags; import com.android.systemui.keyguard.domain.interactor.KeyguardDismissInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardLockWhileAwakeInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardServiceLockNowInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardStateCallbackInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardWakeDirectlyToGoneInteractor; import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindParamsApplier; Loading Loading @@ -330,8 +330,7 @@ public class KeyguardService extends Service { return new FoldGracePeriodProvider(); } }; private final KeyguardLockWhileAwakeInteractor mKeyguardLockWhileAwakeInteractor; private final KeyguardServiceLockNowInteractor mKeyguardServiceLockNowInteractor; @Inject public KeyguardService( Loading @@ -357,7 +356,7 @@ public class KeyguardService extends Service { KeyguardDismissInteractor keyguardDismissInteractor, Lazy<DeviceEntryInteractor> deviceEntryInteractorLazy, KeyguardStateCallbackInteractor keyguardStateCallbackInteractor, KeyguardLockWhileAwakeInteractor keyguardLockWhileAwakeInteractor) { KeyguardServiceLockNowInteractor keyguardServiceLockNowInteractor) { super(); mKeyguardViewMediator = keyguardViewMediator; mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher; Loading Loading @@ -389,7 +388,7 @@ public class KeyguardService extends Service { mKeyguardEnabledInteractor = keyguardEnabledInteractor; mKeyguardWakeDirectlyToGoneInteractor = keyguardWakeDirectlyToGoneInteractor; mKeyguardDismissInteractor = keyguardDismissInteractor; mKeyguardLockWhileAwakeInteractor = keyguardLockWhileAwakeInteractor; mKeyguardServiceLockNowInteractor = keyguardServiceLockNowInteractor; } @Override Loading Loading @@ -665,7 +664,7 @@ public class KeyguardService extends Service { if (SceneContainerFlag.isEnabled()) { mDeviceEntryInteractorLazy.get().lockNow(); } else if (KeyguardWmStateRefactor.isEnabled()) { mKeyguardLockWhileAwakeInteractor.onKeyguardServiceDoKeyguardTimeout(options); mKeyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(options); } mKeyguardViewMediator.doKeyguardTimeout(options); Loading packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +1 −1 Original line number Diff line number Diff line Loading @@ -3943,7 +3943,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, } private void notifyDefaultDisplayCallbacks(boolean showing) { if (SceneContainerFlag.isEnabled()) { if (SceneContainerFlag.isEnabled() || KeyguardWmStateRefactor.isEnabled()) { return; } Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt +58 −8 Original line number Diff line number Diff line Loading @@ -16,39 +16,52 @@ package com.android.systemui.keyguard.domain.interactor import com.android.app.tracing.coroutines.launchTraced as launch import com.android.internal.widget.LockPatternUtils import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.kotlin.sample import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import com.android.app.tracing.coroutines.launchTraced as launch import kotlinx.coroutines.withContext /** * Logic around the keyguard being enabled/disabled, per [KeyguardService]. If the keyguard is not * enabled, the lockscreen cannot be shown and the device will go from AOD/DOZING directly to GONE. * Logic around the keyguard being enabled, disabled, or suppressed via adb. If the keyguard is * disabled or suppressed, the lockscreen cannot be shown and the device will go from AOD/DOZING * directly to GONE. * * Keyguard can be disabled by selecting Security: "None" in settings, or by apps that hold * permission to do so (such as Phone). Some CTS tests also disable keyguard in onCreate or onStart * rather than simply dismissing the keyguard or setting up the device to have Security: None, for * reasons unknown. * * Keyguard can be suppressed by calling "adb shell locksettings set-disabled true", which is * frequently done in tests. If keyguard is suppressed, it won't show even if the keyguard is * enabled. If keyguard is not suppressed, then we defer to whether keyguard is enabled or disabled. */ @SysUISingleton class KeyguardEnabledInteractor @Inject constructor( @Application scope: CoroutineScope, @Application val scope: CoroutineScope, @Background val backgroundDispatcher: CoroutineDispatcher, val repository: KeyguardRepository, val biometricSettingsRepository: BiometricSettingsRepository, keyguardDismissTransitionInteractor: KeyguardDismissTransitionInteractor, private val selectedUserInteractor: SelectedUserInteractor, private val lockPatternUtils: LockPatternUtils, keyguardDismissTransitionInteractor: dagger.Lazy<KeyguardDismissTransitionInteractor>, internalTransitionInteractor: InternalKeyguardTransitionInteractor, ) { Loading @@ -62,6 +75,10 @@ constructor( * If the keyguard is disabled while we're locked, we will transition to GONE unless we're in * lockdown mode. If the keyguard is re-enabled, we'll transition back to LOCKSCREEN if we were * locked when it was disabled. * * Even if the keyguard is enabled, it's possible for it to be suppressed temporarily via adb. * If you need to respect that adb command, you will need to use * [isKeyguardEnabledAndNotSuppressed] instead of using this flow. */ val isKeyguardEnabled: StateFlow<Boolean> = repository.isKeyguardEnabled Loading Loading @@ -96,9 +113,9 @@ constructor( val currentTransitionInfo = internalTransitionInteractor.currentTransitionInfoInternal() if (currentTransitionInfo.to != KeyguardState.GONE && !inLockdown) { keyguardDismissTransitionInteractor.startDismissKeyguardTransition( "keyguard disabled" ) keyguardDismissTransitionInteractor .get() .startDismissKeyguardTransition("keyguard disabled") } } } Loading @@ -116,4 +133,37 @@ constructor( fun isShowKeyguardWhenReenabled(): Boolean { return repository.isShowKeyguardWhenReenabled() } /** * Whether the keyguard is enabled, and has not been suppressed via adb. * * There is unfortunately no callback for [isKeyguardSuppressed], which means this can't be a * flow, since it's ambiguous when we would query the latest suppression value. */ suspend fun isKeyguardEnabledAndNotSuppressed(): Boolean { return isKeyguardEnabled.value && !isKeyguardSuppressed() } /** * Returns whether the lockscreen has been disabled ("suppressed") via "adb shell locksettings * set-disabled". If suppressed, we'll ignore all signals that would typically result in showing * the keyguard, regardless of the value of [isKeyguardEnabled]. * * It's extremely confusing to have [isKeyguardEnabled] not be the inverse of "is lockscreen * disabled", so this method intentionally re-terms it as "suppressed". * * Note that if the lockscreen is currently showing when it's suppressed, it will remain visible * until it's unlocked, at which point it will never re-appear until suppression is removed. */ suspend fun isKeyguardSuppressed( userId: Int = selectedUserInteractor.getSelectedUserId() ): Boolean { // isLockScreenDisabled returns true whenever keyguard is not enabled, even if the adb // command was not used to disable/suppress the lockscreen. To make these booleans as clear // as possible, only return true if keyguard is suppressed when it otherwise would have // been enabled. return withContext(backgroundDispatcher) { isKeyguardEnabled.value && lockPatternUtils.isLockScreenDisabled(userId) } } } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractorTest.kt +65 −3 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.keyguard.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.widget.lockPatternUtils import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues import com.android.systemui.keyguard.data.repository.biometricSettingsRepository Loading @@ -33,6 +34,8 @@ import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) Loading @@ -52,14 +55,21 @@ class KeyguardLockWhileAwakeInteractorTest : SysuiTestCase() { testScope.runTest { val values by collectValues(underTest.lockWhileAwakeEvents) underTest.onKeyguardServiceDoKeyguardTimeout(options = null) kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(true) runCurrent() kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout( options = null ) runCurrent() assertThat(values) .containsExactly(LockWhileAwakeReason.KEYGUARD_TIMEOUT_WHILE_SCREEN_ON) advanceTimeBy(1000) underTest.onKeyguardServiceDoKeyguardTimeout(options = null) kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout( options = null ) runCurrent() assertThat(values) Loading @@ -69,8 +79,15 @@ class KeyguardLockWhileAwakeInteractorTest : SysuiTestCase() { ) } /** * We re-show keyguard when it's re-enabled, but only if it was originally showing when we * disabled it. * * If it wasn't showing when originally disabled it, re-enabling it should do nothing (the * keyguard will re-show next time we're locked). */ @Test fun emitsWhenKeyguardEnabled_onlyIfShowingWhenDisabled() = fun emitsWhenKeyguardReenabled_onlyIfShowingWhenDisabled() = testScope.runTest { val values by collectValues(underTest.lockWhileAwakeEvents) Loading Loading @@ -98,4 +115,49 @@ class KeyguardLockWhileAwakeInteractorTest : SysuiTestCase() { assertThat(values).containsExactly(LockWhileAwakeReason.KEYGUARD_REENABLED) } /** * Un-suppressing keyguard should never cause us to re-show. We'll re-show when we're next * locked, even if we were showing when originally suppressed. */ @Test fun doesNotEmit_keyguardNoLongerSuppressed() = testScope.runTest { val values by collectValues(underTest.lockWhileAwakeEvents) // Enable keyguard and then suppress it. kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(true) whenever(kosmos.lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true) runCurrent() assertEquals(0, values.size) // Un-suppress keyguard. whenever(kosmos.lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false) runCurrent() assertEquals(0, values.size) } /** * Lockdown and lockNow() should not cause us to lock while awake if we are suppressed via adb. */ @Test fun doesNotEmit_fromLockdown_orFromLockNow_ifEnabledButSuppressed() = testScope.runTest { val values by collectValues(underTest.lockWhileAwakeEvents) // Set keyguard enabled, but then disable lockscreen (suppress it). kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(true) whenever(kosmos.lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true) runCurrent() kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(null) runCurrent() kosmos.biometricSettingsRepository.setIsUserInLockdown(true) runCurrent() assertEquals(0, values.size) } }
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt +77 −48 Original line number Diff line number Diff line Loading @@ -87,9 +87,9 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { assertEquals( listOf( false, // Defaults to false. false // Defaults to false. ), canWake canWake, ) repository.setKeyguardEnabled(false) Loading @@ -100,33 +100,26 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { false, // Default to false. true, // True now that keyguard service is disabled ), canWake canWake, ) repository.setKeyguardEnabled(true) runCurrent() assertEquals( listOf( false, true, false, ), canWake ) assertEquals(listOf(false, true, false), canWake) } @Test @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testCanWakeDirectlyToGone_lockscreenDisabledThenEnabled() = fun testCanWakeDirectlyToGone_lockscreenDisabledThenEnabled_onlyAfterWakefulnessChange() = testScope.runTest { val canWake by collectValues(underTest.canWakeDirectlyToGone) assertEquals( listOf( false, // Defaults to false. false // Defaults to false. ), canWake canWake, ) whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true) Loading @@ -136,9 +129,9 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { listOf( // Still false - isLockScreenDisabled only causes canWakeDirectlyToGone to // update on the next wake/sleep event. false, false ), canWake canWake, ) kosmos.powerInteractor.setAsleepForTest() Loading @@ -150,7 +143,7 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { // True since we slept after setting isLockScreenDisabled=true true, ), canWake canWake, ) kosmos.powerInteractor.setAwakeForTest() Loading @@ -159,25 +152,75 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { kosmos.powerInteractor.setAsleepForTest() runCurrent() assertEquals(listOf(false, true), canWake) whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false) kosmos.powerInteractor.setAwakeForTest() runCurrent() assertEquals(listOf(false, true, false), canWake) } @Test @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testCanWakeDirectlyToGone_lockscreenDisabledThenEnabled_lockNowEvent() = testScope.runTest { val canWake by collectValues(underTest.canWakeDirectlyToGone) assertEquals( listOf( false // Defaults to false. ), canWake, ) whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true) runCurrent() assertEquals( listOf( // Still false - isLockScreenDisabled only causes canWakeDirectlyToGone to // update on the next wakefulness or lockNow event. false ), canWake, ) kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(null) runCurrent() assertEquals( listOf( false, // True when lockNow() called after setting isLockScreenDisabled=true true, ), canWake canWake, ) whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false) kosmos.powerInteractor.setAwakeForTest() runCurrent() assertEquals( listOf( false, // Still true since no lockNow() calls made. true, ), canWake, ) kosmos.keyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(null) runCurrent() assertEquals( listOf( false, true, // False again after the lockNow() call. false, ), canWake canWake, ) } Loading @@ -189,9 +232,9 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { assertEquals( listOf( false, // Defaults to false. false // Defaults to false. ), canWake canWake, ) repository.setBiometricUnlockState(BiometricUnlockMode.WAKE_AND_UNLOCK) Loading @@ -213,9 +256,9 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { assertEquals( listOf( false, // Defaults to false. false // Defaults to false. ), canWake canWake, ) repository.setCanIgnoreAuthAndReturnToGone(true) Loading @@ -237,9 +280,9 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { assertEquals( listOf( false, // Defaults to false. false // Defaults to false. ), canWake canWake, ) whenever(kosmos.devicePolicyManager.getMaximumTimeToLock(eq(null), anyInt())) Loading @@ -257,13 +300,7 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { ) runCurrent() assertEquals( listOf( false, true, ), canWake ) assertEquals(listOf(false, true), canWake) verify(kosmos.alarmManager) .setExactAndAllowWhileIdle( Loading @@ -281,9 +318,9 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { assertEquals( listOf( false, // Defaults to false. false // Defaults to false. ), canWake canWake, ) whenever(kosmos.devicePolicyManager.getMaximumTimeToLock(eq(null), anyInt())) Loading Loading @@ -312,7 +349,7 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { // Timed out, so we can ignore auth/return to GONE. true, ), canWake canWake, ) verify(kosmos.alarmManager) Loading @@ -338,7 +375,7 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { // alarm in flight that should be canceled. false, ), canWake canWake, ) kosmos.powerInteractor.setAsleepForTest( Loading @@ -354,25 +391,17 @@ class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() { // Back to sleep. true, ), canWake canWake, ) // Simulate the first sleep's alarm coming in. lastRegisteredBroadcastReceiver?.onReceive( kosmos.mockedContext, Intent("com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD") Intent("com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD"), ) runCurrent() // It should not have any effect. assertEquals( listOf( false, true, false, true, ), canWake ) assertEquals(listOf(false, true, false, true), canWake) } }
packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +5 −6 Original line number Diff line number Diff line Loading @@ -81,7 +81,7 @@ import com.android.systemui.flags.FeatureFlags; import com.android.systemui.keyguard.domain.interactor.KeyguardDismissInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardLockWhileAwakeInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardServiceLockNowInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardStateCallbackInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardWakeDirectlyToGoneInteractor; import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindParamsApplier; Loading Loading @@ -330,8 +330,7 @@ public class KeyguardService extends Service { return new FoldGracePeriodProvider(); } }; private final KeyguardLockWhileAwakeInteractor mKeyguardLockWhileAwakeInteractor; private final KeyguardServiceLockNowInteractor mKeyguardServiceLockNowInteractor; @Inject public KeyguardService( Loading @@ -357,7 +356,7 @@ public class KeyguardService extends Service { KeyguardDismissInteractor keyguardDismissInteractor, Lazy<DeviceEntryInteractor> deviceEntryInteractorLazy, KeyguardStateCallbackInteractor keyguardStateCallbackInteractor, KeyguardLockWhileAwakeInteractor keyguardLockWhileAwakeInteractor) { KeyguardServiceLockNowInteractor keyguardServiceLockNowInteractor) { super(); mKeyguardViewMediator = keyguardViewMediator; mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher; Loading Loading @@ -389,7 +388,7 @@ public class KeyguardService extends Service { mKeyguardEnabledInteractor = keyguardEnabledInteractor; mKeyguardWakeDirectlyToGoneInteractor = keyguardWakeDirectlyToGoneInteractor; mKeyguardDismissInteractor = keyguardDismissInteractor; mKeyguardLockWhileAwakeInteractor = keyguardLockWhileAwakeInteractor; mKeyguardServiceLockNowInteractor = keyguardServiceLockNowInteractor; } @Override Loading Loading @@ -665,7 +664,7 @@ public class KeyguardService extends Service { if (SceneContainerFlag.isEnabled()) { mDeviceEntryInteractorLazy.get().lockNow(); } else if (KeyguardWmStateRefactor.isEnabled()) { mKeyguardLockWhileAwakeInteractor.onKeyguardServiceDoKeyguardTimeout(options); mKeyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(options); } mKeyguardViewMediator.doKeyguardTimeout(options); Loading
packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +1 −1 Original line number Diff line number Diff line Loading @@ -3943,7 +3943,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, } private void notifyDefaultDisplayCallbacks(boolean showing) { if (SceneContainerFlag.isEnabled()) { if (SceneContainerFlag.isEnabled() || KeyguardWmStateRefactor.isEnabled()) { return; } Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt +58 −8 Original line number Diff line number Diff line Loading @@ -16,39 +16,52 @@ package com.android.systemui.keyguard.domain.interactor import com.android.app.tracing.coroutines.launchTraced as launch import com.android.internal.widget.LockPatternUtils import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.kotlin.sample import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import com.android.app.tracing.coroutines.launchTraced as launch import kotlinx.coroutines.withContext /** * Logic around the keyguard being enabled/disabled, per [KeyguardService]. If the keyguard is not * enabled, the lockscreen cannot be shown and the device will go from AOD/DOZING directly to GONE. * Logic around the keyguard being enabled, disabled, or suppressed via adb. If the keyguard is * disabled or suppressed, the lockscreen cannot be shown and the device will go from AOD/DOZING * directly to GONE. * * Keyguard can be disabled by selecting Security: "None" in settings, or by apps that hold * permission to do so (such as Phone). Some CTS tests also disable keyguard in onCreate or onStart * rather than simply dismissing the keyguard or setting up the device to have Security: None, for * reasons unknown. * * Keyguard can be suppressed by calling "adb shell locksettings set-disabled true", which is * frequently done in tests. If keyguard is suppressed, it won't show even if the keyguard is * enabled. If keyguard is not suppressed, then we defer to whether keyguard is enabled or disabled. */ @SysUISingleton class KeyguardEnabledInteractor @Inject constructor( @Application scope: CoroutineScope, @Application val scope: CoroutineScope, @Background val backgroundDispatcher: CoroutineDispatcher, val repository: KeyguardRepository, val biometricSettingsRepository: BiometricSettingsRepository, keyguardDismissTransitionInteractor: KeyguardDismissTransitionInteractor, private val selectedUserInteractor: SelectedUserInteractor, private val lockPatternUtils: LockPatternUtils, keyguardDismissTransitionInteractor: dagger.Lazy<KeyguardDismissTransitionInteractor>, internalTransitionInteractor: InternalKeyguardTransitionInteractor, ) { Loading @@ -62,6 +75,10 @@ constructor( * If the keyguard is disabled while we're locked, we will transition to GONE unless we're in * lockdown mode. If the keyguard is re-enabled, we'll transition back to LOCKSCREEN if we were * locked when it was disabled. * * Even if the keyguard is enabled, it's possible for it to be suppressed temporarily via adb. * If you need to respect that adb command, you will need to use * [isKeyguardEnabledAndNotSuppressed] instead of using this flow. */ val isKeyguardEnabled: StateFlow<Boolean> = repository.isKeyguardEnabled Loading Loading @@ -96,9 +113,9 @@ constructor( val currentTransitionInfo = internalTransitionInteractor.currentTransitionInfoInternal() if (currentTransitionInfo.to != KeyguardState.GONE && !inLockdown) { keyguardDismissTransitionInteractor.startDismissKeyguardTransition( "keyguard disabled" ) keyguardDismissTransitionInteractor .get() .startDismissKeyguardTransition("keyguard disabled") } } } Loading @@ -116,4 +133,37 @@ constructor( fun isShowKeyguardWhenReenabled(): Boolean { return repository.isShowKeyguardWhenReenabled() } /** * Whether the keyguard is enabled, and has not been suppressed via adb. * * There is unfortunately no callback for [isKeyguardSuppressed], which means this can't be a * flow, since it's ambiguous when we would query the latest suppression value. */ suspend fun isKeyguardEnabledAndNotSuppressed(): Boolean { return isKeyguardEnabled.value && !isKeyguardSuppressed() } /** * Returns whether the lockscreen has been disabled ("suppressed") via "adb shell locksettings * set-disabled". If suppressed, we'll ignore all signals that would typically result in showing * the keyguard, regardless of the value of [isKeyguardEnabled]. * * It's extremely confusing to have [isKeyguardEnabled] not be the inverse of "is lockscreen * disabled", so this method intentionally re-terms it as "suppressed". * * Note that if the lockscreen is currently showing when it's suppressed, it will remain visible * until it's unlocked, at which point it will never re-appear until suppression is removed. */ suspend fun isKeyguardSuppressed( userId: Int = selectedUserInteractor.getSelectedUserId() ): Boolean { // isLockScreenDisabled returns true whenever keyguard is not enabled, even if the adb // command was not used to disable/suppress the lockscreen. To make these booleans as clear // as possible, only return true if keyguard is suppressed when it otherwise would have // been enabled. return withContext(backgroundDispatcher) { isKeyguardEnabled.value && lockPatternUtils.isLockScreenDisabled(userId) } } }