summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/layout/udfps_bp_view.xml (renamed from packages/SystemUI/res/layout/udfps_animation_view_bp.xml)4
-rw-r--r--packages/SystemUI/res/layout/udfps_enroll_view.xml (renamed from packages/SystemUI/res/layout/udfps_animation_view_enroll.xml)11
-rw-r--r--packages/SystemUI/res/layout/udfps_fpm_other_view.xml (renamed from packages/SystemUI/res/layout/udfps_animation_view_fpm_other.xml)10
-rw-r--r--packages/SystemUI/res/layout/udfps_keyguard_view.xml (renamed from packages/SystemUI/res/layout/udfps_animation_view_keyguard.xml)12
-rw-r--r--packages/SystemUI/res/layout/udfps_view.xml5
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java135
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java167
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewEnroll.java96
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpView.java (renamed from packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewBp.java)19
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java112
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.java (renamed from packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java)45
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollDrawable.java (renamed from packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationEnroll.java)51
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollView.java (renamed from packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewKeyguard.java)32
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollViewController.java92
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpDrawable.java (renamed from packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationFpmOther.java)29
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherView.java (renamed from packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewFpmOther.java)27
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherViewController.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardDrawable.java (renamed from packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java)59
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java60
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java81
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java90
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java138
25 files changed, 853 insertions, 509 deletions
diff --git a/packages/SystemUI/res/layout/udfps_animation_view_bp.xml b/packages/SystemUI/res/layout/udfps_bp_view.xml
index 0cfbf2e61dd1..f1c55ef16cdc 100644
--- a/packages/SystemUI/res/layout/udfps_animation_view_bp.xml
+++ b/packages/SystemUI/res/layout/udfps_bp_view.xml
@@ -14,9 +14,9 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<com.android.systemui.biometrics.UdfpsAnimationViewBp
+<com.android.systemui.biometrics.UdfpsBpView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/udfps_animation_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
-</com.android.systemui.biometrics.UdfpsAnimationViewBp>
+</com.android.systemui.biometrics.UdfpsBpView>
diff --git a/packages/SystemUI/res/layout/udfps_animation_view_enroll.xml b/packages/SystemUI/res/layout/udfps_enroll_view.xml
index 9b5752d2de59..40353052ca85 100644
--- a/packages/SystemUI/res/layout/udfps_animation_view_enroll.xml
+++ b/packages/SystemUI/res/layout/udfps_enroll_view.xml
@@ -14,13 +14,13 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<com.android.systemui.biometrics.UdfpsAnimationViewEnroll
+<com.android.systemui.biometrics.UdfpsEnrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/udfps_animation_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <!-- Enrollment progress bar-->
+ <!-- Enrollment progress bar -->
<com.android.systemui.biometrics.UdfpsProgressBar
android:id="@+id/progress_bar"
android:layout_width="match_parent"
@@ -31,4 +31,9 @@
android:layout_gravity="center"
android:visibility="gone"/>
-</com.android.systemui.biometrics.UdfpsAnimationViewEnroll>
+ <!-- Fingerprint -->
+ <ImageView
+ android:id="@+id/udfps_enroll_animation_fp_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+</com.android.systemui.biometrics.UdfpsEnrollView>
diff --git a/packages/SystemUI/res/layout/udfps_animation_view_fpm_other.xml b/packages/SystemUI/res/layout/udfps_fpm_other_view.xml
index f32faa0df867..6ecbb473d720 100644
--- a/packages/SystemUI/res/layout/udfps_animation_view_fpm_other.xml
+++ b/packages/SystemUI/res/layout/udfps_fpm_other_view.xml
@@ -14,9 +14,15 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<com.android.systemui.biometrics.UdfpsAnimationViewFpmOther
+<com.android.systemui.biometrics.UdfpsFpmOtherView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/udfps_animation_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
-</com.android.systemui.biometrics.UdfpsAnimationViewFpmOther>
+
+ <!-- Fingerprint -->
+ <ImageView
+ android:id="@+id/udfps_fpm_other_fp_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+</com.android.systemui.biometrics.UdfpsFpmOtherView>
diff --git a/packages/SystemUI/res/layout/udfps_animation_view_keyguard.xml b/packages/SystemUI/res/layout/udfps_keyguard_view.xml
index 644d1adac46b..0199ccb04be6 100644
--- a/packages/SystemUI/res/layout/udfps_animation_view_keyguard.xml
+++ b/packages/SystemUI/res/layout/udfps_keyguard_view.xml
@@ -14,9 +14,17 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<com.android.systemui.biometrics.UdfpsAnimationViewKeyguard
+<com.android.systemui.biometrics.UdfpsKeyguardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/udfps_animation_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
-</com.android.systemui.biometrics.UdfpsAnimationViewKeyguard>
+
+ <!-- TODO: add background protection -->
+
+ <!-- Fingerprint -->
+ <ImageView
+ android:id="@+id/udfps_keyguard_animation_fp_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+</com.android.systemui.biometrics.UdfpsKeyguardView>
diff --git a/packages/SystemUI/res/layout/udfps_view.xml b/packages/SystemUI/res/layout/udfps_view.xml
index e24c9e99a405..50b2f209d871 100644
--- a/packages/SystemUI/res/layout/udfps_view.xml
+++ b/packages/SystemUI/res/layout/udfps_view.xml
@@ -22,6 +22,11 @@
android:layout_height="match_parent"
systemui:sensorTouchAreaCoefficient="0.5">
+ <ViewStub
+ android:id="@+id/animation_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+
<com.android.systemui.biometrics.UdfpsSurfaceView
android:id="@+id/hbm_view"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
index 43ecf6778022..2036150d3679 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
@@ -16,57 +16,63 @@
package com.android.systemui.biometrics;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.PointF;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.widget.FrameLayout;
-import com.android.systemui.doze.DozeReceiver;
-import com.android.systemui.statusbar.phone.StatusBar;
-
/**
* Base class for views containing UDFPS animations. Note that this is a FrameLayout so that we
- * can support multiple child views drawing on the same region around the sensor location.
+ * can support multiple child views drawing in the same region around the sensor location.
+ *
+ * - hides animation view when pausing auth
+ * - sends illumination events to fingerprint drawable
+ * - sends sensor rect updates to fingerprint drawable
+ * - optionally can override dozeTimeTick to adjust views for burn-in mitigation
*/
-public abstract class UdfpsAnimationView extends FrameLayout implements DozeReceiver,
- StatusBar.ExpansionChangedListener {
-
- private static final String TAG = "UdfpsAnimationView";
+abstract class UdfpsAnimationView extends FrameLayout {
- @Nullable protected abstract UdfpsAnimation getUdfpsAnimation();
-
- @NonNull private UdfpsView mParent;
- @NonNull private RectF mSensorRect;
private int mAlpha;
+ private boolean mPauseAuth;
public UdfpsAnimationView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
- mSensorRect = new RectF();
- setWillNotDraw(false);
}
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
+ /**
+ * Fingerprint drawable
+ */
+ abstract UdfpsDrawable getDrawable();
- if (getUdfpsAnimation() != null) {
- final int alpha = mParent.shouldPauseAuth() ? mAlpha : 255;
- getUdfpsAnimation().setAlpha(alpha);
- getUdfpsAnimation().draw(canvas);
- }
+ void onSensorRectUpdated(RectF bounds) {
+ getDrawable().onSensorRectUpdated(bounds);
}
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
+ void onIlluminationStarting() {
+ getDrawable().setIlluminationShowing(true);
+ getDrawable().invalidateSelf();
+ }
+
+ void onIlluminationStopped() {
+ getDrawable().setIlluminationShowing(false);
+ getDrawable().invalidateSelf();
+ }
- if (getUdfpsAnimation() != null) {
- getUdfpsAnimation().onDestroy();
+ /**
+ * @return true if changed
+ */
+ boolean setPauseAuth(boolean pauseAuth) {
+ if (pauseAuth != mPauseAuth) {
+ mPauseAuth = pauseAuth;
+ updateAlpha();
+ return true;
}
+ return false;
+ }
+
+ private void updateAlpha() {
+ getDrawable().setAlpha(mPauseAuth ? mAlpha : 255);
}
private int expansionToAlpha(float expansion) {
@@ -81,76 +87,15 @@ public abstract class UdfpsAnimationView extends FrameLayout implements DozeRece
return (int) ((1 - percent) * 255);
}
- void onIlluminationStarting() {
- if (getUdfpsAnimation() == null) {
- return;
- }
-
- getUdfpsAnimation().setIlluminationShowing(true);
- postInvalidate();
- }
-
- void onIlluminationStopped() {
- if (getUdfpsAnimation() == null) {
- return;
- }
-
- getUdfpsAnimation().setIlluminationShowing(false);
- postInvalidate();
- }
-
- void setParent(@NonNull UdfpsView parent) {
- mParent = parent;
- }
-
- void onSensorRectUpdated(@NonNull RectF sensorRect) {
- mSensorRect = sensorRect;
- if (getUdfpsAnimation() != null) {
- getUdfpsAnimation().onSensorRectUpdated(mSensorRect);
- }
- }
-
- void updateColor() {
- if (getUdfpsAnimation() != null) {
- getUdfpsAnimation().updateColor();
- }
- postInvalidate();
- }
-
- @Override
- public void dozeTimeTick() {
- if (getUdfpsAnimation() instanceof DozeReceiver) {
- ((DozeReceiver) getUdfpsAnimation()).dozeTimeTick();
- }
- }
-
- @Override
public void onExpansionChanged(float expansion, boolean expanded) {
mAlpha = expansionToAlpha(expansion);
- postInvalidate();
- }
-
- public int getPaddingX() {
- if (getUdfpsAnimation() == null) {
- return 0;
- }
- return getUdfpsAnimation().getPaddingX();
- }
-
- public int getPaddingY() {
- if (getUdfpsAnimation() == null) {
- return 0;
- }
- return getUdfpsAnimation().getPaddingY();
+ updateAlpha();
}
/**
- * @return the amount of translation needed if the view currently requires the user to touch
- * somewhere other than the exact center of the sensor. For example, this can happen
- * during guided enrollment.
+ * @return true if handled
*/
- @NonNull
- PointF getTouchTranslation() {
- return new PointF(0, 0);
+ boolean dozeTimeTick() {
+ return false;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java
new file mode 100644
index 000000000000..b6d80ba14dc0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.java
@@ -0,0 +1,167 @@
+/*
+ * 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.statusbar.StatusBarState.FULLSCREEN_USER_SWITCHER;
+import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
+import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED;
+
+import android.annotation.NonNull;
+import android.graphics.PointF;
+import android.graphics.RectF;
+
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.util.ViewController;
+
+/**
+ * Handles:
+ * 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
+ * the affordance. this allows us to fade the view in and out nicely (see shouldPauseAuth)
+ * 3. sending events to its view including:
+ * - illumination events
+ * - sensor position changes
+ * - doze time event
+ */
+abstract class UdfpsAnimationViewController<T extends UdfpsAnimationView>
+ extends ViewController<T> {
+ @NonNull final StatusBarStateController mStatusBarStateController;
+ @NonNull final StatusBar mStatusBar;
+
+ private boolean mNotificationShadeExpanded;
+ private int mStatusBarState;
+
+ protected UdfpsAnimationViewController(
+ T view,
+ StatusBarStateController statusBarStateController,
+ StatusBar statusBar) {
+ super(view);
+ mStatusBarStateController = statusBarStateController;
+ mStatusBar = statusBar;
+ }
+
+ @Override
+ protected void onViewAttached() {
+ mStatusBarStateController.addCallback(mStateListener);
+ mStateListener.onStateChanged(mStatusBarStateController.getState());
+ mStatusBar.addExpansionChangedListener(mStatusBarExpansionChangedListener);
+ }
+
+ @Override
+ protected void onViewDetached() {
+ mStatusBarStateController.removeCallback(mStateListener);
+ mStatusBar.removeExpansionChangedListener(mStatusBarExpansionChangedListener);
+ }
+
+ /**
+ * Returns true if the fingerprint manager is running but we want to temporarily pause
+ * authentication.
+ */
+ boolean shouldPauseAuth() {
+ return (mNotificationShadeExpanded && mStatusBarState != KEYGUARD)
+ || mStatusBarState == SHADE_LOCKED
+ || mStatusBarState == FULLSCREEN_USER_SWITCHER;
+ }
+
+ /**
+ * Send pause auth update to our view.
+ */
+ void updatePauseAuth() {
+ if (mView.setPauseAuth(shouldPauseAuth())) {
+ mView.postInvalidate();
+ }
+ }
+
+ /**
+ * Send sensor position change to our view. This rect contains paddingX and paddingY.
+ */
+ void onSensorRectUpdated(RectF sensorRect) {
+ mView.onSensorRectUpdated(sensorRect);
+ }
+
+ /**
+ * Send dozeTimeTick to view in case it wants to handle its burn-in offset.
+ */
+ void dozeTimeTick() {
+ if (mView.dozeTimeTick()) {
+ mView.postInvalidate();
+ }
+ }
+
+ /**
+ * @return the amount of translation needed if the view currently requires the user to touch
+ * somewhere other than the exact center of the sensor. For example, this can happen
+ * during guided enrollment.
+ */
+ PointF getTouchTranslation() {
+ return new PointF(0, 0);
+ }
+
+ /**
+ * X-Padding to add to left and right of the sensor rectangle area to increase the size of our
+ * window to draw within.
+ * @return
+ */
+ int getPaddingX() {
+ return 0;
+ }
+
+ /**
+ * Y-Padding to add to top and bottom of the sensor rectangle area to increase the size of our
+ * window to draw within.
+ */
+ int getPaddingY() {
+ return 0;
+ }
+
+ /**
+ * Udfps has started illuminating and the fingerprint manager is working on authenticating.
+ */
+ void onIlluminationStarting() {
+ mView.onIlluminationStarting();
+ mView.postInvalidate();
+ }
+
+ /**
+ * Udfps has stopped illuminating and the fingerprint manager is no longer attempting to
+ * authenticate.
+ */
+ void onIlluminationStopped() {
+ mView.onIlluminationStopped();
+ mView.postInvalidate();
+ }
+
+ private final StatusBar.ExpansionChangedListener mStatusBarExpansionChangedListener =
+ new StatusBar.ExpansionChangedListener() {
+ @Override
+ public void onExpansionChanged(float expansion, boolean expanded) {
+ mNotificationShadeExpanded = expanded;
+ mView.onExpansionChanged(expansion, expanded);
+ updatePauseAuth();
+ }
+ };
+
+ private final StatusBarStateController.StateListener mStateListener =
+ new StatusBarStateController.StateListener() {
+ @Override
+ public void onStateChanged(int newState) {
+ mStatusBarState = newState;
+ updatePauseAuth();
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewEnroll.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewEnroll.java
deleted file mode 100644
index 543df33dd5d7..000000000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewEnroll.java
+++ /dev/null
@@ -1,96 +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.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.graphics.PointF;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-
-import com.android.systemui.R;
-
-/**
- * Class that coordinates non-HBM animations during enrollment.
- */
-public class UdfpsAnimationViewEnroll extends UdfpsAnimationView
- implements UdfpsEnrollHelper.Listener {
-
- private static final String TAG = "UdfpsAnimationViewEnroll";
-
- @NonNull private UdfpsAnimationEnroll mUdfpsAnimation;
- @NonNull private UdfpsProgressBar mProgressBar;
- @Nullable private UdfpsEnrollHelper mEnrollHelper;
-
- @NonNull
- @Override
- protected UdfpsAnimation getUdfpsAnimation() {
- return mUdfpsAnimation;
- }
-
- public UdfpsAnimationViewEnroll(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- mUdfpsAnimation = new UdfpsAnimationEnroll(context);
- }
-
- public void setEnrollHelper(@NonNull UdfpsEnrollHelper helper) {
- mEnrollHelper = helper;
- mUdfpsAnimation.setEnrollHelper(helper);
- }
-
- @Override
- protected void onFinishInflate() {
- mProgressBar = findViewById(R.id.progress_bar);
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
-
- if (mEnrollHelper == null) {
- Log.e(TAG, "Enroll helper is null");
- return;
- }
-
- if (mEnrollHelper.shouldShowProgressBar()) {
- mProgressBar.setVisibility(View.VISIBLE);
-
- // Only need enrollment updates if the progress bar is showing :)
- mEnrollHelper.setListener(this);
- }
- }
-
- @Override
- public void onEnrollmentProgress(int remaining, int totalSteps) {
- final int interpolatedProgress = mProgressBar.getMax()
- * Math.max(0, totalSteps + 1 - remaining) / (totalSteps + 1);
-
- mProgressBar.setProgress(interpolatedProgress, true);
- }
-
- @NonNull
- @Override
- PointF getTouchTranslation() {
- if (!mEnrollHelper.isCenterEnrollmentComplete()) {
- return new PointF(0, 0);
- } else {
- return mEnrollHelper.getNextGuidedEnrollmentPoint();
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewBp.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpView.java
index 515b442b61f6..70be907228c8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewBp.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpView.java
@@ -24,19 +24,22 @@ import androidx.annotation.Nullable;
/**
* Class that coordinates non-HBM animations during BiometricPrompt.
*
+ * Currently doesn't draw anything.
+ *
* Note that {@link AuthBiometricUdfpsView} also shows UDFPS animations. At some point we should
- * de-dupe this if necessary. This will probably happen once the top-level TODO in UdfpsController
- * is completed (inflate operation-specific views, instead of inflating generic udfps_view and
- * adding operation-specific animations to it).
+ * de-dupe this if necessary.
*/
-public class UdfpsAnimationViewBp extends UdfpsAnimationView {
- public UdfpsAnimationViewBp(Context context, @Nullable AttributeSet attrs) {
+public class UdfpsBpView extends UdfpsAnimationView {
+ private UdfpsFpDrawable mFingerprintDrawable;
+
+ public UdfpsBpView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
+ // Drawable isn't ever added to the view, so we don't currently show anything
+ mFingerprintDrawable = new UdfpsFpDrawable(mContext);
}
- @Nullable
@Override
- protected UdfpsAnimation getUdfpsAnimation() {
- return null;
+ UdfpsDrawable getDrawable() {
+ return mFingerprintDrawable;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.java
new file mode 100644
index 000000000000..b712c655a6e7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.java
@@ -0,0 +1,32 @@
+/*
+ * 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 com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+/**
+ * Class that coordinates non-HBM animations for biometric prompt.
+ */
+class UdfpsBpViewController extends UdfpsAnimationViewController<UdfpsBpView> {
+ protected UdfpsBpViewController(
+ UdfpsBpView view,
+ StatusBarStateController statusBarStateController,
+ StatusBar statusBar) {
+ super(view, statusBarStateController, statusBar);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 4b6a8f639cc4..94aeb73c4b42 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -31,9 +31,9 @@ import android.graphics.RectF;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IUdfpsOverlayController;
-import android.os.SystemClock;
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -195,17 +195,6 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
}
}
- @VisibleForTesting final StatusBar.ExpansionChangedListener mStatusBarExpansionListener =
- (expansion, expanded) -> mView.onExpansionChanged(expansion, expanded);
-
- @VisibleForTesting final StatusBarStateController.StateListener mStatusBarStateListener =
- new StatusBarStateController.StateListener() {
- @Override
- public void onStateChanged(int newState) {
- mView.onStateChanged(newState);
- }
- };
-
private static float computePointerSpeed(@NonNull VelocityTracker tracker, int pointerId) {
final float vx = tracker.getXVelocity(pointerId);
final float vy = tracker.getYVelocity(pointerId);
@@ -360,10 +349,9 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
@Override
public void dozeTimeTick() {
- if (mView == null) {
- return;
+ if (mView != null) {
+ mView.dozeTimeTick();
}
- mView.dozeTimeTick();
}
/**
@@ -387,7 +375,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
}
}
- private WindowManager.LayoutParams computeLayoutParams(@Nullable UdfpsAnimationView animation) {
+ private WindowManager.LayoutParams computeLayoutParams(
+ @Nullable UdfpsAnimationViewController animation) {
final int paddingX = animation != null ? animation.getPaddingX() : 0;
final int paddingY = animation != null ? animation.getPaddingY() : 0;
@@ -438,20 +427,13 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
mFgExecutor.execute(() -> {
if (mView == null) {
try {
- Log.v(TAG, "showUdfpsOverlay | adding window");
- // TODO: Eventually we should refactor the code to inflate an
- // operation-specific view here, instead of inflating a generic udfps_view
- // and adding operation-specific animations to it.
+ Log.v(TAG, "showUdfpsOverlay | adding window reason=" + reason);
mView = (UdfpsView) mInflater.inflate(R.layout.udfps_view, null, false);
mView.setSensorProperties(mSensorProps);
mView.setHbmCallback(this);
-
- final UdfpsAnimationView animation = getUdfpsAnimationViewForReason(reason);
- mView.setAnimationView(animation);
-
- mStatusBar.addExpansionChangedListener(mStatusBarExpansionListener);
- mStatusBarStateController.addCallback(mStatusBarStateListener);
- mStatusBarStateListener.onStateChanged(mStatusBarStateController.getState());
+ UdfpsAnimationViewController animation = inflateUdfpsAnimation(reason);
+ animation.init();
+ mView.setAnimationViewController(animation);
mWindowManager.addView(mView, computeLayoutParams(animation));
mView.setOnTouchListener(mOnTouchListener);
@@ -464,40 +446,46 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
});
}
- @NonNull
- private UdfpsAnimationView getUdfpsAnimationViewForReason(int reason) {
- Log.d(TAG, "getUdfpsAnimationForReason: " + reason);
-
- final LayoutInflater inflater = LayoutInflater.from(mContext);
-
+ private UdfpsAnimationViewController inflateUdfpsAnimation(int reason) {
switch (reason) {
case IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR:
- case IUdfpsOverlayController.REASON_ENROLL_ENROLLING: {
- final UdfpsAnimationViewEnroll view = (UdfpsAnimationViewEnroll)
- inflater.inflate(R.layout.udfps_animation_view_enroll, null, false);
- view.setEnrollHelper(mServerRequest.mEnrollHelper);
- return view;
- }
-
- case IUdfpsOverlayController.REASON_AUTH_BP: {
- final UdfpsAnimationViewBp view = (UdfpsAnimationViewBp)
- inflater.inflate(R.layout.udfps_animation_view_bp, null, false);
- return view;
- }
-
- case IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD: {
- final UdfpsAnimationViewKeyguard view = (UdfpsAnimationViewKeyguard)
- inflater.inflate(R.layout.udfps_animation_view_keyguard, null, false);
- view.setStatusBarStateController(mStatusBarStateController);
- return view;
- }
-
- case IUdfpsOverlayController.REASON_AUTH_FPM_OTHER: {
- final UdfpsAnimationViewFpmOther view = (UdfpsAnimationViewFpmOther)
- inflater.inflate(R.layout.udfps_animation_view_fpm_other, null, false);
- return view;
- }
-
+ case IUdfpsOverlayController.REASON_ENROLL_ENROLLING:
+ UdfpsEnrollView enrollView = (UdfpsEnrollView) mInflater.inflate(
+ R.layout.udfps_enroll_view, null);
+ mView.addView(enrollView);
+ return new UdfpsEnrollViewController(
+ enrollView,
+ mServerRequest.mEnrollHelper,
+ mStatusBarStateController,
+ mStatusBar
+ );
+ case IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD:
+ UdfpsKeyguardView keyguardView = (UdfpsKeyguardView)
+ mInflater.inflate(R.layout.udfps_keyguard_view, null);
+ mView.addView(keyguardView);
+ return new UdfpsKeyguardViewController(
+ keyguardView,
+ mStatusBarStateController,
+ mStatusBar
+ );
+ case IUdfpsOverlayController.REASON_AUTH_BP:
+ // note: empty controller, currently shows no visual affordance
+ UdfpsBpView bpView = (UdfpsBpView) mInflater.inflate(R.layout.udfps_bp_view, null);
+ mView.addView(bpView);
+ return new UdfpsBpViewController(
+ bpView,
+ mStatusBarStateController,
+ mStatusBar
+ );
+ case IUdfpsOverlayController.REASON_AUTH_FPM_OTHER:
+ UdfpsFpmOtherView authOtherView = (UdfpsFpmOtherView)
+ mInflater.inflate(R.layout.udfps_fpm_other_view, null);
+ mView.addView(authOtherView);
+ return new UdfpsFpmOtherViewController(
+ authOtherView,
+ mStatusBarStateController,
+ mStatusBar
+ );
default:
Log.d(TAG, "Animation for reason " + reason + " not supported yet");
return null;
@@ -510,11 +498,9 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
Log.v(TAG, "hideUdfpsOverlay | removing window");
// Reset the controller back to its starting state.
onFingerUp();
-
- mStatusBar.removeExpansionChangedListener(mStatusBarExpansionListener);
- mStatusBarStateController.removeCallback(mStatusBarStateListener);
-
mWindowManager.removeView(mView);
+ mView.setOnTouchListener(null);
+ mView.setAnimationViewController(null);
mView = null;
} else {
Log.v(TAG, "hideUdfpsOverlay | the overlay is already hidden");
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.java
index a51b6fd16445..13d31cb87fdc 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.java
@@ -17,10 +17,10 @@
package com.android.systemui.biometrics;
import android.content.Context;
+import android.graphics.ColorFilter;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
-import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -28,24 +28,24 @@ import androidx.annotation.Nullable;
import com.android.systemui.R;
/**
- * Abstract base class for animations that should be drawn when the finger is not touching the
+ * Abstract base class for drawable displayed when the finger is not touching the
* sensor area.
*/
-public abstract class UdfpsAnimation extends Drawable {
- protected abstract void updateColor();
- protected abstract void onDestroy();
-
+public abstract class UdfpsDrawable extends Drawable {
@NonNull protected final Context mContext;
@NonNull protected final Drawable mFingerprintDrawable;
- @Nullable private View mView;
private boolean mIlluminationShowing;
- public UdfpsAnimation(@NonNull Context context) {
+ int mAlpha = 255; // 0 - 255
+ public UdfpsDrawable(@NonNull Context context) {
mContext = context;
mFingerprintDrawable = context.getResources().getDrawable(R.drawable.ic_fingerprint, null);
mFingerprintDrawable.mutate();
}
+ /**
+ * @param sensorRect the rect coordinates for the sensor area
+ */
public void onSensorRectUpdated(@NonNull RectF sensorRect) {
final int margin = (int) sensorRect.height() / 8;
@@ -56,17 +56,17 @@ public abstract class UdfpsAnimation extends Drawable {
updateFingerprintIconBounds(bounds);
}
+ /**
+ * Bounds for the fingerprint icon
+ */
protected void updateFingerprintIconBounds(@NonNull Rect bounds) {
mFingerprintDrawable.setBounds(bounds);
}
@Override
public void setAlpha(int alpha) {
- mFingerprintDrawable.setAlpha(alpha);
- }
-
- public void setAnimationView(UdfpsAnimationView view) {
- mView = view;
+ mAlpha = alpha;
+ mFingerprintDrawable.setAlpha(mAlpha);
}
boolean isIlluminationShowing() {
@@ -77,23 +77,12 @@ public abstract class UdfpsAnimation extends Drawable {
mIlluminationShowing = showing;
}
- /**
- * @return The amount of padding that's needed on each side of the sensor, in pixels.
- */
- public int getPaddingX() {
- return 0;
+ @Override
+ public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
- /**
- * @return The amount of padding that's needed on each side of the sensor, in pixels.
- */
- public int getPaddingY() {
+ @Override
+ public int getOpacity() {
return 0;
}
-
- protected void postInvalidateView() {
- if (mView != null) {
- mView.postInvalidate();
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationEnroll.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollDrawable.java
index 015a598e972b..d80e085bdc70 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationEnroll.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollDrawable.java
@@ -20,7 +20,6 @@ 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.PointF;
import android.graphics.Rect;
@@ -33,23 +32,23 @@ import androidx.annotation.Nullable;
import com.android.systemui.R;
/**
- * UDFPS animations that should be shown when enrolling.
+ * UDFPS fingerprint drawable that is shown when enrolling
*/
-public class UdfpsAnimationEnroll extends UdfpsAnimation {
+public class UdfpsEnrollDrawable extends UdfpsDrawable {
private static final String TAG = "UdfpsAnimationEnroll";
private static final float SHADOW_RADIUS = 5.f;
- private static final float PROGRESS_BAR_RADIUS = 140.f;
+ static final float PROGRESS_BAR_RADIUS = 140.f;
@NonNull private final Drawable mMovingTargetFpIcon;
@NonNull private final Paint mSensorPaint;
@NonNull private final Paint mBlueFill;
- @NonNull private final Paint mBlueStroke;;
+ @NonNull private final Paint mBlueStroke;
@Nullable private RectF mSensorRect;
@Nullable private UdfpsEnrollHelper mEnrollHelper;
- UdfpsAnimationEnroll(@NonNull Context context) {
+ UdfpsEnrollDrawable(@NonNull Context context) {
super(context);
mSensorPaint = new Paint(0 /* flags */);
@@ -72,20 +71,12 @@ public class UdfpsAnimationEnroll extends UdfpsAnimation {
mMovingTargetFpIcon = context.getResources().getDrawable(R.drawable.ic_fingerprint, null);
mMovingTargetFpIcon.setTint(Color.WHITE);
mMovingTargetFpIcon.mutate();
- }
-
- void setEnrollHelper(@NonNull UdfpsEnrollHelper helper) {
- mEnrollHelper = helper;
- }
- @Override
- protected void updateColor() {
mFingerprintDrawable.setTint(mContext.getColor(R.color.udfps_enroll_icon));
}
- @Override
- protected void onDestroy() {
-
+ void setEnrollHelper(@NonNull UdfpsEnrollHelper helper) {
+ mEnrollHelper = helper;
}
@Override
@@ -98,6 +89,7 @@ public class UdfpsAnimationEnroll extends UdfpsAnimation {
protected void updateFingerprintIconBounds(@NonNull Rect bounds) {
super.updateFingerprintIconBounds(bounds);
mMovingTargetFpIcon.setBounds(bounds);
+ invalidateSelf();
}
@Override
@@ -117,7 +109,7 @@ public class UdfpsAnimationEnroll extends UdfpsAnimation {
// Draw moving target
if (mEnrollHelper.isCenterEnrollmentComplete()) {
- mFingerprintDrawable.setAlpha(64);
+ mFingerprintDrawable.setAlpha(mAlpha == 255 ? 64 : mAlpha);
canvas.save();
final PointF point = mEnrollHelper.getNextGuidedEnrollmentPoint();
@@ -130,33 +122,16 @@ public class UdfpsAnimationEnroll extends UdfpsAnimation {
mMovingTargetFpIcon.draw(canvas);
canvas.restore();
} else {
- mFingerprintDrawable.setAlpha(255);
+ mFingerprintDrawable.setAlpha(mAlpha);
}
}
@Override
- public int getPaddingX() {
- return (int) Math.ceil(PROGRESS_BAR_RADIUS);
- }
-
- @Override
- public int getPaddingY() {
- return (int) Math.ceil(PROGRESS_BAR_RADIUS);
- }
-
- @Override
public void setAlpha(int alpha) {
super.setAlpha(alpha);
mSensorPaint.setAlpha(alpha);
- }
-
- @Override
- public void setColorFilter(@Nullable ColorFilter colorFilter) {
-
- }
-
- @Override
- public int getOpacity() {
- return 0;
+ mBlueFill.setAlpha(alpha);
+ mBlueStroke.setAlpha(alpha);
+ invalidateSelf();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
index 667b7a7cf0a3..62058a965c09 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
@@ -100,13 +100,13 @@ public class UdfpsEnrollHelper {
}
- void setListener(@NonNull Listener listener) {
+ void setListener(Listener listener) {
mListener = listener;
// Only notify during setListener if enrollment is already in progress, so the progress
// bar can be updated. If enrollment has not started yet, the progress bar will be empty
// anyway.
- if (mTotalSteps != -1) {
+ if (mListener != null && mTotalSteps != -1) {
mListener.onEnrollmentProgress(mRemainingSteps, mTotalSteps);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewKeyguard.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollView.java
index 7d0b3e59feb1..7985d95c7c61 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewKeyguard.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollView.java
@@ -18,32 +18,36 @@ package com.android.systemui.biometrics;
import android.content.Context;
import android.util.AttributeSet;
+import android.widget.ImageView;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.R;
/**
- * Class that coordinates non-HBM animations during keyguard authentication.
+ * View corresponding with udfps_enroll_view.xml
*/
-public class UdfpsAnimationViewKeyguard extends UdfpsAnimationView {
- @Nullable private UdfpsAnimationKeyguard mAnimation;
+public class UdfpsEnrollView extends UdfpsAnimationView {
+ private final UdfpsEnrollDrawable mFingerprintDrawable;
+ private ImageView mFingerprintView;
- public UdfpsAnimationViewKeyguard(Context context, @Nullable AttributeSet attrs) {
+ public UdfpsEnrollView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
+ mFingerprintDrawable = new UdfpsEnrollDrawable(mContext);
}
- void setStatusBarStateController(@NonNull StatusBarStateController statusBarStateController) {
- if (mAnimation == null) {
- mAnimation = new UdfpsAnimationKeyguard(getContext(), statusBarStateController);
- mAnimation.setAnimationView(this);
- }
+ @Override
+ protected void onFinishInflate() {
+ mFingerprintView = findViewById(R.id.udfps_enroll_animation_fp_view);
+ mFingerprintView.setImageDrawable(mFingerprintDrawable);
}
- @Nullable
@Override
- protected UdfpsAnimation getUdfpsAnimation() {
- return mAnimation;
+ public UdfpsDrawable getDrawable() {
+ return mFingerprintDrawable;
+ }
+
+ void setEnrollHelper(UdfpsEnrollHelper enrollHelper) {
+ mFingerprintDrawable.setEnrollHelper(enrollHelper);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollViewController.java
new file mode 100644
index 000000000000..da8d712ebbdc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollViewController.java
@@ -0,0 +1,92 @@
+/*
+ * 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.NonNull;
+import android.graphics.PointF;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+/**
+ * Class that coordinates non-HBM animations during enrollment.
+ */
+public class UdfpsEnrollViewController extends UdfpsAnimationViewController<UdfpsEnrollView> {
+ @NonNull private final UdfpsProgressBar mProgressBar;
+ @NonNull private final UdfpsEnrollHelper mEnrollHelper;
+
+ protected UdfpsEnrollViewController(
+ UdfpsEnrollView view,
+ @NonNull UdfpsEnrollHelper enrollHelper,
+ StatusBarStateController statusBarStateController,
+ StatusBar statusBar) {
+ super(view, statusBarStateController, statusBar);
+ mEnrollHelper = enrollHelper;
+ mProgressBar = mView.findViewById(R.id.progress_bar);
+ mView.setEnrollHelper(mEnrollHelper);
+ }
+
+ @Override
+ protected void onViewAttached() {
+ super.onViewAttached();
+ if (mEnrollHelper.shouldShowProgressBar()) {
+ mProgressBar.setVisibility(View.VISIBLE);
+
+ // Only need enrollment updates if the progress bar is showing :)
+ mEnrollHelper.setListener(mEnrollHelperListener);
+ }
+ }
+
+ @Override
+ protected void onViewDetached() {
+ super.onViewDetached();
+ mEnrollHelper.setListener(null);
+ }
+
+ @NonNull
+ @Override
+ public PointF getTouchTranslation() {
+ if (!mEnrollHelper.isCenterEnrollmentComplete()) {
+ return new PointF(0, 0);
+ } else {
+ return mEnrollHelper.getNextGuidedEnrollmentPoint();
+ }
+ }
+
+ @Override
+ public int getPaddingX() {
+ return (int) Math.ceil(UdfpsEnrollDrawable.PROGRESS_BAR_RADIUS);
+ }
+
+ @Override
+ public int getPaddingY() {
+ return (int) Math.ceil(UdfpsEnrollDrawable.PROGRESS_BAR_RADIUS);
+ }
+
+ private final UdfpsEnrollHelper.Listener mEnrollHelperListener =
+ new UdfpsEnrollHelper.Listener() {
+ @Override
+ public void onEnrollmentProgress(int remaining, int totalSteps) {
+ final int interpolatedProgress = mProgressBar.getMax()
+ * Math.max(0, totalSteps + 1 - remaining) / (totalSteps + 1);
+
+ mProgressBar.setProgress(interpolatedProgress, true);
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationFpmOther.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpDrawable.java
index ef7a34000841..09b6fabbdd15 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationFpmOther.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpDrawable.java
@@ -18,32 +18,19 @@ 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.
+ * Draws udfps fingerprint if sensor isn't illuminating.
*/
-public class UdfpsAnimationFpmOther extends UdfpsAnimation {
+public class UdfpsFpDrawable extends UdfpsDrawable {
- UdfpsAnimationFpmOther(@NonNull Context context) {
+ UdfpsFpDrawable(@NonNull Context context) {
super(context);
}
@Override
- protected void updateColor() {
-
- }
-
- @Override
- protected void onDestroy() {
-
- }
-
- @Override
public void draw(@NonNull Canvas canvas) {
if (isIlluminationShowing()) {
return;
@@ -51,14 +38,4 @@ public class UdfpsAnimationFpmOther extends UdfpsAnimation {
mFingerprintDrawable.draw(canvas);
}
-
- @Override
- public void setColorFilter(@Nullable ColorFilter colorFilter) {
-
- }
-
- @Override
- public int getOpacity() {
- return 0;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewFpmOther.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherView.java
index 3d2f5a0fe5cf..85f16068188e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewFpmOther.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherView.java
@@ -18,25 +18,32 @@ package com.android.systemui.biometrics;
import android.content.Context;
import android.util.AttributeSet;
+import android.widget.ImageView;
import androidx.annotation.Nullable;
+import com.android.systemui.R;
+
/**
- * Class that coordinates non-HBM animations during other usage of FingerprintManager (not
- * including Keyguard).
+ * View corresponding with udfps_fpm_other_view.xml
*/
-public class UdfpsAnimationViewFpmOther extends UdfpsAnimationView {
-
- private final UdfpsAnimationFpmOther mAnimation;
+public class UdfpsFpmOtherView extends UdfpsAnimationView {
+ private final UdfpsFpDrawable mFingerprintDrawable;
+ private ImageView mFingerprintView;
- public UdfpsAnimationViewFpmOther(Context context, @Nullable AttributeSet attrs) {
+ public UdfpsFpmOtherView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
- mAnimation = new UdfpsAnimationFpmOther(context);
+ mFingerprintDrawable = new UdfpsFpDrawable(context);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ mFingerprintView = findViewById(R.id.udfps_fpm_other_fp_view);
+ mFingerprintView.setImageDrawable(mFingerprintDrawable);
}
- @Nullable
@Override
- protected UdfpsAnimation getUdfpsAnimation() {
- return mAnimation;
+ UdfpsDrawable getDrawable() {
+ return mFingerprintDrawable;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherViewController.java
new file mode 100644
index 000000000000..587501bd1aa5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherViewController.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+/**
+ * Class that coordinates non-HBM animations for non keyguard, enrollment or biometric prompt
+ * states.
+ *
+ * Currently only shows the fp drawable.
+ */
+class UdfpsFpmOtherViewController extends UdfpsAnimationViewController<UdfpsFpmOtherView> {
+ protected UdfpsFpmOtherViewController(
+ UdfpsFpmOtherView view,
+ StatusBarStateController statusBarStateController,
+ StatusBar statusBar) {
+ super(view, statusBarStateController, statusBar);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardDrawable.java
index 5f268cfa8fa5..b0c5da09d916 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardDrawable.java
@@ -21,28 +21,25 @@ 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 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 {
+public class UdfpsKeyguardDrawable extends UdfpsDrawable implements DozeReceiver {
private static final String TAG = "UdfpsAnimationKeyguard";
+ private final int mLockScreenColor;
+ private final int mAmbientDisplayColor;
@NonNull private final Context mContext;
- @NonNull private final StatusBarStateController mStatusBarStateController;
private final int mMaxBurnInOffsetX;
private final int mMaxBurnInOffsetY;
@@ -51,18 +48,19 @@ public class UdfpsAnimationKeyguard extends UdfpsAnimation implements DozeReceiv
private float mBurnInOffsetX;
private float mBurnInOffsetY;
- UdfpsAnimationKeyguard(@NonNull Context context,
- @NonNull StatusBarStateController statusBarStateController) {
+ UdfpsKeyguardDrawable(@NonNull Context context) {
super(context);
mContext = context;
- mStatusBarStateController = statusBarStateController;
+ // TODO: move burn-in to view
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);
+ mLockScreenColor = Utils.getColorAttrDefaultColor(mContext, R.attr.wallpaperTextColor);
+ mAmbientDisplayColor = Color.WHITE;
+ updateAodPositionAndColor();
}
private void updateAodPositionAndColor() {
@@ -74,18 +72,14 @@ public class UdfpsAnimationKeyguard extends UdfpsAnimation implements DozeReceiv
getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */)
- mMaxBurnInOffsetY,
mInterpolatedDarkAmount);
- updateColor();
- postInvalidateView();
- }
- @Override
- public void dozeTimeTick() {
- updateAodPositionAndColor();
+ mFingerprintDrawable.setTint(ColorUtils.blendARGB(mLockScreenColor,
+ mAmbientDisplayColor, mInterpolatedDarkAmount));
+ invalidateSelf();
}
@Override
- public void onDozeAmountChanged(float linear, float eased) {
- mInterpolatedDarkAmount = eased;
+ public void dozeTimeTick() {
updateAodPositionAndColor();
}
@@ -94,34 +88,11 @@ public class UdfpsAnimationKeyguard extends UdfpsAnimation implements DozeReceiv
if (isIlluminationShowing()) {
return;
}
-
- canvas.save();
- canvas.translate(mBurnInOffsetX, mBurnInOffsetY);
mFingerprintDrawable.draw(canvas);
- canvas.restore();
}
- @Override
- public void setColorFilter(@Nullable ColorFilter colorFilter) {
-
- }
-
- @Override
- public int getOpacity() {
- return 0;
- }
-
- @Override
- protected void updateColor() {
- final int lockScreenIconColor = Utils.getColorAttrDefaultColor(mContext,
- R.attr.wallpaperTextColor);
- final int ambientDisplayIconColor = Color.WHITE;
- mFingerprintDrawable.setTint(ColorUtils.blendARGB(lockScreenIconColor,
- ambientDisplayIconColor, mInterpolatedDarkAmount));
- }
-
- @Override
- protected void onDestroy() {
- mStatusBarStateController.removeCallback(this);
+ void onDozeAmountChanged(float linear, float eased) {
+ mInterpolatedDarkAmount = eased;
+ updateAodPositionAndColor();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
new file mode 100644
index 000000000000..6a9356034d22
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.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.util.AttributeSet;
+import android.widget.ImageView;
+
+import androidx.annotation.Nullable;
+
+import com.android.systemui.R;
+
+/**
+ * View corresponding with udfps_keyguard_view.xml
+ */
+public class UdfpsKeyguardView extends UdfpsAnimationView {
+ private final UdfpsKeyguardDrawable mFingerprintDrawable;
+ private ImageView mFingerprintView;
+
+ public UdfpsKeyguardView(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ mFingerprintDrawable = new UdfpsKeyguardDrawable(mContext);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ mFingerprintView = findViewById(R.id.udfps_keyguard_animation_fp_view);
+ mFingerprintView.setImageDrawable(mFingerprintDrawable);
+ }
+
+ @Override
+ public UdfpsDrawable getDrawable() {
+ return mFingerprintDrawable;
+ }
+
+ @Override
+ public boolean dozeTimeTick() {
+ // TODO: burnin
+ mFingerprintDrawable.dozeTimeTick();
+ return true;
+ }
+
+ void onDozeAmountChanged(float linear, float eased) {
+ mFingerprintDrawable.onDozeAmountChanged(linear, eased);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
new file mode 100644
index 000000000000..14bb3fee1174
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -0,0 +1,81 @@
+/*
+ * 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 com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+/**
+ * Class that coordinates non-HBM animations during keyguard authentication.
+ */
+public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<UdfpsKeyguardView> {
+ private boolean mForceShow;
+
+ protected UdfpsKeyguardViewController(
+ UdfpsKeyguardView view,
+ StatusBarStateController statusBarStateController,
+ StatusBar statusBar) {
+ super(view, statusBarStateController, statusBar);
+ }
+
+ @Override
+ protected void onViewAttached() {
+ super.onViewAttached();
+ mStatusBarStateController.addCallback(mStateListener);
+ final float dozeAmount = mStatusBarStateController.getDozeAmount();
+ mStateListener.onDozeAmountChanged(dozeAmount, dozeAmount);
+ }
+
+ @Override
+ protected void onViewDetached() {
+ super.onViewDetached();
+ mStatusBarStateController.removeCallback(mStateListener);
+ }
+
+ /**
+ * Overrides non-force show logic in shouldPauseAuth to still auth.
+ */
+ private void forceShow(boolean forceShow) {
+ if (mForceShow == forceShow) {
+ return;
+ }
+
+ mForceShow = forceShow;
+ updatePauseAuth();
+ // TODO: animate show/hide background protection
+ }
+
+ /**
+ * Returns true if the fingerprint manager is running but we want to temporarily pause
+ * authentication. On the keyguard, we may want to show udfps when the shade
+ * is expanded, so this can be overridden with the forceShow method.
+ */
+ public boolean shouldPauseAuth() {
+ if (mForceShow) {
+ return false;
+ }
+ return super.shouldPauseAuth();
+ }
+
+ private final StatusBarStateController.StateListener mStateListener =
+ new StatusBarStateController.StateListener() {
+ @Override
+ public void onDozeAmountChanged(float linear, float eased) {
+ mView.onDozeAmountChanged(linear, eased);
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
index a52bddc1dcd5..42d0d8438e15 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
@@ -16,10 +16,6 @@
package com.android.systemui.biometrics;
-import static com.android.systemui.statusbar.StatusBarState.FULLSCREEN_USER_SWITCHER;
-import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
-import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -39,15 +35,12 @@ import android.widget.FrameLayout;
import com.android.systemui.R;
import com.android.systemui.doze.DozeReceiver;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.phone.StatusBar;
/**
* A view containing 1) A SurfaceView for HBM, and 2) A normal drawable view for all other
* animations.
*/
-public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIlluminator,
- StatusBarStateController.StateListener, StatusBar.ExpansionChangedListener {
+public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIlluminator {
private static final String TAG = "UdfpsView";
private static final int DEBUG_TEXT_SIZE_PX = 32;
@@ -56,7 +49,7 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin
@NonNull private final Paint mDebugTextPaint;
@NonNull private UdfpsSurfaceView mHbmSurfaceView;
- @Nullable private UdfpsAnimationView mAnimationView;
+ @Nullable private UdfpsAnimationViewController mAnimationViewController;
// Used to obtain the sensor location.
@NonNull private FingerprintSensorPropertiesInternal mSensorProps;
@@ -64,8 +57,6 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin
private final float mSensorTouchAreaCoefficient;
@Nullable private String mDebugMessage;
private boolean mIlluminationRequested;
- private int mStatusBarState;
- private boolean mNotificationShadeExpanded;
public UdfpsView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -108,15 +99,6 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin
mSensorProps = properties;
}
- void setAnimationView(@NonNull UdfpsAnimationView animation) {
- mAnimationView = animation;
- animation.setParent(this);
-
- // TODO: Consider using a ViewStub placeholder to maintain positioning and inflating it
- // after the animation type has been decided.
- addView(animation, 0);
- }
-
@Override
public void setHbmCallback(@Nullable HbmCallback callback) {
mHbmSurfaceView.setHbmCallback(callback);
@@ -124,45 +106,38 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin
@Override
public void dozeTimeTick() {
- if (mAnimationView == null) {
- return;
- }
- mAnimationView.dozeTimeTick();
- }
-
- @Override
- public void onStateChanged(int newState) {
- mStatusBarState = newState;
- }
-
- @Override
- public void onExpansionChanged(float expansion, boolean expanded) {
- mNotificationShadeExpanded = expanded;
-
- if (mAnimationView != null) {
- mAnimationView.onExpansionChanged(expansion, expanded);
+ if (mAnimationViewController != null) {
+ mAnimationViewController.dozeTimeTick();
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
- mSensorRect.set(0 + mAnimationView.getPaddingX(),
- 0 + mAnimationView.getPaddingY(),
- 2 * mSensorProps.sensorRadius + mAnimationView.getPaddingX(),
- 2 * mSensorProps.sensorRadius + mAnimationView.getPaddingY());
+ int paddingX = mAnimationViewController == null ? 0
+ : mAnimationViewController.getPaddingX();
+ int paddingY = mAnimationViewController == null ? 0
+ : mAnimationViewController.getPaddingY();
+ mSensorRect.set(
+ paddingX,
+ paddingY,
+ 2 * mSensorProps.sensorRadius + paddingX,
+ 2 * mSensorProps.sensorRadius + paddingY);
mHbmSurfaceView.onSensorRectUpdated(new RectF(mSensorRect));
- mAnimationView.onSensorRectUpdated(new RectF(mSensorRect));
+ if (mAnimationViewController != null) {
+ mAnimationViewController.onSensorRectUpdated(new RectF(mSensorRect));
+ }
+ }
+
+ void setAnimationViewController(UdfpsAnimationViewController animationViewController) {
+ mAnimationViewController = animationViewController;
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
Log.v(TAG, "onAttachedToWindow");
-
- // Retrieve the colors each time, since it depends on day/night mode
- mAnimationView.updateColor();
}
@Override
@@ -188,7 +163,9 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin
boolean isWithinSensorArea(float x, float y) {
// The X and Y coordinates of the sensor's center.
- final PointF translation = mAnimationView.getTouchTranslation();
+ final PointF translation = mAnimationViewController == null
+ ? new PointF(0, 0)
+ : mAnimationViewController.getTouchTranslation();
final float cx = mSensorRect.centerX() + translation.x;
final float cy = mSensorRect.centerY() + translation.y;
// Radii along the X and Y axes.
@@ -199,18 +176,7 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin
&& x < (cx + rx * mSensorTouchAreaCoefficient)
&& y > (cy - ry * mSensorTouchAreaCoefficient)
&& y < (cy + ry * mSensorTouchAreaCoefficient)
- && !shouldPauseAuth();
- }
-
- /**
- * States where UDFPS should temporarily not be authenticating. Instead of completely stopping
- * authentication which would cause the UDFPS icons to abruptly disappear, do it here by not
- * sending onFingerDown and smoothly animating away.
- */
- boolean shouldPauseAuth() {
- return (mNotificationShadeExpanded && mStatusBarState != KEYGUARD)
- || mStatusBarState == SHADE_LOCKED
- || mStatusBarState == FULLSCREEN_USER_SWITCHER;
+ && !mAnimationViewController.shouldPauseAuth();
}
boolean isIlluminationRequested() {
@@ -223,7 +189,9 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin
@Override
public void startIllumination(@Nullable Runnable onIlluminatedRunnable) {
mIlluminationRequested = true;
- mAnimationView.onIlluminationStarting();
+ if (mAnimationViewController != null) {
+ mAnimationViewController.onIlluminationStarting();
+ }
mHbmSurfaceView.setVisibility(View.VISIBLE);
mHbmSurfaceView.startIllumination(onIlluminatedRunnable);
}
@@ -231,7 +199,9 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin
@Override
public void stopIllumination() {
mIlluminationRequested = false;
- mAnimationView.onIlluminationStopped();
+ if (mAnimationViewController != null) {
+ mAnimationViewController.onIlluminationStopped();
+ }
mHbmSurfaceView.setVisibility(View.INVISIBLE);
mHbmSurfaceView.stopIllumination();
}
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 07686181649d..d6f4958942dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -246,20 +246,4 @@ public class UdfpsControllerTest extends SysuiTestCase {
// THEN the illumination is hidden
verify(mUdfpsView).stopIllumination();
}
-
- @Test
- public void registersAndUnregistersViewForCallbacks() throws RemoteException {
- mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
- IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
- mFgExecutor.runAllReady();
- verify(mStatusBarStateController).addCallback(mUdfpsController.mStatusBarStateListener);
- verify(mStatusBar).addExpansionChangedListener(
- mUdfpsController.mStatusBarExpansionListener);
-
- mOverlayController.hideUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
- mFgExecutor.runAllReady();
- verify(mStatusBarStateController).removeCallback(mUdfpsController.mStatusBarStateListener);
- verify(mStatusBar).removeExpansionChangedListener(
- mUdfpsController.mStatusBarExpansionListener);
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
new file mode 100644
index 000000000000..480b33556b27
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2020 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 org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.List;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
+ // Dependencies
+ @Mock
+ private UdfpsKeyguardView mView;
+ @Mock
+ private StatusBarStateController mStatusBarStateController;
+ @Mock
+ private StatusBar mStatusBar;
+
+ private UdfpsKeyguardViewController mController;
+
+ // Capture listeners so that they can be used to send events
+ @Captor private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerCaptor;
+ private StatusBarStateController.StateListener mParentListener;
+ private StatusBarStateController.StateListener mDozeListener;
+
+ @Captor private ArgumentCaptor<StatusBar.ExpansionChangedListener> mExpansionListenerCaptor;
+ private StatusBar.ExpansionChangedListener mExpansionListener;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mController = new UdfpsKeyguardViewController(
+ mView,
+ mStatusBarStateController,
+ mStatusBar);
+ }
+
+ @Test
+ public void testRegistersExpansionChangedListenerOnAttached() {
+ mController.onViewAttached();
+ captureExpansionListener();
+ }
+
+ @Test
+ public void testRegistersStatusBarStateListenersOnAttached() {
+ mController.onViewAttached();
+ captureStatusBarStateListeners();
+ }
+
+ @Test
+ public void testViewControllerQueriesSBStateOnAttached() {
+ mController.onViewAttached();
+ verify(mStatusBarStateController).getState();
+ verify(mStatusBarStateController).getDozeAmount();
+
+ final float dozeAmount = .88f;
+ when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE_LOCKED);
+ when(mStatusBarStateController.getDozeAmount()).thenReturn(dozeAmount);
+ captureStatusBarStateListeners();
+
+ mController.onViewAttached();
+ verify(mView).setPauseAuth(true);
+ verify(mView).onDozeAmountChanged(dozeAmount, dozeAmount);
+ }
+
+ @Test
+ public void testListenersUnregisteredOnDetached() {
+ mController.onViewAttached();
+ captureStatusBarStateListeners();
+ captureExpansionListener();
+ mController.onViewDetached();
+
+ verify(mStatusBarStateController).removeCallback(mParentListener);
+ verify(mStatusBarStateController).removeCallback(mDozeListener);
+ verify(mStatusBar).removeExpansionChangedListener(mExpansionListener);
+ }
+
+ @Test
+ public void testDozeEventsSentToView() {
+ mController.onViewAttached();
+ captureStatusBarStateListeners();
+
+ final float linear = .55f;
+ final float eased = .65f;
+ mDozeListener.onDozeAmountChanged(linear, eased);
+
+ verify(mView).onDozeAmountChanged(linear, eased);
+ }
+
+ private void captureStatusBarStateListeners() {
+ verify(mStatusBarStateController, times(2)).addCallback(mStateListenerCaptor.capture());
+ List<StatusBarStateController.StateListener> stateListeners =
+ mStateListenerCaptor.getAllValues();
+ mParentListener = stateListeners.get(0);
+ mDozeListener = stateListeners.get(1);
+ }
+
+ private void captureExpansionListener() {
+ verify(mStatusBar).addExpansionChangedListener(mExpansionListenerCaptor.capture());
+ mExpansionListener = mExpansionListenerCaptor.getValue();
+ }
+}