Loading core/java/android/hardware/biometrics/BiometricPrompt.java +8 −7 Original line number Diff line number Diff line Loading @@ -240,18 +240,19 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan * * @param logoDescription The logo description text that will be shown on the prompt. * @return This builder. * @throws IllegalArgumentException If logo description is null or exceeds certain character * limit. * @throws IllegalArgumentException If logo description is null. */ @FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT) @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED) @NonNull public BiometricPrompt.Builder setLogoDescription(@NonNull String logoDescription) { if (logoDescription == null || logoDescription.length() > MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER) { throw new IllegalArgumentException( "Logo description passed in can not be null or exceed " + MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER + " character number."); if (logoDescription == null || logoDescription.isEmpty()) { throw new IllegalArgumentException("Logo description passed in can not be null"); } if (logoDescription.length() > MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER) { Log.w(TAG, "Logo description passed in exceeds" + MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER + " character number and may be truncated."); } mPromptInfo.setLogoDescription(logoDescription); return this; Loading core/tests/coretests/src/android/hardware/biometrics/BiometricPromptTest.java +1 −14 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package android.hardware.biometrics; import static android.hardware.biometrics.BiometricPrompt.MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER; import static android.hardware.biometrics.PromptContentViewWithMoreOptionsButton.MAX_DESCRIPTION_CHARACTER_NUMBER; import static android.hardware.biometrics.PromptVerticalListContentView.MAX_EACH_ITEM_CHARACTER_NUMBER; import static android.hardware.biometrics.PromptVerticalListContentView.MAX_ITEM_NUMBER; Loading Loading @@ -116,19 +115,7 @@ public class BiometricPromptTest { () -> new BiometricPrompt.Builder(mContext).setLogoDescription(null) ); assertThat(e).hasMessageThat().contains( "Logo description passed in can not be null or exceed"); } @Test public void testLogoDescription_charLimit() { IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> new BiometricPrompt.Builder(mContext).setLogoDescription( generateRandomString(MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER + 1)) ); assertThat(e).hasMessageThat().contains( "Logo description passed in can not be null or exceed"); assertThat(e).hasMessageThat().isEqualTo("Logo description passed in can not be null"); } @Test Loading packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml +16 −6 Original line number Diff line number Diff line Loading @@ -87,20 +87,21 @@ android:layout_height="match_parent"> android:id="@+id/logo_description" style="@style/TextAppearance.AuthCredential.LogoDescription" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_height="@dimen/biometric_prompt_logo_size" android:gravity="start|center_vertical" android:textAlignment="viewStart" android:paddingStart="16dp" app:layout_constraintBottom_toBottomOf="@+id/logo" android:layout_marginStart="16dp" app:layout_goneMarginStart="0dp" app:layout_constraintBottom_toTopOf="@+id/title" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/logo" app:layout_constraintTop_toTopOf="@+id/logo" /> app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/title" style="@style/TextAppearance.AuthCredential.Title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="12dp" android:gravity="@integer/biometric_dialog_text_gravity" android:paddingHorizontal="0dp" android:textAlignment="viewStart" Loading @@ -108,7 +109,7 @@ android:layout_height="match_parent"> app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/logo" app:layout_constraintTop_toBottomOf="@+id/logoBarrier" app:layout_constraintVertical_bias="0.0" app:layout_constraintVertical_chainStyle="packed" /> Loading Loading @@ -158,6 +159,15 @@ android:layout_height="match_parent"> app:layout_constraintTop_toBottomOf="@+id/subtitle" app:layout_constraintVertical_bias="0.0" /> <androidx.constraintlayout.widget.Barrier android:id="@+id/logoBarrier" android:layout_width="wrap_content" android:layout_height="wrap_content" app:barrierMargin="12dp" app:barrierAllowsGoneWidgets="false" app:barrierDirection="bottom" app:constraint_referenced_ids="logo_description, logo" /> <androidx.constraintlayout.widget.Barrier android:id="@+id/contentBarrier" android:layout_width="wrap_content" Loading packages/SystemUI/res/values/styles.xml +2 −3 Original line number Diff line number Diff line Loading @@ -192,11 +192,10 @@ <style name="TextAppearance.AuthCredential.LogoDescription" parent="TextAppearance.Material3.LabelLarge" > <item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item> <item name="android:ellipsize">marquee</item> <item name="android:gravity">@integer/biometric_dialog_text_gravity</item> <item name="android:marqueeRepeatLimit">1</item> <item name="android:singleLine">true</item> <item name="android:maxLines">1</item> <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item> <item name="android:ellipsize">end</item> </style> <style name="TextAppearance.AuthCredential.Title" parent="TextAppearance.Material3.HeadlineSmall" > Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +8 −1 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch private const val TAG = "BiometricViewBinder" private const val MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER = 30 /** Top-most view binder for BiometricPrompt views. */ object BiometricViewBinder { Loading Loading @@ -167,7 +168,10 @@ object BiometricViewBinder { } logoView.setImageDrawable(viewModel.logo.first()) logoDescriptionView.text = viewModel.logoDescription.first() // The ellipsize effect on xml happens only when the TextView does not have any free // space on the screen to show the text. So we need to manually truncate. logoDescriptionView.text = viewModel.logoDescription.first().ellipsize(MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER) titleView.text = viewModel.title.first() subtitleView.text = viewModel.subtitle.first() descriptionView.text = viewModel.description.first() Loading Loading @@ -684,6 +688,9 @@ private fun BiometricModalities.asDefaultHelpMessage(context: Context): String = else -> "" } private fun String.ellipsize(cutOffLength: Int) = if (length <= cutOffLength) this else replaceRange(cutOffLength, length, "...") private fun Boolean.asVisibleOrGone(): Int = if (this) View.VISIBLE else View.GONE private fun Boolean.asVisibleOrHidden(): Int = if (this) View.VISIBLE else View.INVISIBLE Loading Loading
core/java/android/hardware/biometrics/BiometricPrompt.java +8 −7 Original line number Diff line number Diff line Loading @@ -240,18 +240,19 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan * * @param logoDescription The logo description text that will be shown on the prompt. * @return This builder. * @throws IllegalArgumentException If logo description is null or exceeds certain character * limit. * @throws IllegalArgumentException If logo description is null. */ @FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT) @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED) @NonNull public BiometricPrompt.Builder setLogoDescription(@NonNull String logoDescription) { if (logoDescription == null || logoDescription.length() > MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER) { throw new IllegalArgumentException( "Logo description passed in can not be null or exceed " + MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER + " character number."); if (logoDescription == null || logoDescription.isEmpty()) { throw new IllegalArgumentException("Logo description passed in can not be null"); } if (logoDescription.length() > MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER) { Log.w(TAG, "Logo description passed in exceeds" + MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER + " character number and may be truncated."); } mPromptInfo.setLogoDescription(logoDescription); return this; Loading
core/tests/coretests/src/android/hardware/biometrics/BiometricPromptTest.java +1 −14 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package android.hardware.biometrics; import static android.hardware.biometrics.BiometricPrompt.MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER; import static android.hardware.biometrics.PromptContentViewWithMoreOptionsButton.MAX_DESCRIPTION_CHARACTER_NUMBER; import static android.hardware.biometrics.PromptVerticalListContentView.MAX_EACH_ITEM_CHARACTER_NUMBER; import static android.hardware.biometrics.PromptVerticalListContentView.MAX_ITEM_NUMBER; Loading Loading @@ -116,19 +115,7 @@ public class BiometricPromptTest { () -> new BiometricPrompt.Builder(mContext).setLogoDescription(null) ); assertThat(e).hasMessageThat().contains( "Logo description passed in can not be null or exceed"); } @Test public void testLogoDescription_charLimit() { IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> new BiometricPrompt.Builder(mContext).setLogoDescription( generateRandomString(MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER + 1)) ); assertThat(e).hasMessageThat().contains( "Logo description passed in can not be null or exceed"); assertThat(e).hasMessageThat().isEqualTo("Logo description passed in can not be null"); } @Test Loading
packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml +16 −6 Original line number Diff line number Diff line Loading @@ -87,20 +87,21 @@ android:layout_height="match_parent"> android:id="@+id/logo_description" style="@style/TextAppearance.AuthCredential.LogoDescription" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_height="@dimen/biometric_prompt_logo_size" android:gravity="start|center_vertical" android:textAlignment="viewStart" android:paddingStart="16dp" app:layout_constraintBottom_toBottomOf="@+id/logo" android:layout_marginStart="16dp" app:layout_goneMarginStart="0dp" app:layout_constraintBottom_toTopOf="@+id/title" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/logo" app:layout_constraintTop_toTopOf="@+id/logo" /> app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/title" style="@style/TextAppearance.AuthCredential.Title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="12dp" android:gravity="@integer/biometric_dialog_text_gravity" android:paddingHorizontal="0dp" android:textAlignment="viewStart" Loading @@ -108,7 +109,7 @@ android:layout_height="match_parent"> app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/logo" app:layout_constraintTop_toBottomOf="@+id/logoBarrier" app:layout_constraintVertical_bias="0.0" app:layout_constraintVertical_chainStyle="packed" /> Loading Loading @@ -158,6 +159,15 @@ android:layout_height="match_parent"> app:layout_constraintTop_toBottomOf="@+id/subtitle" app:layout_constraintVertical_bias="0.0" /> <androidx.constraintlayout.widget.Barrier android:id="@+id/logoBarrier" android:layout_width="wrap_content" android:layout_height="wrap_content" app:barrierMargin="12dp" app:barrierAllowsGoneWidgets="false" app:barrierDirection="bottom" app:constraint_referenced_ids="logo_description, logo" /> <androidx.constraintlayout.widget.Barrier android:id="@+id/contentBarrier" android:layout_width="wrap_content" Loading
packages/SystemUI/res/values/styles.xml +2 −3 Original line number Diff line number Diff line Loading @@ -192,11 +192,10 @@ <style name="TextAppearance.AuthCredential.LogoDescription" parent="TextAppearance.Material3.LabelLarge" > <item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item> <item name="android:ellipsize">marquee</item> <item name="android:gravity">@integer/biometric_dialog_text_gravity</item> <item name="android:marqueeRepeatLimit">1</item> <item name="android:singleLine">true</item> <item name="android:maxLines">1</item> <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item> <item name="android:ellipsize">end</item> </style> <style name="TextAppearance.AuthCredential.Title" parent="TextAppearance.Material3.HeadlineSmall" > Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +8 −1 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch private const val TAG = "BiometricViewBinder" private const val MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER = 30 /** Top-most view binder for BiometricPrompt views. */ object BiometricViewBinder { Loading Loading @@ -167,7 +168,10 @@ object BiometricViewBinder { } logoView.setImageDrawable(viewModel.logo.first()) logoDescriptionView.text = viewModel.logoDescription.first() // The ellipsize effect on xml happens only when the TextView does not have any free // space on the screen to show the text. So we need to manually truncate. logoDescriptionView.text = viewModel.logoDescription.first().ellipsize(MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER) titleView.text = viewModel.title.first() subtitleView.text = viewModel.subtitle.first() descriptionView.text = viewModel.description.first() Loading Loading @@ -684,6 +688,9 @@ private fun BiometricModalities.asDefaultHelpMessage(context: Context): String = else -> "" } private fun String.ellipsize(cutOffLength: Int) = if (length <= cutOffLength) this else replaceRange(cutOffLength, length, "...") private fun Boolean.asVisibleOrGone(): Int = if (this) View.VISIBLE else View.GONE private fun Boolean.asVisibleOrHidden(): Int = if (this) View.VISIBLE else View.INVISIBLE Loading