Merge changes I143f7e5d,I87fa7feb into tm-qpr-dev

* changes:
  Add ellipse detection to UdfpsController
  Extend UdfpsView to bottom half of screen
This commit is contained in:
Austin Delgado
2022-11-16 20:49:28 +00:00
committed by Android (Google) Code Review
13 changed files with 345 additions and 28 deletions

View File

@@ -37,6 +37,9 @@ public abstract class UdfpsAnimationView extends FrameLayout {
private float mDialogSuggestedAlpha = 1f;
private float mNotificationShadeExpansion = 0f;
// Used for Udfps ellipse detection when flag is true, set by AnimationViewController
boolean mUseExpandedOverlay = false;
// mAlpha takes into consideration the status bar expansion amount and dialog suggested alpha
private int mAlpha;
boolean mPauseAuth;
@@ -117,6 +120,24 @@ public abstract class UdfpsAnimationView extends FrameLayout {
return (int) ((1 - percent) * 255);
}
/**
* Converts coordinates of RectF relative to the screen to coordinates relative to this view.
*
* @param bounds RectF based off screen coordinates in current orientation
*/
RectF getBoundsRelativeToView(RectF bounds) {
int[] pos = getLocationOnScreen();
RectF output = new RectF(
bounds.left - pos[0],
bounds.top - pos[1],
bounds.right - pos[0],
bounds.bottom - pos[1]
);
return output;
}
/**
* Set the suggested alpha based on whether a dialog was recently shown or hidden.
* @param dialogSuggestedAlpha value from 0f to 1f.

View File

@@ -66,6 +66,7 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeReceiver;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
import com.android.systemui.plugins.FalsingManager;
@@ -149,7 +150,7 @@ public class UdfpsController implements DozeReceiver, Dumpable {
// TODO(b/229290039): UDFPS controller should manage its dimensions on its own. Remove this.
@Nullable private Runnable mAuthControllerUpdateUdfpsLocation;
@Nullable private final AlternateUdfpsTouchProvider mAlternateTouchProvider;
@Nullable private UdfpsDisplayMode mUdfpsDisplayMode;
@Nullable private UdfpsDisplayModeProvider mUdfpsDisplayMode;
// Tracks the velocity of a touch to help filter out the touches that move too fast.
@Nullable private VelocityTracker mVelocityTracker;
@@ -164,6 +165,7 @@ public class UdfpsController implements DozeReceiver, Dumpable {
// The current request from FingerprintService. Null if no current request.
@Nullable UdfpsControllerOverlay mOverlay;
@Nullable private UdfpsEllipseDetection mUdfpsEllipseDetection;
// The fingerprint AOD trigger doesn't provide an ACTION_UP/ACTION_CANCEL event to tell us when
// to turn off high brightness mode. To get around this limitation, the state of the AOD
@@ -320,6 +322,10 @@ public class UdfpsController implements DozeReceiver, Dumpable {
if (!mOverlayParams.equals(overlayParams)) {
mOverlayParams = overlayParams;
if (mFeatureFlags.isEnabled(Flags.UDFPS_ELLIPSE_DETECTION)) {
mUdfpsEllipseDetection.updateOverlayParams(overlayParams);
}
final boolean wasShowingAltAuth = mKeyguardViewManager.isShowingAlternateBouncer();
// When the bounds change it's always necessary to re-create the overlay's window with
@@ -459,8 +465,23 @@ public class UdfpsController implements DozeReceiver, Dumpable {
mVelocityTracker.clear();
}
boolean withinSensorArea =
boolean withinSensorArea;
if (mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)) {
if (mFeatureFlags.isEnabled(Flags.UDFPS_ELLIPSE_DETECTION)) {
// Ellipse detection
withinSensorArea = mUdfpsEllipseDetection.isGoodEllipseOverlap(event);
} else {
// Centroid with expanded overlay
withinSensorArea =
isWithinSensorArea(udfpsView, event.getRawX(),
event.getRawY(), fromUdfpsView);
}
} else {
// Centroid with sensor sized view
withinSensorArea =
isWithinSensorArea(udfpsView, event.getX(), event.getY(), fromUdfpsView);
}
if (withinSensorArea) {
Trace.beginAsyncSection("UdfpsController.e2e.onPointerDown", 0);
Log.v(TAG, "onTouch | action down");
@@ -491,9 +512,25 @@ public class UdfpsController implements DozeReceiver, Dumpable {
? event.getPointerId(0)
: event.findPointerIndex(mActivePointerId);
if (idx == event.getActionIndex()) {
boolean actionMoveWithinSensorArea =
isWithinSensorArea(udfpsView, event.getX(idx), event.getY(idx),
fromUdfpsView);
boolean actionMoveWithinSensorArea;
if (mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)) {
if (mFeatureFlags.isEnabled(Flags.UDFPS_ELLIPSE_DETECTION)) {
// Ellipse detection
actionMoveWithinSensorArea =
mUdfpsEllipseDetection.isGoodEllipseOverlap(event);
} else {
// Centroid with expanded overlay
actionMoveWithinSensorArea =
isWithinSensorArea(udfpsView, event.getRawX(idx),
event.getRawY(idx), fromUdfpsView);
}
} else {
// Centroid with sensor sized view
actionMoveWithinSensorArea =
isWithinSensorArea(udfpsView, event.getX(idx),
event.getY(idx), fromUdfpsView);
}
if ((fromUdfpsView || actionMoveWithinSensorArea)
&& shouldTryToDismissKeyguard()) {
Log.v(TAG, "onTouch | dismiss keyguard ACTION_MOVE");
@@ -691,6 +728,10 @@ public class UdfpsController implements DozeReceiver, Dumpable {
udfpsHapticsSimulator.setUdfpsController(this);
udfpsShell.setUdfpsOverlayController(mUdfpsOverlayController);
if (featureFlags.isEnabled(Flags.UDFPS_ELLIPSE_DETECTION)) {
mUdfpsEllipseDetection = new UdfpsEllipseDetection(mOverlayParams);
}
}
/**

View File

@@ -49,6 +49,7 @@ import com.android.systemui.R
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.dump.DumpManager
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.shade.ShadeExpansionStateManager
@@ -103,6 +104,7 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
private set
private var overlayParams: UdfpsOverlayParams = UdfpsOverlayParams()
private var sensorBounds: Rect = Rect()
private var overlayTouchListener: TouchExplorationStateChangeListener? = null
@@ -120,6 +122,10 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY
// Avoid announcing window title.
accessibilityTitle = " "
if (featureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)) {
inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY
}
}
/** A helper if the [requestReason] was due to enrollment. */
@@ -160,6 +166,7 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
fun show(controller: UdfpsController, params: UdfpsOverlayParams): Boolean {
if (overlayView == null) {
overlayParams = params
sensorBounds = Rect(params.sensorBounds)
try {
overlayView = (inflater.inflate(
R.layout.udfps_view, null, false
@@ -178,6 +185,7 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
}
windowManager.addView(this, coreLayoutParams.updateDimensions(animation))
sensorRect = sensorBounds
touchExplorationEnabled = accessibilityManager.isTouchExplorationEnabled
overlayTouchListener = TouchExplorationStateChangeListener {
if (accessibilityManager.isTouchExplorationEnabled) {
@@ -194,6 +202,7 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
overlayTouchListener!!
)
overlayTouchListener?.onTouchExplorationStateChanged(true)
useExpandedOverlay = featureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)
}
} catch (e: RuntimeException) {
Log.e(TAG, "showUdfpsOverlay | failed to add window", e)
@@ -225,13 +234,14 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
REASON_ENROLL_ENROLLING -> {
UdfpsEnrollViewController(
view.addUdfpsView(R.layout.udfps_enroll_view) {
updateSensorLocation(overlayParams.sensorBounds)
updateSensorLocation(sensorBounds)
},
enrollHelper ?: throw IllegalStateException("no enrollment helper"),
statusBarStateController,
shadeExpansionStateManager,
dialogManager,
dumpManager,
featureFlags,
overlayParams.scaleFactor
)
}
@@ -420,7 +430,12 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
}
// Original sensorBounds assume portrait mode.
val rotatedSensorBounds = Rect(overlayParams.sensorBounds)
var rotatedBounds =
if (featureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)) {
Rect(overlayParams.overlayBounds)
} else {
Rect(overlayParams.sensorBounds)
}
val rot = overlayParams.rotation
if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
@@ -434,18 +449,27 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
} else {
Log.v(TAG, "Rotate UDFPS bounds " + Surface.rotationToString(rot))
RotationUtils.rotateBounds(
rotatedSensorBounds,
rotatedBounds,
overlayParams.naturalDisplayWidth,
overlayParams.naturalDisplayHeight,
rot
)
if (featureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)) {
RotationUtils.rotateBounds(
sensorBounds,
overlayParams.naturalDisplayWidth,
overlayParams.naturalDisplayHeight,
rot
)
}
}
}
x = rotatedSensorBounds.left - paddingX
y = rotatedSensorBounds.top - paddingY
height = rotatedSensorBounds.height() + 2 * paddingX
width = rotatedSensorBounds.width() + 2 * paddingY
x = rotatedBounds.left - paddingX
y = rotatedBounds.top - paddingY
height = rotatedBounds.height() + 2 * paddingX
width = rotatedBounds.width() + 2 * paddingY
return this
}

