From b07e2dbfd383b33ab71cce3fc051275549dcad12 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Mon, 30 Nov 2020 17:16:00 -0800 Subject: [PATCH 1/2] Update portrait enrollment for UDFPS Bug: 171353506 Test: No effect on existing devices Change-Id: I701baf06bf3defde78af50eff5c0e01fafeb07cd --- res/layout/udfps_enroll_enrolling.xml | 26 +++++ res/layout/udfps_enroll_layout.xml | 96 +++++++++++++++++++ .../FingerprintEnrollEnrolling.java | 30 +++++- .../fingerprint/UdfpsEnrollLayout.java | 76 +++++++++++++++ 4 files changed, 223 insertions(+), 5 deletions(-) create mode 100644 res/layout/udfps_enroll_enrolling.xml create mode 100644 res/layout/udfps_enroll_layout.xml create mode 100644 src/com/android/settings/biometrics/fingerprint/UdfpsEnrollLayout.java diff --git a/res/layout/udfps_enroll_enrolling.xml b/res/layout/udfps_enroll_enrolling.xml new file mode 100644 index 00000000000..03b6528b32e --- /dev/null +++ b/res/layout/udfps_enroll_enrolling.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/res/layout/udfps_enroll_layout.xml b/res/layout/udfps_enroll_layout.xml new file mode 100644 index 00000000000..51c788b3bae --- /dev/null +++ b/res/layout/udfps_enroll_layout.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java index 813c384b954..cf458000ddf 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java @@ -27,6 +27,7 @@ import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.hardware.fingerprint.FingerprintManager; +import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.media.AudioAttributes; import android.os.Bundle; import android.os.VibrationEffect; @@ -51,6 +52,8 @@ import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupdesign.util.DescriptionStyler; +import java.util.List; + /** * Activity which handles the actual enrolling for fingerprint. */ @@ -130,12 +133,29 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.fingerprint_enroll_enrolling); + + final FingerprintManager fingerprintManager = getSystemService(FingerprintManager.class); + final List props = + fingerprintManager.getSensorPropertiesInternal(); + final boolean canAssumeUdfps = props.size() == 1 && props.get(0).isAnyUdfpsType(); + + if (canAssumeUdfps) { + // Use a custom layout since animations, etc must be based off of the sensor's physical + // location. + setContentView(R.layout.udfps_enroll_enrolling); + final UdfpsEnrollLayout udfpsEnrollLayout = (UdfpsEnrollLayout) getLayoutInflater() + .inflate(R.layout.udfps_enroll_layout, null /* root */); + getLayout().addView(udfpsEnrollLayout); + } else { + setContentView(R.layout.fingerprint_enroll_enrolling); + } + setHeaderText(R.string.security_settings_fingerprint_enroll_repeat_title); - mStartMessage = (TextView) findViewById(R.id.sud_layout_description); - mRepeatMessage = (TextView) findViewById(R.id.repeat_message); - mErrorText = (TextView) findViewById(R.id.error_text); - mProgressBar = (ProgressBar) findViewById(R.id.fingerprint_progress_bar); + + mStartMessage = findViewById(R.id.sud_layout_description); + mRepeatMessage = findViewById(R.id.repeat_message); + mErrorText = findViewById(R.id.error_text); + mProgressBar = findViewById(R.id.fingerprint_progress_bar); mVibrator = getSystemService(Vibrator.class); if (getLayout().shouldApplyPartnerHeavyThemeResource()) { diff --git a/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollLayout.java b/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollLayout.java new file mode 100644 index 00000000000..ca27e840b8b --- /dev/null +++ b/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollLayout.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.biometrics.fingerprint; + +import android.content.Context; +import android.graphics.Rect; +import android.hardware.fingerprint.FingerprintManager; +import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.view.WindowInsets; +import android.view.WindowManager; +import android.widget.LinearLayout; + +import com.android.settings.R; + +public class UdfpsEnrollLayout extends LinearLayout { + + private static final String TAG = "UdfpsEnrollLayout"; + + private final FingerprintSensorPropertiesInternal mSensorProps; + + public UdfpsEnrollLayout(Context context, AttributeSet attrs) { + super(context, attrs); + mSensorProps = context.getSystemService(FingerprintManager.class) + .getSensorPropertiesInternal().get(0); + } + + @Override + public void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + + final View animation = findViewById(R.id.fingerprint_progress_bar); + final WindowManager wm = getContext().getSystemService(WindowManager.class); + final int statusbarHeight = Math.abs(wm.getCurrentWindowMetrics().getWindowInsets() + .getInsets(WindowInsets.Type.statusBars()).toRect().height()); + + // Calculate the amount of translation required. This is just re-arranged from + // animation.setY(mSensorProps.sensorLocationY-statusbarHeight-mSensorProps.sensorRadius) + // The translationY is the amount of extra height that should be added to the spacer + // above the animation + final int spaceHeight = mSensorProps.sensorLocationY - statusbarHeight + - mSensorProps.sensorRadius - animation.getTop(); + animation.setTranslationY(spaceHeight); + } + + + + @Override + public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + final View animation = findViewById(R.id.fingerprint_progress_bar); + final int sensorDiameter = mSensorProps.sensorRadius * 2; + // Multiply it slightly so that the progress bar is outside the UDFPS affordance, and that + // the animation is within the UDFPS affordance. + final int animationDiameter = (int) (sensorDiameter * 1); + animation.measure(MeasureSpec.makeMeasureSpec(animationDiameter, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(animationDiameter, MeasureSpec.EXACTLY)); + } +} From 201f02758640c29d35611e6e26771380e8540886 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Tue, 1 Dec 2020 17:29:47 -0800 Subject: [PATCH 2/2] Start udfps enroll after activity animates in 1) Do not request enrollment until activity animation is complete 2) Do not show fingerprint icon until activity animation is complete Bug: 171353506 Test: manual Change-Id: I7cdf5fc4888e35c0a7ba38ea622ae9f3fe1a3abf --- .../biometrics/BiometricsEnrollEnrolling.java | 2 ++ .../FingerprintEnrollEnrolling.java | 26 ++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.java b/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.java index f131e35457d..9b86e78eff9 100644 --- a/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.java +++ b/src/com/android/settings/biometrics/BiometricsEnrollEnrolling.java @@ -16,6 +16,7 @@ package com.android.settings.biometrics; +import android.annotation.Nullable; import android.content.Intent; import android.os.UserHandle; import android.view.View; @@ -33,6 +34,7 @@ public abstract class BiometricsEnrollEnrolling extends BiometricEnrollBase private static final String TAG_SIDECAR = "sidecar"; + @Nullable protected BiometricEnrollSidecar mSidecar; /** diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java index cf458000ddf..b33113b74be 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java @@ -33,6 +33,7 @@ import android.os.Bundle; import android.os.VibrationEffect; import android.os.Vibrator; import android.text.TextUtils; +import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.animation.AnimationUtils; @@ -59,6 +60,7 @@ import java.util.List; */ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { + private static final String TAG = "FingerprintEnrollEnrolling"; static final String TAG_SIDECAR = "sidecar"; private static final int PROGRESS_BAR_MAX = 10000; @@ -89,6 +91,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) .build(); + private boolean mCanAssumeUdfps; private ProgressBar mProgressBar; private ObjectAnimator mProgressAnim; private TextView mStartMessage; @@ -137,9 +140,9 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { final FingerprintManager fingerprintManager = getSystemService(FingerprintManager.class); final List props = fingerprintManager.getSensorPropertiesInternal(); - final boolean canAssumeUdfps = props.size() == 1 && props.get(0).isAnyUdfpsType(); + mCanAssumeUdfps = props.size() == 1 && props.get(0).isAnyUdfpsType(); - if (canAssumeUdfps) { + if (mCanAssumeUdfps) { // Use a custom layout since animations, etc must be based off of the sensor's physical // location. setContentView(R.layout.udfps_enroll_enrolling); @@ -158,6 +161,10 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { mProgressBar = findViewById(R.id.fingerprint_progress_bar); mVibrator = getSystemService(Vibrator.class); + if (mCanAssumeUdfps) { + mProgressBar.setVisibility(View.INVISIBLE); + } + if (getLayout().shouldApplyPartnerHeavyThemeResource()) { DescriptionStyler.applyPartnerCustomizationHeavyStyle(mRepeatMessage); } else if (getLayout().shouldApplyPartnerResource()) { @@ -213,7 +220,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { @Override protected boolean shouldStartAutomatically() { - return true; + return !mCanAssumeUdfps; } @Override @@ -229,6 +236,12 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { @Override public void onEnterAnimationComplete() { super.onEnterAnimationComplete(); + + if (mCanAssumeUdfps) { + startEnrollment(); + mProgressBar.setVisibility(View.VISIBLE); + } + mAnimationCancelled = false; startIconAnimation(); } @@ -272,7 +285,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { } private void updateDescription() { - if (mSidecar.getEnrollmentSteps() == -1) { + if (mSidecar == null || mSidecar.getEnrollmentSteps() == -1) { mStartMessage.setVisibility(View.VISIBLE); mRepeatMessage.setVisibility(View.INVISIBLE); } else { @@ -319,6 +332,11 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { } private void updateProgress(boolean animate) { + if (mSidecar == null || !mSidecar.isEnrolling()) { + Log.d(TAG, "Enrollment not started yet"); + return; + } + int progress = getProgress( mSidecar.getEnrollmentSteps(), mSidecar.getEnrollmentRemaining()); if (animate) {