Merge "Add udfps/ and support a11y for the udfps enroll view."
This commit is contained in:
@@ -32,6 +32,7 @@ import android.content.Intent;
|
||||
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.AnimatedVectorDrawable;
|
||||
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.VibrationAttributes;
|
||||
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.BiometricUtils;
|
||||
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 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
||||
private boolean mHaveShownSfpsLeftEdgeLottie;
|
||||
private boolean mHaveShownSfpsRightEdgeLottie;
|
||||
private boolean mShouldShowLottie;
|
||||
private UdfpsUtils mUdfpsUtils;
|
||||
|
||||
private OrientationEventListener mOrientationEventListener;
|
||||
private int mPreviousRotation = 0;
|
||||
@@ -254,6 +255,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
||||
|
||||
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 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
||||
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 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
||||
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 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
||||
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 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
||||
|
||||
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 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
||||
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 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
||||
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
|
||||
|
@@ -25,7 +25,6 @@ import android.util.AttributeSet;
|
||||
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.NonNull;
|
||||
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 @@ public class UdfpsEnrollView extends FrameLayout implements UdfpsEnrollHelper.Li
|
||||
onFingerDown();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPointerUp(int sensorId) {
|
||||
onFingerUp();
|
||||
}
|
||||
|
||||
public UdfpsOverlayParams getOverlayParams() {
|
||||
return mOverlayParams;
|
||||
}
|
||||
|
||||
void setOverlayParams(UdfpsOverlayParams params) {
|
||||
mOverlayParams = params;
|
||||
|
||||
@@ -124,7 +128,6 @@ public class UdfpsEnrollView extends FrameLayout implements UdfpsEnrollHelper.Li
|
||||
|
||||
private void onSensorRectUpdated() {
|
||||
updateDimensions();
|
||||
updateAccessibilityViewLocation();
|
||||
|
||||
// Updates sensor rect in relation to the overlay view
|
||||
mSensorRect.set(getPaddingX(), getPaddingY(),
|
||||
@@ -135,7 +138,7 @@ public class UdfpsEnrollView extends FrameLayout implements UdfpsEnrollHelper.Li
|
||||
|
||||
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 @@ public class UdfpsEnrollView extends FrameLayout implements UdfpsEnrollHelper.Li
|
||||
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() {
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user