Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6b0ef22 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Merge cherrypicks of ['googleplex-android-review.googlesource.com/28470885',...

Merge cherrypicks of ['googleplex-android-review.googlesource.com/28470885', 'googleplex-android-review.googlesource.com/28535949', 'googleplex-android-review.googlesource.com/28580692'] into 24Q3-release.

Change-Id: I138852d1c15892bcb17330419d797647bc31dfa4
parents cd4d3a5d e0d91e4d
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -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;
+1 −14
Original line number Diff line number Diff line
@@ -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;
@@ -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
+16 −6
Original line number Diff line number Diff line
@@ -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"
@@ -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" />

@@ -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"
+2 −3
Original line number Diff line number Diff line
@@ -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" >
+8 −1
Original line number Diff line number Diff line
@@ -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 {
@@ -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()
@@ -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