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

Commit 6656e1db authored by Alejandro Nijamkin's avatar Alejandro Nijamkin
Browse files

[flexiglass] Invoke IKeyguardDismissCallbacks

When we get past the bouncer by unlocking the device or when we leave
the bouncer without unlocking, these callbacks need to be invoked.

This helps, for example, the occluding camera app know to switch to its
insecure version where the user can see the gallery button.

Fix: 348646872
Test: manually verified that tapping on the lock icon in the occluding
camera activity's gallery button (bottom left), unlocking via bouncer or
via face unlock, correctly returns to the camera app, but this time it's
unlocked.
Test: manually verified that exiting the bouncer instead invokes the
onDismissCancelled method on the callbacks
Flag: com.android.systemui.scene_container

Change-Id: I95d9f2205dd022fca6ee2b5d8a2e339d379c4acf
parent 253553e5
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -26,14 +26,18 @@ import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
import com.android.internal.logging.uiEventLoggerFake
import com.android.internal.policy.IKeyguardDismissCallback
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
import com.android.systemui.authentication.domain.interactor.authenticationInteractor
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
import com.android.systemui.bouncer.shared.logging.BouncerUiEvent
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.classifier.falsingCollector
import com.android.systemui.classifier.falsingManager
import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
@@ -44,6 +48,7 @@ import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepo
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeTrustRepository
import com.android.systemui.keyguard.dismissCallbackRegistry
import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
@@ -1457,6 +1462,47 @@ class SceneContainerStartableTest : SysuiTestCase() {
            assertThat(currentScene).isEqualTo(Scenes.Gone)
        }

    @Test
    fun notifyKeyguardDismissCallbacks_whenUnlocking_onDismissSucceeded() =
        testScope.runTest {
            val currentScene by collectLastValue(sceneInteractor.currentScene)
            prepareState()
            underTest.start()
            val dismissCallback: IKeyguardDismissCallback = mock()
            kosmos.dismissCallbackRegistry.addCallback(dismissCallback)

            // Switch to bouncer and unlock device:
            sceneInteractor.changeScene(Scenes.Bouncer, "")
            assertThat(currentScene).isEqualTo(Scenes.Bouncer)
            kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN)
            assertThat(currentScene).isEqualTo(Scenes.Gone)
            kosmos.fakeExecutor.runAllReady()

            verify(dismissCallback).onDismissSucceeded()
        }

    @Test
    fun notifyKeyguardDismissCallbacks_whenLeavingBouncer_onDismissCancelled() =
        testScope.runTest {
            val currentScene by collectLastValue(sceneInteractor.currentScene)
            prepareState()
            underTest.start()
            val dismissCallback: IKeyguardDismissCallback = mock()
            kosmos.dismissCallbackRegistry.addCallback(dismissCallback)

            // Switch to bouncer:
            sceneInteractor.changeScene(Scenes.Bouncer, "")
            assertThat(currentScene).isEqualTo(Scenes.Bouncer)

            // Return to lockscreen:
            sceneInteractor.changeScene(Scenes.Lockscreen, "")
            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
            runCurrent()
            kosmos.fakeExecutor.runAllReady()

            verify(dismissCallback).onDismissCancelled()
        }

    private fun TestScope.emulateSceneTransition(
        transitionStateFlow: MutableStateFlow<ObservableTransitionState>,
        toScene: SceneKey,
+15 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInt
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
import com.android.systemui.deviceentry.shared.model.DeviceUnlockSource
import com.android.systemui.keyguard.DismissCallbackRegistry
import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor
@@ -126,6 +127,7 @@ constructor(
    private val shadeSessionStorage: SessionStorage,
    private val windowMgrLockscreenVisInteractor: WindowManagerLockscreenVisibilityInteractor,
    private val keyguardEnabledInteractor: KeyguardEnabledInteractor,
    private val dismissCallbackRegistry: DismissCallbackRegistry,
) : CoreStartable {
    private val centralSurfaces: CentralSurfaces?
        get() = centralSurfacesOptLazy.get().getOrNull()
@@ -144,6 +146,7 @@ constructor(
            hydrateBackStack()
            resetShadeSessions()
            handleKeyguardEnabledness()
            notifyKeyguardDismissCallbacks()
        } else {
            sceneLogger.logFrameworkEnabled(
                isEnabled = false,
@@ -713,4 +716,16 @@ constructor(
            }
        }
    }

    private fun notifyKeyguardDismissCallbacks() {
        applicationScope.launch {
            sceneInteractor.currentScene.pairwise().collect { (from, to) ->
                when {
                    from != Scenes.Bouncer -> Unit
                    to == Scenes.Gone -> dismissCallbackRegistry.notifyDismissSucceeded()
                    else -> dismissCallbackRegistry.notifyDismissCancelled()
                }
            }
        }
    }
}
+23 −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

import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture

val Kosmos.dismissCallbackRegistry by Fixture { DismissCallbackRegistry(fakeExecutor) }
+2 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import com.android.systemui.classifier.falsingManager
import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.keyguard.dismissCallbackRegistry
import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.domain.interactor.windowManagerLockscreenVisibilityInteractor
@@ -73,5 +74,6 @@ val Kosmos.sceneContainerStartable by Fixture {
        shadeSessionStorage = shadeSessionStorage,
        windowMgrLockscreenVisInteractor = windowManagerLockscreenVisibilityInteractor,
        keyguardEnabledInteractor = keyguardEnabledInteractor,
        dismissCallbackRegistry = dismissCallbackRegistry,
    )
}