Merge "Plumb UDFPS overlay "show reason" from FingerprintService to SysUI"

This commit is contained in:
TreeHugger Robot
2021-01-14 03:30:56 +00:00
committed by Android (Google) Code Review
14 changed files with 95 additions and 29 deletions

View File

@@ -20,8 +20,12 @@ package android.hardware.fingerprint;
* @hide
*/
oneway interface IUdfpsOverlayController {
const int REASON_UNKNOWN = 0;
const int REASON_ENROLL = 1;
const int REASON_AUTH = 2;
// Shows the overlay.
void showUdfpsOverlay(int sensorId);
void showUdfpsOverlay(int sensorId, int reason);
// Hides the overlay.
void hideUdfpsOverlay(int sensorId);

View File

@@ -77,6 +77,9 @@
<color name="biometric_dialog_accent">#ff80cbc4</color> <!-- light teal -->
<color name="biometric_dialog_error">#fff28b82</color> <!-- red 300 -->
<!-- UDFPS colors -->
<color name="udfps_enroll_icon">#ffffff</color> <!-- 100% white -->
<color name="GM2_green_500">#FF41Af6A</color>
<color name="GM2_blue_500">#5195EA</color>
<color name="GM2_red_500">#E25142</color>

View File

@@ -178,6 +178,9 @@
<color name="biometric_dialog_accent">#ff008577</color> <!-- dark teal -->
<color name="biometric_dialog_error">#ffd93025</color> <!-- red 600 -->
<!-- UDFPS colors -->
<color name="udfps_enroll_icon">#000000</color> <!-- 100% black -->
<!-- Logout button -->
<color name="logout_button_bg_color">#ccffffff</color>

View File

@@ -546,6 +546,12 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// UdfpsController is not BiometricPrompt-specific. It can be active for keyguard or
// enrollment.
if (mUdfpsController != null) {
mUdfpsController.onConfigurationChanged();
}
// Save the state of the current dialog (buttons showing, etc)
if (mCurrentDialog != null) {
final Bundle savedState = new Bundle();
@@ -567,10 +573,6 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
promptInfo.setAuthenticators(Authenticators.DEVICE_CREDENTIAL);
}
if (mUdfpsController != null) {
mUdfpsController.onConfigurationChanged();
}
showDialog(mCurrentDialogArgs, true /* skipAnimation */, savedState);
}
}

View File

