Fix udfps flicker on camera launch + exit

Test: atest UdfpsKeyguardViewControllerTest
Test: manually trigger double-tap power button for camera
and then dismiss the camera
Bug: 197160246

Merged-In: Id3aa20662df8cdd6676141f5f70e5eae0cec6215
Change-Id: Id3aa20662df8cdd6676141f5f70e5eae0cec6215
This commit is contained in:
Beverly
2021-08-23 15:46:29 -04:00
committed by Beverly Tai
parent 09ce8952ec
commit e8f14f4813
6 changed files with 130 additions and 21 deletions

View File

@@ -781,6 +781,7 @@ public class UdfpsController implements DozeReceiver {
mKeyguardViewMediator,
mLockscreenShadeTransitionController,
mConfigurationController,
mKeyguardStateController,
this
);
case IUdfpsOverlayController.REASON_AUTH_BP:

View File

@@ -34,6 +34,7 @@ import com.android.systemui.statusbar.phone.KeyguardBouncer;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import java.io.FileDescriptor;
@@ -50,6 +51,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
@NonNull private final KeyguardViewMediator mKeyguardViewMediator;
@NonNull private final LockscreenShadeTransitionController mLockScreenShadeTransitionController;
@NonNull private final ConfigurationController mConfigurationController;
@NonNull private final KeyguardStateController mKeyguardStateController;
@NonNull private final UdfpsController mUdfpsController;
private boolean mShowingUdfpsBouncer;
@@ -60,6 +62,9 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
private float mTransitionToFullShadeProgress;
private float mLastDozeAmount;
private float mStatusBarExpansion;
private boolean mLaunchTransitionFadingAway;
/**
* hidden amount of pin/pattern/password bouncer
* {@link KeyguardBouncer#EXPANSION_VISIBLE} (0f) to
@@ -79,6 +84,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
@NonNull KeyguardViewMediator keyguardViewMediator,
@NonNull LockscreenShadeTransitionController transitionController,
@NonNull ConfigurationController configurationController,
@NonNull KeyguardStateController keyguardStateController,
@NonNull UdfpsController udfpsController) {
super(view, statusBarStateController, statusBar, dumpManager);
mKeyguardViewManager = statusBarKeyguardViewManager;
@@ -87,6 +93,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
mKeyguardViewMediator = keyguardViewMediator;
mLockScreenShadeTransitionController = transitionController;
mConfigurationController = configurationController;
mKeyguardStateController = keyguardStateController;
mUdfpsController = udfpsController;
}
@@ -105,11 +112,14 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
mUdfpsRequested = false;
mLaunchTransitionFadingAway = mKeyguardStateController.isLaunchTransitionFadingAway();
mKeyguardStateController.addCallback(mKeyguardStateControllerCallback);
mStatusBarState = mStatusBarStateController.getState();
mQsExpanded = mKeyguardViewManager.isQsExpanded();
mInputBouncerHiddenAmount = KeyguardBouncer.EXPANSION_HIDDEN;
mIsBouncerVisible = mKeyguardViewManager.bouncerIsOrWillBeShowing();
mConfigurationController.addCallback(mConfigurationListener);
mStatusBar.addExpansionChangedListener(mStatusBarExpansionChangedListener);
updateAlpha();
updatePauseAuth();
@@ -122,10 +132,12 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
super.onViewDetached();
mFaceDetectRunning = false;
mKeyguardStateController.removeCallback(mKeyguardStateControllerCallback);
mStatusBarStateController.removeCallback(mStateListener);
mKeyguardViewManager.removeAlternateAuthInterceptor(mAlternateAuthInterceptor);
mKeyguardUpdateMonitor.requestFaceAuthOnOccludingApp(false);
mConfigurationController.removeCallback(mConfigurationListener);
mStatusBar.removeExpansionChangedListener(mStatusBarExpansionChangedListener);
if (mLockScreenShadeTransitionController.getUdfpsKeyguardViewController() == this) {
mLockScreenShadeTransitionController.setUdfpsKeyguardViewController(null);
}
@@ -140,9 +152,11 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
pw.println("mQsExpanded=" + mQsExpanded);
pw.println("mIsBouncerVisible=" + mIsBouncerVisible);
pw.println("mInputBouncerHiddenAmount=" + mInputBouncerHiddenAmount);
pw.println("mStatusBarExpansion=" + mStatusBarExpansion);
pw.println("mAlpha=" + mView.getAlpha());
pw.println("mUdfpsRequested=" + mUdfpsRequested);
pw.println("mView.mUdfpsRequested=" + mView.mUdfpsRequested);
pw.println("mLaunchTransitionFadingAway=" + mLaunchTransitionFadingAway);
}
/**
@@ -189,6 +203,10 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
return false;
}
if (mLaunchTransitionFadingAway) {
return true;
}
if (mStatusBarState != KEYGUARD) {
return true;
}
@@ -237,10 +255,13 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
}
private void updateAlpha() {
// fade icon on transition to showing bouncer
// fade icon on transitions to showing the status bar, but if mUdfpsRequested, then
// the keyguard is occluded by some application - so instead use the input bouncer
// hidden amount to determine the fade
float expansion = mUdfpsRequested ? mInputBouncerHiddenAmount : mStatusBarExpansion;
int alpha = mShowingUdfpsBouncer ? 255
: (int) MathUtils.constrain(
MathUtils.map(.5f, .9f, 0f, 255f, mInputBouncerHiddenAmount),
MathUtils.map(.5f, .9f, 0f, 255f, expansion),
0f, 255f);
alpha *= (1.0f - mTransitionToFullShadeProgress);
mView.setUnpausedAlpha(alpha);
@@ -356,4 +377,23 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
mView.updateColor();
}
};
private final StatusBar.ExpansionChangedListener mStatusBarExpansionChangedListener =
new StatusBar.ExpansionChangedListener() {
@Override
public void onExpansionChanged(float expansion, boolean expanded) {
mStatusBarExpansion = expansion;
updateAlpha();
}
};
private final KeyguardStateController.Callback mKeyguardStateControllerCallback =
new KeyguardStateController.Callback() {
@Override
public void onLaunchTransitionFadingAwayChanged() {
mLaunchTransitionFadingAway =
mKeyguardStateController.isLaunchTransitionFadingAway();
updatePauseAuth();
}
};
}

View File

@@ -1148,6 +1148,9 @@ public class StatusBar extends SystemUI implements DemoMode,
mStatusBarView.setPanel(mNotificationPanelViewController);
mStatusBarView.setScrimController(mScrimController);
mStatusBarView.setExpansionChangedListeners(mExpansionChangedListeners);
for (ExpansionChangedListener listener : mExpansionChangedListeners) {
sendInitialExpansionAmount(listener);
}
// CollapsedStatusBarFragment re-inflated PhoneStatusBarView and both of
// mStatusBarView.mExpanded and mStatusBarView.mBouncerShowing are false.
@@ -4932,6 +4935,14 @@ public class StatusBar extends SystemUI implements DemoMode,
public void addExpansionChangedListener(@NonNull ExpansionChangedListener listener) {
mExpansionChangedListeners.add(listener);
sendInitialExpansionAmount(listener);
}
private void sendInitialExpansionAmount(ExpansionChangedListener expansionChangedListener) {
if (mStatusBarView != null) {
expansionChangedListener.onExpansionChanged(mStatusBarView.getExpansionFraction(),
mStatusBarView.isExpanded());
}
}
public void removeExpansionChangedListener(@NonNull ExpansionChangedListener listener) {

View File

@@ -245,5 +245,11 @@ public interface KeyguardStateController extends CallbackController<Callback> {
* animation.
*/
default void onKeyguardDismissAmountChanged() {}
/**
* Triggered when the notification panel is starting or has finished
* fading away on transition to an app.
*/
default void onLaunchTransitionFadingAwayChanged() {}
}
}