View File

@@ -0,0 +1,92 @@
/*
* 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.systemui.biometrics
import android.graphics.Point
import android.graphics.Rect
import android.util.RotationUtils
import android.view.MotionEvent
import kotlin.math.cos
import kotlin.math.pow
import kotlin.math.sin
private const val TAG = "UdfpsEllipseDetection"
private const val NEEDED_POINTS = 2
class UdfpsEllipseDetection(overlayParams: UdfpsOverlayParams) {
var sensorRect = Rect()
var points: Array<Point> = emptyArray()
init {
sensorRect = Rect(overlayParams.sensorBounds)
points = calculateSensorPoints(sensorRect)
}
fun updateOverlayParams(params: UdfpsOverlayParams) {
sensorRect = Rect(params.sensorBounds)
val rot = params.rotation
RotationUtils.rotateBounds(
sensorRect,
params.naturalDisplayWidth,
params.naturalDisplayHeight,
rot
)
points = calculateSensorPoints(sensorRect)
}
fun isGoodEllipseOverlap(event: MotionEvent): Boolean {
return points.count { checkPoint(event, it) } >= NEEDED_POINTS
}
private fun checkPoint(event: MotionEvent, point: Point): Boolean {
// Calculate if sensor point is within ellipse
// Formula: ((cos(o)(xE - xS) + sin(o)(yE - yS))^2 / a^2) + ((sin(o)(xE - xS) + cos(o)(yE -
// yS))^2 / b^2) <= 1
val a: Float = cos(event.orientation) * (point.x - event.rawX)
val b: Float = sin(event.orientation) * (point.y - event.rawY)
val c: Float = sin(event.orientation) * (point.x - event.rawX)
val d: Float = cos(event.orientation) * (point.y - event.rawY)
val result =
(a + b).pow(2) / (event.touchMinor / 2).pow(2) +
(c - d).pow(2) / (event.touchMajor / 2).pow(2)
return result <= 1
}
}
fun calculateSensorPoints(sensorRect: Rect): Array<Point> {
val sensorX = sensorRect.centerX()
val sensorY = sensorRect.centerY()
val cornerOffset: Int = sensorRect.width() / 4
val sideOffset: Int = sensorRect.width() / 3
return arrayOf(
Point(sensorX - cornerOffset, sensorY - cornerOffset),
Point(sensorX, sensorY - sideOffset),
Point(sensorX + cornerOffset, sensorY - cornerOffset),
Point(sensorX - sideOffset, sensorY),
Point(sensorX, sensorY),
Point(sensorX + sideOffset, sensorY),
Point(sensorX - cornerOffset, sensorY + cornerOffset),
Point(sensorX, sensorY + sideOffset),
Point(sensorX + cornerOffset, sensorY + cornerOffset)
)
}

View File

@@ -18,6 +18,7 @@ package com.android.systemui.biometrics;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
@@ -41,6 +42,9 @@ public class UdfpsEnrollView extends UdfpsAnimationView {
@NonNull private ImageView mFingerprintView;
@NonNull private ImageView mFingerprintProgressView;
private LayoutParams mProgressParams;
private float mProgressBarRadius;
public UdfpsEnrollView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mFingerprintDrawable = new UdfpsEnrollDrawable(mContext, attrs);
@@ -56,6 +60,32 @@ public class UdfpsEnrollView extends UdfpsAnimationView {
mFingerprintProgressView.setImageDrawable(mFingerprintProgressDrawable);
}
@Override
void onSensorRectUpdated(RectF bounds) {
if (mUseExpandedOverlay) {
RectF converted = getBoundsRelativeToView(bounds);
mProgressParams = new LayoutParams(
(int) (converted.width() + mProgressBarRadius * 2),
(int) (converted.height() + mProgressBarRadius * 2));
mProgressParams.setMargins(
(int) (converted.left - mProgressBarRadius),
(int) (converted.top - mProgressBarRadius),
(int) (converted.right + mProgressBarRadius),
(int) (converted.bottom + mProgressBarRadius)
);
mFingerprintProgressView.setLayoutParams(mProgressParams);
super.onSensorRectUpdated(converted);
} else {
super.onSensorRectUpdated(bounds);
}
}
void setProgressBarRadius(float radius) {
mProgressBarRadius = radius;
}
@Override
public UdfpsDrawable getDrawable() {
return mFingerprintDrawable;

View File

@@ -21,6 +21,8 @@ import android.graphics.PointF;
import com.android.systemui.R;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.statusbar.phone.SystemUIDialogManager;
@@ -57,6 +59,7 @@ public class UdfpsEnrollViewController extends UdfpsAnimationViewController<Udfp
@NonNull ShadeExpansionStateManager shadeExpansionStateManager,
@NonNull SystemUIDialogManager systemUIDialogManager,
@NonNull DumpManager dumpManager,
@NonNull FeatureFlags featureFlags,
float scaleFactor) {
super(view, statusBarStateController, shadeExpansionStateManager, systemUIDialogManager,
dumpManager);
@@ -64,6 +67,11 @@ public class UdfpsEnrollViewController extends UdfpsAnimationViewController<Udfp
R.integer.config_udfpsEnrollProgressBar));
mEnrollHelper = enrollHelper;
mView.setEnrollHelper(mEnrollHelper);
mView.setProgressBarRadius(mEnrollProgressBarRadius);
if (featureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)) {
mView.mUseExpandedOverlay = true;
}
}
@Override

View File

@@ -26,6 +26,7 @@ import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.MathUtils;
import android.view.View;
@@ -75,6 +76,8 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
private int mAnimationType = ANIMATION_NONE;
private boolean mFullyInflated;
private LayoutParams mParams;
public UdfpsKeyguardView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mFingerprintDrawable = new UdfpsFpDrawable(context);
@@ -239,6 +242,22 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
updateAlpha();
}
@Override
void onSensorRectUpdated(RectF bounds) {
super.onSensorRectUpdated(bounds);
if (mUseExpandedOverlay) {
mParams = new LayoutParams((int) bounds.width(), (int) bounds.height());
RectF converted = getBoundsRelativeToView(bounds);
mParams.setMargins(
(int) converted.left,
(int) converted.top,
(int) converted.right,
(int) converted.bottom
);
}
}
/**
* Animates in the bg protection circle behind the fp icon to highlight the icon.
*/
@@ -277,6 +296,7 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
pw.println(" mUdfpsRequested=" + mUdfpsRequested);
pw.println(" mInterpolatedDarkAmount=" + mInterpolatedDarkAmount);
pw.println(" mAnimationType=" + mAnimationType);
pw.println(" mUseExpandedOverlay=" + mUseExpandedOverlay);
}
private final AsyncLayoutInflater.OnInflateFinishedListener mLayoutInflaterFinishListener =
@@ -291,7 +311,12 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
updatePadding();
updateColor();
updateAlpha();
parent.addView(view);
if (mUseExpandedOverlay) {
parent.addView(view, mParams);
} else {
parent.addView(view);
}
// requires call to invalidate to update the color
mLockScreenFp.addValueCallback(

View File

@@ -52,7 +52,6 @@ import com.android.systemui.util.time.SystemClock
import java.io.PrintWriter
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
/** Class that coordinates non-HBM animations during keyguard authentication. */
@@ -82,6 +81,8 @@ constructor(
systemUIDialogManager,
dumpManager
) {
private val useExpandedOverlay: Boolean =
featureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)
private val isModernBouncerEnabled: Boolean = featureFlags.isEnabled(Flags.MODERN_BOUNCER)
private var showingUdfpsBouncer = false
private var udfpsRequested = false
@@ -233,7 +234,13 @@ constructor(
if (transitionToFullShadeProgress != 0f) {
return
}
udfpsController.onTouch(event)
// Forwarding touches not needed with expanded overlay
if (useExpandedOverlay) {
return
} else {
udfpsController.onTouch(event)
}
}
}
@@ -322,6 +329,7 @@ constructor(
keyguardViewManager.setAlternateBouncer(mAlternateBouncer)
lockScreenShadeTransitionController.udfpsKeyguardViewController = this
activityLaunchAnimator.addListener(activityLaunchAnimatorListener)
view.mUseExpandedOverlay = useExpandedOverlay
}
override fun onViewDetached() {

View File

@@ -20,6 +20,7 @@ import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.PointF
import android.graphics.Rect
import android.graphics.RectF
import android.util.AttributeSet
import android.util.Log
@@ -38,9 +39,12 @@ class UdfpsView(
attrs: AttributeSet?
) : FrameLayout(context, attrs), DozeReceiver {
// Use expanded overlay when feature flag is true, set by UdfpsViewController
var useExpandedOverlay: Boolean = false
// sensorRect may be bigger than the sensor. True sensor dimensions are defined in
// overlayParams.sensorBounds
private val sensorRect = RectF()
var sensorRect = Rect()
private var mUdfpsDisplayMode: UdfpsDisplayModeProvider? = null
private val debugTextPaint = Paint().apply {
isAntiAlias = true
@@ -92,13 +96,19 @@ class UdfpsView(
val paddingX = animationViewController?.paddingX ?: 0
val paddingY = animationViewController?.paddingY ?: 0
sensorRect.set(
paddingX.toFloat(),
paddingY.toFloat(),
(overlayParams.sensorBounds.width() + paddingX).toFloat(),
(overlayParams.sensorBounds.height() + paddingY).toFloat()
)
animationViewController?.onSensorRectUpdated(RectF(sensorRect))
// Updates sensor rect in relation to the overlay view
if (useExpandedOverlay) {
animationViewController?.onSensorRectUpdated(RectF(sensorRect))
} else {
sensorRect.set(
paddingX,
paddingY,
(overlayParams.sensorBounds.width() + paddingX),
(overlayParams.sensorBounds.height() + paddingY)
)
animationViewController?.onSensorRectUpdated(RectF(sensorRect))
}
}
fun onTouchOutsideView() {

View File

@@ -405,4 +405,10 @@ object Flags {
// 2100 - Falsing Manager
@JvmField val FALSING_FOR_LONG_TAPS = releasedFlag(2100, "falsing_for_long_taps")
// 2200 - udfps
// TODO(b/259264861): Tracking Bug
@JvmField val UDFPS_NEW_TOUCH_DETECTION = unreleasedFlag(2200, "udfps_new_touch_detection")
@JvmField val UDFPS_ELLIPSE_DEBUG_UI = unreleasedFlag(2201, "udfps_ellipse_debug")
@JvmField val UDFPS_ELLIPSE_DETECTION = unreleasedFlag(2202, "udfps_ellipse_detection")
}

View File

@@ -94,6 +94,11 @@ public class UdfpsKeyguardViewControllerBaseTest extends SysuiTestCase {
mKeyguardStateControllerCallbackCaptor;
protected KeyguardStateController.Callback mKeyguardStateControllerCallback;
private @Captor ArgumentCaptor<StatusBarKeyguardViewManager.KeyguardViewManagerCallback>
mKeyguardViewManagerCallbackArgumentCaptor;
protected StatusBarKeyguardViewManager.KeyguardViewManagerCallback mKeyguardViewManagerCallback;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -143,15 +148,22 @@ public class UdfpsKeyguardViewControllerBaseTest extends SysuiTestCase {
}
public UdfpsKeyguardViewController createUdfpsKeyguardViewController() {
return createUdfpsKeyguardViewController(false);
return createUdfpsKeyguardViewController(false, false);
}
public void captureKeyGuardViewManagerCallback() {
verify(mStatusBarKeyguardViewManager).addCallback(
mKeyguardViewManagerCallbackArgumentCaptor.capture());
mKeyguardViewManagerCallback = mKeyguardViewManagerCallbackArgumentCaptor.getValue();
}
protected UdfpsKeyguardViewController createUdfpsKeyguardViewController(
boolean useModernBouncer) {
boolean useModernBouncer, boolean useExpandedOverlay) {
mFeatureFlags.set(Flags.MODERN_BOUNCER, useModernBouncer);
mFeatureFlags.set(Flags.UDFPS_NEW_TOUCH_DETECTION, useExpandedOverlay);
when(mStatusBarKeyguardViewManager.getPrimaryBouncer()).thenReturn(
useModernBouncer ? null : mBouncer);
return new UdfpsKeyguardViewController(
UdfpsKeyguardViewController controller = new UdfpsKeyguardViewController(
mView,
mStatusBarStateController,
mShadeExpansionStateManager,
@@ -168,5 +180,6 @@ public class UdfpsKeyguardViewControllerBaseTest extends SysuiTestCase {
mActivityLaunchAnimator,
mFeatureFlags,
mPrimaryBouncerInteractor);
return controller;
}
}

View File

@@ -18,6 +18,7 @@ package com.android.systemui.biometrics;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.atLeast;
@@ -30,6 +31,7 @@ import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import android.view.MotionEvent;
import androidx.test.filters.SmallTest;
@@ -52,7 +54,8 @@ public class UdfpsKeyguardViewControllerTest extends UdfpsKeyguardViewController
@Override
public UdfpsKeyguardViewController createUdfpsKeyguardViewController() {
return createUdfpsKeyguardViewController(/* useModernBouncer */ false);
return createUdfpsKeyguardViewController(/* useModernBouncer */ false,
/* useExpandedOverlay */ false);
}
@Test
@@ -422,4 +425,37 @@ public class UdfpsKeyguardViewControllerTest extends UdfpsKeyguardViewController
verify(mBouncer).addBouncerExpansionCallback(mBouncerExpansionCallbackCaptor.capture());
mBouncerExpansionCallback = mBouncerExpansionCallbackCaptor.getValue();
}
@Test
// TODO(b/259264861): Tracking Bug
public void testUdfpsExpandedOverlayOn() {
// GIVEN view is attached and useExpandedOverlay is true
mController = createUdfpsKeyguardViewController(false, true);
mController.onViewAttached();
captureKeyGuardViewManagerCallback();
// WHEN a touch is received
mKeyguardViewManagerCallback.onTouch(
MotionEvent.obtain(0, 0, 0, 0, 0, 0));
// THEN udfpsController onTouch is not called
assertTrue(mView.mUseExpandedOverlay);
verify(mUdfpsController, never()).onTouch(any());
}
@Test
// TODO(b/259264861): Tracking Bug
public void testUdfpsExpandedOverlayOff() {
// GIVEN view is attached and useExpandedOverlay is false
mController.onViewAttached();
captureKeyGuardViewManagerCallback();
// WHEN a touch is received
mKeyguardViewManagerCallback.onTouch(
MotionEvent.obtain(0, 0, 0, 0, 0, 0));
// THEN udfpsController onTouch is called
assertFalse(mView.mUseExpandedOverlay);
verify(mUdfpsController).onTouch(any());
}
}

View File

@@ -72,7 +72,10 @@ class UdfpsKeyguardViewControllerWithCoroutinesTest : UdfpsKeyguardViewControlle
mock(KeyguardBypassController::class.java),
mKeyguardUpdateMonitor
)
return createUdfpsKeyguardViewController(/* useModernBouncer */ true)
return createUdfpsKeyguardViewController(
/* useModernBouncer */ true, /* useExpandedOverlay */
false
)
}
/** After migration, replaces LockIconViewControllerTest version */