Fix Auth Credential PIN layout inconsistence layout in landscape

The layout of AuthCredentialPasswordView in landscape doesn't consist
with layout in portrait.

This change do:
1. Make layout consistence on both portrait & landscape
2. Hook IME insets change callback and refine layout size
3. Optomize layout complexity

Test: atest SystemUITests
Test: Update Display/Font size to largest, and trigger BioMetric prompt
Bug: 230698721
Merged-In: If484225a9b75af42bc4fee4d288c67c7361a1c89
Change-Id: If484225a9b75af42bc4fee4d288c67c7361a1c89
This commit is contained in:
lbill
2022-05-09 09:17:16 +00:00
parent 6ec02000cb
commit d26d4b3bbb
7 changed files with 211 additions and 93 deletions

View File

@@ -18,44 +18,70 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:elevation="@dimen/biometric_dialog_elevation">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/TextAppearance.AuthCredential.Title"/>
<RelativeLayout
android:id="@+id/auth_credential_header"
style="@style/AuthCredentialHeaderStyle"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:id="@+id/subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/TextAppearance.AuthCredential.Subtitle"/>
<ImageView
android:id="@+id/icon"
style="@style/TextAppearance.AuthNonBioCredential.Icon"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:contentDescription="@null"/>
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/TextAppearance.AuthCredential.Description"/>
<TextView
android:id="@+id/title"
style="@style/TextAppearance.AuthNonBioCredential.Title"
android:layout_below="@id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImeAwareEditText
android:id="@+id/lockPassword"
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:minHeight="48dp"
android:gravity="center"
android:inputType="textPassword"
android:maxLength="500"
android:imeOptions="actionNext|flagNoFullscreen|flagForceAscii"
style="@style/TextAppearance.AuthCredential.PasswordEntry"/>
<TextView
android:id="@+id/subtitle"
style="@style/TextAppearance.AuthNonBioCredential.Subtitle"
android:layout_below="@id/title"
android:layout_alignParentLeft="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/error"
android:layout_width="match_parent"
<TextView
android:id="@+id/description"
style="@style/TextAppearance.AuthNonBioCredential.Description"
android:layout_below="@id/subtitle"
android:layout_alignParentLeft="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
<LinearLayout
android:id="@+id/auth_credential_input"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/TextAppearance.AuthCredential.Error"/>
android:orientation="vertical">
<ImeAwareEditText
android:id="@+id/lockPassword"
style="@style/TextAppearance.AuthCredential.PasswordEntry"
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:imeOptions="actionNext|flagNoFullscreen|flagForceAscii"
android:inputType="textPassword"
android:minHeight="48dp" />
<TextView
android:id="@+id/error"
style="@style/TextAppearance.AuthNonBioCredential.Error"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</com.android.systemui.biometrics.AuthCredentialPasswordView>

View File

@@ -22,68 +22,63 @@
android:orientation="vertical">
<RelativeLayout
android:id="@+id/auth_credential_header"
style="@style/AuthCredentialHeaderStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/auth_credential_header"
style="@style/AuthCredentialHeaderStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
<ImageView
android:id="@+id/icon"
style="@style/TextAppearance.AuthNonBioCredential.Icon"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:contentDescription="@null"/>
<ImageView
android:id="@+id/icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/title"
style="@style/TextAppearance.AuthNonBioCredential.Title"
android:layout_below="@id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/title"
style="@style/TextAppearance.AuthNonBioCredential.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/subtitle"
style="@style/TextAppearance.AuthNonBioCredential.Subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/description"
style="@style/TextAppearance.AuthNonBioCredential.Description"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:layout_alignParentBottom="true">
<ImeAwareEditText
android:id="@+id/lockPassword"
style="@style/TextAppearance.AuthCredential.PasswordEntry"
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:imeOptions="actionNext|flagNoFullscreen|flagForceAscii"
android:inputType="textPassword"
android:minHeight="48dp" />
<TextView
android:id="@+id/error"
style="@style/TextAppearance.AuthNonBioCredential.Error"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:id="@+id/subtitle"
style="@style/TextAppearance.AuthNonBioCredential.Subtitle"
android:layout_below="@id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/description"
style="@style/TextAppearance.AuthNonBioCredential.Description"
android:layout_below="@id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
<LinearLayout
android:id="@+id/auth_credential_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImeAwareEditText
android:id="@+id/lockPassword"
style="@style/TextAppearance.AuthCredential.PasswordEntry"
android:layout_width="208dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:imeOptions="actionNext|flagNoFullscreen|flagForceAscii"
android:inputType="textPassword"
android:minHeight="48dp" />
<TextView
android:id="@+id/error"
style="@style/TextAppearance.AuthNonBioCredential.Error"
android:layout_gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</com.android.systemui.biometrics.AuthCredentialPasswordView>

View File

@@ -18,4 +18,13 @@
<style name="BrightnessDialogContainer" parent="@style/BaseBrightnessDialogContainer">
<item name="android:layout_width">360dp</item>
</style>
<style name="AuthCredentialHeaderStyle">
<item name="android:paddingStart">48dp</item>
<item name="android:paddingEnd">24dp</item>
<item name="android:paddingTop">48dp</item>
<item name="android:paddingBottom">10dp</item>
<item name="android:gravity">top|center_horizontal</item>
</style>
</resources>

View File

@@ -949,6 +949,9 @@
<dimen name="biometric_dialog_width">240dp</dimen>
<dimen name="biometric_dialog_height">240dp</dimen>
<!-- Biometric Auth Credential values -->
<dimen name="biometric_auth_icon_size">48dp</dimen>
<!-- Starting text size in sp of batteryLevel for wireless charging animation -->
<item name="wireless_charging_anim_battery_level_text_size_start" format="float" type="dimen">
0

