Merge "Add udfps/ and support a11y for the udfps enroll view."
diff --git a/res/layout/udfps_enroll_view.xml b/res/layout/udfps_enroll_view.xml
index e1c2152..6bf339b 100644
--- a/res/layout/udfps_enroll_view.xml
+++ b/res/layout/udfps_enroll_view.xml
@@ -20,15 +20,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <!-- The layout height/width are placeholders, which will be overwritten by
- FingerprintSensorPropertiesInternal. -->
- <View
- android:id="@+id/udfps_enroll_accessibility_view"
- android:layout_gravity="center"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:contentDescription="@string/accessibility_fingerprint_label"/>
-
<ImageView
android:id="@+id/udfps_enroll_animation_fp_progress_view"
android:layout_width="match_parent"
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
index 139a18f..c9c5b37 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
@@ -32,6 +32,7 @@
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
@@ -40,7 +41,6 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.Bundle;
import android.os.Process;
@@ -48,10 +48,8 @@
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.text.TextUtils;
-import android.util.DisplayUtils;
import android.util.FeatureFlagUtils;
import android.util.Log;
-import android.view.Display;
import android.view.DisplayInfo;
import android.view.MotionEvent;
import android.view.OrientationEventListener;
@@ -77,6 +75,8 @@
import com.android.settings.biometrics.BiometricsEnrollEnrolling;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settingslib.display.DisplayDensityUtils;
+import com.android.settingslib.udfps.UdfpsOverlayParams;
+import com.android.settingslib.udfps.UdfpsUtils;
import com.airbnb.lottie.LottieAnimationView;
import com.airbnb.lottie.LottieCompositionFactory;
@@ -200,6 +200,7 @@
private boolean mHaveShownSfpsLeftEdgeLottie;
private boolean mHaveShownSfpsRightEdgeLottie;
private boolean mShouldShowLottie;
+ private UdfpsUtils mUdfpsUtils;
private OrientationEventListener mOrientationEventListener;
private int mPreviousRotation = 0;
@@ -254,6 +255,7 @@
mAccessibilityManager = getSystemService(AccessibilityManager.class);
mIsAccessibilityEnabled = mAccessibilityManager.isEnabled();
+ mUdfpsUtils = new UdfpsUtils();
final boolean isLayoutRtl = (TextUtils.getLayoutDirectionFromLocale(
Locale.getDefault()) == View.LAYOUT_DIRECTION_RTL);
@@ -280,7 +282,9 @@
layoutContainer.setLayoutParams(lp);
if (FeatureFlagUtils.isEnabled(getApplicationContext(),
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS)) {
- layout.addView(addUdfpsEnrollView(props.get(0)));
+ final UdfpsEnrollView udfpsEnrollView = addUdfpsEnrollView(props.get(0));
+ layout.addView(udfpsEnrollView);
+ setOnHoverListener(true, layout, udfpsEnrollView);
}
setContentView(layout, lp);
break;
@@ -293,6 +297,7 @@
R.layout.udfps_enroll_enrolling, null, false);
if (FeatureFlagUtils.isEnabled(getApplicationContext(),
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS)) {
+ final UdfpsEnrollView udfpsEnrollView = addUdfpsEnrollView(props.get(0));
if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
// In the portrait mode, set layout_container's height 0, so it's
// always shown at the bottom of the screen.
@@ -307,9 +312,11 @@
final ViewGroup.LayoutParams containerLp =
portraitLayoutContainer.getLayoutParams();
containerLp.height = 0;
- portraitLayoutContainer.addView(addUdfpsEnrollView(props.get(0)));
+ portraitLayoutContainer.addView(udfpsEnrollView);
+ setOnHoverListener(false, defaultLayout, udfpsEnrollView);
} else if (rotation == Surface.ROTATION_270) {
- defaultLayout.addView(addUdfpsEnrollView(props.get(0)));
+ defaultLayout.addView(udfpsEnrollView);
+ setOnHoverListener(true, defaultLayout, udfpsEnrollView);
}
}
@@ -1197,17 +1204,7 @@
DisplayInfo displayInfo = new DisplayInfo();
getDisplay().getDisplayInfo(displayInfo);
- final Display.Mode maxDisplayMode =
- DisplayUtils.getMaximumResolutionDisplayMode(displayInfo.supportedModes);
- final float scaleFactor = android.util.DisplayUtils.getPhysicalPixelDisplaySizeRatio(
- maxDisplayMode.getPhysicalWidth(), maxDisplayMode.getPhysicalHeight(),
- displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight());
- if (scaleFactor == Float.POSITIVE_INFINITY) {
- mScaleFactor = 1f;
- } else {
- mScaleFactor = scaleFactor;
- }
-
+ mScaleFactor = mUdfpsUtils.getScaleFactor(displayInfo);
Rect udfpsBounds = udfpsProps.getLocation().getRect();
udfpsBounds.scale(mScaleFactor);
@@ -1217,16 +1214,13 @@
displayInfo.getNaturalWidth(), /* right */
displayInfo.getNaturalHeight() /* botom */);
- // TODO(b/260617060): Extract this logic into a 3rd party library for both Settings and
- // SysUI to depend on.
UdfpsOverlayParams params = new UdfpsOverlayParams(
udfpsBounds,
overlayBounds,
displayInfo.getNaturalWidth(),
displayInfo.getNaturalHeight(),
mScaleFactor,
- displayInfo.rotation,
- udfpsProps.sensorType == FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
+ displayInfo.rotation);
udfpsEnrollView.setOverlayParams(params);
@@ -1244,6 +1238,31 @@
return udfpsEnrollView;
}
+ private void setOnHoverListener(boolean isLandscape, GlifLayout enrollLayout,
+ UdfpsEnrollView udfpsEnrollView) {
+ if (!mIsAccessibilityEnabled) return;
+
+ final Context context = getApplicationContext();
+ final View.OnHoverListener onHoverListener = (v, event) -> {
+ // Map the touch to portrait mode if the device is in
+ // landscape mode.
+ final Point scaledTouch =
+ mUdfpsUtils.getTouchInNativeCoordinates(event.getPointerId(0),
+ event, udfpsEnrollView.getOverlayParams());
+
+ final String theStr = mUdfpsUtils.onTouchOutsideOfSensorArea(
+ mAccessibilityManager.isTouchExplorationEnabled(), context,
+ scaledTouch.x, scaledTouch.y, udfpsEnrollView.getOverlayParams());
+ if (theStr != null) {
+ v.announceForAccessibility(theStr);
+ }
+ return false;
+ };
+
+ enrollLayout.findManagedViewById(isLandscape ? R.id.sud_landscape_content_area
+ : R.id.sud_layout_content).setOnHoverListener(onHoverListener);
+ }
+
public static class IconTouchDialog extends InstrumentedDialogFragment {
@Override
diff --git a/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollView.java b/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollView.java
index 3d77f0e..96b49aa 100644
--- a/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollView.java
+++ b/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollView.java
@@ -25,7 +25,6 @@
import android.util.RotationUtils;
import android.view.Gravity;
import android.view.Surface;
-import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -34,11 +33,13 @@
import androidx.annotation.Nullable;
import com.android.settings.R;
+import com.android.settingslib.udfps.UdfpsOverlayParams;
/**
* View corresponding with udfps_enroll_view.xml
*/
public class UdfpsEnrollView extends FrameLayout implements UdfpsEnrollHelper.Listener {
+ private static final String TAG = "UdfpsEnrollView";
@NonNull
private final UdfpsEnrollDrawable mFingerprintDrawable;
@NonNull
@@ -98,12 +99,15 @@
onFingerDown();
}
-
@Override
public void onPointerUp(int sensorId) {
onFingerUp();
}
+ public UdfpsOverlayParams getOverlayParams() {
+ return mOverlayParams;
+ }
+
void setOverlayParams(UdfpsOverlayParams params) {
mOverlayParams = params;
@@ -124,7 +128,6 @@
private void onSensorRectUpdated() {
updateDimensions();
- updateAccessibilityViewLocation();
// Updates sensor rect in relation to the overlay view
mSensorRect.set(getPaddingX(), getPaddingY(),
@@ -135,7 +138,7 @@
private void updateDimensions() {
// Original sensorBounds assume portrait mode.
- final Rect rotatedBounds = mOverlayParams.getSensorBounds();
+ final Rect rotatedBounds = new Rect(mOverlayParams.getSensorBounds());
int rotation = mOverlayParams.getRotation();
if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
RotationUtils.rotateBounds(
@@ -192,27 +195,14 @@
setLayoutParams(params);
}
- private void updateAccessibilityViewLocation() {
- View fingerprintAccessibilityView = findViewById(R.id.udfps_enroll_accessibility_view);
- ViewGroup.LayoutParams params = fingerprintAccessibilityView.getLayoutParams();
- params.width = mOverlayParams.getSensorBounds().width();
- params.height = mOverlayParams.getSensorBounds().height();
- fingerprintAccessibilityView.setLayoutParams(params);
- fingerprintAccessibilityView.requestLayout();
- }
-
private void onFingerDown() {
- if (mOverlayParams.isOptical()) {
- mFingerprintDrawable.setShouldSkipDraw(true);
- mFingerprintDrawable.invalidateSelf();
- }
+ mFingerprintDrawable.setShouldSkipDraw(true);
+ mFingerprintDrawable.invalidateSelf();
}
private void onFingerUp() {
- if (mOverlayParams.isOptical()) {
- mFingerprintDrawable.setShouldSkipDraw(false);
- mFingerprintDrawable.invalidateSelf();
- }
+ mFingerprintDrawable.setShouldSkipDraw(false);
+ mFingerprintDrawable.invalidateSelf();
}
private int getPaddingX() {
diff --git a/src/com/android/settings/biometrics/fingerprint/UdfpsOverlayParams.java b/src/com/android/settings/biometrics/fingerprint/UdfpsOverlayParams.java
deleted file mode 100644
index 9b52ad6..0000000
--- a/src/com/android/settings/biometrics/fingerprint/UdfpsOverlayParams.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2022 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.graphics.Rect;
-
-import androidx.annotation.NonNull;
-
-/**
- * Collection of parameters that define an under-display fingerprint sensor (UDFPS) overlay.
- *
- * [sensorBounds] coordinates of the bounding box around the sensor in natural orientation, in
- * pixels, for the current resolution.
- *
- * [overlayBounds] coordinates of the UI overlay in natural orientation, in pixels, for the current
- * resolution.
- *
- * [naturalDisplayWidth] width of the physical display in natural orientation, in pixels, for the
- * current resolution.
- *
- * [naturalDisplayHeight] height of the physical display in natural orientation, in pixels, for the
- * current resolution.
- *
- * [scaleFactor] ratio of a dimension in the current resolution to the corresponding dimension in
- * the native resolution.
- *
- * [rotation] current rotation of the display.
- */
-public final class UdfpsOverlayParams {
- @NonNull
- private final Rect mSensorBounds;
- @NonNull
- private final Rect mOverlayBounds;
- private final int mNaturalDisplayWidth;
- private final int mNaturalDisplayHeight;
- private final float mScaleFactor;
- private final int mRotation;
- private final boolean mIsOptical;
-
- public UdfpsOverlayParams(@NonNull Rect sensorBounds, @NonNull Rect overlayBounds,
- int naturalDisplayWidth, int naturalDisplayHeight, float scaleFactor, int rotation,
- boolean isOptical) {
- mSensorBounds = sensorBounds;
- mOverlayBounds = overlayBounds;
- mNaturalDisplayWidth = naturalDisplayWidth;
- mNaturalDisplayHeight = naturalDisplayHeight;
- mScaleFactor = scaleFactor;
- mRotation = rotation;
- mIsOptical = isOptical;
- }
-
- @NonNull
- public Rect getSensorBounds() {
- return mSensorBounds;
- }
-
- @NonNull
- public Rect getOverlayBounds() {
- return mOverlayBounds;
- }
-
- public int getNaturalDisplayWidth() {
- return mNaturalDisplayWidth;
- }
-
- public int getNaturalDisplayHeight() {
- return mNaturalDisplayHeight;
- }
-
- public float getScaleFactor() {
- return mScaleFactor;
- }
-
- public int getRotation() {
- return mRotation;
- }
-
- public boolean isOptical() {
- return mIsOptical;
- }
-}