Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f49ec247 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Tie KeyguardStateCallbackInteractor state to WmLockscreenVisibility +...

Merge "Tie KeyguardStateCallbackInteractor state to WmLockscreenVisibility + add dismiss callback notifications." into main
parents 87c82ef9 09b82637
Loading
Loading
Loading
Loading
+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()
        }
}
+5 −1
Original line number Diff line number Diff line
@@ -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();
+0 −14
Original line number Diff line number Diff line
@@ -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() }
            }
        }
    }
}
+26 −19
Original line number Diff line number Diff line
@@ -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,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()
+0 −1
Original line number Diff line number Diff line
@@ -41,6 +41,5 @@ val Kosmos.keyguardDismissInteractor by
            trustRepository = trustRepository,
            alternateBouncerInteractor = alternateBouncerInteractor,
            powerInteractor = powerInteractor,
            keyguardTransitionInteractor = keyguardTransitionInteractor,
        )
    }
Loading