Merge "Tie KeyguardStateCallbackInteractor state to WmLockscreenVisibility + add dismiss callback notifications." into main
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 0000000..2558d58
--- /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 ba23eb3..0a38ce0 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 @@
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 4457f1d..9b9bdd1 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.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 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 @@
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 @@
}
}
}
-
- 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 7fd348b..6fe4ff5 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.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 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 @@
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 @@
}
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 52416ba..ace1157 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 @@
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 0000000..58dd522
--- /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,
+ )
+ }