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

Commit 4bb2e871 authored by Curtis Belmonte's avatar Curtis Belmonte Committed by Automerger Merge Worker
Browse files

Merge "Fix BiometricPrompt layout for UDFPS in landscape" into sc-dev am: 9dff4b39

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15175065

Change-Id: I509f3317f9cb99acd574d6d1521fd72d6ec61f47
parents dccc693e 9dff4b39
Loading
Loading
Loading
Loading
+45 −16
Original line number Diff line number Diff line
@@ -19,17 +19,19 @@ package com.android.systemui.biometrics;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator.Modality;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;

@@ -87,11 +89,9 @@ public class AuthBiometricFaceToFingerprintView extends AuthBiometricFaceView {
        }
    }

    @Modality
    private int mActiveSensorType = TYPE_FACE;

    @Nullable
    private UdfpsDialogMeasureAdapter mUdfpsMeasureAdapter;
    @Modality private int mActiveSensorType = TYPE_FACE;
    @Nullable private FingerprintSensorPropertiesInternal mFingerprintSensorProps;
    @Nullable private UdfpsDialogMeasureAdapter mUdfpsMeasureAdapter;

    public AuthBiometricFaceToFingerprintView(Context context) {
        super(context);
@@ -106,14 +106,17 @@ public class AuthBiometricFaceToFingerprintView extends AuthBiometricFaceView {
        super(context, attrs, injector);
    }

    void setFingerprintSensorProps(@NonNull FingerprintSensorPropertiesInternal sensorProps) {
        if (!sensorProps.isAnyUdfpsType()) {
            return;
    @Modality
    int getActiveSensorType() {
        return mActiveSensorType;
    }

        if (mUdfpsMeasureAdapter == null || mUdfpsMeasureAdapter.getSensorProps() != sensorProps) {
            mUdfpsMeasureAdapter = new UdfpsDialogMeasureAdapter(this, sensorProps);
    boolean isFingerprintUdfps() {
        return mFingerprintSensorProps.isAnyUdfpsType();
    }

    void setFingerprintSensorProps(@NonNull FingerprintSensorPropertiesInternal sensorProps) {
        mFingerprintSensorProps = sensorProps;
    }

    @Override
@@ -193,8 +196,34 @@ public class AuthBiometricFaceToFingerprintView extends AuthBiometricFaceView {
    @NonNull
    AuthDialog.LayoutParams onMeasureInternal(int width, int height) {
        final AuthDialog.LayoutParams layoutParams = super.onMeasureInternal(width, height);
        return mUdfpsMeasureAdapter != null
                ? mUdfpsMeasureAdapter.onMeasureInternal(width, height, layoutParams)
        return isFingerprintUdfps()
                ? getUdfpsMeasureAdapter().onMeasureInternal(width, height, layoutParams)
                : layoutParams;
    }

    @NonNull
    private UdfpsDialogMeasureAdapter getUdfpsMeasureAdapter() {
        if (mUdfpsMeasureAdapter == null
                || mUdfpsMeasureAdapter.getSensorProps() != mFingerprintSensorProps) {
            mUdfpsMeasureAdapter = new UdfpsDialogMeasureAdapter(this, mFingerprintSensorProps);
        }
        return mUdfpsMeasureAdapter;
    }

    @Override
    public void onSaveState(@NonNull Bundle outState) {
        super.onSaveState(outState);
        outState.putInt(AuthDialog.KEY_BIOMETRIC_SENSOR_TYPE, mActiveSensorType);
        outState.putParcelable(AuthDialog.KEY_BIOMETRIC_SENSOR_PROPS, mFingerprintSensorProps);
    }

    @Override
    public void restoreState(@Nullable Bundle savedState) {
        super.restoreState(savedState);
        if (savedState != null) {
            mActiveSensorType = savedState.getInt(AuthDialog.KEY_BIOMETRIC_SENSOR_TYPE, TYPE_FACE);
            mFingerprintSensorProps =
                    savedState.getParcelable(AuthDialog.KEY_BIOMETRIC_SENSOR_PROPS);
        }
    }
}
+7 −2
Original line number Diff line number Diff line
@@ -593,11 +593,13 @@ public abstract class AuthBiometricView extends LinearLayout {
    }

    public void onSaveState(@NonNull Bundle outState) {
        outState.putInt(AuthDialog.KEY_BIOMETRIC_CONFIRM_VISIBILITY,
                mConfirmButton.getVisibility());
        outState.putInt(AuthDialog.KEY_BIOMETRIC_TRY_AGAIN_VISIBILITY,
                mTryAgainButton.getVisibility());
        outState.putInt(AuthDialog.KEY_BIOMETRIC_STATE, mState);
        outState.putString(AuthDialog.KEY_BIOMETRIC_INDICATOR_STRING,
                mIndicatorView.getText().toString());
                mIndicatorView.getText() != null ? mIndicatorView.getText().toString() : "");
        outState.putBoolean(AuthDialog.KEY_BIOMETRIC_INDICATOR_ERROR_SHOWING,
                mHandler.hasCallbacks(mResetErrorRunnable));
        outState.putBoolean(AuthDialog.KEY_BIOMETRIC_INDICATOR_HELP_SHOWING,
@@ -754,9 +756,12 @@ public abstract class AuthBiometricView extends LinearLayout {
            // Restore as much state as possible first
            updateState(mSavedState.getInt(AuthDialog.KEY_BIOMETRIC_STATE));

            // Restore positive button state
            // Restore positive button(s) state
            mConfirmButton.setVisibility(
                    mSavedState.getInt(AuthDialog.KEY_BIOMETRIC_CONFIRM_VISIBILITY));
            mTryAgainButton.setVisibility(
                    mSavedState.getInt(AuthDialog.KEY_BIOMETRIC_TRY_AGAIN_VISIBILITY));

        }
    }

+53 −25
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.biometrics;

import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricManager.BiometricMultiSensorMode;

import android.annotation.IntDef;
@@ -23,6 +24,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.PixelFormat;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricAuthenticator.Modality;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.PromptInfo;
@@ -487,31 +489,8 @@ public class AuthContainerView extends LinearLayout
                    + mConfig.mPromptInfo.getAuthenticators());
        }

        if (mBiometricView instanceof AuthBiometricUdfpsView) {
            final int displayRotation = getDisplay().getRotation();
            switch (displayRotation) {
                case Surface.ROTATION_0:
                    mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM);
                    setScrollViewGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
                    break;

                case Surface.ROTATION_90:
                    mPanelController.setPosition(AuthPanelController.POSITION_RIGHT);
                    setScrollViewGravity(Gravity.CENTER_VERTICAL | Gravity.RIGHT);
                    break;

                case Surface.ROTATION_270:
                    mPanelController.setPosition(AuthPanelController.POSITION_LEFT);
                    setScrollViewGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
                    break;

                case Surface.ROTATION_180:
                default:
                    Log.e(TAG, "Unsupported display rotation: " + displayRotation);
                    mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM);
                    setScrollViewGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
                    break;
            }
        if (shouldUpdatePositionForUdfps()) {
            updatePositionForUdfps();
        }

        if (mConfig.mSkipIntro) {
@@ -557,6 +536,48 @@ public class AuthContainerView extends LinearLayout
        }
    }

    private boolean shouldUpdatePositionForUdfps() {
        if (mBiometricView instanceof AuthBiometricUdfpsView) {
            return true;
        }

        if (mBiometricView instanceof AuthBiometricFaceToFingerprintView) {
            AuthBiometricFaceToFingerprintView faceToFingerprintView =
                    (AuthBiometricFaceToFingerprintView) mBiometricView;
            return faceToFingerprintView.getActiveSensorType() == TYPE_FINGERPRINT
                    && faceToFingerprintView.isFingerprintUdfps();
        }

        return false;
    }

    private void updatePositionForUdfps() {
        final int displayRotation = getDisplay().getRotation();
        switch (displayRotation) {
            case Surface.ROTATION_0:
                mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM);
                setScrollViewGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
                break;

            case Surface.ROTATION_90:
                mPanelController.setPosition(AuthPanelController.POSITION_RIGHT);
                setScrollViewGravity(Gravity.CENTER_VERTICAL | Gravity.RIGHT);
                break;

            case Surface.ROTATION_270:
                mPanelController.setPosition(AuthPanelController.POSITION_LEFT);
                setScrollViewGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
                break;

            case Surface.ROTATION_180:
            default:
                Log.e(TAG, "Unsupported display rotation: " + displayRotation);
                mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM);
                setScrollViewGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
                break;
        }
    }

    private void setScrollViewGravity(int gravity) {
        final FrameLayout.LayoutParams params =
                (FrameLayout.LayoutParams) mBiometricScrollView.getLayoutParams();
@@ -605,6 +626,13 @@ public class AuthContainerView extends LinearLayout
    @Override
    public void onAuthenticationFailed(@Modality int modality, String failureReason) {
        mBiometricView.onAuthenticationFailed(modality, failureReason);
        if (mBiometricView instanceof AuthBiometricFaceToFingerprintView
                && ((AuthBiometricFaceToFingerprintView) mBiometricView).isFingerprintUdfps()
                && modality == BiometricAuthenticator.TYPE_FACE) {
            updatePositionForUdfps();
            mPanelView.invalidateOutline();
            mBiometricView.requestLayout();
        }
    }

    @Override
+4 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ public interface AuthDialog {
    String KEY_BIOMETRIC_SHOWING = "biometric_showing";
    String KEY_CREDENTIAL_SHOWING = "credential_showing";

    String KEY_BIOMETRIC_CONFIRM_VISIBILITY = "confirm_visibility";
    String KEY_BIOMETRIC_TRY_AGAIN_VISIBILITY = "try_agian_visibility";
    String KEY_BIOMETRIC_STATE = "state";
    String KEY_BIOMETRIC_INDICATOR_STRING = "indicator_string"; // error / help / hint
@@ -42,6 +43,9 @@ public interface AuthDialog {
    String KEY_BIOMETRIC_INDICATOR_HELP_SHOWING = "hint_is_temporary";
    String KEY_BIOMETRIC_DIALOG_SIZE = "size";

    String KEY_BIOMETRIC_SENSOR_TYPE = "sensor_type";
    String KEY_BIOMETRIC_SENSOR_PROPS = "sensor_props";

    int SIZE_UNKNOWN = 0;
    /**
     * Minimal UI, showing only biometric icon.
+12 −4
Original line number Diff line number Diff line
@@ -180,17 +180,25 @@ public class UdfpsDialogMeasureAdapter {
                iconFrame.measure(
                        MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
                        MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY));
            } else if (child.getId() == R.id.space_above_icon || child.getId() == R.id.button_bar) {
                // Adjust the width of the top spacer and button bar while preserving their heights.
            } else if (child.getId() == R.id.space_above_icon) {
                // Adjust the width and height of the top spacer if necessary.
                final int newTopSpacerHeight = child.getLayoutParams().height
                        - Math.min(bottomSpacerHeight, 0);
                child.measure(
                        MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
                        MeasureSpec.makeMeasureSpec(newTopSpacerHeight, MeasureSpec.EXACTLY));
            } else if (child.getId() == R.id.button_bar) {
                // Adjust the width of the button bar while preserving its height.
                child.measure(
                        MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
                        MeasureSpec.makeMeasureSpec(
                                child.getLayoutParams().height, MeasureSpec.EXACTLY));
            } else if (child.getId() == R.id.space_below_icon) {
                // Adjust the bottom spacer height to align the fingerprint icon with the sensor.
                final int newBottomSpacerHeight = Math.max(bottomSpacerHeight, 0);
                child.measure(
                        MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
                        MeasureSpec.makeMeasureSpec(bottomSpacerHeight, MeasureSpec.EXACTLY));
                        MeasureSpec.makeMeasureSpec(newBottomSpacerHeight, MeasureSpec.EXACTLY));
            } else {
                // Use the remeasured width for all other child views.
                child.measure(
@@ -208,7 +216,7 @@ public class UdfpsDialogMeasureAdapter {

    private int getViewHeightPx(@IdRes int viewId) {
        final View view = mView.findViewById(viewId);
        return view != null ? view.getMeasuredHeight() : 0;
        return view != null && view.getVisibility() != View.GONE ? view.getMeasuredHeight() : 0;
    }

    private int getDialogMarginPx() {
Loading