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

Commit 7c0ba9f9 authored by Chandru S's avatar Chandru S Committed by Android (Google) Code Review
Browse files

Merge "Support swiping up on lockscreen to enter the device user is either...

Merge "Support swiping up on lockscreen to enter the device user is either trusted by a trust agent or has authenticated with face auth with bypass disabled" into main
parents 19c98814 f126ffea
Loading
Loading
Loading
Loading
+37 −5
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.deviceentry.domain.interactor

import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
@@ -5,6 +21,8 @@ import com.android.systemui.authentication.domain.model.AuthenticationMethodMode
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.data.repository.DeviceEntryRepository
import com.android.systemui.keyguard.data.repository.DeviceEntryFaceAuthRepository
import com.android.systemui.keyguard.data.repository.TrustRepository
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.SceneKey
import javax.inject.Inject
@@ -14,6 +32,7 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.stateIn

/**
@@ -27,9 +46,11 @@ class DeviceEntryInteractor
@Inject
constructor(
    @Application private val applicationScope: CoroutineScope,
    private val repository: DeviceEntryRepository,
    repository: DeviceEntryRepository,
    private val authenticationInteractor: AuthenticationInteractor,
    sceneInteractor: SceneInteractor,
    deviceEntryFaceAuthRepository: DeviceEntryFaceAuthRepository,
    trustRepository: TrustRepository,
) {
    /**
     * Whether the device is unlocked.
@@ -73,6 +94,13 @@ constructor(
                initialValue = false,
            )

    // Authenticated by a TrustAgent like trusted device, location, etc or by face auth.
    private val passivelyAuthenticated =
        merge(
            trustRepository.isCurrentUserTrusted,
            deviceEntryFaceAuthRepository.isAuthenticated,
        )

    /**
     * Whether it's currently possible to swipe up to enter the device without requiring
     * authentication. This returns `false` whenever the lockscreen has been dismissed.
@@ -81,10 +109,14 @@ constructor(
     * UI.
     */
    val canSwipeToEnter =
        combine(authenticationInteractor.authenticationMethod, isDeviceEntered) {
                authenticationMethod,
                isDeviceEntered ->
                authenticationMethod is AuthenticationMethodModel.Swipe && !isDeviceEntered
        combine(
                authenticationInteractor.authenticationMethod.map {
                    it == AuthenticationMethodModel.Swipe
                },
                passivelyAuthenticated,
                isDeviceEntered
            ) { isSwipeAuthMethod, passivelyAuthenticated, isDeviceEntered ->
                (isSwipeAuthMethod || passivelyAuthenticated) && !isDeviceEntered
            }
            .stateIn(
                scope = applicationScope,
+56 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.deviceentry.domain.interactor

import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -6,6 +22,8 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository
import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepository
import com.android.systemui.keyguard.data.repository.FakeTrustRepository
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
@@ -24,6 +42,8 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
    private val utils = SceneTestUtils(this)
    private val testScope = utils.testScope
    private val repository: FakeDeviceEntryRepository = utils.deviceEntryRepository
    private val faceAuthRepository = FakeDeviceEntryFaceAuthRepository()
    private val trustRepository = FakeTrustRepository()
    private val sceneInteractor = utils.sceneInteractor()
    private val authenticationInteractor = utils.authenticationInteractor()
    private val underTest =
@@ -31,6 +51,8 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
            repository = repository,
            authenticationInteractor = authenticationInteractor,
            sceneInteractor = sceneInteractor,
            faceAuthRepository = faceAuthRepository,
            trustRepository = trustRepository,
        )

    @Test
@@ -170,6 +192,40 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
            assertThat(canSwipeToEnter).isFalse()
        }

    @Test
    fun canSwipeToEnter_whenTrustedByTrustManager_isTrue() =
        testScope.runTest {
            val canSwipeToEnter by collectLastValue(underTest.canSwipeToEnter)
            utils.authenticationRepository.setAuthenticationMethod(
                AuthenticationMethodModel.Password
            )
            switchToScene(SceneKey.Lockscreen)
            assertThat(canSwipeToEnter).isFalse()

            trustRepository.setCurrentUserTrusted(true)
            runCurrent()
            faceAuthRepository.isAuthenticated.value = false

            assertThat(canSwipeToEnter).isTrue()
        }

    @Test
    fun canSwipeToEnter_whenAuthenticatedByFace_isTrue() =
        testScope.runTest {
            val canSwipeToEnter by collectLastValue(underTest.canSwipeToEnter)
            utils.authenticationRepository.setAuthenticationMethod(
                AuthenticationMethodModel.Password
            )
            switchToScene(SceneKey.Lockscreen)
            assertThat(canSwipeToEnter).isFalse()

            faceAuthRepository.isAuthenticated.value = true
            runCurrent()
            trustRepository.setCurrentUserTrusted(false)

            assertThat(canSwipeToEnter).isTrue()
        }

    @Test
    fun isAuthenticationRequired_lockedAndSecured_true() =
        testScope.runTest {
+11 −1
Original line number Diff line number Diff line
@@ -16,6 +16,16 @@
package com.android.systemui.deviceentry.data

import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepositoryModule
import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepositoryModule
import com.android.systemui.keyguard.data.repository.FakeTrustRepositoryModule
import dagger.Module

@Module(includes = [FakeDeviceEntryRepositoryModule::class]) object FakeDeviceEntryDataLayerModule
@Module(
    includes =
        [
            FakeDeviceEntryRepositoryModule::class,
            FakeTrustRepositoryModule::class,
            FakeDeviceEntryFaceAuthRepositoryModule::class,
        ]
)
object FakeDeviceEntryDataLayerModule
+0 −2
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@
package com.android.systemui.keyguard.data

import com.android.systemui.keyguard.data.repository.FakeCommandQueueModule
import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepositoryModule
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepositoryModule
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepositoryModule
import dagger.Module
@@ -25,7 +24,6 @@ import dagger.Module
    includes =
        [
            FakeCommandQueueModule::class,
            FakeDeviceEntryFaceAuthRepositoryModule::class,
            FakeKeyguardRepositoryModule::class,
            FakeKeyguardTransitionRepositoryModule::class,
        ]
+11 −1
Original line number Diff line number Diff line
@@ -18,13 +18,18 @@
package com.android.systemui.keyguard.data.repository

import com.android.keyguard.TrustGrantFlags
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.shared.model.TrustModel
import dagger.Binds
import dagger.Module
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow

class FakeTrustRepository : TrustRepository {
@SysUISingleton
class FakeTrustRepository @Inject constructor() : TrustRepository {
    private val _isTrustUsuallyManaged = MutableStateFlow(false)
    override val isCurrentUserTrustUsuallyManaged: StateFlow<Boolean>
        get() = _isTrustUsuallyManaged
@@ -63,3 +68,8 @@ class FakeTrustRepository : TrustRepository {
        _isTrustUsuallyManaged.value = value
    }
}

@Module
interface FakeTrustRepositoryModule {
    @Binds fun bindFake(fake: FakeTrustRepository): TrustRepository
}
Loading