diff options
20 files changed, 409 insertions, 113 deletions
diff --git a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl index aced9c7c4562..c3b6c052500a 100644 --- a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl +++ b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl @@ -22,7 +22,9 @@ package android.hardware.fingerprint; oneway interface IUdfpsOverlayController { const int REASON_UNKNOWN = 0; const int REASON_ENROLL = 1; - const int REASON_AUTH = 2; + const int REASON_AUTH_BP = 2; // BiometricPrompt + const int REASON_AUTH_FPM_KEYGUARD = 3; // FingerprintManager usage from Keyguard + const int REASON_AUTH_FPM_OTHER = 4; // Other FingerprintManager usage // Shows the overlay. void showUdfpsOverlay(int sensorId, int reason); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java new file mode 100644 index 000000000000..5fc2e5361689 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java @@ -0,0 +1,50 @@ +/* + * 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.content.Context; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; + +import androidx.annotation.NonNull; + +import com.android.systemui.R; + +/** + * Abstract base class for animations that should be drawn when the finger is not touching the + * sensor area. + */ +public abstract class UdfpsAnimation extends Drawable { + abstract void updateColor(); + + @NonNull protected final Context mContext; + @NonNull protected final Drawable mFingerprintDrawable; + + public UdfpsAnimation(@NonNull Context context) { + mContext = context; + mFingerprintDrawable = context.getResources().getDrawable(R.drawable.ic_fingerprint, null); + } + + public void onSensorRectUpdated(@NonNull RectF sensorRect) { + int margin = (int) (sensorRect.bottom - sensorRect.top) / 5; + mFingerprintDrawable.setBounds( + (int) sensorRect.left + margin, + (int) sensorRect.top + margin, + (int) sensorRect.right - margin, + (int) sensorRect.bottom - margin); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationEnroll.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationEnroll.java new file mode 100644 index 000000000000..1a2a4927c3fd --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationEnroll.java @@ -0,0 +1,88 @@ +/* + * 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.content.Context; +import android.content.res.Configuration; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.RectF; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.systemui.R; + +/** + * UDFPS animations that should be shown when enrolling. + */ +public class UdfpsAnimationEnroll extends UdfpsAnimation { + private static final String TAG = "UdfpsAnimationEnroll"; + + @Nullable private RectF mSensorRect; + @NonNull private final Paint mSensorPaint; + + UdfpsAnimationEnroll(@NonNull Context context) { + super(context); + + mSensorPaint = new Paint(0 /* flags */); + mSensorPaint.setAntiAlias(true); + mSensorPaint.setColor(Color.WHITE); + mSensorPaint.setShadowLayer(UdfpsView.SENSOR_SHADOW_RADIUS, 0, 0, Color.BLACK); + mSensorPaint.setStyle(Paint.Style.FILL); + } + + @Override + void updateColor() { + mFingerprintDrawable.setTint(mContext.getColor(R.color.udfps_enroll_icon)); + } + + @Override + public void onSensorRectUpdated(@NonNull RectF sensorRect) { + super.onSensorRectUpdated(sensorRect); + mSensorRect = sensorRect; + } + + @Override + public void draw(@NonNull Canvas canvas) { + final boolean isNightMode = (mContext.getResources().getConfiguration().uiMode + & Configuration.UI_MODE_NIGHT_YES) != 0; + if (!isNightMode) { + if (mSensorRect != null) { + canvas.drawOval(mSensorRect, mSensorPaint); + } + } + mFingerprintDrawable.draw(canvas); + } + + @Override + public void setAlpha(int alpha) { + + } + + @Override + public void setColorFilter(@Nullable ColorFilter colorFilter) { + + } + + @Override + public int getOpacity() { + return 0; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationFpmOther.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationFpmOther.java new file mode 100644 index 000000000000..7563e739c93a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationFpmOther.java @@ -0,0 +1,60 @@ +/* + * 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.content.Context; +import android.graphics.Canvas; +import android.graphics.ColorFilter; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +/** + * UDFPS animations that should be shown when authenticating via FingerprintManager, excluding + * keyguard. + */ +public class UdfpsAnimationFpmOther extends UdfpsAnimation { + + UdfpsAnimationFpmOther(@NonNull Context context) { + super(context); + } + + @Override + void updateColor() { + + } + + @Override + public void draw(@NonNull Canvas canvas) { + mFingerprintDrawable.draw(canvas); + } + + @Override + public void setAlpha(int alpha) { + + } + + @Override + public void setColorFilter(@Nullable ColorFilter colorFilter) { + + } + + @Override + public int getOpacity() { + return 0; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java new file mode 100644 index 000000000000..3e46a656ecd5 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java @@ -0,0 +1,124 @@ +/* + * 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 static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.util.MathUtils; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.internal.graphics.ColorUtils; +import com.android.settingslib.Utils; +import com.android.systemui.R; +import com.android.systemui.doze.DozeReceiver; +import com.android.systemui.plugins.statusbar.StatusBarStateController; + +/** + * UDFPS animations that should be shown when authenticating on keyguard. + */ +public class UdfpsAnimationKeyguard extends UdfpsAnimation implements DozeReceiver, + StatusBarStateController.StateListener { + + private static final String TAG = "UdfpsAnimationKeyguard"; + + @NonNull private final View mParent; + @NonNull private final Context mContext; + private final int mMaxBurnInOffsetX; + private final int mMaxBurnInOffsetY; + + // AOD anti-burn-in offsets + private float mInterpolatedDarkAmount; + private float mBurnInOffsetX; + private float mBurnInOffsetY; + + UdfpsAnimationKeyguard(@NonNull View parent, @NonNull Context context, + @NonNull StatusBarStateController statusBarStateController) { + super(context); + mParent = parent; + mContext = context; + + mMaxBurnInOffsetX = context.getResources() + .getDimensionPixelSize(R.dimen.udfps_burn_in_offset_x); + mMaxBurnInOffsetY = context.getResources() + .getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y); + + statusBarStateController.addCallback(this); + } + + private void updateAodPositionAndColor() { + mBurnInOffsetX = MathUtils.lerp(0f, + getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */) + - mMaxBurnInOffsetX, + mInterpolatedDarkAmount); + mBurnInOffsetY = MathUtils.lerp(0f, + getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */) + - 0.5f * mMaxBurnInOffsetY, + mInterpolatedDarkAmount); + updateColor(); + mParent.postInvalidate(); + } + + @Override + public void dozeTimeTick() { + updateAodPositionAndColor(); + } + + @Override + public void onDozeAmountChanged(float linear, float eased) { + mInterpolatedDarkAmount = eased; + updateAodPositionAndColor(); + } + + @Override + public void draw(@NonNull Canvas canvas) { + canvas.save(); + canvas.translate(mBurnInOffsetX, mBurnInOffsetY); + mFingerprintDrawable.draw(canvas); + canvas.restore(); + } + + @Override + public void setAlpha(int alpha) { + + } + + @Override + public void setColorFilter(@Nullable ColorFilter colorFilter) { + + } + + @Override + public int getOpacity() { + return 0; + } + + @Override + public void updateColor() { + final int lockScreenIconColor = Utils.getColorAttrDefaultColor(mContext, + R.attr.wallpaperTextColor); + final int ambientDisplayIconColor = Color.WHITE; + mFingerprintDrawable.setTint(ColorUtils.blendARGB(lockScreenIconColor, + ambientDisplayIconColor, mInterpolatedDarkAmount)); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 1cafb4c2c313..a2b2bea8a06f 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -81,6 +81,7 @@ class UdfpsController implements DozeReceiver { private final WindowManager mWindowManager; private final SystemSettings mSystemSettings; private final DelayableExecutor mFgExecutor; + private final StatusBarStateController mStatusBarStateController; // 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. @VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps; @@ -181,6 +182,7 @@ class UdfpsController implements DozeReceiver { mWindowManager = windowManager; mSystemSettings = systemSettings; mFgExecutor = fgExecutor; + mStatusBarStateController = statusBarStateController; mSensorProps = findFirstUdfps(); // At least one UDFPS sensor exists @@ -208,7 +210,6 @@ class UdfpsController implements DozeReceiver { mHbmSupported = !TextUtils.isEmpty(mHbmPath); mView.setHbmSupported(mHbmSupported); - statusBarStateController.addCallback(mView); // This range only consists of the minimum and maximum values, which only cover // non-high-brightness mode. @@ -340,7 +341,7 @@ class UdfpsController implements DozeReceiver { if (!mIsOverlayShowing) { try { Log.v(TAG, "showUdfpsOverlay | adding window"); - mView.setShowReason(reason); + mView.setUdfpsAnimation(getUdfpsAnimationForReason(reason)); mWindowManager.addView(mView, computeLayoutParams()); mView.setOnTouchListener(mOnTouchListener); mIsOverlayShowing = true; @@ -353,11 +354,27 @@ class UdfpsController implements DozeReceiver { }); } + @Nullable + private UdfpsAnimation getUdfpsAnimationForReason(int reason) { + Log.d(TAG, "getUdfpsAnimationForReason: " + reason); + switch (reason) { + case IUdfpsOverlayController.REASON_ENROLL: + return new UdfpsAnimationEnroll(mContext); + case IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD: + return new UdfpsAnimationKeyguard(mView, mContext, mStatusBarStateController); + case IUdfpsOverlayController.REASON_AUTH_FPM_OTHER: + return new UdfpsAnimationFpmOther(mContext); + default: + Log.d(TAG, "Animation for reason " + reason + " not supported yet"); + return null; + } + } + private void hideUdfpsOverlay() { mFgExecutor.execute(() -> { if (mIsOverlayShowing) { Log.v(TAG, "hideUdfpsOverlay | removing window"); - mView.setShowReason(IUdfpsOverlayController.REASON_UNKNOWN); + mView.setUdfpsAnimation(null); mView.setOnTouchListener(null); // Reset the controller back to its starting state. onFingerUp(); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java index 033a3555394e..4cb8101385ea 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java @@ -16,45 +16,34 @@ package com.android.systemui.biometrics; -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; import android.graphics.Paint; 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.view.Surface; import android.view.View; import android.view.ViewTreeObserver; -import com.android.internal.graphics.ColorUtils; -import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.doze.DozeReceiver; -import com.android.systemui.plugins.statusbar.StatusBarStateController; /** * A full screen view with a configurable illumination dot and scrim. */ -public class UdfpsView extends View implements DozeReceiver, - StatusBarStateController.StateListener { +public class UdfpsView extends View implements DozeReceiver { private static final String TAG = "UdfpsView"; // Values in pixels. - private static final float SENSOR_SHADOW_RADIUS = 2.0f; - private static final float SENSOR_OUTLINE_WIDTH = 2.0f; + public static final float SENSOR_SHADOW_RADIUS = 2.0f; private static final int DEBUG_TEXT_SIZE_PX = 32; @@ -65,8 +54,7 @@ public class UdfpsView extends View implements DozeReceiver, @NonNull private final RectF mSensorRect; @NonNull private final Paint mSensorPaint; private final float mSensorTouchAreaCoefficient; - private final int mMaxBurnInOffsetX; - private final int mMaxBurnInOffsetY; + // Stores rounded up values from mSensorRect. Necessary for APIs that only take Rect (not RecF). @NonNull private final Rect mTouchableRegion; @@ -75,17 +63,11 @@ public class UdfpsView extends View implements DozeReceiver, // mInsetsListener to restrict the touchable region and allow the touches outside of the sensor // to propagate to the rest of the UI. @NonNull private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener; - @NonNull private final Drawable mFingerprintDrawable; + @Nullable private UdfpsAnimation mUdfpsAnimation; // Used to obtain the sensor location. @NonNull private FingerprintSensorPropertiesInternal mSensorProps; - // AOD anti-burn-in offsets - private float mInterpolatedDarkAmount; - private float mBurnInOffsetX; - private float mBurnInOffsetY; - - private int mShowReason; private boolean mShowScrimAndDot; private boolean mIsHbmSupported; @Nullable private String mDebugMessage; @@ -110,10 +92,6 @@ public class UdfpsView extends View implements DozeReceiver, a.recycle(); } - mMaxBurnInOffsetX = getResources() - .getDimensionPixelSize(R.dimen.udfps_burn_in_offset_x); - mMaxBurnInOffsetY = getResources() - .getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y); mScrimRect = new Rect(); mScrimPaint = new Paint(0 /* flags */); @@ -131,8 +109,6 @@ public class UdfpsView extends View implements DozeReceiver, mDebugTextPaint.setColor(Color.BLUE); mDebugTextPaint.setTextSize(DEBUG_TEXT_SIZE_PX); - mFingerprintDrawable = getResources().getDrawable(R.drawable.ic_fingerprint, null); - mTouchableRegion = new Rect(); // When the device is rotated, it's important that mTouchableRegion is updated before // this listener is called. This listener is usually called shortly after onLayout. @@ -149,39 +125,20 @@ public class UdfpsView extends View implements DozeReceiver, mSensorProps = properties; } - /** - * @param reason See {@link android.hardware.fingerprint.IUdfpsOverlayController} - */ - void setShowReason(int reason) { - mShowReason = reason; + void setUdfpsAnimation(@Nullable UdfpsAnimation animation) { + mUdfpsAnimation = animation; } - @Override - public void dozeTimeTick() { - updateAodPositionAndColor(); - } @Override - public void onDozeAmountChanged(float linear, float eased) { - mInterpolatedDarkAmount = eased; - updateAodPositionAndColor(); - } - - private void updateAodPositionAndColor() { - mBurnInOffsetX = MathUtils.lerp(0f, - getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */) - - mMaxBurnInOffsetX, - mInterpolatedDarkAmount); - mBurnInOffsetY = MathUtils.lerp(0f, - getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */) - - 0.5f * mMaxBurnInOffsetY, - mInterpolatedDarkAmount); - updateColor(); - postInvalidate(); + public void dozeTimeTick() { + if (mUdfpsAnimation instanceof DozeReceiver) { + ((DozeReceiver) mUdfpsAnimation).dozeTimeTick(); + } } // The "h" and "w" are the display's height and width relative to its current rotation. - private void updateSensorRect(int h, int w) { + protected void updateSensorRect(int h, int w) { // mSensorProps coordinates assume portrait mode. mSensorRect.set(mSensorProps.sensorLocationX - mSensorProps.sensorRadius, mSensorProps.sensorLocationY - mSensorProps.sensorRadius, @@ -202,12 +159,9 @@ public class UdfpsView extends View implements DozeReceiver, // Do nothing to stay in portrait mode. } - int margin = (int) (mSensorRect.bottom - mSensorRect.top) / 5; - mFingerprintDrawable.setBounds( - (int) mSensorRect.left + margin, - (int) mSensorRect.top + margin, - (int) mSensorRect.right - margin, - (int) mSensorRect.bottom - margin); + if (mUdfpsAnimation != null) { + mUdfpsAnimation.onSensorRectUpdated(new RectF(mSensorRect)); + } } @Override @@ -239,14 +193,8 @@ public class UdfpsView extends View implements DozeReceiver, } private void updateColor() { - if (mShowReason == IUdfpsOverlayController.REASON_AUTH) { - final int lockScreenIconColor = Utils.getColorAttrDefaultColor(mContext, - com.android.systemui.R.attr.wallpaperTextColor); - final int ambientDisplayIconColor = Color.WHITE; - mFingerprintDrawable.setTint(ColorUtils.blendARGB(lockScreenIconColor, - ambientDisplayIconColor, mInterpolatedDarkAmount)); - } else if (mShowReason == IUdfpsOverlayController.REASON_ENROLL) { - mFingerprintDrawable.setTint(mContext.getColor(R.color.udfps_enroll_icon)); + if (mUdfpsAnimation != null) { + mUdfpsAnimation.updateColor(); } } @@ -266,9 +214,6 @@ public class UdfpsView extends View implements DozeReceiver, canvas.drawRect(mScrimRect, mScrimPaint); } - // Translation should affect everything but the scrim. - canvas.save(); - canvas.translate(mBurnInOffsetX, mBurnInOffsetY); if (!TextUtils.isEmpty(mDebugMessage)) { canvas.drawText(mDebugMessage, 0, 160, mDebugTextPaint); } @@ -277,17 +222,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); + if (mUdfpsAnimation != null) { + mUdfpsAnimation.draw(canvas); } - // draw fingerprint icon - mFingerprintDrawable.draw(canvas); } - canvas.restore(); - if (mShowScrimAndDot && mRunAfterShowingScrimAndDot != null) { post(mRunAfterShowingScrimAndDot); mRunAfterShowingScrimAndDot = null; diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index c052563b36a5..ed3cf9a49a34 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -162,7 +162,7 @@ public class UdfpsControllerTest extends SysuiTestCase { @Test public void showUdfpsOverlay_addsViewToWindow() throws RemoteException { mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH); + IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD); mFgExecutor.runAllReady(); verify(mWindowManager).addView(eq(mUdfpsView), any()); } @@ -170,7 +170,7 @@ public class UdfpsControllerTest extends SysuiTestCase { @Test public void hideUdfpsOverlay_removesViewFromWindow() throws RemoteException { mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH); + IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD); mOverlayController.hideUdfpsOverlay(TEST_UDFPS_SENSOR_ID); mFgExecutor.runAllReady(); verify(mWindowManager).removeView(eq(mUdfpsView)); @@ -184,7 +184,7 @@ public class UdfpsControllerTest extends SysuiTestCase { // GIVEN that the overlay is showing mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH); + IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD); mFgExecutor.runAllReady(); // WHEN ACTION_DOWN is received verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); @@ -205,7 +205,7 @@ public class UdfpsControllerTest extends SysuiTestCase { public void aodInterrupt() throws RemoteException { // GIVEN that the overlay is showing mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH); + IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD); mFgExecutor.runAllReady(); // WHEN fingerprint is requested because of AOD interrupt mUdfpsController.onAodInterrupt(0, 0, 2f, 3f); @@ -223,7 +223,7 @@ public class UdfpsControllerTest extends SysuiTestCase { public void cancelAodInterrupt() throws RemoteException { // GIVEN AOD interrupt mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH); + IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD); mFgExecutor.runAllReady(); mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); // WHEN it is cancelled @@ -236,7 +236,7 @@ public class UdfpsControllerTest extends SysuiTestCase { public void aodInterruptTimeout() throws RemoteException { // GIVEN AOD interrupt mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - IUdfpsOverlayController.REASON_AUTH); + IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD); mFgExecutor.runAllReady(); mUdfpsController.onAodInterrupt(0, 0, 0f, 0f); // WHEN it times out diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java index 55ac24835b2a..d87af4280ca3 100644 --- a/services/core/java/com/android/server/biometrics/Utils.java +++ b/services/core/java/com/android/server/biometrics/Utils.java @@ -50,6 +50,7 @@ import android.hardware.biometrics.IBiometricService; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorProperties; import android.hardware.biometrics.SensorPropertiesInternal; +import android.hardware.fingerprint.IUdfpsOverlayController; import android.os.Binder; import android.os.Build; import android.os.RemoteException; @@ -61,6 +62,7 @@ import android.util.Slog; import com.android.internal.R; import com.android.internal.widget.LockPatternUtils; +import com.android.server.biometrics.sensors.AuthenticationClient; import com.android.server.biometrics.sensors.BaseClientMonitor; import java.util.List; @@ -478,4 +480,14 @@ public class Utils { throw new IllegalArgumentException("Unknown strength: " + strength); } } + + public static int getUdfpsAuthReason(@NonNull AuthenticationClient<?> client) { + if (client.isKeyguard()) { + return IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD; + } else if (client.isBiometricPrompt()) { + return IUdfpsOverlayController.REASON_AUTH_BP; + } else { + return IUdfpsOverlayController.REASON_AUTH_FPM_OTHER; + } + } } diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java index 3f6ae6439aa4..14433fb0ea9a 100644 --- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java @@ -53,6 +53,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> @Nullable private final TaskStackListener mTaskStackListener; private final LockoutTracker mLockoutTracker; private final boolean mIsRestricted; + private final boolean mIsKeyguard; protected final long mOperationId; @@ -65,7 +66,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> int targetUserId, long operationId, boolean restricted, @NonNull String owner, int cookie, boolean requireConfirmation, int sensorId, boolean isStrongBiometric, int statsModality, int statsClient, @Nullable TaskStackListener taskStackListener, - @NonNull LockoutTracker lockoutTracker) { + @NonNull LockoutTracker lockoutTracker, boolean isKeyguard) { super(context, lazyDaemon, token, listener, targetUserId, owner, cookie, sensorId, statsModality, BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient); mIsStrongBiometric = isStrongBiometric; @@ -75,6 +76,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> mTaskStackListener = taskStackListener; mLockoutTracker = lockoutTracker; mIsRestricted = restricted; + mIsKeyguard = isKeyguard; } public @LockoutTracker.LockoutMode int handleFailedAttempt(int userId) { @@ -114,6 +116,10 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> return mIsRestricted; } + public boolean isKeyguard() { + return mIsKeyguard; + } + @Override protected boolean isCryptoOperation() { return mOperationId != 0; diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java index 80f337f0f600..a7bfc4b16dc8 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java @@ -67,11 +67,11 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements @NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId, boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId, boolean isStrongBiometric, int statsClient, @NonNull UsageStats usageStats, - @NonNull LockoutCache lockoutCache) { + @NonNull LockoutCache lockoutCache, boolean isKeyguard) { super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner, cookie, requireConfirmation, sensorId, isStrongBiometric, BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */, - lockoutCache); + lockoutCache, isKeyguard); mUsageStats = usageStats; mLockoutCache = lockoutCache; mNotificationManager = context.getSystemService(NotificationManager.class); diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java index 20318e3f836a..f7feffddb343 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java @@ -451,7 +451,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { mContext, mSensors.get(sensorId).getLazySession(), token, callback, userId, operationId, restricted, opPackageName, cookie, false /* requireConfirmation */, sensorId, isStrongBiometric, statsClient, - mUsageStats, mSensors.get(sensorId).getLockoutCache()); + mUsageStats, mSensors.get(sensorId).getLockoutCache(), isKeyguard); mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client); } catch (RemoteException e) { Slog.e(getTag(), "Remote exception when scheduling authenticate", e); diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java index 7010d9669b8d..775d8d417dda 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java @@ -646,7 +646,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { final FaceAuthenticationClient client = new FaceAuthenticationClient(mContext, mLazyDaemon, token, receiver, userId, operationId, restricted, opPackageName, cookie, false /* requireConfirmation */, mSensorId, isStrongBiometric, - statsClient, mLockoutTracker, mUsageStats); + statsClient, mLockoutTracker, mUsageStats, isKeyguard); mScheduler.scheduleClientMonitor(client); }); } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java index 9dc84394df44..0b78dd01f855 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java @@ -66,12 +66,12 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> { @NonNull LazyDaemon<IBiometricsFace> lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId, boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId, - boolean isStrongBiometric, int statsClient, - @NonNull LockoutTracker lockoutTracker, @NonNull UsageStats usageStats) { + boolean isStrongBiometric, int statsClient, @NonNull LockoutTracker lockoutTracker, + @NonNull UsageStats usageStats, boolean isKeyguard) { super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner, cookie, requireConfirmation, sensorId, isStrongBiometric, BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */, - lockoutTracker); + lockoutTracker, isKeyguard); mNotificationManager = context.getSystemService(NotificationManager.class); mUsageStats = usageStats; diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java index bd57fea25453..f9527d9379bc 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java @@ -30,6 +30,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; +import com.android.server.biometrics.Utils; import com.android.server.biometrics.sensors.AuthenticationClient; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.LockoutCache; @@ -58,11 +59,11 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp boolean restricted, @NonNull String owner, int cookie, boolean requireConfirmation, int sensorId, boolean isStrongBiometric, int statsClient, @Nullable TaskStackListener taskStackListener, @NonNull LockoutCache lockoutCache, - @Nullable IUdfpsOverlayController udfpsOverlayController) { + @Nullable IUdfpsOverlayController udfpsOverlayController, boolean isKeyguard) { super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner, cookie, requireConfirmation, sensorId, isStrongBiometric, BiometricsProtoEnums.MODALITY_FINGERPRINT, statsClient, taskStackListener, - lockoutCache); + lockoutCache, isKeyguard); mLockoutCache = lockoutCache; mUdfpsOverlayController = udfpsOverlayController; } @@ -87,7 +88,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp @Override protected void startHalOperation() { - UdfpsHelper.showUdfpsOverlay(getSensorId(), IUdfpsOverlayController.REASON_AUTH, + UdfpsHelper.showUdfpsOverlay(getSensorId(), Utils.getUdfpsAuthReason(this), mUdfpsOverlayController); try { mCancellationSignal = getFreshDaemon().authenticate(mSequentialId, mOperationId); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java index b4bb4f87a379..9611192fa13e 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java @@ -70,7 +70,8 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> { @Override protected void startHalOperation() { - UdfpsHelper.showUdfpsOverlay(getSensorId(), IUdfpsOverlayController.REASON_AUTH, + UdfpsHelper.showUdfpsOverlay(getSensorId(), + IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayController); try { mCancellationSignal = getFreshDaemon().detectInteraction(mSequentialId); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java index 727184f183c1..f8450245a18d 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java @@ -466,7 +466,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi operationId, restricted, opPackageName, cookie, false /* requireConfirmation */, sensorId, isStrongBiometric, statsClient, mTaskStackListener, mSensors.get(sensorId).getLockoutCache(), - mUdfpsOverlayController); + mUdfpsOverlayController, isKeyguard); mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client); } catch (RemoteException e) { Slog.e(getTag(), "Remote exception when scheduling authenticate", e); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java index 589db6c82488..83a3d9492b22 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java @@ -30,6 +30,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; +import com.android.server.biometrics.Utils; import com.android.server.biometrics.sensors.AuthenticationClient; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.LockoutTracker; @@ -48,7 +49,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi private static final String TAG = "Biometrics/FingerprintAuthClient"; - private final boolean mIsKeyguard; private final LockoutFrameworkImpl mLockoutFrameworkImpl; @Nullable private final IUdfpsOverlayController mUdfpsOverlayController; @@ -63,10 +63,9 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner, cookie, requireConfirmation, sensorId, isStrongBiometric, BiometricsProtoEnums.MODALITY_FINGERPRINT, statsClient, taskStackListener, - lockoutTracker); + lockoutTracker, isKeyguard); mLockoutFrameworkImpl = lockoutTracker; mUdfpsOverlayController = udfpsOverlayController; - mIsKeyguard = isKeyguard; } @Override @@ -120,7 +119,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi @Override protected void startHalOperation() { - UdfpsHelper.showUdfpsOverlay(getSensorId(), IUdfpsOverlayController.REASON_AUTH, + UdfpsHelper.showUdfpsOverlay(getSensorId(), Utils.getUdfpsAuthReason(this), mUdfpsOverlayController); try { // GroupId was never used. In fact, groupId is always the same as userId. @@ -170,8 +169,4 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi } } } - - public boolean isKeyguard() { - return mIsKeyguard; - } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java index 6318139f3aae..7989dca3e06f 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java @@ -83,7 +83,8 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint> @Override protected void startHalOperation() { - UdfpsHelper.showUdfpsOverlay(getSensorId(), IUdfpsOverlayController.REASON_AUTH, + UdfpsHelper.showUdfpsOverlay(getSensorId(), + IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayController); try { getFreshDaemon().authenticate(0 /* operationId */, getTargetUserId()); diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java index 832f918c8044..90ce6cbb7718 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java @@ -34,7 +34,6 @@ import android.hardware.biometrics.IBiometricService; import android.os.Binder; import android.os.IBinder; import android.platform.test.annotations.Presubmit; -import android.util.proto.ProtoOutputStream; import androidx.annotation.NonNull; import androidx.test.InstrumentationRegistry; @@ -279,7 +278,8 @@ public class BiometricSchedulerTest { super(context, lazyDaemon, token, listener, 0 /* targetUserId */, 0 /* operationId */, false /* restricted */, TAG, 1 /* cookie */, false /* requireConfirmation */, TEST_SENSOR_ID, true /* isStrongBiometric */, 0 /* statsModality */, - 0 /* statsClient */, null /* taskStackListener */, mock(LockoutTracker.class)); + 0 /* statsClient */, null /* taskStackListener */, mock(LockoutTracker.class), + false /* isKeyguard */); } @Override |