View File

@@ -198,6 +198,11 @@
<item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
<style name="TextAppearance.AuthNonBioCredential.Icon">
<item name="android:layout_width">@dimen/biometric_auth_icon_size</item>
<item name="android:layout_height">@dimen/biometric_auth_icon_size</item>
</style>
<style name="TextAppearance.AuthNonBioCredential.Title">
<item name="android:fontFamily">google-sans</item>
<item name="android:layout_marginTop">20dp</item>
@@ -227,6 +232,7 @@
<style name="TextAppearance.AuthCredential.PasswordEntry" parent="@android:style/TextAppearance.DeviceDefault">
<item name="android:gravity">center</item>
<item name="android:paddingTop">28dp</item>
<item name="android:singleLine">true</item>
<item name="android:textColor">?android:attr/colorForeground</item>
<item name="android:textSize">24sp</item>
@@ -235,7 +241,7 @@
<style name="AuthCredentialHeaderStyle">
<item name="android:paddingStart">48dp</item>
<item name="android:paddingEnd">24dp</item>
<item name="android:paddingEnd">48dp</item>
<item name="android:paddingTop">28dp</item>
<item name="android:paddingBottom">20dp</item>
<item name="android:orientation">vertical</item>

View File

@@ -16,12 +16,20 @@
package com.android.systemui.biometrics;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.view.WindowInsets.Type.ime;
import android.annotation.NonNull;
import android.content.Context;
import android.graphics.Insets;
import android.os.UserHandle;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnApplyWindowInsetsListener;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImeAwareEditText;
@@ -31,18 +39,24 @@ import com.android.internal.widget.LockPatternChecker;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import java.io.PrintWriter;
/**
* Pin and Password UI
*/
public class AuthCredentialPasswordView extends AuthCredentialView
implements TextView.OnEditorActionListener {
implements TextView.OnEditorActionListener, OnApplyWindowInsetsListener, Dumpable {
private static final String TAG = "BiometricPrompt/AuthCredentialPasswordView";
private final InputMethodManager mImm;
private ImeAwareEditText mPasswordField;
private ViewGroup mAuthCredentialHeader;
private ViewGroup mAuthCredentialInput;
private int mBottomInset = 0;
public AuthCredentialPasswordView(Context context,
AttributeSet attrs) {
@@ -53,6 +67,9 @@ public class AuthCredentialPasswordView extends AuthCredentialView
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mAuthCredentialHeader = findViewById(R.id.auth_credential_header);
mAuthCredentialInput = findViewById(R.id.auth_credential_input);
mPasswordField = findViewById(R.id.lockPassword);
mPasswordField.setOnEditorActionListener(this);
// TODO: De-dupe the logic with AuthContainerView
@@ -66,6 +83,8 @@ public class AuthCredentialPasswordView extends AuthCredentialView
}
return true;
});
setOnApplyWindowInsetsListener(this);
}
@Override
@@ -127,4 +146,65 @@ public class AuthCredentialPasswordView extends AuthCredentialView
mPasswordField.setText("");
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mAuthCredentialInput == null || mAuthCredentialHeader == null
|| mSubtitleView == null || mPasswordField == null || mErrorView == null) {
return;
}
// b/157910732 In AuthContainerView#getLayoutParams() we used to prevent jank risk when
// resizing by IME show or hide, we used to setFitInsetsTypes `~WindowInsets.Type.ime()` to
// LP. As a result this view needs to listen onApplyWindowInsets() and handle onLayout.
int inputLeftBound;
int inputTopBound;
int headerRightBound = right;
if (getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE) {
inputTopBound = (bottom - (mPasswordField.getHeight() + mErrorView.getHeight())) / 2;
inputLeftBound = (right - left) / 2;
headerRightBound = inputLeftBound;
} else {
inputTopBound = mSubtitleView.getBottom() + (bottom - mSubtitleView.getBottom()) / 2;
inputLeftBound = (right - left - mAuthCredentialInput.getWidth()) / 2;
}
mAuthCredentialHeader.layout(left, top, headerRightBound, bottom);
mAuthCredentialInput.layout(inputLeftBound, inputTopBound, right, bottom);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int newHeight = MeasureSpec.getSize(heightMeasureSpec) - mBottomInset;
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), newHeight);
measureChildren(widthMeasureSpec,
MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.AT_MOST));
}
@NonNull
@Override
public WindowInsets onApplyWindowInsets(@NonNull View v, WindowInsets insets) {
final Insets bottomInset = insets.getInsets(ime());
if (v instanceof AuthCredentialPasswordView && mBottomInset != bottomInset.bottom) {
mBottomInset = bottomInset.bottom;
requestLayout();
}
return insets;
}
@Override
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
pw.println(TAG + "State:");
pw.println(" mBottomInset=" + mBottomInset);
pw.println(" mAuthCredentialHeader size=(" + mAuthCredentialHeader.getWidth() + ","
+ mAuthCredentialHeader.getHeight());
pw.println(" mAuthCredentialInput size=(" + mAuthCredentialInput.getWidth() + ","
+ mAuthCredentialInput.getHeight());
}
}

View File

@@ -30,7 +30,6 @@ import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.pm.UserInfo;
import android.graphics.drawable.Drawable;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.PromptInfo;
import android.os.AsyncTask;
import android.os.CountDownTimer;
@@ -87,7 +86,7 @@ public abstract class AuthCredentialView extends LinearLayout {
private boolean mShouldAnimateContents;
private TextView mTitleView;
private TextView mSubtitleView;
protected TextView mSubtitleView;
private TextView mDescriptionView;
private ImageView mIconView;
protected TextView mErrorView;