summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hao Dong <spdonghao@google.com> 2024-05-30 05:57:37 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-05-30 05:57:37 +0000
commit61ed776f5f47368d562eefd41bd89accbcc435ce (patch)
treec8fc539c381e2085c24c406648878cbe1a1be612
parentdc390212974148108fbfd7224de41b77e9ad3c88 (diff)
parentc44a5e788428e975ab35b664929e7ab989b8ccc1 (diff)
Merge "Use one-pane and two-pane layout instead of depending on orientation." into main
-rw-r--r--packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml237
-rw-r--r--packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml (renamed from packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml)18
-rw-r--r--packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml (renamed from packages/SystemUI/res/layout-land/biometric_prompt_constraint_layout.xml)0
-rw-r--r--packages/SystemUI/res/values-sw600dp/dimens.xml11
-rw-r--r--packages/SystemUI/res/values/dimens.xml18
-rw-r--r--packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/PromptKind.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt30
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt47
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt140
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt10
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt7
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorKosmos.kt1
17 files changed, 269 insertions, 355 deletions
diff --git a/packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml b/packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml
deleted file mode 100644
index 8b9eabc5bd93..000000000000
--- a/packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml
+++ /dev/null
@@ -1,237 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- android:id="@+id/biometric_prompt_constraint_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <ImageView
- android:id="@+id/background"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:contentDescription="@string/biometric_dialog_empty_space_description"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
- <View
- android:id="@+id/panel"
- style="@style/AuthCredentialPanelStyle"
- android:layout_width="0dp"
- android:layout_height="0dp"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toStartOf="@+id/rightGuideline"
- app:layout_constraintStart_toStartOf="@+id/leftGuideline"
- app:layout_constraintTop_toTopOf="@+id/topBarrier"
- app:layout_constraintWidth_max="640dp" />
-
- <include
- android:id="@+id/button_bar"
- layout="@layout/biometric_prompt_button_bar"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- app:layout_constraintBottom_toBottomOf="@id/bottomGuideline"
- app:layout_constraintEnd_toEndOf="@id/panel"
- app:layout_constraintStart_toStartOf="@id/panel" />
-
- <ScrollView
- android:id="@+id/scrollView"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:fadeScrollbars="false"
- android:fillViewport="true"
- android:paddingBottom="32dp"
- android:paddingHorizontal="32dp"
- android:paddingTop="24dp"
- app:layout_constrainedHeight="true"
- app:layout_constrainedWidth="true"
- app:layout_constraintBottom_toTopOf="@+id/scrollBarrier"
- app:layout_constraintEnd_toEndOf="@id/panel"
- app:layout_constraintStart_toStartOf="@id/panel"
- app:layout_constraintTop_toTopOf="@+id/topGuideline"
- app:layout_constraintVertical_bias="1.0">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/innerConstraint"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <ImageView
- android:id="@+id/logo"
- android:layout_width="@dimen/biometric_prompt_logo_size"
- android:layout_height="@dimen/biometric_prompt_logo_size"
- android:layout_gravity="center"
- android:contentDescription="@string/biometric_dialog_logo"
- android:scaleType="fitXY"
- android:visibility="visible"
- app:layout_constraintBottom_toTopOf="@+id/logo_description"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
- <TextView
- android:id="@+id/logo_description"
- style="@style/TextAppearance.AuthCredential.LogoDescription"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="16dp"
- app:layout_constraintBottom_toTopOf="@+id/title"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/logo" />
-
- <TextView
- android:id="@+id/title"
- style="@style/TextAppearance.AuthCredential.Title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="@integer/biometric_dialog_text_gravity"
- android:paddingTop="16dp"
- app:layout_constraintBottom_toTopOf="@+id/subtitle"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/logo_description" />
-
- <TextView
- android:id="@+id/subtitle"
- style="@style/TextAppearance.AuthCredential.Subtitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="@integer/biometric_dialog_text_gravity"
- android:paddingTop="16dp"
- app:layout_constraintBottom_toTopOf="@+id/contentBarrier"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/title" />
-
- <LinearLayout
- android:id="@+id/customized_view_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:orientation="vertical"
- android:paddingTop="24dp"
- android:visibility="gone"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/subtitle" />
-
- <TextView
- android:id="@+id/description"
- style="@style/TextAppearance.AuthCredential.Description"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="@integer/biometric_dialog_text_gravity"
- android:paddingTop="16dp"
- android:textAlignment="viewStart"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/subtitle" />
-
- <androidx.constraintlayout.widget.Barrier
- android:id="@+id/contentBarrier"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:barrierAllowsGoneWidgets="false"
- app:barrierDirection="top"
- app:constraint_referenced_ids="description, customized_view_container" />
-
- </androidx.constraintlayout.widget.ConstraintLayout>
- </ScrollView>
-
- <!-- Cancel Button, replaces negative button when biometric is accepted -->
- <TextView
- android:id="@+id/indicator"
- style="@style/TextAppearance.AuthCredential.Indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="24dp"
- android:accessibilityLiveRegion="assertive"
- android:fadingEdge="horizontal"
- android:gravity="center_horizontal"
- android:scrollHorizontally="true"
- app:layout_constraintBottom_toTopOf="@+id/button_bar"
- app:layout_constraintEnd_toEndOf="@+id/panel"
- app:layout_constraintStart_toStartOf="@+id/panel"
- app:layout_constraintTop_toBottomOf="@+id/biometric_icon"
- app:layout_constraintVertical_bias="0.0" />
-
- <!-- "Use Credential" Button, replaces if device credential is allowed -->
-
- <!-- Positive Button -->
- <androidx.constraintlayout.widget.Barrier
- android:id="@+id/topBarrier"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:barrierAllowsGoneWidgets="false"
- app:barrierDirection="top"
- app:constraint_referenced_ids="scrollView" />
-
- <!-- Try Again Button -->
- <androidx.constraintlayout.widget.Barrier
- android:id="@+id/scrollBarrier"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:barrierAllowsGoneWidgets="false"
- app:barrierDirection="top"
- app:constraint_referenced_ids="biometric_icon, button_bar" />
-
- <!-- Guidelines for setting panel border -->
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/leftGuideline"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- app:layout_constraintGuide_begin="@dimen/biometric_dialog_border_padding" />
-
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/rightGuideline"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- app:layout_constraintGuide_end="@dimen/biometric_dialog_border_padding" />
-
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/bottomGuideline"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- app:layout_constraintGuide_end="40dp" />
-
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/topGuideline"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:orientation="horizontal"
- app:layout_constraintGuide_begin="56dp" />
-
- <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper
- android:id="@+id/biometric_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintVertical_bias="1.0"
- tools:srcCompat="@tools:sample/avatars" />
-
- <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper
- android:id="@+id/biometric_icon_overlay"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_gravity="center"
- android:contentDescription="@null"
- android:scaleType="fitXY"
- android:importantForAccessibility="no"
- app:layout_constraintBottom_toBottomOf="@+id/biometric_icon"
- app:layout_constraintEnd_toEndOf="@+id/biometric_icon"
- app:layout_constraintStart_toStartOf="@+id/biometric_icon"
- app:layout_constraintTop_toTopOf="@+id/biometric_icon" />
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml
index 9b5b59fc116f..8d50bfa00fd5 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml
@@ -22,9 +22,11 @@
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="@id/rightGuideline"
+ app:layout_constraintEnd_toStartOf="@id/rightGuideline"
app:layout_constraintStart_toStartOf="@id/leftGuideline"
- app:layout_constraintTop_toTopOf="@id/topBarrier" />
+ app:layout_constraintTop_toTopOf="@id/topBarrier"
+ app:layout_constraintWidth_max="@dimen/biometric_prompt_panel_max_width" />
+
<include
android:id="@+id/button_bar"
@@ -41,8 +43,8 @@
android:layout_height="wrap_content"
android:fillViewport="true"
android:fadeScrollbars="false"
- android:paddingBottom="24dp"
- android:paddingHorizontal="24dp"
+ android:paddingBottom="@dimen/biometric_prompt_top_scroll_view_bottom_padding"
+ android:paddingHorizontal="@dimen/biometric_prompt_top_scroll_view_horizontal_padding"
android:paddingTop="24dp"
app:layout_constrainedHeight="true"
app:layout_constrainedWidth="true"
@@ -76,7 +78,7 @@
style="@style/TextAppearance.AuthCredential.LogoDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingTop="8dp"
+ android:paddingTop="@dimen/biometric_prompt_logo_description_top_padding"
app:layout_constraintBottom_toTopOf="@+id/title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -180,14 +182,14 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
- app:layout_constraintGuide_begin="0dp" />
+ app:layout_constraintGuide_begin="@dimen/biometric_prompt_one_pane_medium_horizontal_guideline_padding" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/rightGuideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
- app:layout_constraintGuide_end="0dp" />
+ app:layout_constraintGuide_end="@dimen/biometric_prompt_one_pane_medium_horizontal_guideline_padding" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/bottomGuideline"
@@ -201,7 +203,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="horizontal"
- app:layout_constraintGuide_begin="119dp" />
+ app:layout_constraintGuide_begin="@dimen/biometric_prompt_one_pane_medium_top_guideline_padding" />
<com.android.systemui.biometrics.BiometricPromptLottieViewWrapper
android:id="@+id/biometric_icon"
diff --git a/packages/SystemUI/res/layout-land/biometric_prompt_constraint_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml
index 01b9f7e2e38a..01b9f7e2e38a 100644
--- a/packages/SystemUI/res/layout-land/biometric_prompt_constraint_layout.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 2cfba01fe1c8..664fbeb29c8e 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -102,6 +102,17 @@
<dimen name="lockscreen_shade_status_bar_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<dimen name="lockscreen_shade_keyguard_transition_distance">@dimen/lockscreen_shade_media_transition_distance</dimen>
+ <!-- Dimensions for biometric prompt panel padding -->
+ <dimen name="biometric_prompt_one_pane_medium_top_guideline_padding">56dp</dimen>
+ <dimen name="biometric_prompt_one_pane_medium_horizontal_guideline_padding">@dimen/biometric_dialog_border_padding</dimen>
+
+ <!-- Dimensions for biometric prompt scroll view padding -->
+ <dimen name="biometric_prompt_top_scroll_view_bottom_padding">32dp</dimen>
+ <dimen name="biometric_prompt_top_scroll_view_horizontal_padding">32dp</dimen>
+
+ <!-- Dimensions for biometric prompt custom content view. -->
+ <dimen name="biometric_prompt_logo_description_top_padding">16dp</dimen>
+
<!-- Biometric Auth pattern view size, better to align keyguard_security_width -->
<dimen name="biometric_auth_pattern_view_size">348dp</dimen>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index edd3d77555f7..380a79e5a289 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1119,11 +1119,18 @@
<dimen name="biometric_dialog_height">240dp</dimen>
<!-- Dimensions for biometric prompt panel padding -->
- <dimen name="biometric_prompt_small_horizontal_guideline_padding">344dp</dimen>
- <dimen name="biometric_prompt_udfps_horizontal_guideline_padding">114dp</dimen>
- <dimen name="biometric_prompt_udfps_mid_guideline_padding">409dp</dimen>
- <dimen name="biometric_prompt_medium_horizontal_guideline_padding">640dp</dimen>
- <dimen name="biometric_prompt_medium_mid_guideline_padding">330dp</dimen>
+ <dimen name="biometric_prompt_panel_max_width">640dp</dimen>
+ <dimen name="biometric_prompt_land_small_horizontal_guideline_padding">344dp</dimen>
+ <dimen name="biometric_prompt_two_pane_udfps_horizontal_guideline_padding">114dp</dimen>
+ <dimen name="biometric_prompt_two_pane_udfps_mid_guideline_padding">409dp</dimen>
+ <dimen name="biometric_prompt_two_pane_medium_horizontal_guideline_padding">640dp</dimen>
+ <dimen name="biometric_prompt_two_pane_medium_mid_guideline_padding">330dp</dimen>
+ <dimen name="biometric_prompt_one_pane_medium_top_guideline_padding">119dp</dimen>
+ <dimen name="biometric_prompt_one_pane_medium_horizontal_guideline_padding">0dp</dimen>
+
+ <!-- Dimensions for biometric prompt scroll view padding -->
+ <dimen name="biometric_prompt_top_scroll_view_bottom_padding">24dp</dimen>
+ <dimen name="biometric_prompt_top_scroll_view_horizontal_padding">24dp</dimen>
<!-- Dimensions for biometric prompt icon padding -->
<dimen name="biometric_prompt_portrait_small_bottom_padding">60dp</dimen>
@@ -1136,6 +1143,7 @@
<!-- Dimensions for biometric prompt custom content view. -->
<dimen name="biometric_prompt_logo_size">32dp</dimen>
+ <dimen name="biometric_prompt_logo_description_top_padding">8dp</dimen>
<dimen name="biometric_prompt_content_corner_radius">28dp</dimen>
<dimen name="biometric_prompt_content_padding_horizontal">24dp</dimen>
<dimen name="biometric_prompt_content_padding_vertical">16dp</dimen>
diff --git a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/PromptKind.kt b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/PromptKind.kt
index b99c51489521..44f2059d4e41 100644
--- a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/PromptKind.kt
+++ b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/PromptKind.kt
@@ -22,15 +22,28 @@ sealed interface PromptKind {
data class Biometric(
/** The available modalities for the authentication on the prompt. */
val activeModalities: BiometricModalities = BiometricModalities(),
- // TODO(b/330908557): Use this value to decide whether to show two pane layout, instead of
- // simply depending on rotations.
- val showTwoPane: Boolean = false,
- ) : PromptKind
+ val paneType: PaneType = PaneType.ONE_PANE_PORTRAIT,
+ ) : PromptKind {
+ enum class PaneType {
+ TWO_PANE_LANDSCAPE,
+ ONE_PANE_PORTRAIT,
+ ONE_PANE_NO_SENSOR_LANDSCAPE,
+ ONE_PANE_LARGE_SCREEN_LANDSCAPE
+ }
+ }
- object Pin : PromptKind
- object Pattern : PromptKind
- object Password : PromptKind
+ data object Pin : PromptKind
+ data object Pattern : PromptKind
+ data object Password : PromptKind
fun isBiometric() = this is Biometric
- fun isCredential() = (this is Pin) or (this is Pattern) or (this is Password)
+ fun isTwoPaneLandscapeBiometric(): Boolean =
+ (this as? Biometric)?.paneType == Biometric.PaneType.TWO_PANE_LANDSCAPE
+ fun isOnePanePortraitBiometric() =
+ (this as? Biometric)?.paneType == Biometric.PaneType.ONE_PANE_PORTRAIT
+ fun isOnePaneNoSensorLandscapeBiometric() =
+ (this as? Biometric)?.paneType == Biometric.PaneType.ONE_PANE_NO_SENSOR_LANDSCAPE
+ fun isOnePaneLargeScreenLandscapeBiometric() =
+ (this as? Biometric)?.paneType == Biometric.PaneType.ONE_PANE_LARGE_SCREEN_LANDSCAPE
+ fun isCredential() = (this is Pin) || (this is Pattern) || (this is Password)
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 3d7accbd961f..1ee4908437a6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -29,6 +29,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AlertDialog;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.PixelFormat;
@@ -360,15 +361,23 @@ public class AuthContainerView extends LinearLayout
Utils.findFirstSensorProperties(fpProps, mConfig.mSensorIds),
Utils.findFirstSensorProperties(faceProps, mConfig.mSensorIds));
+ final boolean isLandscape = mContext.getResources().getConfiguration().orientation
+ == Configuration.ORIENTATION_LANDSCAPE;
mPromptSelectorInteractorProvider = promptSelectorInteractorProvider;
mPromptSelectorInteractorProvider.get().setPrompt(mConfig.mPromptInfo, mEffectiveUserId,
getRequestId(), biometricModalities, mConfig.mOperationId, mConfig.mOpPackageName,
- false /*onSwitchToCredential*/);
+ false /*onSwitchToCredential*/, isLandscape);
final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
- if (constraintBp() && mPromptViewModel.getPromptKind().getValue().isBiometric()) {
- mLayout = (ConstraintLayout) layoutInflater.inflate(
- R.layout.biometric_prompt_constraint_layout, this, false /* attachToRoot */);
+ final PromptKind kind = mPromptViewModel.getPromptKind().getValue();
+ if (constraintBp() && kind.isBiometric()) {
+ if (kind.isTwoPaneLandscapeBiometric()) {
+ mLayout = (ConstraintLayout) layoutInflater.inflate(
+ R.layout.biometric_prompt_two_pane_layout, this, false /* attachToRoot */);
+ } else {
+ mLayout = (ConstraintLayout) layoutInflater.inflate(
+ R.layout.biometric_prompt_one_pane_layout, this, false /* attachToRoot */);
+ }
} else {
mLayout = (FrameLayout) layoutInflater.inflate(
R.layout.auth_container_view, this, false /* attachToRoot */);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt
index 8e5a97bd5d8d..9b14d6f68e35 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt
@@ -29,11 +29,10 @@ import com.android.systemui.display.data.repository.DeviceStateRepository
import com.android.systemui.display.data.repository.DeviceStateRepository.DeviceState.REAR_DISPLAY
import com.android.systemui.display.data.repository.DisplayRepository
import javax.inject.Inject
+import kotlin.math.min
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
@@ -58,7 +57,7 @@ interface DisplayStateRepository {
val currentDisplaySize: StateFlow<Size>
/** Provides whether the current display is large screen */
- val isLargeScreen: Flow<Boolean>
+ val isLargeScreen: StateFlow<Boolean>
}
@SysUISingleton
@@ -127,16 +126,29 @@ constructor(
),
)
- override val isLargeScreen: Flow<Boolean> =
+ override val isLargeScreen: StateFlow<Boolean> =
currentDisplayInfo
.map {
- // TODO: This works, but investigate better way to handle this
- it.logicalWidth * 160 / it.logicalDensityDpi > DisplayMetrics.DENSITY_XXXHIGH &&
- it.logicalHeight * 160 / it.logicalDensityDpi > DisplayMetrics.DENSITY_XXHIGH
+ // copied from systemui/shared/...Utilities.java
+ val smallestWidth =
+ dpiFromPx(
+ min(it.logicalWidth, it.logicalHeight).toFloat(),
+ context.resources.configuration.densityDpi
+ )
+ smallestWidth >= LARGE_SCREEN_MIN_DPS
}
- .distinctUntilChanged()
+ .stateIn(
+ backgroundScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = false,
+ )
+ private fun dpiFromPx(size: Float, densityDpi: Int): Float {
+ val densityRatio = densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT
+ return size / densityRatio
+ }
companion object {
const val TAG = "DisplayStateRepositoryImpl"
+ const val LARGE_SCREEN_MIN_DPS = 600f
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt
index 591da4096956..40313e3158aa 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt
@@ -65,7 +65,8 @@ interface DisplayStateInteractor {
/** Called on configuration changes, used to keep the display state in sync */
fun onConfigurationChanged(newConfig: Configuration)
- val isLargeScreen: Flow<Boolean>
+ /** Provides whether the current display is large screen */
+ val isLargeScreen: StateFlow<Boolean>
}
/** Encapsulates logic for interacting with the display state. */
@@ -127,7 +128,7 @@ constructor(
override val isDefaultDisplayOff = displayRepository.defaultDisplayOff
- override val isLargeScreen: Flow<Boolean> = displayStateRepository.isLargeScreen
+ override val isLargeScreen: StateFlow<Boolean> = displayStateRepository.isLargeScreen
companion object {
private const val TAG = "DisplayStateInteractor"
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
index dc338d07f9e7..c08756f6ae36 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
@@ -91,6 +91,7 @@ interface PromptSelectorInteractor {
challenge: Long,
opPackageName: String,
onSwitchToCredential: Boolean,
+ isLandscape: Boolean,
)
/** Unset the current authentication request. */
@@ -102,6 +103,7 @@ class PromptSelectorInteractorImpl
@Inject
constructor(
fingerprintPropertyRepository: FingerprintPropertyRepository,
+ private val displayStateInteractor: DisplayStateInteractor,
private val promptRepository: PromptRepository,
private val lockPatternUtils: LockPatternUtils,
) : PromptSelectorInteractor {
@@ -166,7 +168,9 @@ constructor(
modalities,
promptRepository.challenge.value!!,
promptRepository.opPackageName.value!!,
- true /*onSwitchToCredential*/
+ onSwitchToCredential = true,
+ // isLandscape value is not important when onSwitchToCredential is true
+ isLandscape = false,
)
}
@@ -178,6 +182,7 @@ constructor(
challenge: Long,
opPackageName: String,
onSwitchToCredential: Boolean,
+ isLandscape: Boolean,
) {
val hasCredentialViewShown = promptKind.value.isCredential()
val showBpForCredential =
@@ -189,11 +194,30 @@ constructor(
!promptInfo.isContentViewMoreOptionsButtonUsed
val showBpWithoutIconForCredential = showBpForCredential && !hasCredentialViewShown
var kind: PromptKind = PromptKind.None
+
if (onSwitchToCredential) {
kind = getCredentialType(lockPatternUtils, effectiveUserId)
} else if (Utils.isBiometricAllowed(promptInfo) || showBpWithoutIconForCredential) {
- // TODO(b/330908557): check to show one pane or two pane
- kind = PromptKind.Biometric(modalities)
+ // TODO(b/330908557): Subscribe to
+ // displayStateInteractor.currentRotation.value.isDefaultOrientation() for checking
+ // `isLandscape` after removing AuthContinerView.
+ kind =
+ if (isLandscape) {
+ val paneType =
+ when {
+ displayStateInteractor.isLargeScreen.value ->
+ PromptKind.Biometric.PaneType.ONE_PANE_LARGE_SCREEN_LANDSCAPE
+ showBpWithoutIconForCredential ->
+ PromptKind.Biometric.PaneType.ONE_PANE_NO_SENSOR_LANDSCAPE
+ else -> PromptKind.Biometric.PaneType.TWO_PANE_LANDSCAPE
+ }
+ PromptKind.Biometric(
+ modalities,
+ paneType = paneType,
+ )
+ } else {
+ PromptKind.Biometric(modalities)
+ }
} else if (isDeviceCredentialAllowed(promptInfo)) {
kind = getCredentialType(lockPatternUtils, effectiveUserId)
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
index 47174c006735..c836f89a8ff4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
@@ -93,6 +93,7 @@ object BiometricViewSizeBinder {
if (constraintBp()) {
val leftGuideline = view.requireViewById<Guideline>(R.id.leftGuideline)
+ val topGuideline = view.requireViewById<Guideline>(R.id.topGuideline)
val rightGuideline = view.requireViewById<Guideline>(R.id.rightGuideline)
val midGuideline = view.findViewById<Guideline>(R.id.midGuideline)
@@ -355,6 +356,18 @@ object BiometricViewSizeBinder {
)
}
+ if (bounds.top >= 0) {
+ mediumConstraintSet.setGuidelineBegin(topGuideline.id, bounds.top)
+ smallConstraintSet.setGuidelineBegin(topGuideline.id, bounds.top)
+ } else if (bounds.top < 0) {
+ mediumConstraintSet.setGuidelineEnd(
+ topGuideline.id,
+ abs(bounds.top)
+ )
+ smallConstraintSet.setGuidelineEnd(topGuideline.id, abs(bounds.top))
+ }
+
+ // Use rect bottom to set mid guideline of two-pane.
if (midGuideline != null) {
if (bounds.bottom >= 0) {
midGuideline.setGuidelineEnd(bounds.bottom)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
index 156ec6b975a5..c17b83dd4fbe 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -261,10 +261,13 @@ constructor(
combine(
_forceLargeSize,
displayStateInteractor.isLargeScreen,
- displayStateInteractor.currentRotation
+ displayStateInteractor.currentRotation,
) { forceLarge, isLargeScreen, rotation ->
when {
- forceLarge || isLargeScreen -> PromptPosition.Bottom
+ forceLarge ||
+ isLargeScreen ||
+ promptKind.value.isOnePaneNoSensorLandscapeBiometric() ->
+ PromptPosition.Bottom
rotation == DisplayRotation.ROTATION_90 -> PromptPosition.Right
rotation == DisplayRotation.ROTATION_270 -> PromptPosition.Left
rotation == DisplayRotation.ROTATION_180 -> PromptPosition.Top
@@ -297,23 +300,27 @@ constructor(
/** Prompt panel size padding */
private val smallHorizontalGuidelinePadding =
context.resources.getDimensionPixelSize(
- R.dimen.biometric_prompt_small_horizontal_guideline_padding
+ R.dimen.biometric_prompt_land_small_horizontal_guideline_padding
)
private val udfpsHorizontalGuidelinePadding =
context.resources.getDimensionPixelSize(
- R.dimen.biometric_prompt_udfps_horizontal_guideline_padding
+ R.dimen.biometric_prompt_two_pane_udfps_horizontal_guideline_padding
)
private val udfpsMidGuidelinePadding =
context.resources.getDimensionPixelSize(
- R.dimen.biometric_prompt_udfps_mid_guideline_padding
+ R.dimen.biometric_prompt_two_pane_udfps_mid_guideline_padding
+ )
+ private val mediumTopGuidelinePadding =
+ context.resources.getDimensionPixelSize(
+ R.dimen.biometric_prompt_one_pane_medium_top_guideline_padding
)
private val mediumHorizontalGuidelinePadding =
context.resources.getDimensionPixelSize(
- R.dimen.biometric_prompt_medium_horizontal_guideline_padding
+ R.dimen.biometric_prompt_two_pane_medium_horizontal_guideline_padding
)
private val mediumMidGuidelinePadding =
context.resources.getDimensionPixelSize(
- R.dimen.biometric_prompt_medium_mid_guideline_padding
+ R.dimen.biometric_prompt_two_pane_medium_mid_guideline_padding
)
/** Rect for positioning biometric icon */
@@ -416,9 +423,9 @@ constructor(
* asset to be loaded before determining the prompt size.
*/
val isIconViewLoaded: Flow<Boolean> =
- combine(modalities, _isIconViewLoaded.asStateFlow()) { modalities, isIconViewLoaded ->
- val noIcon = modalities.isEmpty
- noIcon || isIconViewLoaded
+ combine(hideSensorIcon, _isIconViewLoaded.asStateFlow()) { hideSensorIcon, isIconViewLoaded
+ ->
+ hideSensorIcon || isIconViewLoaded
}
.distinctUntilChanged()
@@ -448,17 +455,24 @@ constructor(
* from opposite side of the screen
*/
val guidelineBounds: Flow<Rect> =
- combine(iconPosition, size, position, modalities) { _, size, position, modalities ->
+ combine(iconPosition, promptKind, size, position, modalities) {
+ _,
+ promptKind,
+ size,
+ position,
+ modalities ->
when (position) {
- PromptPosition.Bottom -> Rect(0, 0, 0, 0)
+ PromptPosition.Bottom ->
+ if (promptKind.isOnePaneNoSensorLandscapeBiometric()) {
+ Rect(0, 0, 0, 0)
+ } else {
+ Rect(0, mediumTopGuidelinePadding, 0, 0)
+ }
PromptPosition.Right ->
if (size.isSmall) {
Rect(-smallHorizontalGuidelinePadding, 0, 0, 0)
} else if (modalities.hasUdfps) {
Rect(udfpsHorizontalGuidelinePadding, 0, 0, udfpsMidGuidelinePadding)
- } else if (modalities.isEmpty) {
- // TODO: Temporary fix until no biometric landscape layout is added
- Rect(-mediumHorizontalGuidelinePadding, 0, 0, 6)
} else {
Rect(-mediumHorizontalGuidelinePadding, 0, 0, mediumMidGuidelinePadding)
}
@@ -467,9 +481,6 @@ constructor(
Rect(0, 0, -smallHorizontalGuidelinePadding, 0)
} else if (modalities.hasUdfps) {
Rect(0, 0, udfpsHorizontalGuidelinePadding, -udfpsMidGuidelinePadding)
- } else if (modalities.isEmpty) {
- // TODO: Temporary fix until no biometric landscape layout is added
- Rect(0, 0, -mediumHorizontalGuidelinePadding, -6)
} else {
Rect(
0,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index 63426a43e552..9a99ed7bb512 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -128,6 +128,12 @@ open class AuthContainerViewTest : SysuiTestCase() {
private lateinit var packageManager: PackageManager
@Mock private lateinit var activityTaskManager: ActivityTaskManager
+ private lateinit var displayRepository: FakeDisplayRepository
+ private lateinit var displayStateInteractor: DisplayStateInteractor
+ private lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor
+ private lateinit var biometricStatusInteractor: BiometricStatusInteractor
+ private lateinit var iconProvider: IconProvider
+
private val testScope = TestScope(StandardTestDispatcher())
private val fakeExecutor = FakeExecutor(FakeSystemClock())
private val biometricPromptRepository = FakePromptRepository()
@@ -143,17 +149,12 @@ open class AuthContainerViewTest : SysuiTestCase() {
private val promptSelectorInteractor by lazy {
PromptSelectorInteractorImpl(
fingerprintRepository,
+ displayStateInteractor,
biometricPromptRepository,
lockPatternUtils,
)
}
- private lateinit var displayRepository: FakeDisplayRepository
- private lateinit var displayStateInteractor: DisplayStateInteractor
- private lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor
- private lateinit var biometricStatusInteractor: BiometricStatusInteractor
- private lateinit var iconProvider: IconProvider
-
private val credentialViewModel = CredentialViewModel(mContext, bpCredentialInteractor)
private val defaultLogoIcon = context.getDrawable(R.drawable.ic_android)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
index 3102a84b852a..6e78e334891b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
@@ -25,13 +25,16 @@ import android.hardware.biometrics.PromptVerticalListContentView
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository
import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
import com.android.systemui.biometrics.data.repository.FakePromptRepository
import com.android.systemui.biometrics.faceSensorPropertiesInternal
import com.android.systemui.biometrics.fingerprintSensorPropertiesInternal
import com.android.systemui.biometrics.shared.model.BiometricModalities
+import com.android.systemui.biometrics.shared.model.DisplayRotation
import com.android.systemui.biometrics.shared.model.PromptKind
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.display.data.repository.FakeDisplayRepository
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.whenever
@@ -75,12 +78,30 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
private val promptRepository = FakePromptRepository()
private val fakeExecutor = FakeExecutor(FakeSystemClock())
+ private lateinit var displayStateRepository: FakeDisplayStateRepository
+ private lateinit var displayRepository: FakeDisplayRepository
+ private lateinit var displayStateInteractor: DisplayStateInteractor
private lateinit var interactor: PromptSelectorInteractor
@Before
fun setup() {
+ displayStateRepository = FakeDisplayStateRepository()
+ displayRepository = FakeDisplayRepository()
+ displayStateInteractor =
+ DisplayStateInteractorImpl(
+ testScope.backgroundScope,
+ mContext,
+ fakeExecutor,
+ displayStateRepository,
+ displayRepository,
+ )
interactor =
- PromptSelectorInteractorImpl(fingerprintRepository, promptRepository, lockPatternUtils)
+ PromptSelectorInteractorImpl(
+ fingerprintRepository,
+ displayStateInteractor,
+ promptRepository,
+ lockPatternUtils
+ )
}
private fun basicPromptInfo() =
@@ -155,7 +176,8 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
modalities,
CHALLENGE,
OP_PACKAGE_NAME,
- false /*onSwitchToCredential*/
+ onSwitchToCredential = false,
+ isLandscape = false,
)
assertThat(currentPrompt).isNotNull()
@@ -200,22 +222,49 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
fun promptKind_isBiometric_whenBiometricAllowed() =
testScope.runTest {
setUserCredentialType(isPassword = true)
- val info = basicPromptInfo()
val promptKind by collectLastValue(interactor.promptKind)
assertThat(promptKind).isEqualTo(PromptKind.None)
- interactor.setPrompt(
- info,
- USER_ID,
- REQUEST_ID,
- modalities,
- CHALLENGE,
- OP_PACKAGE_NAME,
- false /*onSwitchToCredential*/
- )
+ setPrompt()
+
+ assertThat(promptKind?.isOnePanePortraitBiometric()).isTrue()
+
+ interactor.resetPrompt(REQUEST_ID)
+ verifyUnset()
+ }
+
+ @Test
+ fun promptKind_isBiometricTwoPane_whenBiometricAllowed_landscape() =
+ testScope.runTest {
+ setUserCredentialType(isPassword = true)
+ displayStateRepository.setIsLargeScreen(false)
+ displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90)
+
+ val promptKind by collectLastValue(interactor.promptKind)
+ assertThat(promptKind).isEqualTo(PromptKind.None)
+
+ setPrompt()
+
+ assertThat(promptKind?.isTwoPaneLandscapeBiometric()).isTrue()
+
+ interactor.resetPrompt(REQUEST_ID)
+ verifyUnset()
+ }
+
+ @Test
+ fun promptKind_isBiometricOnePane_whenBiometricAllowed_largeScreenLandscape() =
+ testScope.runTest {
+ setUserCredentialType(isPassword = true)
+ displayStateRepository.setIsLargeScreen(true)
+ displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90)
+
+ val promptKind by collectLastValue(interactor.promptKind)
+ assertThat(promptKind).isEqualTo(PromptKind.None)
- assertThat(promptKind?.isBiometric()).isTrue()
+ setPrompt()
+
+ assertThat(promptKind?.isOnePaneLargeScreenLandscapeBiometric()).isTrue()
interactor.resetPrompt(REQUEST_ID)
verifyUnset()
@@ -225,20 +274,11 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
fun promptKind_isCredential_onSwitchToCredential() =
testScope.runTest {
setUserCredentialType(isPassword = true)
- val info = basicPromptInfo()
val promptKind by collectLastValue(interactor.promptKind)
assertThat(promptKind).isEqualTo(PromptKind.None)
- interactor.setPrompt(
- info,
- USER_ID,
- REQUEST_ID,
- modalities,
- CHALLENGE,
- OP_PACKAGE_NAME,
- true /*onSwitchToCredential*/
- )
+ setPrompt(onSwitchToCredential = true)
assertThat(promptKind).isEqualTo(PromptKind.Password)
@@ -259,15 +299,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
val promptKind by collectLastValue(interactor.promptKind)
assertThat(promptKind).isEqualTo(PromptKind.None)
- interactor.setPrompt(
- info,
- USER_ID,
- REQUEST_ID,
- modalities,
- CHALLENGE,
- OP_PACKAGE_NAME,
- false /*onSwitchToCredential*/
- )
+ setPrompt(info)
assertThat(promptKind).isEqualTo(PromptKind.Password)
@@ -292,15 +324,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
val promptKind by collectLastValue(interactor.promptKind)
assertThat(promptKind).isEqualTo(PromptKind.None)
- interactor.setPrompt(
- info,
- USER_ID,
- REQUEST_ID,
- modalities,
- CHALLENGE,
- OP_PACKAGE_NAME,
- false /*onSwitchToCredential*/
- )
+ setPrompt(info)
assertThat(promptKind).isEqualTo(PromptKind.Password)
@@ -312,6 +336,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
fun promptKind_isBiometric_whenBiometricIsNotAllowed_withVerticalList() =
testScope.runTest {
setUserCredentialType(isPassword = true)
+ displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90)
val info =
basicPromptInfo().apply {
isDeviceCredentialAllowed = true
@@ -322,22 +347,32 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
val promptKind by collectLastValue(interactor.promptKind)
assertThat(promptKind).isEqualTo(PromptKind.None)
- interactor.setPrompt(
- info,
- USER_ID,
- REQUEST_ID,
- modalities,
- CHALLENGE,
- OP_PACKAGE_NAME,
- false /*onSwitchToCredential*/
- )
+ setPrompt(info)
- assertThat(promptKind?.isBiometric()).isTrue()
+ assertThat(promptKind?.isOnePaneNoSensorLandscapeBiometric()).isTrue()
interactor.resetPrompt(REQUEST_ID)
verifyUnset()
}
+ private fun setPrompt(
+ info: PromptInfo = basicPromptInfo(),
+ onSwitchToCredential: Boolean = false
+ ) {
+ interactor.setPrompt(
+ info,
+ USER_ID,
+ REQUEST_ID,
+ modalities,
+ CHALLENGE,
+ OP_PACKAGE_NAME,
+ onSwitchToCredential = onSwitchToCredential,
+ isLandscape =
+ displayStateRepository.currentRotation.value == DisplayRotation.ROTATION_90 ||
+ displayStateRepository.currentRotation.value == DisplayRotation.ROTATION_270,
+ )
+ }
+
private fun TestScope.useCredentialAndReset(kind: PromptKind) {
setUserCredentialType(
isPin = kind == PromptKind.Pin,
@@ -366,7 +401,8 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() {
BiometricModalities(),
CHALLENGE,
OP_PACKAGE_NAME,
- false /*onSwitchToCredential*/
+ onSwitchToCredential = false,
+ isLandscape = false,
)
// not using biometrics, should be null with no fallback option
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
index c177511a2df4..1167fce7524b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -1407,7 +1407,12 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
runningTaskInfo.topActivity = topActivity
whenever(activityTaskManager.getTasks(1)).thenReturn(listOf(runningTaskInfo))
selector =
- PromptSelectorInteractorImpl(fingerprintRepository, promptRepository, lockPatternUtils)
+ PromptSelectorInteractorImpl(
+ fingerprintRepository,
+ displayStateInteractor,
+ promptRepository,
+ lockPatternUtils
+ )
selector.resetPrompt(REQUEST_ID)
viewModel =
@@ -1643,7 +1648,8 @@ private fun PromptSelectorInteractor.initializePrompt(
BiometricModalities(fingerprintProperties = fingerprint, faceProperties = face),
CHALLENGE,
packageName,
- false /*onUseDeviceCredential*/
+ onSwitchToCredential = false,
+ isLandscape = false,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt
index 9765d531472c..53285eb715ba 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt
@@ -23,7 +23,6 @@ import com.android.systemui.dagger.SysUISingleton
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
@@ -40,7 +39,7 @@ class FakeDisplayStateRepository @Inject constructor() : DisplayStateRepository
override val currentDisplaySize: StateFlow<Size> = _currentDisplaySize.asStateFlow()
private val _isLargeScreen = MutableStateFlow<Boolean>(false)
- override val isLargeScreen: Flow<Boolean> = _isLargeScreen.asStateFlow()
+ override val isLargeScreen: StateFlow<Boolean> = _isLargeScreen.asStateFlow()
override val isReverseDefaultRotation = false
@@ -55,6 +54,10 @@ class FakeDisplayStateRepository @Inject constructor() : DisplayStateRepository
fun setCurrentDisplaySize(size: Size) {
_currentDisplaySize.value = size
}
+
+ fun setIsLargeScreen(isLargeScreen: Boolean) {
+ _isLargeScreen.value = isLargeScreen
+ }
}
@Module
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorKosmos.kt
index 7f9a71cd149e..56297f0d7f43 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorKosmos.kt
@@ -25,6 +25,7 @@ import com.android.systemui.kosmos.Kosmos.Fixture
val Kosmos.promptSelectorInteractor by Fixture {
PromptSelectorInteractorImpl(
fingerprintPropertyRepository = fingerprintPropertyRepository,
+ displayStateInteractor = displayStateInteractor,
promptRepository = promptRepository,
lockPatternUtils = lockPatternUtils
)