diff options
| author | 2024-05-30 05:57:37 +0000 | |
|---|---|---|
| committer | 2024-05-30 05:57:37 +0000 | |
| commit | 61ed776f5f47368d562eefd41bd89accbcc435ce (patch) | |
| tree | c8fc539c381e2085c24c406648878cbe1a1be612 | |
| parent | dc390212974148108fbfd7224de41b77e9ad3c88 (diff) | |
| parent | c44a5e788428e975ab35b664929e7ab989b8ccc1 (diff) | |
Merge "Use one-pane and two-pane layout instead of depending on orientation." into main
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 ) |