Loading packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml 0 → 100644 +244 −0 Original line number Diff line number Diff line <?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" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/logo" android:layout_width="@dimen/biometric_auth_icon_size" android:layout_height="@dimen/biometric_auth_icon_size" android:layout_gravity="center" android:scaleType="fitXY" android:visibility="gone" /> <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" android:layout_width="0dp" android:layout_height="0dp" android:background="?android:attr/colorBackgroundFloating" android:clickable="true" android:clipToOutline="true" android:importantForAccessibility="no" android:paddingHorizontal="16dp" android:paddingVertical="16dp" android:visibility="visible" app:layout_constraintBottom_toTopOf="@+id/bottomGuideline" app:layout_constraintEnd_toStartOf="@+id/rightGuideline" app:layout_constraintStart_toStartOf="@+id/leftGuideline" app:layout_constraintTop_toTopOf="@+id/title" /> <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="0.8" 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" app:layout_constraintBottom_toBottomOf="@+id/biometric_icon" app:layout_constraintEnd_toEndOf="@+id/biometric_icon" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toStartOf="@+id/biometric_icon" app:layout_constraintTop_toTopOf="@+id/biometric_icon" app:layout_constraintVertical_bias="0.0" /> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="@integer/biometric_dialog_text_gravity" android:singleLine="true" android:marqueeRepeatLimit="1" android:ellipsize="marquee" style="@style/TextAppearance.AuthCredential.Title" app:layout_constraintBottom_toTopOf="@+id/subtitle" app:layout_constraintEnd_toEndOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel" /> <TextView android:id="@+id/subtitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="@integer/biometric_dialog_text_gravity" android:singleLine="true" android:marqueeRepeatLimit="1" android:ellipsize="marquee" style="@style/TextAppearance.AuthCredential.Subtitle" app:layout_constraintBottom_toTopOf="@+id/description" app:layout_constraintEnd_toEndOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel" /> <Space android:id="@+id/space_above_content" android:layout_width="match_parent" android:layout_height="@dimen/biometric_prompt_space_above_content" android:visibility="gone" app:layout_constraintTop_toBottomOf="@+id/subtitle" app:layout_constraintEnd_toEndOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel"/> <ScrollView android:id="@+id/customized_view_container" android:layout_width="0dp" android:layout_height="0dp" android:fillViewport="true" android:fadeScrollbars="false" android:gravity="center_vertical" android:orientation="vertical" android:paddingHorizontal="@dimen/biometric_prompt_content_container_padding_horizontal" android:scrollbars="vertical" android:visibility="gone" app:layout_constraintTop_toBottomOf="@+id/space_above_content" app:layout_constraintBottom_toTopOf="@+id/biometric_icon" app:layout_constraintEnd_toEndOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel"/> <TextView android:id="@+id/description" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="24dp" android:scrollbars="vertical" android:gravity="@integer/biometric_dialog_text_gravity" style="@style/TextAppearance.AuthCredential.Description" app:layout_constraintBottom_toTopOf="@+id/biometric_icon" app:layout_constraintEnd_toEndOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel" /> <TextView android:id="@+id/indicator" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:gravity="center_horizontal" android:textColor="@color/biometric_dialog_gray" android:textSize="12sp" android:accessibilityLiveRegion="polite" android:marqueeRepeatLimit="marquee_forever" android:scrollHorizontally="true" android:fadingEdge="horizontal" app:layout_constraintEnd_toEndOf="@+id/panel" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="@+id/panel" app:layout_constraintTop_toBottomOf="@+id/biometric_icon" /> <!-- Negative Button, reserved for app --> <Button android:id="@+id/button_negative" style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginBottom="8dp" android:layout_marginLeft="8dp" android:ellipsize="end" android:maxLines="2" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel" /> <!-- Cancel Button, replaces negative button when biometric is accepted --> <Button android:id="@+id/button_cancel" style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginBottom="8dp" android:layout_marginLeft="8dp" android:text="@string/cancel" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel" /> <!-- "Use Credential" Button, replaces if device credential is allowed --> <Button android:id="@+id/button_use_credential" style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginBottom="8dp" android:layout_marginLeft="8dp" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel" /> <!-- Positive Button --> <Button android:id="@+id/button_confirm" style="@*android:style/Widget.DeviceDefault.Button.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginBottom="8dp" android:layout_marginRight="8dp" android:ellipsize="end" android:maxLines="2" android:text="@string/biometric_dialog_confirm" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="@+id/panel" app:layout_constraintEnd_toEndOf="@+id/panel" tools:visibility="invisible" /> <!-- Try Again Button --> <Button android:id="@+id/button_try_again" style="@*android:style/Widget.DeviceDefault.Button.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginBottom="8dp" android:layout_marginRight="8dp" android:ellipsize="end" android:maxLines="2" android:text="@string/biometric_dialog_try_again" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="@+id/panel" app:layout_constraintEnd_toEndOf="@+id/panel" /> <!-- 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="@dimen/biometric_dialog_border_padding" /> </androidx.constraintlayout.widget.ConstraintLayout> packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +48 −25 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static com.android.internal.jank.InteractionJankMonitor.CUJ_BIOMETRIC_PROMPT_TRANSITION; import static com.android.systemui.Flags.constraintBp; import android.animation.Animator; import android.annotation.IntDef; Loading Loading @@ -57,6 +58,7 @@ import android.widget.ScrollView; import android.window.OnBackInvokedCallback; import android.window.OnBackInvokedDispatcher; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.view.AccessibilityDelegateCompat; import androidx.core.view.ViewCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; Loading Loading @@ -153,7 +155,7 @@ public class AuthContainerView extends LinearLayout @Nullable private Spaghetti mBiometricView; @Nullable private View mCredentialView; private final AuthPanelController mPanelController; private final FrameLayout mFrameLayout; private final ViewGroup mLayout; private final ImageView mBackgroundView; private final ScrollView mBiometricScrollView; private final View mPanelView; Loading Loading @@ -339,11 +341,16 @@ public class AuthContainerView extends LinearLayout mBiometricCallback = new BiometricCallback(); final LayoutInflater layoutInflater = LayoutInflater.from(mContext); mFrameLayout = (FrameLayout) layoutInflater.inflate( if (constraintBp()) { mLayout = (ConstraintLayout) layoutInflater.inflate( R.layout.biometric_prompt_constraint_layout, this, false /* attachToRoot */); } else { mLayout = (FrameLayout) layoutInflater.inflate( R.layout.auth_container_view, this, false /* attachToRoot */); addView(mFrameLayout); mBiometricScrollView = mFrameLayout.findViewById(R.id.biometric_scrollview); mBackgroundView = mFrameLayout.findViewById(R.id.background); } mBiometricScrollView = mLayout.findViewById(R.id.biometric_scrollview); addView(mLayout); mBackgroundView = mLayout.findViewById(R.id.background); ViewCompat.setAccessibilityDelegate(mBackgroundView, new AccessibilityDelegateCompat() { @Override public void onInitializeAccessibilityNodeInfo(View host, Loading @@ -358,7 +365,7 @@ public class AuthContainerView extends LinearLayout } }); mPanelView = mFrameLayout.findViewById(R.id.panel); mPanelView = mLayout.findViewById(R.id.panel); mPanelController = new AuthPanelController(mContext, mPanelView); mBackgroundExecutor = bgExecutor; mInteractionJankMonitor = jankMonitor; Loading Loading @@ -402,6 +409,14 @@ public class AuthContainerView extends LinearLayout new BiometricModalities(fpProps, faceProps), config.mOpPackageName); if (constraintBp()) { mBiometricView = BiometricViewBinder.bind(mLayout, viewModel, null, // TODO(b/201510778): This uses the wrong timeout in some cases getJankListener(mLayout, TRANSIT, BiometricViewSizeBinder.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS), mBackgroundView, mBiometricCallback, mApplicationCoroutineScope, vibratorHelper); } else { final BiometricPromptLayout view = (BiometricPromptLayout) layoutInflater.inflate( R.layout.biometric_prompt_layout, null, false); mBiometricView = BiometricViewBinder.bind(view, viewModel, mPanelController, Loading @@ -416,6 +431,9 @@ public class AuthContainerView extends LinearLayout view.setUdfpsAdapter(new UdfpsDialogMeasureAdapter(view, fpProps), config.mScaleProvider); } } } else if (constraintBp() && Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo)) { addCredentialView(true, false); } else { mPromptSelectorInteractorProvider.get().resetPrompt(); } Loading Loading @@ -477,7 +495,7 @@ public class AuthContainerView extends LinearLayout vm.setAnimateContents(animateContents); ((CredentialView) mCredentialView).init(vm, this, mPanelController, animatePanel); mFrameLayout.addView(mCredentialView); mLayout.addView(mCredentialView); } @Override Loading @@ -488,8 +506,10 @@ public class AuthContainerView extends LinearLayout @Override public void onOrientationChanged() { if (!constraintBp()) { maybeUpdatePositionForUdfps(true /* invalidate */); } } @Override public void onAttachedToWindow() { Loading @@ -502,8 +522,9 @@ public class AuthContainerView extends LinearLayout mWakefulnessLifecycle.addObserver(this); mPanelInteractionDetector.enable( () -> animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED)); if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) { if (constraintBp()) { // Do nothing on attachment with constraintLayout } else if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) { mBiometricScrollView.addView(mBiometricView.asView()); } else if (Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo)) { addCredentialView(true /* animatePanel */, false /* animateContents */); Loading @@ -512,7 +533,9 @@ public class AuthContainerView extends LinearLayout + mConfig.mPromptInfo.getAuthenticators()); } if (!constraintBp()) { maybeUpdatePositionForUdfps(false /* invalidate */); } if (mConfig.mSkipIntro) { mContainerState = STATE_SHOWING; Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +12 −4 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.airbnb.lottie.LottieAnimationView import com.airbnb.lottie.LottieCompositionFactory import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.AuthPanelController import com.android.systemui.biometrics.shared.model.BiometricModalities import com.android.systemui.biometrics.shared.model.BiometricModality Loading Loading @@ -70,9 +71,9 @@ object BiometricViewBinder { @SuppressLint("ClickableViewAccessibility") @JvmStatic fun bind( view: BiometricPromptLayout, view: View, viewModel: PromptViewModel, panelViewController: AuthPanelController, panelViewController: AuthPanelController?, jankListener: BiometricJankListener, backgroundView: View, legacyCallback: Spaghetti.Callback, Loading Loading @@ -112,11 +113,18 @@ object BiometricViewBinder { val iconOverlayView = view.requireViewById<LottieAnimationView>(R.id.biometric_icon_overlay) val iconView = view.requireViewById<LottieAnimationView>(R.id.biometric_icon) val iconSizeOverride = if (constraintBp()) { viewModel.fingerprintAffordanceSize } else { (view as BiometricPromptLayout).updatedFingerprintAffordanceSize } PromptIconViewBinder.bind( iconView, iconOverlayView, view.getUpdatedFingerprintAffordanceSize(), viewModel iconSizeOverride, viewModel, ) val indicatorMessageView = view.requireViewById<TextView>(R.id.indicator) Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt +358 −134 File changed.Preview size limit exceeded, changes collapsed. Show changes packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt +22 −0 Original line number Diff line number Diff line Loading @@ -17,13 +17,17 @@ package com.android.systemui.biometrics.ui.binder import android.graphics.Rect import android.graphics.drawable.Animatable2 import android.graphics.drawable.AnimatedVectorDrawable import android.graphics.drawable.Drawable import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.airbnb.lottie.LottieAnimationView import com.android.settingslib.widget.LottieColorUtils import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel.AuthType import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel Loading Loading @@ -118,6 +122,24 @@ object PromptIconViewBinder { } } launch { viewModel.iconPosition.collect { position -> if (constraintBp() && position != Rect()) { val iconParams = iconView.layoutParams as ConstraintLayout.LayoutParams if (position.left != -1) { iconParams.endToEnd = ConstraintSet.UNSET iconParams.leftMargin = position.left } if (position.top != -1) { iconParams.bottomToBottom = ConstraintSet.UNSET iconParams.topMargin = position.top } iconView.layoutParams = iconParams } } } launch { viewModel.iconAsset .sample( Loading Loading
packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml 0 → 100644 +244 −0 Original line number Diff line number Diff line <?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" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/logo" android:layout_width="@dimen/biometric_auth_icon_size" android:layout_height="@dimen/biometric_auth_icon_size" android:layout_gravity="center" android:scaleType="fitXY" android:visibility="gone" /> <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" android:layout_width="0dp" android:layout_height="0dp" android:background="?android:attr/colorBackgroundFloating" android:clickable="true" android:clipToOutline="true" android:importantForAccessibility="no" android:paddingHorizontal="16dp" android:paddingVertical="16dp" android:visibility="visible" app:layout_constraintBottom_toTopOf="@+id/bottomGuideline" app:layout_constraintEnd_toStartOf="@+id/rightGuideline" app:layout_constraintStart_toStartOf="@+id/leftGuideline" app:layout_constraintTop_toTopOf="@+id/title" /> <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="0.8" 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" app:layout_constraintBottom_toBottomOf="@+id/biometric_icon" app:layout_constraintEnd_toEndOf="@+id/biometric_icon" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toStartOf="@+id/biometric_icon" app:layout_constraintTop_toTopOf="@+id/biometric_icon" app:layout_constraintVertical_bias="0.0" /> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="@integer/biometric_dialog_text_gravity" android:singleLine="true" android:marqueeRepeatLimit="1" android:ellipsize="marquee" style="@style/TextAppearance.AuthCredential.Title" app:layout_constraintBottom_toTopOf="@+id/subtitle" app:layout_constraintEnd_toEndOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel" /> <TextView android:id="@+id/subtitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="@integer/biometric_dialog_text_gravity" android:singleLine="true" android:marqueeRepeatLimit="1" android:ellipsize="marquee" style="@style/TextAppearance.AuthCredential.Subtitle" app:layout_constraintBottom_toTopOf="@+id/description" app:layout_constraintEnd_toEndOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel" /> <Space android:id="@+id/space_above_content" android:layout_width="match_parent" android:layout_height="@dimen/biometric_prompt_space_above_content" android:visibility="gone" app:layout_constraintTop_toBottomOf="@+id/subtitle" app:layout_constraintEnd_toEndOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel"/> <ScrollView android:id="@+id/customized_view_container" android:layout_width="0dp" android:layout_height="0dp" android:fillViewport="true" android:fadeScrollbars="false" android:gravity="center_vertical" android:orientation="vertical" android:paddingHorizontal="@dimen/biometric_prompt_content_container_padding_horizontal" android:scrollbars="vertical" android:visibility="gone" app:layout_constraintTop_toBottomOf="@+id/space_above_content" app:layout_constraintBottom_toTopOf="@+id/biometric_icon" app:layout_constraintEnd_toEndOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel"/> <TextView android:id="@+id/description" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="24dp" android:scrollbars="vertical" android:gravity="@integer/biometric_dialog_text_gravity" style="@style/TextAppearance.AuthCredential.Description" app:layout_constraintBottom_toTopOf="@+id/biometric_icon" app:layout_constraintEnd_toEndOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel" /> <TextView android:id="@+id/indicator" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:gravity="center_horizontal" android:textColor="@color/biometric_dialog_gray" android:textSize="12sp" android:accessibilityLiveRegion="polite" android:marqueeRepeatLimit="marquee_forever" android:scrollHorizontally="true" android:fadingEdge="horizontal" app:layout_constraintEnd_toEndOf="@+id/panel" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="@+id/panel" app:layout_constraintTop_toBottomOf="@+id/biometric_icon" /> <!-- Negative Button, reserved for app --> <Button android:id="@+id/button_negative" style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginBottom="8dp" android:layout_marginLeft="8dp" android:ellipsize="end" android:maxLines="2" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel" /> <!-- Cancel Button, replaces negative button when biometric is accepted --> <Button android:id="@+id/button_cancel" style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginBottom="8dp" android:layout_marginLeft="8dp" android:text="@string/cancel" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel" /> <!-- "Use Credential" Button, replaces if device credential is allowed --> <Button android:id="@+id/button_use_credential" style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginBottom="8dp" android:layout_marginLeft="8dp" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="@+id/panel" app:layout_constraintStart_toStartOf="@+id/panel" /> <!-- Positive Button --> <Button android:id="@+id/button_confirm" style="@*android:style/Widget.DeviceDefault.Button.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginBottom="8dp" android:layout_marginRight="8dp" android:ellipsize="end" android:maxLines="2" android:text="@string/biometric_dialog_confirm" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="@+id/panel" app:layout_constraintEnd_toEndOf="@+id/panel" tools:visibility="invisible" /> <!-- Try Again Button --> <Button android:id="@+id/button_try_again" style="@*android:style/Widget.DeviceDefault.Button.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginBottom="8dp" android:layout_marginRight="8dp" android:ellipsize="end" android:maxLines="2" android:text="@string/biometric_dialog_try_again" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="@+id/panel" app:layout_constraintEnd_toEndOf="@+id/panel" /> <!-- 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="@dimen/biometric_dialog_border_padding" /> </androidx.constraintlayout.widget.ConstraintLayout>
packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +48 −25 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static com.android.internal.jank.InteractionJankMonitor.CUJ_BIOMETRIC_PROMPT_TRANSITION; import static com.android.systemui.Flags.constraintBp; import android.animation.Animator; import android.annotation.IntDef; Loading Loading @@ -57,6 +58,7 @@ import android.widget.ScrollView; import android.window.OnBackInvokedCallback; import android.window.OnBackInvokedDispatcher; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.view.AccessibilityDelegateCompat; import androidx.core.view.ViewCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; Loading Loading @@ -153,7 +155,7 @@ public class AuthContainerView extends LinearLayout @Nullable private Spaghetti mBiometricView; @Nullable private View mCredentialView; private final AuthPanelController mPanelController; private final FrameLayout mFrameLayout; private final ViewGroup mLayout; private final ImageView mBackgroundView; private final ScrollView mBiometricScrollView; private final View mPanelView; Loading Loading @@ -339,11 +341,16 @@ public class AuthContainerView extends LinearLayout mBiometricCallback = new BiometricCallback(); final LayoutInflater layoutInflater = LayoutInflater.from(mContext); mFrameLayout = (FrameLayout) layoutInflater.inflate( if (constraintBp()) { mLayout = (ConstraintLayout) layoutInflater.inflate( R.layout.biometric_prompt_constraint_layout, this, false /* attachToRoot */); } else { mLayout = (FrameLayout) layoutInflater.inflate( R.layout.auth_container_view, this, false /* attachToRoot */); addView(mFrameLayout); mBiometricScrollView = mFrameLayout.findViewById(R.id.biometric_scrollview); mBackgroundView = mFrameLayout.findViewById(R.id.background); } mBiometricScrollView = mLayout.findViewById(R.id.biometric_scrollview); addView(mLayout); mBackgroundView = mLayout.findViewById(R.id.background); ViewCompat.setAccessibilityDelegate(mBackgroundView, new AccessibilityDelegateCompat() { @Override public void onInitializeAccessibilityNodeInfo(View host, Loading @@ -358,7 +365,7 @@ public class AuthContainerView extends LinearLayout } }); mPanelView = mFrameLayout.findViewById(R.id.panel); mPanelView = mLayout.findViewById(R.id.panel); mPanelController = new AuthPanelController(mContext, mPanelView); mBackgroundExecutor = bgExecutor; mInteractionJankMonitor = jankMonitor; Loading Loading @@ -402,6 +409,14 @@ public class AuthContainerView extends LinearLayout new BiometricModalities(fpProps, faceProps), config.mOpPackageName); if (constraintBp()) { mBiometricView = BiometricViewBinder.bind(mLayout, viewModel, null, // TODO(b/201510778): This uses the wrong timeout in some cases getJankListener(mLayout, TRANSIT, BiometricViewSizeBinder.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS), mBackgroundView, mBiometricCallback, mApplicationCoroutineScope, vibratorHelper); } else { final BiometricPromptLayout view = (BiometricPromptLayout) layoutInflater.inflate( R.layout.biometric_prompt_layout, null, false); mBiometricView = BiometricViewBinder.bind(view, viewModel, mPanelController, Loading @@ -416,6 +431,9 @@ public class AuthContainerView extends LinearLayout view.setUdfpsAdapter(new UdfpsDialogMeasureAdapter(view, fpProps), config.mScaleProvider); } } } else if (constraintBp() && Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo)) { addCredentialView(true, false); } else { mPromptSelectorInteractorProvider.get().resetPrompt(); } Loading Loading @@ -477,7 +495,7 @@ public class AuthContainerView extends LinearLayout vm.setAnimateContents(animateContents); ((CredentialView) mCredentialView).init(vm, this, mPanelController, animatePanel); mFrameLayout.addView(mCredentialView); mLayout.addView(mCredentialView); } @Override Loading @@ -488,8 +506,10 @@ public class AuthContainerView extends LinearLayout @Override public void onOrientationChanged() { if (!constraintBp()) { maybeUpdatePositionForUdfps(true /* invalidate */); } } @Override public void onAttachedToWindow() { Loading @@ -502,8 +522,9 @@ public class AuthContainerView extends LinearLayout mWakefulnessLifecycle.addObserver(this); mPanelInteractionDetector.enable( () -> animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED)); if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) { if (constraintBp()) { // Do nothing on attachment with constraintLayout } else if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) { mBiometricScrollView.addView(mBiometricView.asView()); } else if (Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo)) { addCredentialView(true /* animatePanel */, false /* animateContents */); Loading @@ -512,7 +533,9 @@ public class AuthContainerView extends LinearLayout + mConfig.mPromptInfo.getAuthenticators()); } if (!constraintBp()) { maybeUpdatePositionForUdfps(false /* invalidate */); } if (mConfig.mSkipIntro) { mContainerState = STATE_SHOWING; Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +12 −4 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.airbnb.lottie.LottieAnimationView import com.airbnb.lottie.LottieCompositionFactory import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.AuthPanelController import com.android.systemui.biometrics.shared.model.BiometricModalities import com.android.systemui.biometrics.shared.model.BiometricModality Loading Loading @@ -70,9 +71,9 @@ object BiometricViewBinder { @SuppressLint("ClickableViewAccessibility") @JvmStatic fun bind( view: BiometricPromptLayout, view: View, viewModel: PromptViewModel, panelViewController: AuthPanelController, panelViewController: AuthPanelController?, jankListener: BiometricJankListener, backgroundView: View, legacyCallback: Spaghetti.Callback, Loading Loading @@ -112,11 +113,18 @@ object BiometricViewBinder { val iconOverlayView = view.requireViewById<LottieAnimationView>(R.id.biometric_icon_overlay) val iconView = view.requireViewById<LottieAnimationView>(R.id.biometric_icon) val iconSizeOverride = if (constraintBp()) { viewModel.fingerprintAffordanceSize } else { (view as BiometricPromptLayout).updatedFingerprintAffordanceSize } PromptIconViewBinder.bind( iconView, iconOverlayView, view.getUpdatedFingerprintAffordanceSize(), viewModel iconSizeOverride, viewModel, ) val indicatorMessageView = view.requireViewById<TextView>(R.id.indicator) Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt +358 −134 File changed.Preview size limit exceeded, changes collapsed. Show changes
packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt +22 −0 Original line number Diff line number Diff line Loading @@ -17,13 +17,17 @@ package com.android.systemui.biometrics.ui.binder import android.graphics.Rect import android.graphics.drawable.Animatable2 import android.graphics.drawable.AnimatedVectorDrawable import android.graphics.drawable.Drawable import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.airbnb.lottie.LottieAnimationView import com.android.settingslib.widget.LottieColorUtils import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel.AuthType import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel Loading Loading @@ -118,6 +122,24 @@ object PromptIconViewBinder { } } launch { viewModel.iconPosition.collect { position -> if (constraintBp() && position != Rect()) { val iconParams = iconView.layoutParams as ConstraintLayout.LayoutParams if (position.left != -1) { iconParams.endToEnd = ConstraintSet.UNSET iconParams.leftMargin = position.left } if (position.top != -1) { iconParams.bottomToBottom = ConstraintSet.UNSET iconParams.topMargin = position.top } iconView.layoutParams = iconParams } } } launch { viewModel.iconAsset .sample( Loading