diff options
6 files changed, 214 insertions, 35 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardStateCallbackInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardStateCallbackInteractorTest.kt new file mode 100644 index 000000000000..2558d583b001 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardStateCallbackInteractorTest.kt @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.keyguard.domain.interactor + +import android.platform.test.annotations.EnableFlags +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.internal.policy.IKeyguardDismissCallback +import com.android.internal.policy.IKeyguardStateCallback +import com.android.keyguard.trustManager +import com.android.systemui.Flags +import com.android.systemui.SysuiTestCase +import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.dismissCallbackRegistry +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.kosmos.testScope +import com.android.systemui.statusbar.domain.interactor.keyguardStateCallbackInteractor +import com.android.systemui.testKosmos +import com.android.systemui.util.time.FakeSystemClock +import com.android.systemui.util.time.fakeSystemClock +import kotlin.test.Test +import kotlinx.coroutines.test.currentTime +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.eq +import org.mockito.Mockito +import org.mockito.Mockito.anyBoolean +import org.mockito.Mockito.anyInt +import org.mockito.kotlin.atLeast +import org.mockito.kotlin.atLeastOnce +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify + +@SmallTest +@RunWith(AndroidJUnit4::class) +class KeyguardStateCallbackInteractorTest : SysuiTestCase() { + + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + + private lateinit var underTest: KeyguardStateCallbackInteractor + private lateinit var callback: IKeyguardStateCallback + private lateinit var systemClock: FakeSystemClock + + @Before + fun setUp() { + systemClock = kosmos.fakeSystemClock + systemClock.setCurrentTimeMillis(testScope.currentTime) + + underTest = kosmos.keyguardStateCallbackInteractor + underTest.start() + + callback = mock<IKeyguardStateCallback>() + } + + @Test + fun test_addCallback_passesInitialValues() = + testScope.runTest { + underTest.addCallback(callback) + + verify(callback).onShowingStateChanged(anyBoolean(), anyInt()) + verify(callback).onInputRestrictedStateChanged(anyBoolean()) + verify(callback).onTrustedChanged(anyBoolean()) + verify(callback).onSimSecureStateChanged(anyBoolean()) + } + + @Test + @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) + fun test_lockscreenVisibility_notifyDismissSucceeded_ifNotVisible() = + testScope.runTest { + underTest.addCallback(callback) + + val dismissCallback = mock<IKeyguardDismissCallback>() + kosmos.dismissCallbackRegistry.addCallback(dismissCallback) + runCurrent() + + kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + testScope = testScope, + ) + + systemClock.advanceTime(1) // Required for DismissCallbackRegistry's bgExecutor + verify(dismissCallback).onDismissSucceeded() + + kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + testScope = testScope, + ) + + Mockito.verifyNoMoreInteractions(dismissCallback) + } + + @Test + @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) + fun test_lockscreenVisibility_reportsKeyguardShowingChanged() = + testScope.runTest { + underTest.addCallback(callback) + + Mockito.clearInvocations(callback) + Mockito.clearInvocations(kosmos.trustManager) + + kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + testScope = testScope, + ) + runCurrent() + + verify(callback, atLeastOnce()).onShowingStateChanged(eq(false), anyInt()) + verify(kosmos.trustManager, atLeastOnce()).reportKeyguardShowingChanged() + + kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + testScope = testScope, + ) + + verify(callback, atLeastOnce()).onShowingStateChanged(eq(true), anyInt()) + verify(kosmos.trustManager, atLeast(2)).reportKeyguardShowingChanged() + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index ba23eb341b89..0a38ce07a798 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -3314,7 +3314,11 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, setShowingLocked(false, "onKeyguardExitFinished: " + reason); mWakeAndUnlocking = false; - mDismissCallbackRegistry.notifyDismissSucceeded(); + + if (!KeyguardWmStateRefactor.isEnabled()) { + mDismissCallbackRegistry.notifyDismissSucceeded(); + } + resetKeyguardDonePendingLocked(); mHideAnimationRun = false; adjustStatusBarLocked(); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractor.kt index 4457f1dfaf09..9b9bdd1bde9b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractor.kt @@ -23,12 +23,10 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.DismissCallbackRegistry -import com.android.systemui.keyguard.KeyguardWmStateRefactor import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.keyguard.data.repository.TrustRepository import com.android.systemui.keyguard.shared.model.DismissAction import com.android.systemui.keyguard.shared.model.KeyguardDone -import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.kotlin.Utils.Companion.toQuad @@ -37,7 +35,6 @@ import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map @@ -59,7 +56,6 @@ constructor( trustRepository: TrustRepository, alternateBouncerInteractor: AlternateBouncerInteractor, powerInteractor: PowerInteractor, - keyguardTransitionInteractor: KeyguardTransitionInteractor, ) { /* * Updates when a biometric has authenticated the device and is requesting to dismiss @@ -165,14 +161,4 @@ constructor( } } } - - init { - if (KeyguardWmStateRefactor.isEnabled) { - scope.launch { - keyguardTransitionInteractor.currentKeyguardState - .filter { it == KeyguardState.GONE } - .collect { dismissCallbackRegistry.notifyDismissSucceeded() } - } - } - } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardStateCallbackInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardStateCallbackInteractor.kt index 7fd348b8b40e..6fe4ff5122d0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardStateCallbackInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardStateCallbackInteractor.kt @@ -16,6 +16,7 @@ package com.android.systemui.keyguard.domain.interactor +import android.app.trust.TrustManager import android.os.DeadObjectException import android.os.RemoteException import com.android.internal.policy.IKeyguardStateCallback @@ -24,6 +25,7 @@ import com.android.systemui.bouncer.domain.interactor.SimBouncerInteractor 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.DismissCallbackRegistry import com.android.systemui.keyguard.KeyguardWmStateRefactor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.scene.shared.flag.SceneContainerFlag @@ -32,7 +34,6 @@ import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -53,6 +54,9 @@ constructor( private val keyguardTransitionInteractor: KeyguardTransitionInteractor, private val trustInteractor: TrustInteractor, private val simBouncerInteractor: SimBouncerInteractor, + private val dismissCallbackRegistry: DismissCallbackRegistry, + private val wmLockscreenVisibilityInteractor: WindowManagerLockscreenVisibilityInteractor, + private val trustManager: TrustManager, ) : CoreStartable { private val callbacks = mutableListOf<IKeyguardStateCallback>() @@ -62,28 +66,31 @@ constructor( } applicationScope.launch { - combine( - selectedUserInteractor.selectedUser, - keyguardTransitionInteractor.currentKeyguardState, - keyguardTransitionInteractor.startedKeyguardTransitionStep, - ::Triple, - ) - .collectLatest { (selectedUser, _, _) -> - val iterator = callbacks.iterator() - withContext(backgroundDispatcher) { - while (iterator.hasNext()) { - val callback = iterator.next() - try { - callback.onShowingStateChanged(!isIdleInGone(), selectedUser) - callback.onInputRestrictedStateChanged(!isIdleInGone()) - } catch (e: RemoteException) { - if (e is DeadObjectException) { - iterator.remove() - } + wmLockscreenVisibilityInteractor.lockscreenVisibility.collectLatest { visible -> + val iterator = callbacks.iterator() + withContext(backgroundDispatcher) { + while (iterator.hasNext()) { + val callback = iterator.next() + try { + callback.onShowingStateChanged( + visible, + selectedUserInteractor.getSelectedUserId(), + ) + callback.onInputRestrictedStateChanged(visible) + + trustManager.reportKeyguardShowingChanged() + + if (!visible) { + dismissCallbackRegistry.notifyDismissSucceeded() + } + } catch (e: RemoteException) { + if (e is DeadObjectException) { + iterator.remove() } } } } + } } applicationScope.launch { diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorKosmos.kt index 52416bae0d9d..ace11573c7c6 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorKosmos.kt @@ -41,6 +41,5 @@ val Kosmos.keyguardDismissInteractor by trustRepository = trustRepository, alternateBouncerInteractor = alternateBouncerInteractor, powerInteractor = powerInteractor, - keyguardTransitionInteractor = keyguardTransitionInteractor, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardStateCallbackInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardStateCallbackInteractorKosmos.kt new file mode 100644 index 000000000000..58dd522d40ec --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardStateCallbackInteractorKosmos.kt @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.domain.interactor + +import com.android.keyguard.trustManager +import com.android.systemui.bouncer.domain.interactor.simBouncerInteractor +import com.android.systemui.keyguard.dismissCallbackRegistry +import com.android.systemui.keyguard.domain.interactor.KeyguardStateCallbackInteractor +import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor +import com.android.systemui.keyguard.domain.interactor.trustInteractor +import com.android.systemui.keyguard.domain.interactor.windowManagerLockscreenVisibilityInteractor +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.kosmos.testScope +import com.android.systemui.user.domain.interactor.selectedUserInteractor + +val Kosmos.keyguardStateCallbackInteractor by + Kosmos.Fixture { + KeyguardStateCallbackInteractor( + applicationScope = testScope.backgroundScope, + backgroundDispatcher = testDispatcher, + selectedUserInteractor = selectedUserInteractor, + keyguardTransitionInteractor = keyguardTransitionInteractor, + trustInteractor = trustInteractor, + simBouncerInteractor = simBouncerInteractor, + dismissCallbackRegistry = dismissCallbackRegistry, + wmLockscreenVisibilityInteractor = windowManagerLockscreenVisibilityInteractor, + trustManager = trustManager, + ) + } |