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

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

Merge changes Ia7cc37cf,I78237002 into main

* changes:
  [flexiglass] Immediately locks device when sleep button is pressed.
  [flexiglass] Adds support for "lock now" from KeyguardService
parents 1ab7b554 b214d151
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -568,6 +568,41 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() {
            assertThat(isUnlocked).isFalse()
        }

    @Test
    fun lockNow() =
        testScope.runTest {
            setLockAfterScreenTimeout(5000)
            val isUnlocked by collectLastValue(underTest.deviceUnlockStatus.map { it.isUnlocked })
            unlockDevice()
            assertThat(isUnlocked).isTrue()

            underTest.lockNow()
            runCurrent()

            assertThat(isUnlocked).isFalse()
        }

    @Test
    fun deviceUnlockStatus_isResetToFalse_whenDeviceGoesToSleep_fromSleepButton() =
        testScope.runTest {
            setLockAfterScreenTimeout(5000)
            kosmos.fakeAuthenticationRepository.powerButtonInstantlyLocks = false
            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)

            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
                SuccessFingerprintAuthenticationStatus(0, true)
            )
            runCurrent()
            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()

            kosmos.powerInteractor.setAsleepForTest(
                sleepReason = PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON
            )
            runCurrent()

            assertThat(deviceUnlockStatus?.isUnlocked).isFalse()
        }

    private fun TestScope.unlockDevice() {
        val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)

+13 −8
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.deviceentry.domain.interactor

import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.internal.policy.IKeyguardDismissCallback
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
@@ -43,7 +44,6 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import com.android.app.tracing.coroutines.launchTraced as launch

/**
 * Hosts application business logic related to device entry.
@@ -173,6 +173,14 @@ constructor(
            )
    }

    /**
     * Whether lockscreen bypass is enabled. When enabled, the lockscreen will be automatically
     * dismissed once the authentication challenge is completed. For example, completing a biometric
     * authentication challenge via face unlock or fingerprint sensor can automatically bypass the
     * lockscreen.
     */
    val isBypassEnabled: StateFlow<Boolean> = repository.isBypassEnabled

    /**
     * Attempt to enter the device and dismiss the lockscreen. If authentication is required to
     * unlock the device it will transition to bouncer.
@@ -238,11 +246,8 @@ constructor(
        isLockscreenEnabled()
    }

    /**
     * Whether lockscreen bypass is enabled. When enabled, the lockscreen will be automatically
     * dismissed once the authentication challenge is completed. For example, completing a biometric
     * authentication challenge via face unlock or fingerprint sensor can automatically bypass the
     * lockscreen.
     */
    val isBypassEnabled: StateFlow<Boolean> = repository.isBypassEnabled
    /** Locks the device instantly. */
    fun lockNow() {
        deviceUnlockedInteractor.lockNow()
    }
}
+13 −1
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
@@ -57,6 +58,7 @@ import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch

@OptIn(ExperimentalCoroutinesApi::class)
@@ -178,6 +180,8 @@ constructor(
    val deviceUnlockStatus: StateFlow<DeviceUnlockStatus> =
        repository.deviceUnlockStatus.asStateFlow()

    private val lockNowRequests = Channel<Unit>()

    override suspend fun onActivated(): Nothing {
        authenticationInteractor.authenticationMethod.collectLatest { authMethod ->
            if (!authMethod.isSecure) {
@@ -196,6 +200,11 @@ constructor(
        awaitCancellation()
    }

    /** Locks the device instantly. */
    fun lockNow() {
        lockNowRequests.trySend(Unit)
    }

    private suspend fun handleLockAndUnlockEvents() {
        try {
            Log.d(TAG, "started watching for lock and unlock events")
@@ -225,10 +234,12 @@ constructor(
                    .map { (isAsleep, lastSleepReason) ->
                        if (isAsleep) {
                            if (
                                lastSleepReason == WakeSleepReason.POWER_BUTTON &&
                                (lastSleepReason == WakeSleepReason.POWER_BUTTON) &&
                                    authenticationInteractor.getPowerButtonInstantlyLocks()
                            ) {
                                LockImmediately("locked instantly from power button")
                            } else if (lastSleepReason == WakeSleepReason.SLEEP_BUTTON) {
                                LockImmediately("locked instantly from sleep button")
                            } else {
                                LockWithDelay("entering sleep")
                            }
@@ -256,6 +267,7 @@ constructor(
                        emptyFlow()
                    }
                },
                lockNowRequests.receiveAsFlow().map { LockImmediately("lockNow") },
            )
            .collectLatest(::onLockEvent)
    }
+3 −1
Original line number Diff line number Diff line
@@ -662,7 +662,9 @@ public class KeyguardService extends Service {
            trace("doKeyguardTimeout");
            checkPermission();

            if (KeyguardWmStateRefactor.isEnabled()) {
            if (SceneContainerFlag.isEnabled()) {
                mDeviceEntryInteractorLazy.get().lockNow();
            } else if (KeyguardWmStateRefactor.isEnabled()) {
                mKeyguardLockWhileAwakeInteractor.onKeyguardServiceDoKeyguardTimeout(options);
            }

+4 −0
Original line number Diff line number Diff line
@@ -26,6 +26,9 @@ enum class WakeSleepReason(
    /** The physical power button was pressed to wake up or sleep the device. */
    POWER_BUTTON(isTouch = false, PowerManager.WAKE_REASON_POWER_BUTTON),

    /** The sleep button was pressed to sleep the device. */
    SLEEP_BUTTON(isTouch = false, PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON),

    /** The user has tapped or double tapped to wake the screen. */
    TAP(isTouch = true, PowerManager.WAKE_REASON_TAP),

@@ -78,6 +81,7 @@ enum class WakeSleepReason(
        fun fromPowerManagerSleepReason(reason: Int): WakeSleepReason {
            return when (reason) {
                PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON -> POWER_BUTTON
                PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON -> SLEEP_BUTTON
                PowerManager.GO_TO_SLEEP_REASON_TIMEOUT -> TIMEOUT
                PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD -> FOLD
                else -> OTHER