Merge "Add repository to be the source of truth for device posture" into tm-qpr-dev
This commit is contained in:
@@ -24,8 +24,10 @@ import android.hardware.biometrics.BiometricManager
|
|||||||
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback
|
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.os.UserHandle
|
import android.os.UserHandle
|
||||||
|
import android.util.Log
|
||||||
import com.android.internal.widget.LockPatternUtils
|
import com.android.internal.widget.LockPatternUtils
|
||||||
import com.android.systemui.Dumpable
|
import com.android.systemui.Dumpable
|
||||||
|
import com.android.systemui.R
|
||||||
import com.android.systemui.biometrics.AuthController
|
import com.android.systemui.biometrics.AuthController
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher
|
import com.android.systemui.broadcast.BroadcastDispatcher
|
||||||
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
|
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
|
||||||
@@ -35,6 +37,7 @@ import com.android.systemui.dagger.qualifiers.Application
|
|||||||
import com.android.systemui.dagger.qualifiers.Background
|
import com.android.systemui.dagger.qualifiers.Background
|
||||||
import com.android.systemui.dagger.qualifiers.Main
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
import com.android.systemui.dump.DumpManager
|
import com.android.systemui.dump.DumpManager
|
||||||
|
import com.android.systemui.keyguard.shared.model.DevicePosture
|
||||||
import com.android.systemui.user.data.repository.UserRepository
|
import com.android.systemui.user.data.repository.UserRepository
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -47,8 +50,10 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.flatMapLatest
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.onStart
|
import kotlinx.coroutines.flow.onStart
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.flow.transformLatest
|
import kotlinx.coroutines.flow.transformLatest
|
||||||
@@ -82,6 +87,12 @@ interface BiometricSettingsRepository {
|
|||||||
|
|
||||||
/** Whether fingerprint feature is enabled for the current user by the DevicePolicy */
|
/** Whether fingerprint feature is enabled for the current user by the DevicePolicy */
|
||||||
val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean>
|
val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether face authentication is supported for the current device posture. Face auth can be
|
||||||
|
* restricted to specific postures using [R.integer.config_face_auth_supported_posture]
|
||||||
|
*/
|
||||||
|
val isFaceAuthSupportedInCurrentPosture: Flow<Boolean>
|
||||||
}
|
}
|
||||||
|
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
@@ -98,11 +109,27 @@ constructor(
|
|||||||
@Background backgroundDispatcher: CoroutineDispatcher,
|
@Background backgroundDispatcher: CoroutineDispatcher,
|
||||||
biometricManager: BiometricManager?,
|
biometricManager: BiometricManager?,
|
||||||
@Main looper: Looper,
|
@Main looper: Looper,
|
||||||
|
devicePostureRepository: DevicePostureRepository,
|
||||||
dumpManager: DumpManager,
|
dumpManager: DumpManager,
|
||||||
) : BiometricSettingsRepository, Dumpable {
|
) : BiometricSettingsRepository, Dumpable {
|
||||||
|
|
||||||
|
override val isFaceAuthSupportedInCurrentPosture: Flow<Boolean>
|
||||||
|
|
||||||
init {
|
init {
|
||||||
dumpManager.registerDumpable(this)
|
dumpManager.registerDumpable(this)
|
||||||
|
val configFaceAuthSupportedPosture =
|
||||||
|
DevicePosture.toPosture(
|
||||||
|
context.resources.getInteger(R.integer.config_face_auth_supported_posture)
|
||||||
|
)
|
||||||
|
isFaceAuthSupportedInCurrentPosture =
|
||||||
|
if (configFaceAuthSupportedPosture == DevicePosture.UNKNOWN) {
|
||||||
|
flowOf(true)
|
||||||
|
} else {
|
||||||
|
devicePostureRepository.currentDevicePosture.map {
|
||||||
|
it == configFaceAuthSupportedPosture
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onEach { Log.d(TAG, "isFaceAuthSupportedInCurrentPosture value changed to: $it") }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dump(pw: PrintWriter, args: Array<String?>) {
|
override fun dump(pw: PrintWriter, args: Array<String?>) {
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* 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.keyguard.data.repository
|
||||||
|
|
||||||
|
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
|
||||||
|
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
||||||
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
|
import com.android.systemui.keyguard.shared.model.DevicePosture
|
||||||
|
import com.android.systemui.statusbar.policy.DevicePostureController
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
/** Provide current device posture state. */
|
||||||
|
interface DevicePostureRepository {
|
||||||
|
/** Provides the current device posture. */
|
||||||
|
val currentDevicePosture: Flow<DevicePosture>
|
||||||
|
}
|
||||||
|
|
||||||
|
@SysUISingleton
|
||||||
|
class DevicePostureRepositoryImpl
|
||||||
|
@Inject
|
||||||
|
constructor(private val postureController: DevicePostureController) : DevicePostureRepository {
|
||||||
|
override val currentDevicePosture: Flow<DevicePosture>
|
||||||
|
get() = conflatedCallbackFlow {
|
||||||
|
val sendPostureUpdate = { posture: Int ->
|
||||||
|
val currentDevicePosture = DevicePosture.toPosture(posture)
|
||||||
|
trySendWithFailureLogging(
|
||||||
|
currentDevicePosture,
|
||||||
|
TAG,
|
||||||
|
"Error sending posture update to $currentDevicePosture"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = DevicePostureController.Callback { sendPostureUpdate(it) }
|
||||||
|
postureController.addCallback(callback)
|
||||||
|
sendPostureUpdate(postureController.devicePosture)
|
||||||
|
|
||||||
|
awaitClose { postureController.removeCallback(callback) }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val TAG = "PostureRepositoryImpl"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,6 +31,8 @@ interface KeyguardRepositoryModule {
|
|||||||
@Binds
|
@Binds
|
||||||
fun lightRevealScrimRepository(impl: LightRevealScrimRepositoryImpl): LightRevealScrimRepository
|
fun lightRevealScrimRepository(impl: LightRevealScrimRepositoryImpl): LightRevealScrimRepository
|
||||||
|
|
||||||
|
@Binds fun devicePostureRepository(impl: DevicePostureRepositoryImpl): DevicePostureRepository
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
fun biometricSettingsRepository(
|
fun biometricSettingsRepository(
|
||||||
impl: BiometricSettingsRepositoryImpl
|
impl: BiometricSettingsRepositoryImpl
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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.keyguard.shared.model
|
||||||
|
|
||||||
|
import com.android.systemui.statusbar.policy.DevicePostureController
|
||||||
|
|
||||||
|
/** Represents the possible posture states of the device. */
|
||||||
|
enum class DevicePosture {
|
||||||
|
UNKNOWN,
|
||||||
|
CLOSED,
|
||||||
|
HALF_OPENED,
|
||||||
|
OPENED,
|
||||||
|
FLIPPED;
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun toPosture(@DevicePostureController.DevicePostureInt posture: Int): DevicePosture {
|
||||||
|
return when (posture) {
|
||||||
|
DevicePostureController.DEVICE_POSTURE_CLOSED -> CLOSED
|
||||||
|
DevicePostureController.DEVICE_POSTURE_HALF_OPENED -> HALF_OPENED
|
||||||
|
DevicePostureController.DEVICE_POSTURE_OPENED -> OPENED
|
||||||
|
DevicePostureController.DEVICE_POSTURE_FLIPPED -> FLIPPED
|
||||||
|
DevicePostureController.DEVICE_POSTURE_UNKNOWN -> UNKNOWN
|
||||||
|
else -> UNKNOWN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@ import androidx.test.filters.SmallTest
|
|||||||
import com.android.internal.widget.LockPatternUtils
|
import com.android.internal.widget.LockPatternUtils
|
||||||
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED
|
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED
|
||||||
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
|
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
|
||||||
|
import com.android.systemui.R
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.biometrics.AuthController
|
import com.android.systemui.biometrics.AuthController
|
||||||
import com.android.systemui.coroutines.collectLastValue
|
import com.android.systemui.coroutines.collectLastValue
|
||||||
@@ -38,11 +39,14 @@ import com.android.systemui.keyguard.data.repository.BiometricType.FACE
|
|||||||
import com.android.systemui.keyguard.data.repository.BiometricType.REAR_FINGERPRINT
|
import com.android.systemui.keyguard.data.repository.BiometricType.REAR_FINGERPRINT
|
||||||
import com.android.systemui.keyguard.data.repository.BiometricType.SIDE_FINGERPRINT
|
import com.android.systemui.keyguard.data.repository.BiometricType.SIDE_FINGERPRINT
|
||||||
import com.android.systemui.keyguard.data.repository.BiometricType.UNDER_DISPLAY_FINGERPRINT
|
import com.android.systemui.keyguard.data.repository.BiometricType.UNDER_DISPLAY_FINGERPRINT
|
||||||
|
import com.android.systemui.keyguard.shared.model.DevicePosture
|
||||||
|
import com.android.systemui.statusbar.policy.DevicePostureController
|
||||||
import com.android.systemui.user.data.repository.FakeUserRepository
|
import com.android.systemui.user.data.repository.FakeUserRepository
|
||||||
import com.android.systemui.util.mockito.argumentCaptor
|
import com.android.systemui.util.mockito.argumentCaptor
|
||||||
import com.android.systemui.util.mockito.eq
|
import com.android.systemui.util.mockito.eq
|
||||||
import com.android.systemui.util.mockito.whenever
|
import com.android.systemui.util.mockito.whenever
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||||
import kotlinx.coroutines.test.TestDispatcher
|
import kotlinx.coroutines.test.TestDispatcher
|
||||||
import kotlinx.coroutines.test.TestScope
|
import kotlinx.coroutines.test.TestScope
|
||||||
@@ -62,6 +66,7 @@ import org.mockito.Mockito.times
|
|||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
@@ -78,6 +83,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
|
|||||||
private lateinit var biometricManagerCallback:
|
private lateinit var biometricManagerCallback:
|
||||||
ArgumentCaptor<IBiometricEnabledOnKeyguardCallback.Stub>
|
ArgumentCaptor<IBiometricEnabledOnKeyguardCallback.Stub>
|
||||||
private lateinit var userRepository: FakeUserRepository
|
private lateinit var userRepository: FakeUserRepository
|
||||||
|
private lateinit var devicePostureRepository: FakeDevicePostureRepository
|
||||||
|
|
||||||
private lateinit var testDispatcher: TestDispatcher
|
private lateinit var testDispatcher: TestDispatcher
|
||||||
private lateinit var testScope: TestScope
|
private lateinit var testScope: TestScope
|
||||||
@@ -90,6 +96,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
|
|||||||
testDispatcher = StandardTestDispatcher()
|
testDispatcher = StandardTestDispatcher()
|
||||||
testScope = TestScope(testDispatcher)
|
testScope = TestScope(testDispatcher)
|
||||||
userRepository = FakeUserRepository()
|
userRepository = FakeUserRepository()
|
||||||
|
devicePostureRepository = FakeDevicePostureRepository()
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun createBiometricSettingsRepository() {
|
private suspend fun createBiometricSettingsRepository() {
|
||||||
@@ -108,6 +115,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
|
|||||||
looper = testableLooper!!.looper,
|
looper = testableLooper!!.looper,
|
||||||
dumpManager = dumpManager,
|
dumpManager = dumpManager,
|
||||||
biometricManager = biometricManager,
|
biometricManager = biometricManager,
|
||||||
|
devicePostureRepository = devicePostureRepository,
|
||||||
)
|
)
|
||||||
testScope.runCurrent()
|
testScope.runCurrent()
|
||||||
}
|
}
|
||||||
@@ -299,6 +307,50 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
|
|||||||
verify(biometricManager, times(1)).registerEnabledOnKeyguardCallback(any())
|
verify(biometricManager, times(1)).registerEnabledOnKeyguardCallback(any())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun faceAuthIsAlwaysSupportedIfSpecificPostureIsNotConfigured() =
|
||||||
|
testScope.runTest {
|
||||||
|
overrideResource(
|
||||||
|
R.integer.config_face_auth_supported_posture,
|
||||||
|
DevicePostureController.DEVICE_POSTURE_UNKNOWN
|
||||||
|
)
|
||||||
|
|
||||||
|
createBiometricSettingsRepository()
|
||||||
|
|
||||||
|
assertThat(collectLastValue(underTest.isFaceAuthSupportedInCurrentPosture)()).isTrue()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun faceAuthIsSupportedOnlyWhenDevicePostureMatchesConfigValue() =
|
||||||
|
testScope.runTest {
|
||||||
|
overrideResource(
|
||||||
|
R.integer.config_face_auth_supported_posture,
|
||||||
|
DevicePostureController.DEVICE_POSTURE_FLIPPED
|
||||||
|
)
|
||||||
|
|
||||||
|
createBiometricSettingsRepository()
|
||||||
|
|
||||||
|
val isFaceAuthSupported =
|
||||||
|
collectLastValue(underTest.isFaceAuthSupportedInCurrentPosture)
|
||||||
|
|
||||||
|
assertThat(isFaceAuthSupported()).isFalse()
|
||||||
|
|
||||||
|
devicePostureRepository.setCurrentPosture(DevicePosture.CLOSED)
|
||||||
|
assertThat(isFaceAuthSupported()).isFalse()
|
||||||
|
|
||||||
|
devicePostureRepository.setCurrentPosture(DevicePosture.HALF_OPENED)
|
||||||
|
assertThat(isFaceAuthSupported()).isFalse()
|
||||||
|
|
||||||
|
devicePostureRepository.setCurrentPosture(DevicePosture.OPENED)
|
||||||
|
assertThat(isFaceAuthSupported()).isFalse()
|
||||||
|
|
||||||
|
devicePostureRepository.setCurrentPosture(DevicePosture.UNKNOWN)
|
||||||
|
assertThat(isFaceAuthSupported()).isFalse()
|
||||||
|
|
||||||
|
devicePostureRepository.setCurrentPosture(DevicePosture.FLIPPED)
|
||||||
|
assertThat(isFaceAuthSupported()).isTrue()
|
||||||
|
}
|
||||||
|
|
||||||
private fun enrollmentChange(biometricType: BiometricType, userId: Int, enabled: Boolean) {
|
private fun enrollmentChange(biometricType: BiometricType, userId: Int, enabled: Boolean) {
|
||||||
authControllerCallback.value.onEnrollmentsChanged(biometricType, userId, enabled)
|
authControllerCallback.value.onEnrollmentsChanged(biometricType, userId, enabled)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* 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.keyguard.data.repository
|
||||||
|
|
||||||
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.coroutines.collectLastValue
|
||||||
|
import com.android.systemui.keyguard.shared.model.DevicePosture
|
||||||
|
import com.android.systemui.statusbar.policy.DevicePostureController
|
||||||
|
import com.android.systemui.util.mockito.whenever
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.TestScope
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.junit.runners.JUnit4
|
||||||
|
import org.mockito.ArgumentCaptor
|
||||||
|
import org.mockito.Captor
|
||||||
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito.verify
|
||||||
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@SmallTest
|
||||||
|
@RunWith(JUnit4::class)
|
||||||
|
class DevicePostureRepositoryTest : SysuiTestCase() {
|
||||||
|
private lateinit var underTest: DevicePostureRepository
|
||||||
|
private lateinit var testScope: TestScope
|
||||||
|
@Mock private lateinit var devicePostureController: DevicePostureController
|
||||||
|
@Captor private lateinit var callback: ArgumentCaptor<DevicePostureController.Callback>
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
MockitoAnnotations.initMocks(this)
|
||||||
|
testScope = TestScope()
|
||||||
|
underTest = DevicePostureRepositoryImpl(postureController = devicePostureController)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun postureChangesArePropagated() =
|
||||||
|
testScope.runTest {
|
||||||
|
whenever(devicePostureController.devicePosture)
|
||||||
|
.thenReturn(DevicePostureController.DEVICE_POSTURE_FLIPPED)
|
||||||
|
val currentPosture = collectLastValue(underTest.currentDevicePosture)
|
||||||
|
assertThat(currentPosture()).isEqualTo(DevicePosture.FLIPPED)
|
||||||
|
|
||||||
|
verify(devicePostureController).addCallback(callback.capture())
|
||||||
|
|
||||||
|
callback.value.onPostureChanged(DevicePostureController.DEVICE_POSTURE_UNKNOWN)
|
||||||
|
assertThat(currentPosture()).isEqualTo(DevicePosture.UNKNOWN)
|
||||||
|
|
||||||
|
callback.value.onPostureChanged(DevicePostureController.DEVICE_POSTURE_CLOSED)
|
||||||
|
assertThat(currentPosture()).isEqualTo(DevicePosture.CLOSED)
|
||||||
|
|
||||||
|
callback.value.onPostureChanged(DevicePostureController.DEVICE_POSTURE_HALF_OPENED)
|
||||||
|
assertThat(currentPosture()).isEqualTo(DevicePosture.HALF_OPENED)
|
||||||
|
|
||||||
|
callback.value.onPostureChanged(DevicePostureController.DEVICE_POSTURE_OPENED)
|
||||||
|
assertThat(currentPosture()).isEqualTo(DevicePosture.OPENED)
|
||||||
|
|
||||||
|
callback.value.onPostureChanged(DevicePostureController.DEVICE_POSTURE_FLIPPED)
|
||||||
|
assertThat(currentPosture()).isEqualTo(DevicePosture.FLIPPED)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
|
||||||
class FakeBiometricSettingsRepository : BiometricSettingsRepository {
|
class FakeBiometricSettingsRepository : BiometricSettingsRepository {
|
||||||
|
|
||||||
@@ -42,6 +43,9 @@ class FakeBiometricSettingsRepository : BiometricSettingsRepository {
|
|||||||
override val isFingerprintEnabledByDevicePolicy =
|
override val isFingerprintEnabledByDevicePolicy =
|
||||||
_isFingerprintEnabledByDevicePolicy.asStateFlow()
|
_isFingerprintEnabledByDevicePolicy.asStateFlow()
|
||||||
|
|
||||||
|
override val isFaceAuthSupportedInCurrentPosture: Flow<Boolean>
|
||||||
|
get() = flowOf(true)
|
||||||
|
|
||||||
fun setFingerprintEnrolled(isFingerprintEnrolled: Boolean) {
|
fun setFingerprintEnrolled(isFingerprintEnrolled: Boolean) {
|
||||||
_isFingerprintEnrolled.value = isFingerprintEnrolled
|
_isFingerprintEnrolled.value = isFingerprintEnrolled
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 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.keyguard.data.repository
|
||||||
|
|
||||||
|
import com.android.systemui.keyguard.shared.model.DevicePosture
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
|
class FakeDevicePostureRepository : DevicePostureRepository {
|
||||||
|
private val _currentDevicePosture = MutableStateFlow(DevicePosture.UNKNOWN)
|
||||||
|
override val currentDevicePosture: Flow<DevicePosture>
|
||||||
|
get() = _currentDevicePosture
|
||||||
|
|
||||||
|
fun setCurrentPosture(posture: DevicePosture) {
|
||||||
|
_currentDevicePosture.value = posture
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user