Merge "Refactor UDFPS display logic and remove illumination" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
1ecaa4d68e
@@ -315,17 +315,17 @@ public interface BiometricFingerprintConstants {
|
|||||||
int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
|
int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the FingerprintAcquired message is a signal to turn off HBM
|
* Whether the FingerprintAcquired message is a signal to disable the UDFPS display mode.
|
||||||
|
* We want to disable the UDFPS mode as soon as possible to conserve power and provide better
|
||||||
|
* UX. For example, prolonged high-brightness illumination of optical sensors can be unpleasant
|
||||||
|
* to the user, can cause long term display burn-in, and can drain the battery faster.
|
||||||
*/
|
*/
|
||||||
static boolean shouldTurnOffHbm(@FingerprintAcquired int acquiredInfo) {
|
static boolean shouldDisableUdfpsDisplayMode(@FingerprintAcquired int acquiredInfo) {
|
||||||
switch (acquiredInfo) {
|
switch (acquiredInfo) {
|
||||||
case FINGERPRINT_ACQUIRED_START:
|
case FINGERPRINT_ACQUIRED_START:
|
||||||
// Authentication just began
|
// Keep the UDFPS mode because the authentication just began.
|
||||||
return false;
|
return false;
|
||||||
case FINGERPRINT_ACQUIRED_GOOD:
|
case FINGERPRINT_ACQUIRED_GOOD:
|
||||||
// Good image captured. Turn off HBM. Success/Reject comes after, which is when
|
|
||||||
// hideUdfpsOverlay will be called.
|
|
||||||
return true;
|
|
||||||
case FINGERPRINT_ACQUIRED_PARTIAL:
|
case FINGERPRINT_ACQUIRED_PARTIAL:
|
||||||
case FINGERPRINT_ACQUIRED_INSUFFICIENT:
|
case FINGERPRINT_ACQUIRED_INSUFFICIENT:
|
||||||
case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
|
case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
|
||||||
@@ -334,11 +334,12 @@ public interface BiometricFingerprintConstants {
|
|||||||
case FINGERPRINT_ACQUIRED_IMMOBILE:
|
case FINGERPRINT_ACQUIRED_IMMOBILE:
|
||||||
case FINGERPRINT_ACQUIRED_TOO_BRIGHT:
|
case FINGERPRINT_ACQUIRED_TOO_BRIGHT:
|
||||||
case FINGERPRINT_ACQUIRED_VENDOR:
|
case FINGERPRINT_ACQUIRED_VENDOR:
|
||||||
// Bad image captured. Turn off HBM. Matcher will not run, so there's no need to
|
// Disable the UDFPS mode because the image capture has finished. The overlay
|
||||||
// keep HBM on.
|
// can be hidden later, once the authentication result arrives.
|
||||||
return true;
|
return true;
|
||||||
case FINGERPRINT_ACQUIRED_UNKNOWN:
|
case FINGERPRINT_ACQUIRED_UNKNOWN:
|
||||||
default:
|
default:
|
||||||
|
// Keep the UDFPS mode in case of an unknown message.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4877,9 +4877,6 @@
|
|||||||
-->
|
-->
|
||||||
</array>
|
</array>
|
||||||
|
|
||||||
<!-- How long it takes for the HW to start illuminating after the illumination is requested. -->
|
|
||||||
<integer name="config_udfps_illumination_transition_ms">50</integer>
|
|
||||||
|
|
||||||
<!-- Indicates whether device has a power button fingerprint sensor. -->
|
<!-- Indicates whether device has a power button fingerprint sensor. -->
|
||||||
<bool name="config_is_powerbutton_fps" translatable="false" >false</bool>
|
<bool name="config_is_powerbutton_fps" translatable="false" >false</bool>
|
||||||
|
|
||||||
|
|||||||
@@ -2706,7 +2706,6 @@
|
|||||||
<java-symbol type="bool" name="allow_test_udfps" />
|
<java-symbol type="bool" name="allow_test_udfps" />
|
||||||
<java-symbol type="array" name="config_udfps_sensor_props" />
|
<java-symbol type="array" name="config_udfps_sensor_props" />
|
||||||
<java-symbol type="array" name="config_sfps_sensor_props" />
|
<java-symbol type="array" name="config_sfps_sensor_props" />
|
||||||
<java-symbol type="integer" name="config_udfps_illumination_transition_ms" />
|
|
||||||
<java-symbol type="bool" name="config_is_powerbutton_fps" />
|
<java-symbol type="bool" name="config_is_powerbutton_fps" />
|
||||||
<java-symbol type="array" name="config_udfps_enroll_stage_thresholds" />
|
<java-symbol type="array" name="config_udfps_enroll_stage_thresholds" />
|
||||||
<java-symbol type="array" name="config_sfps_enroll_stage_thresholds" />
|
<java-symbol type="array" name="config_sfps_enroll_stage_thresholds" />
|
||||||
|
|||||||
@@ -291,7 +291,6 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
mUdfpsController.setAuthControllerUpdateUdfpsLocation(this::updateUdfpsLocation);
|
mUdfpsController.setAuthControllerUpdateUdfpsLocation(this::updateUdfpsLocation);
|
||||||
mUdfpsController.setHalControlsIllumination(mUdfpsProps.get(0).halControlsIllumination);
|
|
||||||
mUdfpsBounds = mUdfpsProps.get(0).getLocation().getRect();
|
mUdfpsBounds = mUdfpsProps.get(0).getLocation().getRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ class AuthRippleController @Inject constructor(
|
|||||||
acquireInfo: Int
|
acquireInfo: Int
|
||||||
) {
|
) {
|
||||||
if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
|
if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
|
||||||
BiometricFingerprintConstants.shouldTurnOffHbm(acquireInfo) &&
|
BiometricFingerprintConstants.shouldDisableUdfpsDisplayMode(acquireInfo) &&
|
||||||
acquireInfo != BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) {
|
acquireInfo != BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) {
|
||||||
// received an 'acquiredBad' message, so immediately retract
|
// received an 'acquiredBad' message, so immediately retract
|
||||||
mView.retractDwellRipple()
|
mView.retractDwellRipple()
|
||||||
|
|||||||
@@ -54,13 +54,13 @@ public abstract class UdfpsAnimationView extends FrameLayout {
|
|||||||
getDrawable().onSensorRectUpdated(bounds);
|
getDrawable().onSensorRectUpdated(bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onIlluminationStarting() {
|
void onDisplayConfiguring() {
|
||||||
getDrawable().setIlluminationShowing(true);
|
getDrawable().setDisplayConfigured(true);
|
||||||
getDrawable().invalidateSelf();
|
getDrawable().invalidateSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onIlluminationStopped() {
|
void onDisplayUnconfigured() {
|
||||||
getDrawable().setIlluminationShowing(false);
|
getDrawable().setDisplayConfigured(false);
|
||||||
getDrawable().invalidateSelf();
|
getDrawable().invalidateSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ import java.io.PrintWriter
|
|||||||
/**
|
/**
|
||||||
* Handles:
|
* Handles:
|
||||||
* 1. registering for listeners when its view is attached and unregistering on view detached
|
* 1. registering for listeners when its view is attached and unregistering on view detached
|
||||||
* 2. pausing udfps when fingerprintManager may still be running but we temporarily want to hide
|
* 2. pausing UDFPS when FingerprintManager may still be running but we temporarily want to hide
|
||||||
* the affordance. this allows us to fade the view in and out nicely (see shouldPauseAuth)
|
* the affordance. this allows us to fade the view in and out nicely (see shouldPauseAuth)
|
||||||
* 3. sending events to its view including:
|
* 3. sending events to its view including:
|
||||||
* - illumination events
|
* - enabling and disabling of the UDFPS display mode
|
||||||
* - sensor position changes
|
* - sensor position changes
|
||||||
* - doze time event
|
* - doze time event
|
||||||
*/
|
*/
|
||||||
@@ -167,19 +167,20 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Udfps has started illuminating and the fingerprint manager is working on authenticating.
|
* The display began transitioning into the UDFPS mode and the fingerprint manager started
|
||||||
|
* authenticating.
|
||||||
*/
|
*/
|
||||||
fun onIlluminationStarting() {
|
fun onDisplayConfiguring() {
|
||||||
view.onIlluminationStarting()
|
view.onDisplayConfiguring()
|
||||||
view.postInvalidate()
|
view.postInvalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Udfps has stopped illuminating and the fingerprint manager is no longer attempting to
|
* The display transitioned away from the UDFPS mode and the fingerprint manager stopped
|
||||||
* authenticate.
|
* authenticating.
|
||||||
*/
|
*/
|
||||||
fun onIlluminationStopped() {
|
fun onDisplayUnconfigured() {
|
||||||
view.onIlluminationStopped()
|
view.onDisplayUnconfigured()
|
||||||
view.postInvalidate()
|
view.postInvalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,4 +198,4 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>(
|
|||||||
* Called when a view should announce an accessibility event.
|
* Called when a view should announce an accessibility event.
|
||||||
*/
|
*/
|
||||||
open fun doAnnounceForAccessibility(str: String) {}
|
open fun doAnnounceForAccessibility(str: String) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ import kotlin.Unit;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows and hides the under-display fingerprint sensor (UDFPS) overlay, handles UDFPS touch events,
|
* Shows and hides the under-display fingerprint sensor (UDFPS) overlay, handles UDFPS touch events,
|
||||||
* and coordinates triggering of the high-brightness mode (HBM).
|
* and toggles the UDFPS display mode.
|
||||||
*
|
*
|
||||||
* Note that the current architecture is designed so that a single {@link UdfpsController}
|
* Note that the current architecture is designed so that a single {@link UdfpsController}
|
||||||
* controls/manages all UDFPS sensors. In other words, a single controller is registered with
|
* controls/manages all UDFPS sensors. In other words, a single controller is registered with
|
||||||
@@ -123,7 +123,7 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
@NonNull private final PowerManager mPowerManager;
|
@NonNull private final PowerManager mPowerManager;
|
||||||
@NonNull private final AccessibilityManager mAccessibilityManager;
|
@NonNull private final AccessibilityManager mAccessibilityManager;
|
||||||
@NonNull private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
|
@NonNull private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
|
||||||
@Nullable private final UdfpsHbmProvider mHbmProvider;
|
@Nullable private final UdfpsDisplayModeProvider mUdfpsDisplayMode;
|
||||||
@NonNull private final ConfigurationController mConfigurationController;
|
@NonNull private final ConfigurationController mConfigurationController;
|
||||||
@NonNull private final SystemClock mSystemClock;
|
@NonNull private final SystemClock mSystemClock;
|
||||||
@NonNull private final UnlockedScreenOffAnimationController
|
@NonNull private final UnlockedScreenOffAnimationController
|
||||||
@@ -135,7 +135,6 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
// Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
|
// Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
|
||||||
// sensors, this, in addition to a lot of the code here, will be updated.
|
// sensors, this, in addition to a lot of the code here, will be updated.
|
||||||
@VisibleForTesting int mSensorId;
|
@VisibleForTesting int mSensorId;
|
||||||
private boolean mHalControlsIllumination;
|
|
||||||
@VisibleForTesting @NonNull UdfpsOverlayParams mOverlayParams = new UdfpsOverlayParams();
|
@VisibleForTesting @NonNull UdfpsOverlayParams mOverlayParams = new UdfpsOverlayParams();
|
||||||
// TODO(b/229290039): UDFPS controller should manage its dimensions on its own. Remove this.
|
// TODO(b/229290039): UDFPS controller should manage its dimensions on its own. Remove this.
|
||||||
@Nullable private Runnable mAuthControllerUpdateUdfpsLocation;
|
@Nullable private Runnable mAuthControllerUpdateUdfpsLocation;
|
||||||
@@ -147,10 +146,9 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
private int mActivePointerId = -1;
|
private int mActivePointerId = -1;
|
||||||
// The timestamp of the most recent touch log.
|
// The timestamp of the most recent touch log.
|
||||||
private long mTouchLogTime;
|
private long mTouchLogTime;
|
||||||
// Sensor has a capture (good or bad) for this touch. Do not need to illuminate for this
|
// Sensor has a capture (good or bad) for this touch. No need to enable the UDFPS display mode
|
||||||
// particular touch event anymore. In other words, do not illuminate until user lifts and
|
// anymore for this particular touch event. In other words, do not enable the UDFPS mode until
|
||||||
// touches the sensor area again.
|
// the user touches the sensor area again.
|
||||||
// TODO: We should probably try to make touch/illumination things more of a FSM
|
|
||||||
private boolean mAcquiredReceived;
|
private boolean mAcquiredReceived;
|
||||||
|
|
||||||
// The current request from FingerprintService. Null if no current request.
|
// The current request from FingerprintService. Null if no current request.
|
||||||
@@ -211,8 +209,8 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
mKeyguardUpdateMonitor, mDialogManager, mDumpManager,
|
mKeyguardUpdateMonitor, mDialogManager, mDumpManager,
|
||||||
mLockscreenShadeTransitionController, mConfigurationController,
|
mLockscreenShadeTransitionController, mConfigurationController,
|
||||||
mSystemClock, mKeyguardStateController,
|
mSystemClock, mKeyguardStateController,
|
||||||
mUnlockedScreenOffAnimationController, mHalControlsIllumination,
|
mUnlockedScreenOffAnimationController,
|
||||||
mHbmProvider, requestId, reason, callback,
|
mUdfpsDisplayMode, requestId, reason, callback,
|
||||||
(view, event, fromUdfpsView) -> onTouch(requestId, event,
|
(view, event, fromUdfpsView) -> onTouch(requestId, event,
|
||||||
fromUdfpsView), mActivityLaunchAnimator)));
|
fromUdfpsView), mActivityLaunchAnimator)));
|
||||||
}
|
}
|
||||||
@@ -236,7 +234,7 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
int sensorId,
|
int sensorId,
|
||||||
@BiometricFingerprintConstants.FingerprintAcquired int acquiredInfo
|
@BiometricFingerprintConstants.FingerprintAcquired int acquiredInfo
|
||||||
) {
|
) {
|
||||||
if (BiometricFingerprintConstants.shouldTurnOffHbm(acquiredInfo)) {
|
if (BiometricFingerprintConstants.shouldDisableUdfpsDisplayMode(acquiredInfo)) {
|
||||||
boolean acquiredGood = acquiredInfo == FINGERPRINT_ACQUIRED_GOOD;
|
boolean acquiredGood = acquiredInfo == FINGERPRINT_ACQUIRED_GOOD;
|
||||||
mFgExecutor.execute(() -> {
|
mFgExecutor.execute(() -> {
|
||||||
if (mOverlay == null) {
|
if (mOverlay == null) {
|
||||||
@@ -247,7 +245,7 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
mAcquiredReceived = true;
|
mAcquiredReceived = true;
|
||||||
final UdfpsView view = mOverlay.getOverlayView();
|
final UdfpsView view = mOverlay.getOverlayView();
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
view.stopIllumination(); // turn off HBM
|
view.unconfigureDisplay();
|
||||||
}
|
}
|
||||||
if (acquiredGood) {
|
if (acquiredGood) {
|
||||||
mOverlay.onAcquiredGood();
|
mOverlay.onAcquiredGood();
|
||||||
@@ -292,7 +290,7 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
/**
|
/**
|
||||||
* Updates the overlay parameters and reconstructs or redraws the overlay, if necessary.
|
* Updates the overlay parameters and reconstructs or redraws the overlay, if necessary.
|
||||||
*
|
*
|
||||||
* @param sensorId sensor for which the overlay is getting updated.
|
* @param sensorId sensor for which the overlay is getting updated.
|
||||||
* @param overlayParams See {@link UdfpsOverlayParams}.
|
* @param overlayParams See {@link UdfpsOverlayParams}.
|
||||||
*/
|
*/
|
||||||
public void updateOverlayParams(int sensorId, @NonNull UdfpsOverlayParams overlayParams) {
|
public void updateOverlayParams(int sensorId, @NonNull UdfpsOverlayParams overlayParams) {
|
||||||
@@ -321,11 +319,6 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
mAuthControllerUpdateUdfpsLocation = r;
|
mAuthControllerUpdateUdfpsLocation = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(b/229290039): UDFPS controller should manage its properties on its own. Remove this.
|
|
||||||
public void setHalControlsIllumination(boolean value) {
|
|
||||||
mHalControlsIllumination = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the pointer speed given a velocity tracker and the pointer id.
|
* Calculate the pointer speed given a velocity tracker and the pointer id.
|
||||||
* This assumes that the velocity tracker has already been passed all relevant motion events.
|
* This assumes that the velocity tracker has already been passed all relevant motion events.
|
||||||
@@ -369,8 +362,8 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param x coordinate
|
* @param x coordinate
|
||||||
* @param y coordinate
|
* @param y coordinate
|
||||||
* @param relativeToUdfpsView true if the coordinates are relative to the udfps view; else,
|
* @param relativeToUdfpsView true if the coordinates are relative to the udfps view; else,
|
||||||
* calculate from the display dimensions in portrait orientation
|
* calculate from the display dimensions in portrait orientation
|
||||||
*/
|
*/
|
||||||
@@ -423,7 +416,7 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final UdfpsView udfpsView = mOverlay.getOverlayView();
|
final UdfpsView udfpsView = mOverlay.getOverlayView();
|
||||||
final boolean isIlluminationRequested = udfpsView.isIlluminationRequested();
|
final boolean isDisplayConfigured = udfpsView.isDisplayConfigured();
|
||||||
boolean handled = false;
|
boolean handled = false;
|
||||||
switch (event.getActionMasked()) {
|
switch (event.getActionMasked()) {
|
||||||
case MotionEvent.ACTION_OUTSIDE:
|
case MotionEvent.ACTION_OUTSIDE:
|
||||||
@@ -507,7 +500,7 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
"minor: %.1f, major: %.1f, v: %.1f, exceedsVelocityThreshold: %b",
|
"minor: %.1f, major: %.1f, v: %.1f, exceedsVelocityThreshold: %b",
|
||||||
minor, major, v, exceedsVelocityThreshold);
|
minor, major, v, exceedsVelocityThreshold);
|
||||||
final long sinceLastLog = mSystemClock.elapsedRealtime() - mTouchLogTime;
|
final long sinceLastLog = mSystemClock.elapsedRealtime() - mTouchLogTime;
|
||||||
if (!isIlluminationRequested && !mAcquiredReceived
|
if (!isDisplayConfigured && !mAcquiredReceived
|
||||||
&& !exceedsVelocityThreshold) {
|
&& !exceedsVelocityThreshold) {
|
||||||
|
|
||||||
final float scale = mOverlayParams.getScaleFactor();
|
final float scale = mOverlayParams.getScaleFactor();
|
||||||
@@ -598,7 +591,7 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
@NonNull VibratorHelper vibrator,
|
@NonNull VibratorHelper vibrator,
|
||||||
@NonNull UdfpsHapticsSimulator udfpsHapticsSimulator,
|
@NonNull UdfpsHapticsSimulator udfpsHapticsSimulator,
|
||||||
@NonNull UdfpsShell udfpsShell,
|
@NonNull UdfpsShell udfpsShell,
|
||||||
@NonNull Optional<UdfpsHbmProvider> hbmProvider,
|
@NonNull Optional<UdfpsDisplayModeProvider> udfpsDisplayMode,
|
||||||
@NonNull KeyguardStateController keyguardStateController,
|
@NonNull KeyguardStateController keyguardStateController,
|
||||||
@NonNull DisplayManager displayManager,
|
@NonNull DisplayManager displayManager,
|
||||||
@Main Handler mainHandler,
|
@Main Handler mainHandler,
|
||||||
@@ -630,7 +623,7 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
mPowerManager = powerManager;
|
mPowerManager = powerManager;
|
||||||
mAccessibilityManager = accessibilityManager;
|
mAccessibilityManager = accessibilityManager;
|
||||||
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
|
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
|
||||||
mHbmProvider = hbmProvider.orElse(null);
|
mUdfpsDisplayMode = udfpsDisplayMode.orElse(null);
|
||||||
screenLifecycle.addObserver(mScreenObserver);
|
screenLifecycle.addObserver(mScreenObserver);
|
||||||
mScreenOn = screenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON;
|
mScreenOn = screenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON;
|
||||||
mConfigurationController = configurationController;
|
mConfigurationController = configurationController;
|
||||||
@@ -804,15 +797,14 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel updfs scan affordances - ability to hide the HbmSurfaceView (white circle) before
|
* Cancel UDFPS affordances - ability to hide the UDFPS overlay before the user explicitly
|
||||||
* user explicitly lifts their finger. Generally, this should be called whenever udfps fails
|
* lifts their finger. Generally, this should be called on errors in the authentication flow.
|
||||||
* or errors.
|
|
||||||
*
|
*
|
||||||
* The sensor that triggers an AOD fingerprint interrupt (see onAodInterrupt) doesn't give
|
* The sensor that triggers an AOD fingerprint interrupt (see onAodInterrupt) doesn't give
|
||||||
* ACTION_UP/ACTION_CANCEL events, so and AOD interrupt scan needs to be cancelled manually.
|
* ACTION_UP/ACTION_CANCEL events, so and AOD interrupt scan needs to be cancelled manually.
|
||||||
* This should be called when authentication either succeeds or fails. Failing to cancel the
|
* This should be called when authentication either succeeds or fails. Failing to cancel the
|
||||||
* scan will leave the screen in high brightness mode and will show the HbmSurfaceView until
|
* scan will leave the display in the UDFPS mode until the user lifts their finger. On optical
|
||||||
* the user lifts their finger.
|
* sensors, this can result in illumination persisting for longer than necessary.
|
||||||
*/
|
*/
|
||||||
void onCancelUdfps() {
|
void onCancelUdfps() {
|
||||||
if (mOverlay != null && mOverlay.getOverlayView() != null) {
|
if (mOverlay != null && mOverlay.getOverlayView() != null) {
|
||||||
@@ -874,7 +866,7 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
Trace.endAsyncSection("UdfpsController.e2e.onPointerDown", 0);
|
Trace.endAsyncSection("UdfpsController.e2e.onPointerDown", 0);
|
||||||
final UdfpsView view = mOverlay.getOverlayView();
|
final UdfpsView view = mOverlay.getOverlayView();
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
view.startIllumination(() -> {
|
view.configureDisplay(() -> {
|
||||||
if (mAlternateTouchProvider != null) {
|
if (mAlternateTouchProvider != null) {
|
||||||
mBiometricExecutor.execute(() -> {
|
mBiometricExecutor.execute(() -> {
|
||||||
mAlternateTouchProvider.onUiReady();
|
mAlternateTouchProvider.onUiReady();
|
||||||
@@ -914,8 +906,8 @@ public class UdfpsController implements DozeReceiver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mOnFingerDown = false;
|
mOnFingerDown = false;
|
||||||
if (view.isIlluminationRequested()) {
|
if (view.isDisplayConfigured()) {
|
||||||
view.stopIllumination();
|
view.unconfigureDisplay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,8 +77,7 @@ class UdfpsControllerOverlay(
|
|||||||
private val systemClock: SystemClock,
|
private val systemClock: SystemClock,
|
||||||
private val keyguardStateController: KeyguardStateController,
|
private val keyguardStateController: KeyguardStateController,
|
||||||
private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController,
|
private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController,
|
||||||
private val halControlsIllumination: Boolean,
|
private var udfpsDisplayModeProvider: UdfpsDisplayModeProvider,
|
||||||
private var hbmProvider: UdfpsHbmProvider,
|
|
||||||
val requestId: Long,
|
val requestId: Long,
|
||||||
@ShowReason val requestReason: Int,
|
@ShowReason val requestReason: Int,
|
||||||
private val controllerCallback: IUdfpsOverlayControllerCallback,
|
private val controllerCallback: IUdfpsOverlayControllerCallback,
|
||||||
@@ -102,8 +101,8 @@ class UdfpsControllerOverlay(
|
|||||||
fitInsetsTypes = 0
|
fitInsetsTypes = 0
|
||||||
gravity = android.view.Gravity.TOP or android.view.Gravity.LEFT
|
gravity = android.view.Gravity.TOP or android.view.Gravity.LEFT
|
||||||
layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
|
layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
|
||||||
flags =
|
flags = (Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS or
|
||||||
(Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS or WindowManager.LayoutParams.FLAG_SPLIT_TOUCH)
|
WindowManager.LayoutParams.FLAG_SPLIT_TOUCH)
|
||||||
privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY
|
privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY
|
||||||
// Avoid announcing window title.
|
// Avoid announcing window title.
|
||||||
accessibilityTitle = " "
|
accessibilityTitle = " "
|
||||||
@@ -140,8 +139,7 @@ class UdfpsControllerOverlay(
|
|||||||
R.layout.udfps_view, null, false
|
R.layout.udfps_view, null, false
|
||||||
) as UdfpsView).apply {
|
) as UdfpsView).apply {
|
||||||
overlayParams = params
|
overlayParams = params
|
||||||
halControlsIllumination = this@UdfpsControllerOverlay.halControlsIllumination
|
setUdfpsDisplayModeProvider(udfpsDisplayModeProvider)
|
||||||
setHbmProvider(hbmProvider)
|
|
||||||
val animation = inflateUdfpsAnimation(this, controller)
|
val animation = inflateUdfpsAnimation(this, controller)
|
||||||
if (animation != null) {
|
if (animation != null) {
|
||||||
animation.init()
|
animation.init()
|
||||||
@@ -250,8 +248,8 @@ class UdfpsControllerOverlay(
|
|||||||
val wasShowing = isShowing
|
val wasShowing = isShowing
|
||||||
|
|
||||||
overlayView?.apply {
|
overlayView?.apply {
|
||||||
if (isIlluminationRequested) {
|
if (isDisplayConfigured) {
|
||||||
stopIllumination()
|
unconfigureDisplay()
|
||||||
}
|
}
|
||||||
windowManager.removeView(this)
|
windowManager.removeView(this)
|
||||||
setOnTouchListener(null)
|
setOnTouchListener(null)
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* 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.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for toggling the optimal display mode for the under-display fingerprint sensor
|
||||||
|
* (UDFPS). For example, the implementation might change the refresh rate and activate a
|
||||||
|
* high-brightness mode.
|
||||||
|
*/
|
||||||
|
public interface UdfpsDisplayModeProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the optimal display mode for UDFPS. The mode will persist until
|
||||||
|
* {@link #disable(Runnable)} is called.
|
||||||
|
*
|
||||||
|
* This call must be made from the UI thread. The callback, if provided, will also be invoked
|
||||||
|
* from the UI thread.
|
||||||
|
*
|
||||||
|
* @param onEnabled A runnable that will be executed once the mode is enabled.
|
||||||
|
*/
|
||||||
|
void enable(@Nullable Runnable onEnabled);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables the mode that was enabled by {@link #enable(Runnable)}.
|
||||||
|
*
|
||||||
|
* The call must be made from the UI thread. The callback, if provided, will also be invoked
|
||||||
|
* from the UI thread.
|
||||||
|
*
|
||||||
|
* @param onDisabled A runnable that will be executed once mode is disabled.
|
||||||
|
*/
|
||||||
|
void disable(@Nullable Runnable onDisabled);
|
||||||
|
}
|
||||||
@@ -51,7 +51,7 @@ abstract class UdfpsDrawable(
|
|||||||
invalidateSelf()
|
invalidateSelf()
|
||||||
}
|
}
|
||||||
|
|
||||||
var isIlluminationShowing: Boolean = false
|
var isDisplayConfigured: Boolean = false
|
||||||
set(showing) {
|
set(showing) {
|
||||||
if (field == showing) {
|
if (field == showing) {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ public class UdfpsEnrollDrawable extends UdfpsDrawable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(@NonNull Canvas canvas) {
|
public void draw(@NonNull Canvas canvas) {
|
||||||
if (isIlluminationShowing()) {
|
if (isDisplayConfigured()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import android.graphics.Canvas
|
|||||||
*/
|
*/
|
||||||
class UdfpsFpDrawable(context: Context) : UdfpsDrawable(context) {
|
class UdfpsFpDrawable(context: Context) : UdfpsDrawable(context) {
|
||||||
override fun draw(canvas: Canvas) {
|
override fun draw(canvas: Canvas) {
|
||||||
if (isIlluminationShowing) {
|
if (isDisplayConfigured) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fingerprintDrawable.draw(canvas)
|
fingerprintDrawable.draw(canvas)
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2021 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.annotation.Nullable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for controlling the high-brightness mode (HBM). UdfpsView can use this callback to
|
|
||||||
* enable the HBM while showing the fingerprint illumination, and to disable the HBM after the
|
|
||||||
* illumination is no longer necessary.
|
|
||||||
*/
|
|
||||||
public interface UdfpsHbmProvider {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UdfpsView will call this to enable the HBM when the fingerprint illumination is needed.
|
|
||||||
*
|
|
||||||
* This method is a no-op when some type of HBM is already enabled.
|
|
||||||
*
|
|
||||||
* This method must be called from the UI thread. The callback, if provided, will also be
|
|
||||||
* invoked from the UI thread.
|
|
||||||
*
|
|
||||||
* @param onHbmEnabled A runnable that will be executed once HBM is enabled.
|
|
||||||
*
|
|
||||||
* TODO(b/231335067): enableHbm with halControlsIllumination=true shouldn't make sense.
|
|
||||||
* This only makes sense now because vendor code may rely on the side effects of enableHbm.
|
|
||||||
*/
|
|
||||||
void enableHbm(boolean halControlsIllumination, @Nullable Runnable onHbmEnabled);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UdfpsView will call this to disable HBM when illumination is no longer needed.
|
|
||||||
*
|
|
||||||
* This method will disable HBM if HBM is enabled. Otherwise, if HBM is already disabled,
|
|
||||||
* this method is a no-op.
|
|
||||||
*
|
|
||||||
* The call must be made from the UI thread. The callback, if provided, will also be invoked
|
|
||||||
* from the UI thread.
|
|
||||||
*
|
|
||||||
* @param onHbmDisabled A runnable that will be executed once HBM is disabled.
|
|
||||||
*/
|
|
||||||
void disableHbm(@Nullable Runnable onHbmDisabled);
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2021 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.annotation.Nullable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface that should be implemented by UI's that need to coordinate user touches,
|
|
||||||
* views/animations, and modules that start/stop display illumination.
|
|
||||||
*/
|
|
||||||
interface UdfpsIlluminator {
|
|
||||||
/**
|
|
||||||
* @param hbmProvider Invoked when HBM should be enabled or disabled.
|
|
||||||
*/
|
|
||||||
void setHbmProvider(@Nullable UdfpsHbmProvider hbmProvider);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoked when illumination should start.
|
|
||||||
* @param onIlluminatedRunnable Invoked when the display has been illuminated.
|
|
||||||
*/
|
|
||||||
void startIllumination(@Nullable Runnable onIlluminatedRunnable);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoked when illumination should end.
|
|
||||||
*/
|
|
||||||
void stopIllumination();
|
|
||||||
}
|
|
||||||
@@ -101,11 +101,11 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onIlluminationStarting() {
|
void onDisplayConfiguring() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onIlluminationStopped() {
|
void onDisplayUnconfigured() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -36,12 +36,12 @@ private const val TAG = "UdfpsView"
|
|||||||
class UdfpsView(
|
class UdfpsView(
|
||||||
context: Context,
|
context: Context,
|
||||||
attrs: AttributeSet?
|
attrs: AttributeSet?
|
||||||
) : FrameLayout(context, attrs), DozeReceiver, UdfpsIlluminator {
|
) : FrameLayout(context, attrs), DozeReceiver {
|
||||||
|
|
||||||
// sensorRect may be bigger than the sensor. True sensor dimensions are defined in
|
// sensorRect may be bigger than the sensor. True sensor dimensions are defined in
|
||||||
// overlayParams.sensorBounds
|
// overlayParams.sensorBounds
|
||||||
private val sensorRect = RectF()
|
private val sensorRect = RectF()
|
||||||
private var hbmProvider: UdfpsHbmProvider? = null
|
private var mUdfpsDisplayMode: UdfpsDisplayModeProvider? = null
|
||||||
private val debugTextPaint = Paint().apply {
|
private val debugTextPaint = Paint().apply {
|
||||||
isAntiAlias = true
|
isAntiAlias = true
|
||||||
color = Color.BLUE
|
color = Color.BLUE
|
||||||
@@ -56,19 +56,12 @@ class UdfpsView(
|
|||||||
a.getFloat(R.styleable.UdfpsView_sensorTouchAreaCoefficient, 0f)
|
a.getFloat(R.styleable.UdfpsView_sensorTouchAreaCoefficient, 0f)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val onIlluminatedDelayMs = context.resources.getInteger(
|
|
||||||
com.android.internal.R.integer.config_udfps_illumination_transition_ms
|
|
||||||
).toLong()
|
|
||||||
|
|
||||||
/** View controller (can be different for enrollment, BiometricPrompt, Keyguard, etc.). */
|
/** View controller (can be different for enrollment, BiometricPrompt, Keyguard, etc.). */
|
||||||
var animationViewController: UdfpsAnimationViewController<*>? = null
|
var animationViewController: UdfpsAnimationViewController<*>? = null
|
||||||
|
|
||||||
/** Parameters that affect the position and size of the overlay. */
|
/** Parameters that affect the position and size of the overlay. */
|
||||||
var overlayParams = UdfpsOverlayParams()
|
var overlayParams = UdfpsOverlayParams()
|
||||||
|
|
||||||
/** Whether the HAL is responsible for enabling and disabling of LHBM. */
|
|
||||||
var halControlsIllumination: Boolean = true
|
|
||||||
|
|
||||||
/** Debug message. */
|
/** Debug message. */
|
||||||
var debugMessage: String? = null
|
var debugMessage: String? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
@@ -76,12 +69,12 @@ class UdfpsView(
|
|||||||
postInvalidate()
|
postInvalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** When [startIllumination] has been called but not stopped via [stopIllumination]. */
|
/** True after the call to [configureDisplay] and before the call to [unconfigureDisplay]. */
|
||||||
var isIlluminationRequested: Boolean = false
|
var isDisplayConfigured: Boolean = false
|
||||||
private set
|
private set
|
||||||
|
|
||||||
override fun setHbmProvider(provider: UdfpsHbmProvider?) {
|
fun setUdfpsDisplayModeProvider(udfpsDisplayModeProvider: UdfpsDisplayModeProvider?) {
|
||||||
hbmProvider = provider
|
mUdfpsDisplayMode = udfpsDisplayModeProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't propagate any touch events to the child views.
|
// Don't propagate any touch events to the child views.
|
||||||
@@ -124,7 +117,7 @@ class UdfpsView(
|
|||||||
|
|
||||||
override fun onDraw(canvas: Canvas) {
|
override fun onDraw(canvas: Canvas) {
|
||||||
super.onDraw(canvas)
|
super.onDraw(canvas)
|
||||||
if (!isIlluminationRequested) {
|
if (!isDisplayConfigured) {
|
||||||
if (!debugMessage.isNullOrEmpty()) {
|
if (!debugMessage.isNullOrEmpty()) {
|
||||||
canvas.drawText(debugMessage!!, 0f, 160f, debugTextPaint)
|
canvas.drawText(debugMessage!!, 0f, 160f, debugTextPaint)
|
||||||
}
|
}
|
||||||
@@ -147,36 +140,15 @@ class UdfpsView(
|
|||||||
!(animationViewController?.shouldPauseAuth() ?: false)
|
!(animationViewController?.shouldPauseAuth() ?: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
fun configureDisplay(onDisplayConfigured: Runnable) {
|
||||||
* Start and run [onIlluminatedRunnable] when the first illumination frame reaches the panel.
|
isDisplayConfigured = true
|
||||||
*/
|
animationViewController?.onDisplayConfiguring()
|
||||||
override fun startIllumination(onIlluminatedRunnable: Runnable?) {
|
mUdfpsDisplayMode?.enable(onDisplayConfigured)
|
||||||
isIlluminationRequested = true
|
|
||||||
animationViewController?.onIlluminationStarting()
|
|
||||||
doIlluminate(onIlluminatedRunnable)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doIlluminate(onIlluminatedRunnable: Runnable?) {
|
fun unconfigureDisplay() {
|
||||||
// TODO(b/231335067): enableHbm with halControlsIllumination=true shouldn't make sense.
|
isDisplayConfigured = false
|
||||||
// This only makes sense now because vendor code may rely on the side effects of enableHbm.
|
animationViewController?.onDisplayUnconfigured()
|
||||||
hbmProvider?.enableHbm(halControlsIllumination) {
|
mUdfpsDisplayMode?.disable(null /* onDisabled */)
|
||||||
if (onIlluminatedRunnable != null) {
|
|
||||||
if (halControlsIllumination) {
|
|
||||||
onIlluminatedRunnable.run()
|
|
||||||
} else {
|
|
||||||
// No framework API can reliably tell when a frame reaches the panel. A timeout
|
|
||||||
// is the safest solution.
|
|
||||||
postDelayed(onIlluminatedRunnable, onIlluminatedDelayMs)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "doIlluminate | onIlluminatedRunnable is null")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun stopIllumination() {
|
|
||||||
isIlluminationRequested = false
|
|
||||||
animationViewController?.onIlluminationStopped()
|
|
||||||
hbmProvider?.disableHbm(null /* onHbmDisabled */)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import com.android.systemui.BootCompleteCacheImpl;
|
|||||||
import com.android.systemui.appops.dagger.AppOpsModule;
|
import com.android.systemui.appops.dagger.AppOpsModule;
|
||||||
import com.android.systemui.assist.AssistModule;
|
import com.android.systemui.assist.AssistModule;
|
||||||
import com.android.systemui.biometrics.AlternateUdfpsTouchProvider;
|
import com.android.systemui.biometrics.AlternateUdfpsTouchProvider;
|
||||||
import com.android.systemui.biometrics.UdfpsHbmProvider;
|
import com.android.systemui.biometrics.UdfpsDisplayModeProvider;
|
||||||
import com.android.systemui.biometrics.dagger.BiometricsModule;
|
import com.android.systemui.biometrics.dagger.BiometricsModule;
|
||||||
import com.android.systemui.classifier.FalsingModule;
|
import com.android.systemui.classifier.FalsingModule;
|
||||||
import com.android.systemui.controls.dagger.ControlsModule;
|
import com.android.systemui.controls.dagger.ControlsModule;
|
||||||
@@ -197,7 +197,7 @@ public abstract class SystemUIModule {
|
|||||||
abstract CentralSurfaces optionalCentralSurfaces();
|
abstract CentralSurfaces optionalCentralSurfaces();
|
||||||
|
|
||||||
@BindsOptionalOf
|
@BindsOptionalOf
|
||||||
abstract UdfpsHbmProvider optionalUdfpsHbmProvider();
|
abstract UdfpsDisplayModeProvider optionalUdfpsDisplayModeProvider();
|
||||||
|
|
||||||
@BindsOptionalOf
|
@BindsOptionalOf
|
||||||
abstract AlternateUdfpsTouchProvider optionalUdfpsTouchProvider();
|
abstract AlternateUdfpsTouchProvider optionalUdfpsTouchProvider();
|
||||||
|
|||||||
@@ -17,23 +17,13 @@
|
|||||||
package com.android.systemui.biometrics
|
package com.android.systemui.biometrics
|
||||||
|
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_BP
|
import android.hardware.biometrics.BiometricOverlayConstants.*
|
||||||
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
|
|
||||||
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_OTHER
|
|
||||||
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS
|
|
||||||
import android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_ENROLLING
|
|
||||||
import android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR
|
|
||||||
import android.hardware.biometrics.BiometricOverlayConstants.ShowReason
|
|
||||||
import android.hardware.fingerprint.FingerprintManager
|
import android.hardware.fingerprint.FingerprintManager
|
||||||
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback
|
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper.RunWithLooper
|
import android.testing.TestableLooper.RunWithLooper
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.MotionEvent
|
|
||||||
import android.view.View
|
|
||||||
import android.view.Surface
|
|
||||||
import android.view.Surface.Rotation
|
import android.view.Surface.Rotation
|
||||||
import android.view.WindowManager
|
|
||||||
import android.view.accessibility.AccessibilityManager
|
import android.view.accessibility.AccessibilityManager
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.keyguard.KeyguardUpdateMonitor
|
import com.android.keyguard.KeyguardUpdateMonitor
|
||||||
@@ -65,7 +55,6 @@ import org.mockito.Mockito.verify
|
|||||||
import org.mockito.junit.MockitoJUnit
|
import org.mockito.junit.MockitoJUnit
|
||||||
import org.mockito.Mockito.`when` as whenever
|
import org.mockito.Mockito.`when` as whenever
|
||||||
|
|
||||||
private const val HAL_CONTROLS_ILLUMINATION = true
|
|
||||||
private const val REQUEST_ID = 2L
|
private const val REQUEST_ID = 2L
|
||||||
|
|
||||||
// Dimensions for the current display resolution.
|
// Dimensions for the current display resolution.
|
||||||
@@ -95,8 +84,9 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var configurationController: ConfigurationController
|
@Mock private lateinit var configurationController: ConfigurationController
|
||||||
@Mock private lateinit var systemClock: SystemClock
|
@Mock private lateinit var systemClock: SystemClock
|
||||||
@Mock private lateinit var keyguardStateController: KeyguardStateController
|
@Mock private lateinit var keyguardStateController: KeyguardStateController
|
||||||
@Mock private lateinit var unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController
|
@Mock private lateinit var unlockedScreenOffAnimationController:
|
||||||
@Mock private lateinit var hbmProvider: UdfpsHbmProvider
|
UnlockedScreenOffAnimationController
|
||||||
|
@Mock private lateinit var udfpsDisplayMode: UdfpsDisplayModeProvider
|
||||||
@Mock private lateinit var controllerCallback: IUdfpsOverlayControllerCallback
|
@Mock private lateinit var controllerCallback: IUdfpsOverlayControllerCallback
|
||||||
@Mock private lateinit var udfpsController: UdfpsController
|
@Mock private lateinit var udfpsController: UdfpsController
|
||||||
@Mock private lateinit var udfpsView: UdfpsView
|
@Mock private lateinit var udfpsView: UdfpsView
|
||||||
@@ -130,8 +120,9 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
|
|||||||
statusBarStateController, panelExpansionStateManager, statusBarKeyguardViewManager,
|
statusBarStateController, panelExpansionStateManager, statusBarKeyguardViewManager,
|
||||||
keyguardUpdateMonitor, dialogManager, dumpManager, transitionController,
|
keyguardUpdateMonitor, dialogManager, dumpManager, transitionController,
|
||||||
configurationController, systemClock, keyguardStateController,
|
configurationController, systemClock, keyguardStateController,
|
||||||
unlockedScreenOffAnimationController, HAL_CONTROLS_ILLUMINATION, hbmProvider,
|
unlockedScreenOffAnimationController, udfpsDisplayMode, REQUEST_ID, reason,
|
||||||
REQUEST_ID, reason, controllerCallback, onTouch, activityLaunchAnimator)
|
controllerCallback, onTouch, activityLaunchAnimator
|
||||||
|
)
|
||||||
block()
|
block()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,7 +237,7 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
|
|||||||
val didShow = controllerOverlay.show(udfpsController, overlayParams)
|
val didShow = controllerOverlay.show(udfpsController, overlayParams)
|
||||||
|
|
||||||
verify(windowManager).addView(eq(controllerOverlay.overlayView), any())
|
verify(windowManager).addView(eq(controllerOverlay.overlayView), any())
|
||||||
verify(udfpsView).setHbmProvider(eq(hbmProvider))
|
verify(udfpsView).setUdfpsDisplayModeProvider(eq(udfpsDisplayMode))
|
||||||
verify(udfpsView).animationViewController = any()
|
verify(udfpsView).animationViewController = any()
|
||||||
verify(udfpsView).addView(any())
|
verify(udfpsView).addView(any())
|
||||||
|
|
||||||
@@ -351,12 +342,12 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun stopIlluminatingOnHide() = withReason(REASON_AUTH_BP) {
|
fun unconfigureDisplayOnHide() = withReason(REASON_AUTH_BP) {
|
||||||
whenever(udfpsView.isIlluminationRequested).thenReturn(true)
|
whenever(udfpsView.isDisplayConfigured).thenReturn(true)
|
||||||
|
|
||||||
controllerOverlay.show(udfpsController, overlayParams)
|
controllerOverlay.show(udfpsController, overlayParams)
|
||||||
controllerOverlay.hide()
|
controllerOverlay.hide()
|
||||||
verify(udfpsView).stopIllumination()
|
verify(udfpsView).unconfigureDisplay()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
private WindowManager mWindowManager;
|
private WindowManager mWindowManager;
|
||||||
@Mock
|
@Mock
|
||||||
private UdfpsHbmProvider mHbmProvider;
|
private UdfpsDisplayModeProvider mDisplayModeProvider;
|
||||||
@Mock
|
@Mock
|
||||||
private StatusBarStateController mStatusBarStateController;
|
private StatusBarStateController mStatusBarStateController;
|
||||||
@Mock
|
@Mock
|
||||||
@@ -193,7 +193,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
private IUdfpsOverlayController mOverlayController;
|
private IUdfpsOverlayController mOverlayController;
|
||||||
@Captor private ArgumentCaptor<UdfpsView.OnTouchListener> mTouchListenerCaptor;
|
@Captor private ArgumentCaptor<UdfpsView.OnTouchListener> mTouchListenerCaptor;
|
||||||
@Captor private ArgumentCaptor<View.OnHoverListener> mHoverListenerCaptor;
|
@Captor private ArgumentCaptor<View.OnHoverListener> mHoverListenerCaptor;
|
||||||
@Captor private ArgumentCaptor<Runnable> mOnIlluminatedRunnableCaptor;
|
@Captor private ArgumentCaptor<Runnable> mOnDisplayConfiguredCaptor;
|
||||||
@Captor private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor;
|
@Captor private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor;
|
||||||
private ScreenLifecycle.Observer mScreenObserver;
|
private ScreenLifecycle.Observer mScreenObserver;
|
||||||
|
|
||||||
@@ -256,7 +256,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
mVibrator,
|
mVibrator,
|
||||||
mUdfpsHapticsSimulator,
|
mUdfpsHapticsSimulator,
|
||||||
mUdfpsShell,
|
mUdfpsShell,
|
||||||
Optional.of(mHbmProvider),
|
Optional.of(mDisplayModeProvider),
|
||||||
mKeyguardStateController,
|
mKeyguardStateController,
|
||||||
mDisplayManager,
|
mDisplayManager,
|
||||||
mHandler,
|
mHandler,
|
||||||
@@ -506,7 +506,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
final float expectedMajor = touchMajor / scaleFactor;
|
final float expectedMajor = touchMajor / scaleFactor;
|
||||||
|
|
||||||
// Configure UdfpsView to accept the ACTION_DOWN event
|
// Configure UdfpsView to accept the ACTION_DOWN event
|
||||||
when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
|
when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
|
||||||
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
|
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
|
||||||
|
|
||||||
// Show the overlay.
|
// Show the overlay.
|
||||||
@@ -584,7 +584,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void fingerDown() throws RemoteException {
|
public void fingerDown() throws RemoteException {
|
||||||
// Configure UdfpsView to accept the ACTION_DOWN event
|
// Configure UdfpsView to accept the ACTION_DOWN event
|
||||||
when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
|
when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
|
||||||
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
|
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
|
||||||
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
|
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
|
||||||
|
|
||||||
@@ -611,12 +611,12 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
verify(mFingerprintManager, never()).onPointerDown(anyLong(), anyInt(), anyInt(), anyInt(),
|
verify(mFingerprintManager, never()).onPointerDown(anyLong(), anyInt(), anyInt(), anyInt(),
|
||||||
anyFloat(), anyFloat());
|
anyFloat(), anyFloat());
|
||||||
verify(mLatencyTracker).onActionStart(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
|
verify(mLatencyTracker).onActionStart(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
|
||||||
// AND illumination begins
|
// AND display configuration begins
|
||||||
verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture());
|
verify(mUdfpsView).configureDisplay(mOnDisplayConfiguredCaptor.capture());
|
||||||
verify(mLatencyTracker, never()).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
|
verify(mLatencyTracker, never()).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
|
||||||
verify(mKeyguardUpdateMonitor).onUdfpsPointerDown(eq((int) TEST_REQUEST_ID));
|
verify(mKeyguardUpdateMonitor).onUdfpsPointerDown(eq((int) TEST_REQUEST_ID));
|
||||||
// AND onIlluminatedRunnable notifies FingerprintManager about onUiReady
|
// AND onDisplayConfigured notifies FingerprintManager about onUiReady
|
||||||
mOnIlluminatedRunnableCaptor.getValue().run();
|
mOnDisplayConfiguredCaptor.getValue().run();
|
||||||
mBiometricsExecutor.runAllReady();
|
mBiometricsExecutor.runAllReady();
|
||||||
InOrder inOrder = inOrder(mAlternateTouchProvider, mLatencyTracker);
|
InOrder inOrder = inOrder(mAlternateTouchProvider, mLatencyTracker);
|
||||||
inOrder.verify(mAlternateTouchProvider).onUiReady();
|
inOrder.verify(mAlternateTouchProvider).onUiReady();
|
||||||
@@ -634,10 +634,10 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
// WHEN fingerprint is requested because of AOD interrupt
|
// WHEN fingerprint is requested because of AOD interrupt
|
||||||
mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
|
mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
|
||||||
mFgExecutor.runAllReady();
|
mFgExecutor.runAllReady();
|
||||||
// THEN illumination begins
|
// THEN display configuration begins
|
||||||
// AND onIlluminatedRunnable that notifies FingerprintManager is set
|
// AND onDisplayConfigured notifies FingerprintManager about onUiReady
|
||||||
verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture());
|
verify(mUdfpsView).configureDisplay(mOnDisplayConfiguredCaptor.capture());
|
||||||
mOnIlluminatedRunnableCaptor.getValue().run();
|
mOnDisplayConfiguredCaptor.getValue().run();
|
||||||
mBiometricsExecutor.runAllReady();
|
mBiometricsExecutor.runAllReady();
|
||||||
verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID),
|
verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID),
|
||||||
eq(0), eq(0), eq(3f) /* minor */, eq(2f) /* major */);
|
eq(0), eq(0), eq(3f) /* minor */, eq(2f) /* major */);
|
||||||
@@ -655,11 +655,11 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
mFgExecutor.runAllReady();
|
mFgExecutor.runAllReady();
|
||||||
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
|
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
|
||||||
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
||||||
when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
|
when(mUdfpsView.isDisplayConfigured()).thenReturn(true);
|
||||||
// WHEN it is cancelled
|
// WHEN it is cancelled
|
||||||
mUdfpsController.onCancelUdfps();
|
mUdfpsController.onCancelUdfps();
|
||||||
// THEN the illumination is hidden
|
// THEN the display is unconfigured
|
||||||
verify(mUdfpsView).stopIllumination();
|
verify(mUdfpsView).unconfigureDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -672,12 +672,12 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
|
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
|
||||||
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
||||||
mFgExecutor.runAllReady();
|
mFgExecutor.runAllReady();
|
||||||
when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
|
when(mUdfpsView.isDisplayConfigured()).thenReturn(true);
|
||||||
// WHEN it times out
|
// WHEN it times out
|
||||||
mFgExecutor.advanceClockToNext();
|
mFgExecutor.advanceClockToNext();
|
||||||
mFgExecutor.runAllReady();
|
mFgExecutor.runAllReady();
|
||||||
// THEN the illumination is hidden
|
// THEN the display is unconfigured
|
||||||
verify(mUdfpsView).stopIllumination();
|
verify(mUdfpsView).unconfigureDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -692,8 +692,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
|
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
|
||||||
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
||||||
|
|
||||||
// THEN no illumination because screen is off
|
// THEN display doesn't get configured because it's off
|
||||||
verify(mUdfpsView, never()).startIllumination(any());
|
verify(mUdfpsView, never()).configureDisplay(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -709,14 +709,14 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(false);
|
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(false);
|
||||||
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
|
||||||
|
|
||||||
// THEN no illumination because screen is off
|
// THEN display doesn't get configured because it's off
|
||||||
verify(mUdfpsView, never()).startIllumination(any());
|
verify(mUdfpsView, never()).configureDisplay(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void playHapticOnTouchUdfpsArea_a11yTouchExplorationEnabled() throws RemoteException {
|
public void playHapticOnTouchUdfpsArea_a11yTouchExplorationEnabled() throws RemoteException {
|
||||||
// Configure UdfpsView to accept the ACTION_DOWN event
|
// Configure UdfpsView to accept the ACTION_DOWN event
|
||||||
when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
|
when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
|
||||||
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
|
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
|
||||||
|
|
||||||
// GIVEN that the overlay is showing and a11y touch exploration enabled
|
// GIVEN that the overlay is showing and a11y touch exploration enabled
|
||||||
@@ -751,7 +751,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void noHapticOnTouchUdfpsArea_a11yTouchExplorationDisabled() throws RemoteException {
|
public void noHapticOnTouchUdfpsArea_a11yTouchExplorationDisabled() throws RemoteException {
|
||||||
// Configure UdfpsView to accept the ACTION_DOWN event
|
// Configure UdfpsView to accept the ACTION_DOWN event
|
||||||
when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
|
when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
|
||||||
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
|
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
|
||||||
|
|
||||||
// GIVEN that the overlay is showing and a11y touch exploration NOT enabled
|
// GIVEN that the overlay is showing and a11y touch exploration NOT enabled
|
||||||
|
|||||||
@@ -36,13 +36,12 @@ import org.junit.Before
|
|||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.ArgumentMatchers.anyBoolean
|
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.never
|
import org.mockito.Mockito.never
|
||||||
import org.mockito.Mockito.nullable
|
import org.mockito.Mockito.nullable
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
import org.mockito.junit.MockitoJUnit
|
|
||||||
import org.mockito.Mockito.`when` as whenever
|
import org.mockito.Mockito.`when` as whenever
|
||||||
|
import org.mockito.junit.MockitoJUnit
|
||||||
|
|
||||||
private const val SENSOR_X = 50
|
private const val SENSOR_X = 50
|
||||||
private const val SENSOR_Y = 250
|
private const val SENSOR_Y = 250
|
||||||
@@ -57,7 +56,7 @@ class UdfpsViewTest : SysuiTestCase() {
|
|||||||
var rule = MockitoJUnit.rule()
|
var rule = MockitoJUnit.rule()
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var hbmProvider: UdfpsHbmProvider
|
lateinit var hbmProvider: UdfpsDisplayModeProvider
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var animationViewController: UdfpsAnimationViewController<UdfpsAnimationView>
|
lateinit var animationViewController: UdfpsAnimationViewController<UdfpsAnimationView>
|
||||||
|
|
||||||
@@ -66,13 +65,11 @@ class UdfpsViewTest : SysuiTestCase() {
|
|||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
context.setTheme(R.style.Theme_AppCompat)
|
context.setTheme(R.style.Theme_AppCompat)
|
||||||
context.orCreateTestableResources.addOverride(
|
|
||||||
com.android.internal.R.integer.config_udfps_illumination_transition_ms, 0)
|
|
||||||
view = LayoutInflater.from(context).inflate(R.layout.udfps_view, null) as UdfpsView
|
view = LayoutInflater.from(context).inflate(R.layout.udfps_view, null) as UdfpsView
|
||||||
view.animationViewController = animationViewController
|
view.animationViewController = animationViewController
|
||||||
val sensorBounds = SensorLocationInternal("", SENSOR_X, SENSOR_Y, SENSOR_RADIUS).rect
|
val sensorBounds = SensorLocationInternal("", SENSOR_X, SENSOR_Y, SENSOR_RADIUS).rect
|
||||||
view.overlayParams = UdfpsOverlayParams(sensorBounds, 1920, 1080, 1f, Surface.ROTATION_0)
|
view.overlayParams = UdfpsOverlayParams(sensorBounds, 1920, 1080, 1f, Surface.ROTATION_0)
|
||||||
view.setHbmProvider(hbmProvider)
|
view.setUdfpsDisplayModeProvider(hbmProvider)
|
||||||
ViewUtils.attachView(view)
|
ViewUtils.attachView(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,27 +140,27 @@ class UdfpsViewTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun startAndStopIllumination() {
|
fun startAndStopIllumination() {
|
||||||
val onDone: Runnable = mock()
|
val onDone: Runnable = mock()
|
||||||
view.startIllumination(onDone)
|
view.configureDisplay(onDone)
|
||||||
|
|
||||||
val illuminator = withArgCaptor<Runnable> {
|
val illuminator = withArgCaptor<Runnable> {
|
||||||
verify(hbmProvider).enableHbm(anyBoolean(), capture())
|
verify(hbmProvider).enable(capture())
|
||||||
}
|
}
|
||||||
|
|
||||||
assertThat(view.isIlluminationRequested).isTrue()
|
assertThat(view.isDisplayConfigured).isTrue()
|
||||||
verify(animationViewController).onIlluminationStarting()
|
verify(animationViewController).onDisplayConfiguring()
|
||||||
verify(animationViewController, never()).onIlluminationStopped()
|
verify(animationViewController, never()).onDisplayUnconfigured()
|
||||||
verify(onDone, never()).run()
|
verify(onDone, never()).run()
|
||||||
|
|
||||||
// fake illumination event
|
// fake illumination event
|
||||||
illuminator.run()
|
illuminator.run()
|
||||||
waitForLooper()
|
waitForLooper()
|
||||||
verify(onDone).run()
|
verify(onDone).run()
|
||||||
verify(hbmProvider, never()).disableHbm(any())
|
verify(hbmProvider, never()).disable(any())
|
||||||
|
|
||||||
view.stopIllumination()
|
view.unconfigureDisplay()
|
||||||
assertThat(view.isIlluminationRequested).isFalse()
|
assertThat(view.isDisplayConfigured).isFalse()
|
||||||
verify(animationViewController).onIlluminationStopped()
|
verify(animationViewController).onDisplayUnconfigured()
|
||||||
verify(hbmProvider).disableHbm(nullable(Runnable::class.java))
|
verify(hbmProvider).disable(nullable(Runnable::class.java))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun waitForLooper() = TestableLooper.get(this).processAllMessages()
|
private fun waitForLooper() = TestableLooper.get(this).processAllMessages()
|
||||||
|
|||||||
Reference in New Issue
Block a user