View File

@@ -343,6 +343,7 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
@Override
public void setLaunchTransitionFadingAway(boolean fadingAway) {
mLaunchTransitionFadingAway = fadingAway;
new ArrayList<>(mCallbacks).forEach(Callback::onLaunchTransitionFadingAwayChanged);
}
@Override

View File

@@ -20,6 +20,11 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -30,7 +35,6 @@ import android.testing.TestableLooper.RunWithLooper;
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
@@ -40,6 +44,7 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import org.junit.Before;
@@ -50,6 +55,8 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.List;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -75,6 +82,8 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
@Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock
private KeyguardStateController mKeyguardStateController;
@Mock
private KeyguardViewMediator mKeyguardViewMediator;
@Mock
private ConfigurationController mConfigurationController;
@@ -88,14 +97,15 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
private StatusBarStateController.StateListener mStatusBarStateListener;
@Captor private ArgumentCaptor<StatusBar.ExpansionChangedListener> mExpansionListenerCaptor;
private StatusBar.ExpansionChangedListener mExpansionListener;
private List<StatusBar.ExpansionChangedListener> mExpansionListeners;
@Captor private ArgumentCaptor<StatusBarKeyguardViewManager.AlternateAuthInterceptor>
mAltAuthInterceptorCaptor;
private StatusBarKeyguardViewManager.AlternateAuthInterceptor mAltAuthInterceptor;
@Captor private ArgumentCaptor<KeyguardUpdateMonitorCallback> mUpdateMonitorCallbackCaptor;
private KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback;
@Captor private ArgumentCaptor<KeyguardStateController.Callback>
mKeyguardStateControllerCallbackCaptor;
private KeyguardStateController.Callback mKeyguardStateControllerCallback;
@Before
public void setUp() {
@@ -114,13 +124,14 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
mKeyguardViewMediator,
mLockscreenShadeTransitionController,
mConfigurationController,
mKeyguardStateController,
mUdfpsController);
}
@Test
public void testRegistersExpansionChangedListenerOnAttached() {
mController.onViewAttached();
captureExpansionListener();
captureExpansionListeners();
}
@Test
@@ -149,11 +160,15 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
public void testListenersUnregisteredOnDetached() {
mController.onViewAttached();
captureStatusBarStateListeners();
captureExpansionListener();
captureExpansionListeners();
captureKeyguardStateControllerCallback();
mController.onViewDetached();
verify(mStatusBarStateController).removeCallback(mStatusBarStateListener);
verify(mStatusBar).removeExpansionChangedListener(mExpansionListener);
for (StatusBar.ExpansionChangedListener listener : mExpansionListeners) {
verify(mStatusBar).removeExpansionChangedListener(listener);
}
verify(mKeyguardStateController).removeCallback(mKeyguardStateControllerCallback);
}
@Test
@@ -172,7 +187,6 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
public void testShouldPauseAuthBouncerShowing() {
mController.onViewAttached();
captureStatusBarStateListeners();
captureExpansionListener();
sendStatusBarStateChanged(StatusBarState.KEYGUARD);
@@ -183,18 +197,32 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
public void testShouldNotPauseAuthOnKeyguard() {
mController.onViewAttached();
captureStatusBarStateListeners();
captureExpansionListener();
sendStatusBarStateChanged(StatusBarState.KEYGUARD);
assertFalse(mController.shouldPauseAuth());
}
@Test
public void testShouldPauseAuthIsLaunchTransitionFadingAway() {
// GIVEN view is attached and we're on the keyguard (see testShouldNotPauseAuthOnKeyguard)
mController.onViewAttached();
captureStatusBarStateListeners();
sendStatusBarStateChanged(StatusBarState.KEYGUARD);
// WHEN isLaunchTransitionFadingAway=true
captureKeyguardStateControllerCallback();
when(mKeyguardStateController.isLaunchTransitionFadingAway()).thenReturn(true);
mKeyguardStateControllerCallback.onLaunchTransitionFadingAwayChanged();
// THEN pause auth
assertTrue(mController.shouldPauseAuth());
}
@Test
public void testShouldPauseAuthOnShadeLocked() {
mController.onViewAttached();
captureStatusBarStateListeners();
captureExpansionListener();
sendStatusBarStateChanged(StatusBarState.SHADE_LOCKED);
@@ -205,7 +233,6 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
public void testShouldPauseAuthOnShade() {
mController.onViewAttached();
captureStatusBarStateListeners();
captureExpansionListener();
// WHEN not on keyguard yet (shade = home)
sendStatusBarStateChanged(StatusBarState.SHADE);
@@ -218,7 +245,6 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
public void testShouldPauseAuthAnimatingScreenOffFromShade() {
mController.onViewAttached();
captureStatusBarStateListeners();
captureExpansionListener();
// WHEN transitioning from home/shade => keyguard + animating screen off
mStatusBarStateListener.onStatePreChange(StatusBarState.SHADE, StatusBarState.KEYGUARD);
@@ -232,7 +258,6 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
public void testDoNotPauseAuthAnimatingScreenOffFromLS() {
mController.onViewAttached();
captureStatusBarStateListeners();
captureExpansionListener();
// WHEN animating screen off transition from LS => AOD
sendStatusBarStateChanged(StatusBarState.KEYGUARD);
@@ -273,6 +298,21 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
verify(mStatusBarKeyguardViewManager).removeAlternateAuthInterceptor(mAltAuthInterceptor);
}
@Test
public void testFadeInWithStatusBarExpansion() {
// GIVEN view is attached
mController.onViewAttached();
captureExpansionListeners();
captureKeyguardStateControllerCallback();
reset(mView);
// WHEN status bar expansion is 0
updateStatusBarExpansion(0, true);
// THEN alpha is 0
verify(mView).setUnpausedAlpha(0);
}
private void sendStatusBarStateChanged(int statusBarState) {
mStatusBarStateListener.onStateChanged(statusBarState);
}
@@ -282,9 +322,18 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
mStatusBarStateListener = mStateListenerCaptor.getValue();
}
private void captureExpansionListener() {
verify(mStatusBar).addExpansionChangedListener(mExpansionListenerCaptor.capture());
mExpansionListener = mExpansionListenerCaptor.getValue();
private void captureExpansionListeners() {
verify(mStatusBar, times(2))
.addExpansionChangedListener(mExpansionListenerCaptor.capture());
// first (index=0) is from super class, UdfpsAnimationViewController.
// second (index=1) is from UdfpsKeyguardViewController
mExpansionListeners = mExpansionListenerCaptor.getAllValues();
}
private void updateStatusBarExpansion(float expansion, boolean expanded) {
for (StatusBar.ExpansionChangedListener listener : mExpansionListeners) {
listener.onExpansionChanged(expansion, expanded);
}
}
private void captureAltAuthInterceptor() {
@@ -293,8 +342,9 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
mAltAuthInterceptor = mAltAuthInterceptorCaptor.getValue();
}
private void captureKeyguardUpdateMonitorCallback() {
verify(mKeyguardUpdateMonitor).registerCallback(mUpdateMonitorCallbackCaptor.capture());
mKeyguardUpdateMonitorCallback = mUpdateMonitorCallbackCaptor.getValue();
private void captureKeyguardStateControllerCallback() {
verify(mKeyguardStateController).addCallback(
mKeyguardStateControllerCallbackCaptor.capture());
mKeyguardStateControllerCallback = mKeyguardStateControllerCallbackCaptor.getValue();
}
}