Merge "Update light reveal + udfps icon vis" into sc-dev

This commit is contained in:
TreeHugger Robot
2021-04-05 18:28:21 +00:00
committed by Android (Google) Code Review
10 changed files with 150 additions and 56 deletions

View File

@@ -32,9 +32,10 @@ import android.widget.FrameLayout;
* - optionally can override dozeTimeTick to adjust views for burn-in mitigation
*/
abstract class UdfpsAnimationView extends FrameLayout {
// mAlpha takes into consideration the status bar expansion amount to fade out icon when
// the status bar is expanded
private int mAlpha;
private boolean mPauseAuth;
boolean mPauseAuth;
public UdfpsAnimationView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
@@ -75,7 +76,7 @@ abstract class UdfpsAnimationView extends FrameLayout {
getDrawable().setAlpha(calculateAlpha());
}
protected final int calculateAlpha() {
int calculateAlpha() {
return mPauseAuth ? mAlpha : 255;
}

View File

@@ -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.graphics.PointF;
import android.graphics.RectF;
@@ -68,18 +64,13 @@ abstract class UdfpsAnimationViewController<T extends UdfpsAnimationView>
@Override
protected void onViewAttached() {
mStatusBarStateController.addCallback(mStateListener);
mStateListener.onStateChanged(mStatusBarStateController.getState());
mStatusBar.addExpansionChangedListener(mStatusBarExpansionChangedListener);
mDumpManger.registerDumpable(getDumpTag(), this);
}
@Override
protected void onViewDetached() {
mStatusBarStateController.removeCallback(mStateListener);
mStatusBar.removeExpansionChangedListener(mStatusBarExpansionChangedListener);
mDumpManger.unregisterDumpable(getDumpTag());
}
@@ -106,9 +97,7 @@ abstract class UdfpsAnimationViewController<T extends UdfpsAnimationView>
* authentication.
*/
boolean shouldPauseAuth() {
return (mNotificationShadeExpanded && mStatusBarState != KEYGUARD)
|| mStatusBarState == SHADE_LOCKED
|| mStatusBarState == FULLSCREEN_USER_SWITCHER;
return mNotificationShadeExpanded;
}
/**
@@ -188,13 +177,4 @@ abstract class UdfpsAnimationViewController<T extends UdfpsAnimationView>
updatePauseAuth();
}
};
private final StatusBarStateController.StateListener mStateListener =
new StatusBarStateController.StateListener() {
@Override
public void onStateChanged(int newState) {
mStatusBarState = newState;
updatePauseAuth();
}
};
}

View File

@@ -52,6 +52,7 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeReceiver;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -90,6 +91,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
@NonNull private final DumpManager mDumpManager;
@NonNull private final AuthRippleController mAuthRippleController;
@NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@NonNull private final KeyguardViewMediator mKeyguardViewMediator;
// 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;
@@ -310,7 +312,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
@NonNull StatusBarKeyguardViewManager statusBarKeyguardViewManager,
@NonNull DumpManager dumpManager,
@NonNull AuthRippleController authRippleController,
@NonNull KeyguardUpdateMonitor keyguardUpdateMonitor) {
@NonNull KeyguardUpdateMonitor keyguardUpdateMonitor,
@NonNull KeyguardViewMediator keyguardViewMediator) {
mContext = context;
mInflater = inflater;
// The fingerprint manager is queried for UDFPS before this class is constructed, so the
@@ -324,6 +327,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
mDumpManager = dumpManager;
mAuthRippleController = authRippleController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mKeyguardViewMediator = keyguardViewMediator;
mSensorProps = findFirstUdfps();
// At least one UDFPS sensor exists
@@ -491,7 +495,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
mKeyguardViewManager,
mKeyguardUpdateMonitor,
mFgExecutor,
mDumpManager
mDumpManager,
mKeyguardViewMediator
);
case IUdfpsOverlayController.REASON_AUTH_BP:
// note: empty controller, currently shows no visual affordance

View File

@@ -97,6 +97,11 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
}
}
@Override
int calculateAlpha() {
return mPauseAuth ? 0 : 255;
}
void onDozeAmountChanged(float linear, float eased) {
mFingerprintDrawable.onDozeAmountChanged(linear, eased);
}
@@ -153,6 +158,10 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
return mStatusBarState == StatusBarState.SHADE_LOCKED;
}
boolean isHome() {
return mStatusBarState == StatusBarState.SHADE;
}
/**
* Animates out the bg protection circle behind the fp icon to unhighlight the icon.
*/

View File

@@ -16,6 +16,8 @@
package com.android.systemui.biometrics;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import android.annotation.NonNull;
import android.hardware.biometrics.BiometricSourceType;
@@ -24,7 +26,9 @@ import androidx.annotation.Nullable;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -45,12 +49,15 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
@NonNull private final StatusBarKeyguardViewManager mKeyguardViewManager;
@NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@NonNull private final DelayableExecutor mExecutor;
@NonNull private final KeyguardViewMediator mKeyguardViewMediator;
@Nullable private Runnable mCancelRunnable;
private boolean mShowBouncer;
private boolean mQsExpanded;
private boolean mFaceDetectRunning;
private boolean mHintShown;
private boolean mTransitioningFromHome;
private int mStatusBarState;
protected UdfpsKeyguardViewController(
@NonNull UdfpsKeyguardView view,
@@ -59,11 +66,13 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
@NonNull StatusBarKeyguardViewManager statusBarKeyguardViewManager,
@NonNull KeyguardUpdateMonitor keyguardUpdateMonitor,
@NonNull DelayableExecutor mainDelayableExecutor,
@NonNull DumpManager dumpManager) {
@NonNull DumpManager dumpManager,
@NonNull KeyguardViewMediator keyguardViewMediator) {
super(view, statusBarStateController, statusBar, dumpManager);
mKeyguardViewManager = statusBarKeyguardViewManager;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mExecutor = mainDelayableExecutor;
mKeyguardViewMediator = keyguardViewMediator;
}
@Override
@@ -94,6 +103,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
mStatusBarStateController.removeCallback(mStateListener);
mAlternateAuthInterceptor.hideAlternateAuthBouncer();
mKeyguardViewManager.setAlternateAuthInterceptor(null);
mTransitioningFromHome = false;
if (mCancelRunnable != null) {
mCancelRunnable.run();
@@ -106,17 +116,18 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
super.dump(fd, pw, args);
pw.println("mShowBouncer=" + mShowBouncer);
pw.println("mFaceDetectRunning=" + mFaceDetectRunning);
pw.println("mTransitioningFromHomeToKeyguard=" + mTransitioningFromHome);
}
/**
* Overrides non-bouncer show logic in shouldPauseAuth to still auth.
*/
private void showBouncer(boolean forceShow) {
if (mShowBouncer == forceShow) {
private void showBouncer(boolean show) {
if (mShowBouncer == show) {
return;
}
mShowBouncer = forceShow;
mShowBouncer = show;
updatePauseAuth();
if (mShowBouncer) {
mView.animateUdfpsBouncer();
@@ -128,18 +139,26 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
/**
* 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.
* is expanded, so this can be overridden with the showBouncer method.
*/
public boolean shouldPauseAuth() {
if (mShowBouncer) {
return false;
}
if (mStatusBarState != KEYGUARD) {
return true;
}
if (mTransitioningFromHome && mKeyguardViewMediator.isAnimatingScreenOff()) {
return true;
}
if (mQsExpanded) {
return true;
}
return super.shouldPauseAuth();
return false;
}
private void cancelDelayedHint() {
@@ -176,12 +195,25 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
new StatusBarStateController.StateListener() {
@Override
public void onDozeAmountChanged(float linear, float eased) {
mView.onDozeAmountChanged(linear, eased);
if (linear != 0) showBouncer(false);
mView.onDozeAmountChanged(linear, eased);
if (linear == 1f) {
// transition has finished
mTransitioningFromHome = false;
}
updatePauseAuth();
}
@Override
public void onStatePreChange(int oldState, int newState) {
mTransitioningFromHome = oldState == StatusBarState.SHADE
&& newState == StatusBarState.KEYGUARD;
updatePauseAuth();
}
@Override
public void onStateChanged(int statusBarState) {
mStatusBarState = statusBarState;
mView.setStatusBarState(statusBarState);
}
};

View File

@@ -239,6 +239,7 @@ import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.volume.VolumeComponent;
import com.android.systemui.wmshell.BubblesManager;
import com.android.wm.shell.bubbles.Bubbles;
@@ -791,6 +792,7 @@ public class StatusBar extends SystemUI implements DemoMode,
BrightnessSlider.Factory brightnessSliderFactory,
WiredChargingRippleController chargingRippleAnimationController,
OngoingCallController ongoingCallController,
TunerService tunerService,
FeatureFlags featureFlags) {
super(context);
mNotificationsController = notificationsController;
@@ -873,6 +875,15 @@ public class StatusBar extends SystemUI implements DemoMode,
mOngoingCallController = ongoingCallController;
mFeatureFlags = featureFlags;
tunerService.addTunable(
(key, newValue) -> {
if (key.equals(Settings.Secure.DOZE_ALWAYS_ON)) {
updateLightRevealScrimVisibility();
}
},
Settings.Secure.DOZE_ALWAYS_ON
);
mExpansionChangedListeners = new ArrayList<>();
mBubbleExpandListener =
@@ -1216,15 +1227,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mLightRevealScrim = mNotificationShadeWindowView.findViewById(R.id.light_reveal_scrim);
mChargingRippleAnimationController.setViewHost(mNotificationShadeWindowView);
if (mFeatureFlags.useNewLockscreenAnimations()
&& (mDozeParameters.getAlwaysOn() || mDozeParameters.isQuickPickupEnabled())) {
mLightRevealScrim.setVisibility(View.VISIBLE);
mLightRevealScrim.setRevealEffect(LiftReveal.INSTANCE);
} else {
mLightRevealScrim.setVisibility(View.GONE);
}
updateLightRevealScrimVisibility();
mNotificationPanelViewController.initDependencies(
this,
@@ -4654,4 +4657,19 @@ public class StatusBar extends SystemUI implements DemoMode,
public void removeExpansionChangedListener(@NonNull ExpansionChangedListener listener) {
mExpansionChangedListeners.remove(listener);
}
private void updateLightRevealScrimVisibility() {
if (mLightRevealScrim == null) {
// status bar may not be inflated yet
return;
}
if (mFeatureFlags.useNewLockscreenAnimations()
&& (mDozeParameters.getAlwaysOn() || mDozeParameters.isQuickPickupEnabled())) {
mLightRevealScrim.setVisibility(View.VISIBLE);
mLightRevealScrim.setRevealEffect(LiftReveal.INSTANCE);
} else {
mLightRevealScrim.setVisibility(View.GONE);
}
}
}

View File

@@ -100,6 +100,7 @@ import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.volume.VolumeComponent;
import com.android.systemui.wmshell.BubblesManager;
import com.android.wm.shell.bubbles.Bubbles;
@@ -208,6 +209,7 @@ public interface StatusBarPhoneModule {
BrightnessSlider.Factory brightnessSliderFactory,
WiredChargingRippleController chargingRippleAnimationController,
OngoingCallController ongoingCallController,
TunerService tunerService,
FeatureFlags featureFlags) {
return new StatusBar(
context,
@@ -291,6 +293,7 @@ public interface StatusBarPhoneModule {
brightnessSliderFactory,
chargingRippleAnimationController,
ongoingCallController,
tunerService,
featureFlags);
}
}

View File

@@ -47,6 +47,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -103,6 +104,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock
private KeyguardViewMediator mKeyguardViewMediator;
@Mock
private IUdfpsOverlayControllerCallback mUdfpsOverlayControllerCallback;
private FakeExecutor mFgExecutor;
@@ -155,7 +158,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
mStatusBarKeyguardViewManager,
mDumpManager,
mAuthRippleController,
mKeyguardUpdateMonitor);
mKeyguardUpdateMonitor,
mKeyguardViewMediator);
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
mOverlayController = mOverlayCaptor.getValue();

View File

@@ -18,7 +18,7 @@ package com.android.systemui.biometrics;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -30,6 +30,7 @@ import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -44,7 +45,6 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.List;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -65,12 +65,13 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
private DelayableExecutor mExecutor;
@Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock
private KeyguardViewMediator mKeyguardViewMediator;
private UdfpsKeyguardViewController mController;
// Capture listeners so that they can be used to send events
@Captor private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerCaptor;
private StatusBarStateController.StateListener mParentStatusBarStateListener;
private StatusBarStateController.StateListener mStatusBarStateListener;
@Captor private ArgumentCaptor<StatusBar.ExpansionChangedListener> mExpansionListenerCaptor;
@@ -83,6 +84,7 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mKeyguardViewMediator.isAnimatingScreenOff()).thenReturn(false);
mController = new UdfpsKeyguardViewController(
mView,
mStatusBarStateController,
@@ -90,7 +92,8 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
mStatusBarKeyguardViewManager,
mKeyguardUpdateMonitor,
mExecutor,
mDumpManager);
mDumpManager,
mKeyguardViewMediator);
}
@Test
@@ -108,7 +111,7 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
@Test
public void testViewControllerQueriesSBStateOnAttached() {
mController.onViewAttached();
verify(mStatusBarStateController, times(2)).getState();
verify(mStatusBarStateController).getState();
verify(mStatusBarStateController).getDozeAmount();
final float dozeAmount = .88f;
@@ -117,7 +120,7 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
captureStatusBarStateListeners();
mController.onViewAttached();
verify(mView).setPauseAuth(true);
verify(mView, atLeast(1)).setPauseAuth(true);
verify(mView).onDozeAmountChanged(dozeAmount, dozeAmount);
}
@@ -128,7 +131,6 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
captureExpansionListener();
mController.onViewDetached();
verify(mStatusBarStateController).removeCallback(mParentStatusBarStateListener);
verify(mStatusBarStateController).removeCallback(mStatusBarStateListener);
verify(mStatusBar).removeExpansionChangedListener(mExpansionListener);
}
@@ -167,6 +169,47 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
assertTrue(mController.shouldPauseAuth());
}
@Test
public void testShouldPauseAuthOnShade() {
mController.onViewAttached();
captureStatusBarStateListeners();
captureExpansionListener();
// WHEN not on keyguard yet (shade = home)
sendStatusBarStateChanged(StatusBarState.SHADE);
// THEN pause auth
assertTrue(mController.shouldPauseAuth());
}
@Test
public void testShouldPauseAuthAnimatingScreenOffFromShade() {
mController.onViewAttached();
captureStatusBarStateListeners();
captureExpansionListener();
// WHEN transitioning from home/shade => keyguard + animating screen off
mStatusBarStateListener.onStatePreChange(StatusBarState.SHADE, StatusBarState.KEYGUARD);
when(mKeyguardViewMediator.isAnimatingScreenOff()).thenReturn(true);
// THEN pause auth
assertTrue(mController.shouldPauseAuth());
}
@Test
public void testDoNotPauseAuthAnimatingScreenOffFromLS() {
mController.onViewAttached();
captureStatusBarStateListeners();
captureExpansionListener();
// WHEN animating screen off transition from LS => AOD
sendStatusBarStateChanged(StatusBarState.KEYGUARD);
when(mKeyguardViewMediator.isAnimatingScreenOff()).thenReturn(true);
// THEN don't pause auth
assertFalse(mController.shouldPauseAuth());
}
@Test
public void testOverrideShouldPauseAuthOnShadeLocked() {
mController.onViewAttached();
@@ -203,15 +246,11 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
private void sendStatusBarStateChanged(int statusBarState) {
mStatusBarStateListener.onStateChanged(statusBarState);
mParentStatusBarStateListener.onStateChanged(statusBarState);
}
private void captureStatusBarStateListeners() {
verify(mStatusBarStateController, times(2)).addCallback(mStateListenerCaptor.capture());
List<StatusBarStateController.StateListener> stateListeners =
mStateListenerCaptor.getAllValues();
mParentStatusBarStateListener = stateListeners.get(0);
mStatusBarStateListener = stateListeners.get(1);
verify(mStatusBarStateController).addCallback(mStateListenerCaptor.capture());
mStatusBarStateListener = mStateListenerCaptor.getValue();
}
private void captureExpansionListener() {

View File

@@ -143,6 +143,7 @@ import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.volume.VolumeComponent;
@@ -265,6 +266,7 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private BrightnessSlider.Factory mBrightnessSliderFactory;
@Mock private WiredChargingRippleController mWiredChargingRippleController;
@Mock private OngoingCallController mOngoingCallController;
@Mock private TunerService mTunerService;
@Mock private FeatureFlags mFeatureFlags;
private ShadeController mShadeController;
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
@@ -430,6 +432,7 @@ public class StatusBarTest extends SysuiTestCase {
mBrightnessSliderFactory,
mWiredChargingRippleController,
mOngoingCallController,
mTunerService,
mFeatureFlags);
when(mNotificationShadeWindowView.findViewById(R.id.lock_icon_container)).thenReturn(