Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardStateCallbackInteractorTest.kt 0 → 100644 +139 −0 Original line number Diff line number Diff line /* * 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() } } packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +5 −1 Original line number Diff line number Diff line Loading @@ -3314,7 +3314,11 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, setShowingLocked(false, "onKeyguardExitFinished: " + reason); mWakeAndUnlocking = false; if (!KeyguardWmStateRefactor.isEnabled()) { mDismissCallbackRegistry.notifyDismissSucceeded(); } resetKeyguardDonePendingLocked(); mHideAnimationRun = false; adjustStatusBarLocked(); Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractor.kt +0 −14 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -165,14 +161,4 @@ constructor( } } } init { if (KeyguardWmStateRefactor.isEnabled) { scope.launch { keyguardTransitionInteractor.currentKeyguardState .filter { it == KeyguardState.GONE } .collect { dismissCallbackRegistry.notifyDismissSucceeded() } } } } } packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardStateCallbackInteractor.kt +26 −19 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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>() Loading @@ -62,20 +66,23 @@ constructor( } applicationScope.launch { combine( selectedUserInteractor.selectedUser, keyguardTransitionInteractor.currentKeyguardState, keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Triple, ) .collectLatest { (selectedUser, _, _) -> wmLockscreenVisibilityInteractor.lockscreenVisibility.collectLatest { visible -> val iterator = callbacks.iterator() withContext(backgroundDispatcher) { while (iterator.hasNext()) { val callback = iterator.next() try { callback.onShowingStateChanged(!isIdleInGone(), selectedUser) callback.onInputRestrictedStateChanged(!isIdleInGone()) callback.onShowingStateChanged( visible, selectedUserInteractor.getSelectedUserId(), ) callback.onInputRestrictedStateChanged(visible) trustManager.reportKeyguardShowingChanged() if (!visible) { dismissCallbackRegistry.notifyDismissSucceeded() } } catch (e: RemoteException) { if (e is DeadObjectException) { iterator.remove() Loading packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorKosmos.kt +0 −1 Original line number Diff line number Diff line Loading @@ -41,6 +41,5 @@ val Kosmos.keyguardDismissInteractor by trustRepository = trustRepository, alternateBouncerInteractor = alternateBouncerInteractor, powerInteractor = powerInteractor, keyguardTransitionInteractor = keyguardTransitionInteractor, ) } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardStateCallbackInteractorTest.kt 0 → 100644 +139 −0 Original line number Diff line number Diff line /* * 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() } }
packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +5 −1 Original line number Diff line number Diff line Loading @@ -3314,7 +3314,11 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, setShowingLocked(false, "onKeyguardExitFinished: " + reason); mWakeAndUnlocking = false; if (!KeyguardWmStateRefactor.isEnabled()) { mDismissCallbackRegistry.notifyDismissSucceeded(); } resetKeyguardDonePendingLocked(); mHideAnimationRun = false; adjustStatusBarLocked(); Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractor.kt +0 −14 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -165,14 +161,4 @@ constructor( } } } init { if (KeyguardWmStateRefactor.isEnabled) { scope.launch { keyguardTransitionInteractor.currentKeyguardState .filter { it == KeyguardState.GONE } .collect { dismissCallbackRegistry.notifyDismissSucceeded() } } } } }
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardStateCallbackInteractor.kt +26 −19 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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>() Loading @@ -62,20 +66,23 @@ constructor( } applicationScope.launch { combine( selectedUserInteractor.selectedUser, keyguardTransitionInteractor.currentKeyguardState, keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Triple, ) .collectLatest { (selectedUser, _, _) -> wmLockscreenVisibilityInteractor.lockscreenVisibility.collectLatest { visible -> val iterator = callbacks.iterator() withContext(backgroundDispatcher) { while (iterator.hasNext()) { val callback = iterator.next() try { callback.onShowingStateChanged(!isIdleInGone(), selectedUser) callback.onInputRestrictedStateChanged(!isIdleInGone()) callback.onShowingStateChanged( visible, selectedUserInteractor.getSelectedUserId(), ) callback.onInputRestrictedStateChanged(visible) trustManager.reportKeyguardShowingChanged() if (!visible) { dismissCallbackRegistry.notifyDismissSucceeded() } } catch (e: RemoteException) { if (e is DeadObjectException) { iterator.remove() Loading
packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorKosmos.kt +0 −1 Original line number Diff line number Diff line Loading @@ -41,6 +41,5 @@ val Kosmos.keyguardDismissInteractor by trustRepository = trustRepository, alternateBouncerInteractor = alternateBouncerInteractor, powerInteractor = powerInteractor, keyguardTransitionInteractor = keyguardTransitionInteractor, ) }