Delay the transition to AOD1 if udfps is activated
We don't want to change display states while the user is interacting with the UDFPS sensor or else we'll lose the touch and cut fp authentication short. Test: atest DozeScreenSTateTest Bug: 198710028 Change-Id: I3a8168e6f1970c36717e0a7a223bcc74c3ec5600
This commit is contained in:
@@ -213,6 +213,14 @@ public class DozeLog implements Dumpable {
|
||||
mLogger.logStateChangedSent(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends display state delayed by UDFPS event to the logs
|
||||
* @param delayedDisplayState the display screen state that was delayed
|
||||
*/
|
||||
public void traceDisplayStateDelayedByUdfps(int delayedDisplayState) {
|
||||
mLogger.logDisplayStateDelayedByUdfps(delayedDisplayState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends display state changed event to the logs
|
||||
* @param displayState new DozeMachine state
|
||||
|
||||
@@ -160,6 +160,14 @@ class DozeLogger @Inject constructor(
|
||||
})
|
||||
}
|
||||
|
||||
fun logDisplayStateDelayedByUdfps(delayedDisplayState: Int) {
|
||||
buffer.log(TAG, INFO, {
|
||||
str1 = Display.stateToString(delayedDisplayState)
|
||||
}, {
|
||||
"Delaying display state change to: $str1 due to UDFPS activity"
|
||||
})
|
||||
}
|
||||
|
||||
fun logDisplayStateChanged(displayState: Int) {
|
||||
buffer.log(TAG, INFO, {
|
||||
str1 = Display.stateToString(displayState)
|
||||
|
||||
@@ -26,6 +26,11 @@ import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.systemui.biometrics.AuthController;
|
||||
import com.android.systemui.biometrics.UdfpsController;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.doze.dagger.DozeScope;
|
||||
import com.android.systemui.doze.dagger.WrappedService;
|
||||
@@ -34,6 +39,7 @@ import com.android.systemui.util.wakelock.SettableWakeLock;
|
||||
import com.android.systemui.util.wakelock.WakeLock;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
/**
|
||||
* Controls the screen when dozing.
|
||||
@@ -56,23 +62,61 @@ public class DozeScreenState implements DozeMachine.Part {
|
||||
*/
|
||||
public static final int ENTER_DOZE_HIDE_WALLPAPER_DELAY = 2500;
|
||||
|
||||
/**
|
||||
* Add an extra delay to the transition to DOZE when udfps is current activated before
|
||||
* the display state transitions from ON => DOZE.
|
||||
*/
|
||||
public static final int UDFPS_DISPLAY_STATE_DELAY = 1200;
|
||||
|
||||
private final DozeMachine.Service mDozeService;
|
||||
private final Handler mHandler;
|
||||
private final Runnable mApplyPendingScreenState = this::applyPendingScreenState;
|
||||
private final DozeParameters mParameters;
|
||||
private final DozeHost mDozeHost;
|
||||
private final AuthController mAuthController;
|
||||
private final Provider<UdfpsController> mUdfpsControllerProvider;
|
||||
@Nullable private UdfpsController mUdfpsController;
|
||||
private final DozeLog mDozeLog;
|
||||
|
||||
private int mPendingScreenState = Display.STATE_UNKNOWN;
|
||||
private SettableWakeLock mWakeLock;
|
||||
|
||||
@Inject
|
||||
public DozeScreenState(@WrappedService DozeMachine.Service service, @Main Handler handler,
|
||||
DozeHost host, DozeParameters parameters, WakeLock wakeLock) {
|
||||
public DozeScreenState(
|
||||
@WrappedService DozeMachine.Service service,
|
||||
@Main Handler handler,
|
||||
DozeHost host,
|
||||
DozeParameters parameters,
|
||||
WakeLock wakeLock,
|
||||
AuthController authController,
|
||||
Provider<UdfpsController> udfpsControllerProvider,
|
||||
DozeLog dozeLog) {
|
||||
mDozeService = service;
|
||||
mHandler = handler;
|
||||
mParameters = parameters;
|
||||
mDozeHost = host;
|
||||
mWakeLock = new SettableWakeLock(wakeLock, TAG);
|
||||
mAuthController = authController;
|
||||
mUdfpsControllerProvider = udfpsControllerProvider;
|
||||
mDozeLog = dozeLog;
|
||||
|
||||
updateUdfpsController();
|
||||
if (mUdfpsController == null) {
|
||||
mAuthController.addCallback(new AuthController.Callback() {
|
||||
@Override
|
||||
public void onAllAuthenticatorsRegistered() {
|
||||
updateUdfpsController();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUdfpsController() {
|
||||
if (mAuthController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser())) {
|
||||
mUdfpsController = mUdfpsControllerProvider.get();
|
||||
} else {
|
||||
mUdfpsController = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -110,21 +154,28 @@ public class DozeScreenState implements DozeMachine.Part {
|
||||
mPendingScreenState = screenState;
|
||||
|
||||
// Delay screen state transitions even longer while animations are running.
|
||||
boolean shouldDelayTransition = newState == DOZE_AOD
|
||||
boolean shouldDelayTransitionEnteringDoze = newState == DOZE_AOD
|
||||
&& mParameters.shouldControlScreenOff() && !turningOn;
|
||||
|
||||
if (shouldDelayTransition) {
|
||||
// Delay screen state transition longer if UDFPS is actively authenticating a fp
|
||||
boolean shouldDelayTransitionForUDFPS = newState == DOZE_AOD
|
||||
&& mUdfpsController != null && mUdfpsController.isFingerDown();
|
||||
|
||||
if (shouldDelayTransitionEnteringDoze || shouldDelayTransitionForUDFPS) {
|
||||
mWakeLock.setAcquired(true);
|
||||
}
|
||||
|
||||
if (!messagePending) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Display state changed to " + screenState + " delayed by "
|
||||
+ (shouldDelayTransition ? ENTER_DOZE_DELAY : 1));
|
||||
+ (shouldDelayTransitionEnteringDoze ? ENTER_DOZE_DELAY : 1));
|
||||
}
|
||||
|
||||
if (shouldDelayTransition) {
|
||||
if (shouldDelayTransitionEnteringDoze) {
|
||||
mHandler.postDelayed(mApplyPendingScreenState, ENTER_DOZE_DELAY);
|
||||
} else if (shouldDelayTransitionForUDFPS) {
|
||||
mDozeLog.traceDisplayStateDelayedByUdfps(mPendingScreenState);
|
||||
mHandler.postDelayed(mApplyPendingScreenState, UDFPS_DISPLAY_STATE_DELAY);
|
||||
} else {
|
||||
mHandler.post(mApplyPendingScreenState);
|
||||
}
|
||||
@@ -139,6 +190,12 @@ public class DozeScreenState implements DozeMachine.Part {
|
||||
}
|
||||
|
||||
private void applyPendingScreenState() {
|
||||
if (mUdfpsController != null && mUdfpsController.isFingerDown()) {
|
||||
mDozeLog.traceDisplayStateDelayedByUdfps(mPendingScreenState);
|
||||
mHandler.postDelayed(mApplyPendingScreenState, UDFPS_DISPLAY_STATE_DELAY);
|
||||
return;
|
||||
}
|
||||
|
||||
applyScreenState(mPendingScreenState);
|
||||
mPendingScreenState = Display.STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
|
||||
import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_DOCKED;
|
||||
import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSED;
|
||||
import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSING;
|
||||
import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSE_DONE;
|
||||
import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING;
|
||||
import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE;
|
||||
import static com.android.systemui.doze.DozeMachine.State.FINISH;
|
||||
@@ -34,6 +35,7 @@ import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -45,6 +47,8 @@ import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.biometrics.AuthController;
|
||||
import com.android.systemui.biometrics.UdfpsController;
|
||||
import com.android.systemui.statusbar.phone.DozeParameters;
|
||||
import com.android.systemui.util.wakelock.WakeLockFake;
|
||||
import com.android.systemui.utils.os.FakeHandler;
|
||||
@@ -56,6 +60,8 @@ import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class DozeScreenStateTest extends SysuiTestCase {
|
||||
@@ -68,17 +74,29 @@ public class DozeScreenStateTest extends SysuiTestCase {
|
||||
private DozeParameters mDozeParameters;
|
||||
private WakeLockFake mWakeLock;
|
||||
private DozeScreenState mScreen;
|
||||
@Mock
|
||||
private Provider<UdfpsController> mUdfpsControllerProvider;
|
||||
@Mock
|
||||
private AuthController mAuthController;
|
||||
@Mock
|
||||
private UdfpsController mUdfpsController;
|
||||
@Mock
|
||||
private DozeLog mDozeLog;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(true);
|
||||
when(mDozeParameters.getAlwaysOn()).thenReturn(true);
|
||||
when(mUdfpsControllerProvider.get()).thenReturn(mUdfpsController);
|
||||
when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(true);
|
||||
when(mUdfpsController.isFingerDown()).thenReturn(false);
|
||||
|
||||
mServiceFake = new DozeServiceFake();
|
||||
mHandlerFake = new FakeHandler(Looper.getMainLooper());
|
||||
mWakeLock = new WakeLockFake();
|
||||
mScreen = new DozeScreenState(mServiceFake, mHandlerFake, mDozeHost, mDozeParameters,
|
||||
mWakeLock);
|
||||
mWakeLock, mAuthController, mUdfpsControllerProvider, mDozeLog);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -233,4 +251,56 @@ public class DozeScreenStateTest extends SysuiTestCase {
|
||||
assertEquals(Display.STATE_OFF, mServiceFake.screenState);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelayEnterDozeScreenState_whenUdfpsFingerDown() {
|
||||
// GIVEN AOD is initialized
|
||||
when(mDozeParameters.shouldControlScreenOff()).thenReturn(true);
|
||||
mHandlerFake.setMode(QUEUEING);
|
||||
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
|
||||
mHandlerFake.dispatchQueuedMessages();
|
||||
|
||||
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
|
||||
|
||||
// WHEN udfps is activated (fingerDown)
|
||||
when(mUdfpsController.isFingerDown()).thenReturn(true);
|
||||
mHandlerFake.dispatchQueuedMessages();
|
||||
|
||||
// THEN the display screen state doesn't immediately change
|
||||
assertEquals(Display.STATE_ON, mServiceFake.screenState);
|
||||
|
||||
// WHEN udfpsController finger is no longer down and the queued messages are run
|
||||
when(mUdfpsController.isFingerDown()).thenReturn(false);
|
||||
mHandlerFake.dispatchQueuedMessages();
|
||||
|
||||
// THEN the display screen state will change
|
||||
assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelayExitPulsingScreenState_whenUdfpsFingerDown() {
|
||||
// GIVEN we're pulsing
|
||||
when(mDozeParameters.shouldControlScreenOff()).thenReturn(true);
|
||||
mHandlerFake.setMode(QUEUEING);
|
||||
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
|
||||
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
|
||||
mScreen.transitionTo(DOZE_AOD, DOZE_REQUEST_PULSE);
|
||||
mScreen.transitionTo(DOZE_REQUEST_PULSE, DOZE_PULSING);
|
||||
mScreen.transitionTo(DOZE_PULSING, DOZE_PULSE_DONE);
|
||||
mHandlerFake.dispatchQueuedMessages();
|
||||
|
||||
// WHEN udfps is activated while are transitioning back to DOZE_AOD
|
||||
mScreen.transitionTo(DOZE_PULSE_DONE, DOZE_AOD);
|
||||
when(mUdfpsController.isFingerDown()).thenReturn(true);
|
||||
mHandlerFake.dispatchQueuedMessages();
|
||||
|
||||
// THEN the display screen state doesn't immediately change
|
||||
assertEquals(Display.STATE_ON, mServiceFake.screenState);
|
||||
|
||||
// WHEN udfpsController finger is no longer down and the queued messages are run
|
||||
when(mUdfpsController.isFingerDown()).thenReturn(false);
|
||||
mHandlerFake.dispatchQueuedMessages();
|
||||
|
||||
// THEN the display screen state will change
|
||||
assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user