diff --git a/src/com/android/settings/biometrics/BiometricEnrollSidecar.java b/src/com/android/settings/biometrics/BiometricEnrollSidecar.java index 9a89f7a349f..97d46a420e3 100644 --- a/src/com/android/settings/biometrics/BiometricEnrollSidecar.java +++ b/src/com/android/settings/biometrics/BiometricEnrollSidecar.java @@ -45,6 +45,14 @@ public abstract class BiometricEnrollSidecar extends InstrumentedFragment { * @param isAcquiredGood whether the fingerprint image was good. */ default void onAcquired(boolean isAcquiredGood) { } + /** + * Called when a pointer down event has occurred. + */ + default void onPointerDown(int sensorId) { } + /** + * Called when a pointer up event has occurred. + */ + default void onPointerUp(int sensorId) { } } private int mEnrollmentSteps = -1; @@ -118,6 +126,32 @@ public abstract class BiometricEnrollSidecar extends InstrumentedFragment { } } + private class QueuedPointerDown extends QueuedEvent { + private final int sensorId; + + public QueuedPointerDown(int sensorId) { + this.sensorId = sensorId; + } + + @Override + public void send(Listener listener) { + listener.onPointerDown(sensorId); + } + } + + private class QueuedPointerUp extends QueuedEvent { + private final int sensorId; + + public QueuedPointerUp(int sensorId) { + this.sensorId = sensorId; + } + + @Override + public void send(Listener listener) { + listener.onPointerUp(sensorId); + } + } + private final Runnable mTimeoutRunnable = new Runnable() { @Override public void run() { @@ -215,6 +249,22 @@ public abstract class BiometricEnrollSidecar extends InstrumentedFragment { } } + protected void onPointerDown(int sensorId) { + if (mListener != null) { + mListener.onPointerDown(sensorId); + } else { + mQueuedEvents.add(new QueuedPointerDown(sensorId)); + } + } + + protected void onPointerUp(int sensorId) { + if (mListener != null) { + mListener.onPointerUp(sensorId); + } else { + mQueuedEvents.add(new QueuedPointerUp(sensorId)); + } + } + public void setListener(Listener listener) { mListener = listener; if (mListener != null) { diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java index 60959e399a3..139a18fa376 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java @@ -82,6 +82,7 @@ import com.airbnb.lottie.LottieAnimationView; import com.airbnb.lottie.LottieCompositionFactory; import com.airbnb.lottie.LottieProperty; import com.airbnb.lottie.model.KeyPath; +import com.google.android.setupcompat.template.FooterActionButton; import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupcompat.util.WizardManagerHelper; @@ -101,6 +102,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { private static final String TAG = "FingerprintEnrollEnrolling"; static final String TAG_SIDECAR = "sidecar"; + static final String TAG_UDFPS_HELPER = "udfps_helper"; static final String KEY_STATE_CANCELED = "is_canceled"; static final String KEY_STATE_PREVIOUS_ROTATION = "previous_rotation"; @@ -353,6 +355,24 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { .build() ); + if (FeatureFlagUtils.isEnabled(getApplicationContext(), + FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS)) { + // Remove the space view and make the width of footer button container WRAP_CONTENT + // to avoid hiding the udfps view progress bar bottom. + final LinearLayout buttonContainer = mFooterBarMixin.getButtonContainer(); + View spaceView = null; + for (int i = 0; i < buttonContainer.getChildCount(); i++) { + if (!(buttonContainer.getChildAt(i) instanceof FooterActionButton)) { + spaceView = buttonContainer.getChildAt(i); + break; + } + } + if (spaceView != null) { + spaceView.setVisibility(View.GONE); + buttonContainer.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT; + } + } + final LayerDrawable fingerprintDrawable = mProgressBar != null ? (LayerDrawable) mProgressBar.getBackground() : null; if (fingerprintDrawable != null) { @@ -867,6 +887,20 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { } } + @Override + public void onPointerDown(int sensorId) { + if (mUdfpsEnrollHelper != null) { + mUdfpsEnrollHelper.onPointerDown(sensorId); + } + } + + @Override + public void onPointerUp(int sensorId) { + if (mUdfpsEnrollHelper != null) { + mUdfpsEnrollHelper.onPointerUp(sensorId); + } + } + private void updateProgress(boolean animate) { if (mSidecar == null || !mSidecar.isEnrolling()) { Log.d(TAG, "Enrollment not started yet"); @@ -1195,7 +1229,16 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { udfpsProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL); udfpsEnrollView.setOverlayParams(params); - mUdfpsEnrollHelper = new UdfpsEnrollHelper(getApplicationContext(), mFingerprintManager); + + mUdfpsEnrollHelper = (UdfpsEnrollHelper) getSupportFragmentManager().findFragmentByTag( + FingerprintEnrollEnrolling.TAG_UDFPS_HELPER); + if (mUdfpsEnrollHelper == null) { + mUdfpsEnrollHelper = new UdfpsEnrollHelper(getApplicationContext(), + mFingerprintManager); + getSupportFragmentManager().beginTransaction() + .add(mUdfpsEnrollHelper, FingerprintEnrollEnrolling.TAG_UDFPS_HELPER) + .commitAllowingStateLoss(); + } udfpsEnrollView.setEnrollHelper(mUdfpsEnrollHelper); return udfpsEnrollView; diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollSidecar.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollSidecar.java index 3adfc28b113..5d04cd6c5ed 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollSidecar.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollSidecar.java @@ -122,6 +122,16 @@ public class FingerprintEnrollSidecar extends BiometricEnrollSidecar { public void onEnrollmentError(int errMsgId, CharSequence errString) { FingerprintEnrollSidecar.super.onEnrollmentError(errMsgId, errString); } + + @Override + public void onPointerDown(int sensorId) { + FingerprintEnrollSidecar.super.onPointerDown(sensorId); + } + + @Override + public void onPointerUp(int sensorId) { + FingerprintEnrollSidecar.super.onPointerUp(sensorId); + } }; @Override diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintUpdater.java b/src/com/android/settings/biometrics/fingerprint/FingerprintUpdater.java index 25689374da8..36325a7b975 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintUpdater.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintUpdater.java @@ -96,6 +96,16 @@ public class FingerprintUpdater { public void onAcquired(boolean isAcquiredGood) { mCallback.onAcquired(isAcquiredGood); } + + @Override + public void onPointerDown(int sensorId) { + mCallback.onPointerDown(sensorId); + } + + @Override + public void onPointerUp(int sensorId) { + mCallback.onPointerUp(sensorId); + } } /** diff --git a/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollHelper.java b/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollHelper.java index f42b8eca2fc..f7f138cbabd 100644 --- a/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollHelper.java +++ b/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollHelper.java @@ -22,19 +22,22 @@ import android.content.Context; import android.graphics.PointF; import android.hardware.fingerprint.FingerprintManager; import android.os.Build; +import android.os.Bundle; import android.os.UserHandle; import android.provider.Settings; import android.util.Log; import android.util.TypedValue; import android.view.accessibility.AccessibilityManager; +import com.android.settings.core.InstrumentedFragment; + import java.util.ArrayList; import java.util.List; /** * Helps keep track of enrollment state and animates the progress bar accordingly. */ -public class UdfpsEnrollHelper { +public class UdfpsEnrollHelper extends InstrumentedFragment { private static final String TAG = "UdfpsEnrollHelper"; private static final String SCALE_OVERRIDE = @@ -50,6 +53,10 @@ public class UdfpsEnrollHelper { void onEnrollmentHelp(int remaining, int totalSteps); void onAcquired(boolean animateIfLastStepGood); + + void onPointerDown(int sensorId); + + void onPointerUp(int sensorId); } @NonNull @@ -124,6 +131,17 @@ public class UdfpsEnrollHelper { } } + @Override + public int getMetricsCategory() { + return 0; + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setRetainInstance(true); + } + void onEnrollmentProgress(int totalSteps, int remaining) { if (mTotalSteps == -1) { mTotalSteps = totalSteps; @@ -144,7 +162,7 @@ public class UdfpsEnrollHelper { } void onEnrollmentHelp() { - if (mListener != null && mTotalSteps != -1) { + if (mListener != null) { mListener.onEnrollmentHelp(mRemainingSteps, mTotalSteps); } } @@ -155,6 +173,18 @@ public class UdfpsEnrollHelper { } } + void onPointerDown(int sensorId) { + if (mListener != null) { + mListener.onPointerDown(sensorId); + } + } + + void onPointerUp(int sensorId) { + if (mListener != null) { + mListener.onPointerUp(sensorId); + } + } + void setListener(UdfpsEnrollHelper.Listener listener) { mListener = listener; diff --git a/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollView.java b/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollView.java index 3e3fd0e436d..3d77f0e8b63 100644 --- a/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollView.java +++ b/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollView.java @@ -88,10 +88,22 @@ public class UdfpsEnrollView extends FrameLayout implements UdfpsEnrollHelper.Li @Override public void onAcquired(boolean animateIfLastStepGood) { mHandler.post(() -> { + onFingerUp(); if (animateIfLastStepGood) mFingerprintProgressDrawable.onLastStepAcquired(); }); } + @Override + public void onPointerDown(int sensorId) { + onFingerDown(); + } + + + @Override + public void onPointerUp(int sensorId) { + onFingerUp(); + } + void setOverlayParams(UdfpsOverlayParams params) { mOverlayParams = params; @@ -99,7 +111,7 @@ public class UdfpsEnrollView extends FrameLayout implements UdfpsEnrollHelper.Li mProgressBarRadius = (int) (mOverlayParams.getScaleFactor() * getContext().getResources().getInteger( R.integer.config_udfpsEnrollProgressBar)); - mSensorRect = mOverlayParams.getSensorBounds(); + mSensorRect = new Rect(mOverlayParams.getSensorBounds()); onSensorRectUpdated(); }); @@ -123,7 +135,7 @@ public class UdfpsEnrollView extends FrameLayout implements UdfpsEnrollHelper.Li private void updateDimensions() { // Original sensorBounds assume portrait mode. - Rect rotatedBounds = mOverlayParams.getSensorBounds(); + final Rect rotatedBounds = mOverlayParams.getSensorBounds(); int rotation = mOverlayParams.getRotation(); if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) { RotationUtils.rotateBounds( @@ -137,33 +149,42 @@ public class UdfpsEnrollView extends FrameLayout implements UdfpsEnrollHelper.Li // Use parent view's and rotatedBound's absolute coordinates to decide the margins of // UdfpsEnrollView, so that its center keeps consistent with sensor rect's. ViewGroup parentView = (ViewGroup) getParent(); - int[] coords = parentView.getLocationOnScreen(); - int parentLeft = coords[0]; - int parentTop = coords[1]; - int parentRight = parentLeft + parentView.getWidth(); - int parentBottom = parentTop + parentView.getHeight(); MarginLayoutParams marginLayoutParams = (MarginLayoutParams) getLayoutParams(); FrameLayout.LayoutParams params = (LayoutParams) getLayoutParams(); - - switch (rotation) { - case Surface.ROTATION_0: - case Surface.ROTATION_180: + if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) { + parentView.getViewTreeObserver().addOnDrawListener(() -> { + final int[] coords = parentView.getLocationOnScreen(); + final int parentLeft = coords[0]; + final int parentTop = coords[1]; + final int parentRight = parentLeft + parentView.getWidth(); params.gravity = Gravity.RIGHT | Gravity.TOP; - marginLayoutParams.rightMargin = parentRight - rotatedBounds.right - getPaddingX(); - marginLayoutParams.topMargin = rotatedBounds.top - parentTop - getPaddingY(); - break; - case Surface.ROTATION_90: + final int rightMargin = parentRight - rotatedBounds.right - getPaddingX(); + final int topMargin = rotatedBounds.top - parentTop - getPaddingY(); + if (marginLayoutParams.rightMargin == rightMargin + && marginLayoutParams.topMargin == topMargin) { + return; + } + marginLayoutParams.rightMargin = rightMargin; + marginLayoutParams.topMargin = topMargin; + setLayoutParams(params); + }); + } else { + final int[] coords = parentView.getLocationOnScreen(); + final int parentLeft = coords[0]; + final int parentTop = coords[1]; + final int parentRight = parentLeft + parentView.getWidth(); + final int parentBottom = parentTop + parentView.getHeight(); + if (rotation == Surface.ROTATION_90) { params.gravity = Gravity.RIGHT | Gravity.BOTTOM; marginLayoutParams.rightMargin = parentRight - rotatedBounds.right - getPaddingX(); marginLayoutParams.bottomMargin = parentBottom - rotatedBounds.bottom - getPaddingY(); - break; - case Surface.ROTATION_270: + } else if (rotation == Surface.ROTATION_270) { params.gravity = Gravity.LEFT | Gravity.BOTTOM; marginLayoutParams.leftMargin = rotatedBounds.left - parentLeft - getPaddingX(); marginLayoutParams.bottomMargin = parentBottom - rotatedBounds.bottom - getPaddingY(); - break; + } } params.height = rotatedBounds.height() + 2 * getPaddingX();