summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorTest.kt100
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt91
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/shared/model/SensorLocation.kt43
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorKosmos.kt36
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt32
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayRepositoryKosmos.kt22
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayStateRepositoryKosmos.kt23
8 files changed, 359 insertions, 11 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorTest.kt
new file mode 100644
index 000000000000..ccf119ab3088
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorTest.kt
@@ -0,0 +1,100 @@
+/*
+ * 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.biometrics.domain.interactor
+
+import android.hardware.biometrics.SensorLocationInternal
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
+import com.android.systemui.biometrics.shared.model.FingerprintSensorType
+import com.android.systemui.biometrics.shared.model.SensorStrength
+import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class FingerprintPropertyInteractorTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private val underTest = kosmos.fingerprintPropertyInteractor
+ private val repository = kosmos.fingerprintPropertyRepository
+ private val configurationRepository = kosmos.fakeConfigurationRepository
+ private val displayRepository = kosmos.displayRepository
+
+ @Test
+ fun sensorLocation_resolution1f() =
+ testScope.runTest {
+ val currSensorLocation by collectLastValue(underTest.sensorLocation)
+
+ displayRepository.emitDisplayChangeEvent(0)
+ runCurrent()
+ repository.setProperties(
+ sensorId = 0,
+ strength = SensorStrength.STRONG,
+ sensorType = FingerprintSensorType.UDFPS_OPTICAL,
+ sensorLocations =
+ mapOf(
+ Pair("", SensorLocationInternal("", 4, 4, 2)),
+ Pair("otherDisplay", SensorLocationInternal("", 1, 1, 1))
+ )
+ )
+ runCurrent()
+ configurationRepository.setScaleForResolution(1f)
+ runCurrent()
+
+ assertThat(currSensorLocation?.centerX).isEqualTo(4)
+ assertThat(currSensorLocation?.centerY).isEqualTo(4)
+ assertThat(currSensorLocation?.radius).isEqualTo(2)
+ }
+
+ @Test
+ fun sensorLocation_resolution2f() =
+ testScope.runTest {
+ val currSensorLocation by collectLastValue(underTest.sensorLocation)
+
+ displayRepository.emitDisplayChangeEvent(0)
+ runCurrent()
+ repository.setProperties(
+ sensorId = 0,
+ strength = SensorStrength.STRONG,
+ sensorType = FingerprintSensorType.UDFPS_OPTICAL,
+ sensorLocations =
+ mapOf(
+ Pair("", SensorLocationInternal("", 4, 4, 2)),
+ Pair("otherDisplay", SensorLocationInternal("", 1, 1, 1))
+ )
+ )
+ runCurrent()
+ configurationRepository.setScaleForResolution(2f)
+ runCurrent()
+
+ assertThat(currSensorLocation?.centerX).isEqualTo(4 * 2)
+ assertThat(currSensorLocation?.centerY).isEqualTo(4 * 2)
+ assertThat(currSensorLocation?.radius).isEqualTo(2 * 2)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
new file mode 100644
index 000000000000..e6939f06b642
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
@@ -0,0 +1,91 @@
+/*
+ * 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.biometrics.domain.interactor
+
+import android.content.Context
+import android.hardware.biometrics.SensorLocationInternal
+import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository
+import com.android.systemui.biometrics.shared.model.SensorLocation
+import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.map
+
+@SysUISingleton
+class FingerprintPropertyInteractor
+@Inject
+constructor(
+ @Application private val context: Context,
+ repository: FingerprintPropertyRepository,
+ configurationInteractor: ConfigurationInteractor,
+ displayStateInteractor: DisplayStateInteractor,
+) {
+ /**
+ * Devices with multiple physical displays use unique display ids to determine which sensor is
+ * on the active physical display. This value represents a unique physical display id.
+ */
+ private val uniqueDisplayId: Flow<String> =
+ displayStateInteractor.displayChanges
+ .map { context.display?.uniqueId }
+ .filterNotNull()
+ .distinctUntilChanged()
+
+ /**
+ * Sensor location for the:
+ * - current physical display
+ * - device's natural screen resolution
+ * - device's natural orientation
+ */
+ private val unscaledSensorLocation: Flow<SensorLocationInternal> =
+ combine(
+ repository.sensorLocations,
+ uniqueDisplayId,
+ ) { locations, displayId ->
+ // Devices without multiple physical displays do not use the display id as the key;
+ // instead, the key is an empty string.
+ locations.getOrDefault(
+ displayId,
+ locations.getOrDefault("", SensorLocationInternal.DEFAULT)
+ )
+ }
+
+ /**
+ * Sensor location for the:
+ * - current physical display
+ * - current screen resolution
+ * - device's natural orientation
+ */
+ val sensorLocation: Flow<SensorLocation> =
+ combine(
+ unscaledSensorLocation,
+ configurationInteractor.scaleForResolution,
+ ) { unscaledSensorLocation, scale ->
+ val sensorLocation =
+ SensorLocation(
+ unscaledSensorLocation.sensorLocationX,
+ unscaledSensorLocation.sensorLocationY,
+ unscaledSensorLocation.sensorRadius,
+ )
+ sensorLocation.scale = scale
+ sensorLocation
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/SensorLocation.kt b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/SensorLocation.kt
new file mode 100644
index 000000000000..dddadbd5e036
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/SensorLocation.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.biometrics.shared.model
+
+/** Provides current sensor location information in the current screen resolution [scale]. */
+data class SensorLocation(
+ private val naturalCenterX: Int,
+ private val naturalCenterY: Int,
+ private val naturalRadius: Int
+) {
+ /**
+ * Scale to apply to the sensor location's natural parameters to support different screen
+ * resolutions.
+ */
+ var scale: Float = 1f
+
+ val centerX: Float
+ get() {
+ return naturalCenterX * scale
+ }
+ val centerY: Float
+ get() {
+ return naturalCenterY * scale
+ }
+ val radius: Float
+ get() {
+ return naturalRadius * scale
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt
index fa4de044623d..ce4511237e40 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt
@@ -17,14 +17,12 @@
package com.android.systemui.keyguard.ui.viewmodel
import android.content.Context
-import android.hardware.biometrics.SensorLocationInternal
import com.android.settingslib.Utils
-import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository
+import com.android.systemui.biometrics.domain.interactor.FingerprintPropertyInteractor
import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
import com.android.systemui.keyguard.ui.view.DeviceEntryIconView
-import com.android.systemui.res.R
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -44,21 +42,24 @@ constructor(
configurationInteractor: ConfigurationInteractor,
deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
deviceEntryBackgroundViewModel: DeviceEntryBackgroundViewModel,
- fingerprintPropertyRepository: FingerprintPropertyRepository,
+ fingerprintPropertyInteractor: FingerprintPropertyInteractor,
udfpsOverlayInteractor: UdfpsOverlayInteractor,
) {
private val isSupported: Flow<Boolean> = deviceEntryUdfpsInteractor.isUdfpsSupported
+
+ /**
+ * UDFPS icon location in pixels for the current display and screen resolution, in natural
+ * orientation.
+ */
val iconLocation: Flow<IconLocation> =
isSupported.flatMapLatest { supportsUI ->
if (supportsUI) {
- fingerprintPropertyRepository.sensorLocations.map { sensorLocations ->
- val sensorLocation =
- sensorLocations.getOrDefault("", SensorLocationInternal.DEFAULT)
+ fingerprintPropertyInteractor.sensorLocation.map { sensorLocation ->
IconLocation(
- left = sensorLocation.sensorLocationX - sensorLocation.sensorRadius,
- top = sensorLocation.sensorLocationY - sensorLocation.sensorRadius,
- right = sensorLocation.sensorLocationX + sensorLocation.sensorRadius,
- bottom = sensorLocation.sensorLocationY + sensorLocation.sensorRadius,
+ left = (sensorLocation.centerX - sensorLocation.radius).toInt(),
+ top = (sensorLocation.centerY - sensorLocation.radius).toInt(),
+ right = (sensorLocation.centerX + sensorLocation.radius).toInt(),
+ bottom = (sensorLocation.centerY + sensorLocation.radius).toInt(),
)
}
} else {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorKosmos.kt
new file mode 100644
index 000000000000..4a089d3c6d7c
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorKosmos.kt
@@ -0,0 +1,36 @@
+/*
+ * 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.biometrics.domain.interactor
+
+import android.content.applicationContext
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.display.data.repository.displayStateRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.util.mockito.mock
+import java.util.concurrent.Executor
+
+val Kosmos.displayStateInteractor by Fixture {
+ DisplayStateInteractorImpl(
+ applicationScope = applicationCoroutineScope,
+ context = applicationContext,
+ mainExecutor = mock<Executor>(),
+ displayStateRepository = displayStateRepository,
+ displayRepository = displayRepository,
+ )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt
new file mode 100644
index 000000000000..e26206625c6d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.biometrics.domain.interactor
+
+import android.content.applicationContext
+import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.fingerprintPropertyInteractor by Fixture {
+ FingerprintPropertyInteractor(
+ context = applicationContext,
+ repository = fingerprintPropertyRepository,
+ configurationInteractor = configurationInteractor,
+ displayStateInteractor = displayStateInteractor,
+ )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayRepositoryKosmos.kt
new file mode 100644
index 000000000000..048ea3c25388
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayRepositoryKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * 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.display.data.repository
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.displayRepository by Fixture { FakeDisplayRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayStateRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayStateRepositoryKosmos.kt
new file mode 100644
index 000000000000..4a71a099d0d5
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayStateRepositoryKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * 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.display.data.repository
+
+import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.displayStateRepository by Fixture { FakeDisplayStateRepository() }