@@ -108,6 +108,8 @@ class UdfpsController implements DozeReceiver {
private boolean mIsOverlayShowing;
// Indicates whether the overlay has been requested.
private boolean mIsOverlayRequested;
// Reason the overlay has been requested. See IUdfpsOverlayController for definitions.
private int mRequestReason;
// 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
@@ -118,13 +120,13 @@ class UdfpsController implements DozeReceiver {
public class UdfpsOverlayController extends IUdfpsOverlayController.Stub {
@Override
public void showUdfpsOverlay(int sensorId) {
UdfpsController.this.setShowOverlay(true);
public void showUdfpsOverlay(int sensorId, int reason) {
UdfpsController.this.showOverlay(reason);
}
@Override
public void hideUdfpsOverlay(int sensorId) {
UdfpsController.this.setShowOverlay(false);
UdfpsController.this.hideOverlay();
}
@Override
@@ -285,17 +287,27 @@ class UdfpsController implements DozeReceiver {
return mView.getSensorRect();
}
private void setShowOverlay(boolean show) {
if (show == mIsOverlayRequested) {
private void showOverlay(int reason) {
if (mIsOverlayRequested) {
return;
}
mIsOverlayRequested = show;
mIsOverlayRequested = true;
mRequestReason = reason;
updateOverlay();
}
private void hideOverlay() {
if (!mIsOverlayRequested) {
return;
}
mIsOverlayRequested = false;
mRequestReason = IUdfpsOverlayController.REASON_UNKNOWN;
updateOverlay();
}
private void updateOverlay() {
if (mIsOverlayRequested) {
showUdfpsOverlay();
showUdfpsOverlay(mRequestReason);
} else {
hideUdfpsOverlay();
}
@@ -323,11 +335,12 @@ class UdfpsController implements DozeReceiver {
updateOverlay();
}
private void showUdfpsOverlay() {
private void showUdfpsOverlay(int reason) {
mFgExecutor.execute(() -> {
if (!mIsOverlayShowing) {
try {
Log.v(TAG, "showUdfpsOverlay | adding window");
mView.setShowReason(reason);
mWindowManager.addView(mView, computeLayoutParams());
mIsOverlayShowing = true;
mView.setOnTouchListener(mOnTouchListener);
@@ -344,6 +357,7 @@ class UdfpsController implements DozeReceiver {
mFgExecutor.execute(() -> {
if (mIsOverlayShowing) {
Log.v(TAG, "hideUdfpsOverlay | removing window");
mView.setShowReason(IUdfpsOverlayController.REASON_UNKNOWN);
mView.setOnTouchListener(null);
// Reset the controller back to its starting state.
onFingerUp();

View File

@@ -21,6 +21,7 @@ import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -29,10 +30,12 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.MathUtils;
import android.util.TypedValue;
import android.view.Surface;
import android.view.View;
import android.view.ViewTreeObserver;
@@ -81,6 +84,7 @@ public class UdfpsView extends View implements DozeReceiver,
private float mBurnInOffsetX;
private float mBurnInOffsetY;
private int mShowReason;
private boolean mShowScrimAndDot;
private boolean mIsHbmSupported;
@Nullable private String mDebugMessage;
@@ -140,6 +144,13 @@ public class UdfpsView extends View implements DozeReceiver,
mSensorProps = properties;
}
/**
* @param reason See {@link android.hardware.fingerprint.IUdfpsOverlayController}
*/
void setShowReason(int reason) {
mShowReason = reason;
}
@Override
public void dozeTimeTick() {
updateAodPosition();
@@ -208,14 +219,26 @@ public class UdfpsView extends View implements DozeReceiver,
// is finished, mTouchableRegion will be used by mInsetsListener to compute the touch
// insets.
mSensorRect.roundOut(mTouchableRegion);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
Log.v(TAG, "onAttachedToWindow");
// Retrieve the colors each time, since it depends on day/night mode
final TypedValue tv = new TypedValue();
mContext.getTheme().resolveAttribute(R.attr.wallpaperTextColor, tv, true);
final int authIconColor = mContext.getResources()
.getColor(tv.resourceId, mContext.getTheme());
final int enrollIconColor = mContext.getColor(R.color.udfps_enroll_icon);
if (mShowReason == IUdfpsOverlayController.REASON_AUTH) {
mFingerprintDrawable.setTint(authIconColor);
} else if (mShowReason == IUdfpsOverlayController.REASON_ENROLL) {
mFingerprintDrawable.setTint(enrollIconColor);
}
getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener);
}
@@ -246,6 +269,11 @@ public class UdfpsView extends View implements DozeReceiver,
// draw dot (white circle)
canvas.drawOval(mSensorRect, mSensorPaint);
} else {
final boolean isNightMode = (getResources().getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_YES) != 0;
if (mShowReason == IUdfpsOverlayController.REASON_ENROLL && !isNightMode) {
canvas.drawOval(mSensorRect, mSensorPaint);
}
// draw fingerprint icon
mFingerprintDrawable.draw(canvas);
}

View File

@@ -160,14 +160,16 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Test
public void showUdfpsOverlay_addsViewToWindow() throws RemoteException {
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH);
mFgExecutor.runAllReady();
verify(mWindowManager).addView(eq(mUdfpsView), any());
}
@Test
public void hideUdfpsOverlay_removesViewFromWindow() throws RemoteException {
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH);
mOverlayController.hideUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
mFgExecutor.runAllReady();
verify(mWindowManager).removeView(eq(mUdfpsView));
@@ -180,7 +182,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
when(mUdfpsView.isValidTouch(anyFloat(), anyFloat(), anyFloat())).thenReturn(true);
// GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH);
mFgExecutor.runAllReady();
// WHEN ACTION_DOWN is received
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
@@ -197,7 +200,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Test
public void aodInterrupt() throws RemoteException {
// GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH);
mFgExecutor.runAllReady();
// WHEN fingerprint is requested because of AOD interrupt
mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
@@ -211,7 +215,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Test
public void cancelAodInterrupt() throws RemoteException {
// GIVEN AOD interrupt
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH);
mFgExecutor.runAllReady();
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
// WHEN it is cancelled
@@ -223,7 +228,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Test
public void aodInterruptTimeout() throws RemoteException {
// GIVEN AOD interrupt
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH);
mFgExecutor.runAllReady();
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
// WHEN it times out

View File

@@ -62,13 +62,13 @@ public class UdfpsHelper {
}
}
public static void showUdfpsOverlay(int sensorId,
public static void showUdfpsOverlay(int sensorId, int reason,
@Nullable IUdfpsOverlayController udfpsOverlayController) {
if (udfpsOverlayController == null) {
return;
}
try {
udfpsOverlayController.showUdfpsOverlay(sensorId);
udfpsOverlayController.showUdfpsOverlay(sensorId, reason);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when showing the UDFPS overlay", e);
}

View File

@@ -80,7 +80,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
@Override
protected void startHalOperation() {
UdfpsHelper.showUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
UdfpsHelper.showUdfpsOverlay(getSensorId(), IUdfpsOverlayController.REASON_AUTH,
mUdfpsOverlayController);
try {
mCancellationSignal = getFreshDaemon().authenticate(mSequentialId, mOperationId);
} catch (RemoteException e) {

View File

@@ -69,7 +69,8 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> {
@Override
protected void startHalOperation() {
UdfpsHelper.showUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
UdfpsHelper.showUdfpsOverlay(getSensorId(), IUdfpsOverlayController.REASON_AUTH,
mUdfpsOverlayController);
try {
mCancellationSignal = getFreshDaemon().detectInteraction(mSequentialId);
} catch (RemoteException e) {

View File

@@ -94,7 +94,8 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
@Override
protected void startHalOperation() {
UdfpsHelper.showUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
UdfpsHelper.showUdfpsOverlay(getSensorId(), IUdfpsOverlayController.REASON_ENROLL,
mUdfpsOverlayController);
try {
mCancellationSignal = getFreshDaemon().enroll(mSequentialId,
HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken));

View File

@@ -113,7 +113,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
@Override
protected void startHalOperation() {
UdfpsHelper.showUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
UdfpsHelper.showUdfpsOverlay(getSensorId(), IUdfpsOverlayController.REASON_AUTH,
mUdfpsOverlayController);
try {
// GroupId was never used. In fact, groupId is always the same as userId.
getFreshDaemon().authenticate(mOperationId, getTargetUserId());

View File

@@ -82,7 +82,8 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
@Override
protected void startHalOperation() {
UdfpsHelper.showUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
UdfpsHelper.showUdfpsOverlay(getSensorId(), IUdfpsOverlayController.REASON_AUTH,
mUdfpsOverlayController);
try {
getFreshDaemon().authenticate(0 /* operationId */, getTargetUserId());
} catch (RemoteException e) {

View File

@@ -76,7 +76,8 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
@Override
protected void startHalOperation() {
UdfpsHelper.showUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
UdfpsHelper.showUdfpsOverlay(getSensorId(), IUdfpsOverlayController.REASON_ENROLL,
mUdfpsOverlayController);
try {
// GroupId was never used. In fact, groupId is always the same as userId.
getFreshDaemon().enroll(mHardwareAuthToken, getTargetUserId(), mTimeoutSec);