Merge "Hide Udfps icon when shade is expanded" into sc-dev
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java
index 5fc2e53..40fe7b1 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimation.java
@@ -47,4 +47,9 @@
(int) sensorRect.right - margin,
(int) sensorRect.bottom - margin);
}
+
+ @Override
+ public void setAlpha(int alpha) {
+ mFingerprintDrawable.setAlpha(alpha);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationEnroll.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationEnroll.java
index 58ebadeb..52662ae 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationEnroll.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationEnroll.java
@@ -28,6 +28,8 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.internal.graphics.ColorUtils;
+import com.android.settingslib.Utils;
import com.android.systemui.R;
/**
@@ -36,8 +38,11 @@
public class UdfpsAnimationEnroll extends UdfpsAnimation {
private static final String TAG = "UdfpsAnimationEnroll";
+ private static final float SHADOW_RADIUS = 5.f;
+
@Nullable private RectF mSensorRect;
@NonNull private final Paint mSensorPaint;
+ private final int mNotificationShadeColor;
UdfpsAnimationEnroll(@NonNull Context context) {
super(context);
@@ -45,8 +50,11 @@
mSensorPaint = new Paint(0 /* flags */);
mSensorPaint.setAntiAlias(true);
mSensorPaint.setColor(Color.WHITE);
- mSensorPaint.setShadowLayer(UdfpsView.SENSOR_SHADOW_RADIUS, 0, 0, Color.BLACK);
+ mSensorPaint.setShadowLayer(SHADOW_RADIUS, 0, 0, Color.BLACK);
mSensorPaint.setStyle(Paint.Style.FILL);
+
+ mNotificationShadeColor = Utils.getColorAttr(context,
+ android.R.attr.colorBackgroundFloating).getDefaultColor();
}
@Override
@@ -74,7 +82,14 @@
@Override
public void setAlpha(int alpha) {
+ super.setAlpha(alpha);
+ // Gradually fade into the notification shade color. This needs to be done because the
+ // UDFPS view is drawn on a layer on top of the notification shade
+ final float percent = alpha / 255.f;
+ mSensorPaint.setColor(ColorUtils.blendARGB(mNotificationShadeColor, Color.WHITE, percent));
+ mSensorPaint.setShadowLayer(SHADOW_RADIUS, 0, 0,
+ ColorUtils.blendARGB(mNotificationShadeColor, Color.BLACK, percent));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationFpmOther.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationFpmOther.java
index 7563e73..efc864a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationFpmOther.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationFpmOther.java
@@ -44,11 +44,6 @@
}
@Override
- public void setAlpha(int alpha) {
-
- }
-
- @Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java
index 3e46a65..501de9d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationKeyguard.java
@@ -99,11 +99,6 @@
}
@Override
- public void setAlpha(int alpha) {
-
- }
-
- @Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 001730a..dc09fa7 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -50,6 +50,7 @@
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeReceiver;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.settings.SystemSettings;
@@ -184,7 +185,8 @@
WindowManager windowManager,
SystemSettings systemSettings,
@NonNull StatusBarStateController statusBarStateController,
- @Main DelayableExecutor fgExecutor) {
+ @Main DelayableExecutor fgExecutor,
+ @NonNull ScrimController scrimController) {
mContext = context;
// The fingerprint manager is queried for UDFPS before this class is constructed, so the
// fingerprint manager should never be null.
@@ -220,6 +222,8 @@
mHbmSupported = !TextUtils.isEmpty(mHbmPath);
mView.setHbmSupported(mHbmSupported);
+ scrimController.addScrimChangedListener(mView);
+ statusBarStateController.addCallback(mView);
// This range only consists of the minimum and maximum values, which only cover
// non-high-brightness mode.
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
index 983206e..265703e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
@@ -16,6 +16,10 @@
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;
@@ -35,15 +39,19 @@
import com.android.systemui.R;
import com.android.systemui.doze.DozeReceiver;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.phone.ScrimController;
/**
* A full screen view with a configurable illumination dot and scrim.
*/
-public class UdfpsView extends View implements DozeReceiver {
+public class UdfpsView extends View implements DozeReceiver,
+ StatusBarStateController.StateListener, ScrimController.ScrimChangedListener{
private static final String TAG = "UdfpsView";
// Values in pixels.
- public static final float SENSOR_SHADOW_RADIUS = 2.0f;
+ private static final float SENSOR_SHADOW_RADIUS = 2.0f;
private static final int DEBUG_TEXT_SIZE_PX = 32;
@@ -70,6 +78,9 @@
private boolean mShowScrimAndDot;
private boolean mIsHbmSupported;
@Nullable private String mDebugMessage;
+ private int mStatusBarState;
+ private boolean mNotificationShadeExpanded;
+ private int mNotificationPanelAlpha;
// Runnable that will be run after the illumination dot and scrim are shown.
// The runnable is reset to null after it's executed once.
@@ -136,6 +147,22 @@
}
}
+ @Override
+ public void onExpandedChanged(boolean isExpanded) {
+ mNotificationShadeExpanded = isExpanded;
+ }
+
+ @Override
+ public void onStateChanged(int newState) {
+ mStatusBarState = newState;
+ }
+
+ @Override
+ public void onAlphaChanged(float alpha) {
+ mNotificationPanelAlpha = (int) (alpha * 255);
+ postInvalidate();
+ }
+
// The "h" and "w" are the display's height and width relative to its current rotation.
protected void updateSensorRect(int h, int w) {
// mSensorProps coordinates assume portrait mode.
@@ -147,10 +174,12 @@
// Transform mSensorRect if the device is in landscape mode.
switch (mContext.getDisplay().getRotation()) {
case Surface.ROTATION_90:
+ //noinspection SuspiciousNameCombination
mSensorRect.set(mSensorRect.top, h - mSensorRect.right, mSensorRect.bottom,
h - mSensorRect.left);
break;
case Surface.ROTATION_270:
+ //noinspection SuspiciousNameCombination
mSensorRect.set(w - mSensorRect.bottom, mSensorRect.left, w - mSensorRect.top,
mSensorRect.right);
break;
@@ -222,6 +251,8 @@
canvas.drawOval(mSensorRect, mSensorPaint);
} else {
if (mUdfpsAnimation != null) {
+ final int alpha = shouldPauseAuth() ? 255 - mNotificationPanelAlpha : 255;
+ mUdfpsAnimation.setAlpha(alpha);
mUdfpsAnimation.draw(canvas);
}
}
@@ -260,7 +291,19 @@
return x > (cx - rx * mSensorTouchAreaCoefficient)
&& x < (cx + rx * mSensorTouchAreaCoefficient)
&& y > (cy - ry * 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.
+ */
+ private boolean shouldPauseAuth() {
+ return (mNotificationShadeExpanded && mStatusBarState != KEYGUARD)
+ || mStatusBarState == SHADE_LOCKED
+ || mStatusBarState == FULLSCREEN_USER_SWITCHER;
}
void setScrimAlpha(int alpha) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 03d17e5..19c0b6d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -34,6 +34,7 @@
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
@@ -62,6 +63,8 @@
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
import java.util.function.Consumer;
import javax.inject.Inject;
@@ -195,6 +198,16 @@
private boolean mWakeLockHeld;
private boolean mKeyguardOccluded;
+ /**
+ * Notifies listeners of animation-related changes (currently just opacity changes).
+ */
+ public interface ScrimChangedListener {
+ void onAlphaChanged(float alpha);
+ }
+
+ @NonNull
+ private final List<ScrimChangedListener> mScrimChangedListeners;
+
@Inject
public ScrimController(LightBarController lightBarController, DozeParameters dozeParameters,
AlarmManager alarmManager, KeyguardStateController keyguardStateController,
@@ -208,6 +221,7 @@
ScrimState.BUBBLE_EXPANDED.setBubbleAlpha(featureFlags.isShadeOpaque()
? BUSY_SCRIM_ALPHA : GAR_SCRIM_ALPHA);
mBlurUtils = blurUtils;
+ mScrimChangedListeners = new ArrayList<>();
mKeyguardStateController = keyguardStateController;
mDarkenWhileDragging = !mKeyguardStateController.canDismissLockScreen();
@@ -284,6 +298,10 @@
mScrimVisibleListener = listener;
}
+ public void addScrimChangedListener(@NonNull ScrimChangedListener listener) {
+ mScrimChangedListeners.add(listener);
+ }
+
public void transitionTo(ScrimState state) {
transitionTo(state, null);
}
@@ -559,6 +577,10 @@
throw new IllegalStateException("Scrim opacity is NaN for state: " + mState
+ ", front: " + mInFrontAlpha + ", back: " + mBehindAlpha);
}
+
+ for (ScrimChangedListener listener : mScrimChangedListeners) {
+ listener.onAlphaChanged(mBehindAlpha);
+ }
}
private void applyAndDispatchExpansion() {
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 ed3cf9a..dd145e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -45,6 +45,7 @@
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.settings.FakeSettings;
import com.android.systemui.util.time.FakeSystemClock;
@@ -90,6 +91,8 @@
private WindowManager mWindowManager;
@Mock
private StatusBarStateController mStatusBarStateController;
+ @Mock
+ private ScrimController mScrimController;
private FakeSettings mSystemSettings;
private FakeExecutor mFgExecutor;
@@ -130,7 +133,8 @@
mWindowManager,
mSystemSettings,
mStatusBarStateController,
- mFgExecutor);
+ mFgExecutor,
+ mScrimController);
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
mOverlayController = mOverlayCaptor.getValue();
@@ -245,4 +249,10 @@
// THEN the scrim and dot is hidden
verify(mUdfpsView).hideScrimAndDot();
}
+
+ @Test
+ public void registersViewForCallbacks() throws RemoteException {
+ verify(mStatusBarStateController).addCallback(mUdfpsView);
+ verify(mScrimController).addScrimChangedListener(mUdfpsView);
+ }
}