Wait for screen on callback to send aodInterrupt

We don't want to pre-emptively attempt to turn on HBM before the screen
is on.

Test: manual, atest SystemUITests
Fixes: 186079912
Change-Id: I88f89d1fde2dd5bcf3b99e38043a48382e807d7f
This commit is contained in:
Beverly
2021-05-04 12:40:05 -04:00
committed by Beverly Tai
parent 19c15e3a37
commit 56e8540e14
2 changed files with 69 additions and 11 deletions

View File

@@ -65,6 +65,7 @@ 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.keyguard.ScreenLifecycle;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -131,6 +132,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
// mode.
private boolean mIsAodInterruptActive;
@Nullable private Runnable mCancelAodTimeoutAction;
private boolean mScreenOn;
private Runnable mAodInterruptRunnable;
private static final AudioAttributes VIBRATION_SONIFICATION_ATTRIBUTES =
new AudioAttributes.Builder()
@@ -155,6 +158,22 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
}
};
private final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
@Override
public void onScreenTurnedOn() {
mScreenOn = true;
if (mAodInterruptRunnable != null) {
mAodInterruptRunnable.run();
mAodInterruptRunnable = null;
}
}
@Override
public void onScreenTurnedOff() {
mScreenOn = false;
}
};
/**
* Keeps track of state within a single FingerprintService request. Note that this state
* persists across configuration changes, etc, since it is considered a single request.
@@ -438,7 +457,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
@NonNull KeyguardViewMediator keyguardViewMediator,
@NonNull FalsingManager falsingManager,
@NonNull PowerManager powerManager,
@NonNull AccessibilityManager accessibilityManager) {
@NonNull AccessibilityManager accessibilityManager,
@NonNull ScreenLifecycle screenLifecycle) {
mContext = context;
// TODO (b/185124905): inject main handler and vibrator once done prototyping
mMainHandler = new Handler(Looper.getMainLooper());
@@ -458,6 +478,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
mFalsingManager = falsingManager;
mPowerManager = powerManager;
mAccessibilityManager = accessibilityManager;
screenLifecycle.addObserver(mScreenObserver);
mScreenOn = screenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON;
mSensorProps = findFirstUdfps();
// At least one UDFPS sensor exists
@@ -691,14 +713,23 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
if (mIsAodInterruptActive) {
return;
}
mIsAodInterruptActive = true;
// Since the sensor that triggers the AOD interrupt doesn't provide ACTION_UP/ACTION_CANCEL,
// we need to be careful about not letting the screen accidentally remain in high brightness
// mode. As a mitigation, queue a call to cancel the fingerprint scan.
mCancelAodTimeoutAction = mFgExecutor.executeDelayed(this::onCancelUdfps,
AOD_INTERRUPT_TIMEOUT_MILLIS);
// using a hard-coded value for major and minor until it is available from the sensor
onFingerDown(screenX, screenY, minor, major);
mAodInterruptRunnable = () -> {
mIsAodInterruptActive = true;
// Since the sensor that triggers the AOD interrupt doesn't provide
// ACTION_UP/ACTION_CANCEL, we need to be careful about not letting the screen
// accidentally remain in high brightness mode. As a mitigation, queue a call to
// cancel the fingerprint scan.
mCancelAodTimeoutAction = mFgExecutor.executeDelayed(this::onCancelUdfps,
AOD_INTERRUPT_TIMEOUT_MILLIS);
// using a hard-coded value for major and minor until it is available from the sensor
onFingerDown(screenX, screenY, minor, major);
};
if (mScreenOn && mAodInterruptRunnable != null) {
mAodInterruptRunnable.run();
mAodInterruptRunnable = null;
}
}
/**

View File

@@ -21,6 +21,7 @@ import static junit.framework.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -48,6 +49,7 @@ 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.keyguard.ScreenLifecycle;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -110,6 +112,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
private PowerManager mPowerManager;
@Mock
private AccessibilityManager mAccessibilityManager;
@Mock
private ScreenLifecycle mScreenLifecycle;
private FakeExecutor mFgExecutor;
@@ -126,6 +130,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
private IUdfpsOverlayController mOverlayController;
@Captor private ArgumentCaptor<UdfpsView.OnTouchListener> mTouchListenerCaptor;
@Captor private ArgumentCaptor<Runnable> mOnIlluminatedRunnableCaptor;
@Captor private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor;
private ScreenLifecycle.Observer mScreenObserver;
@Before
public void setUp() {
@@ -163,9 +169,12 @@ public class UdfpsControllerTest extends SysuiTestCase {
mKeyguardViewMediator,
mFalsingManager,
mPowerManager,
mAccessibilityManager);
mAccessibilityManager,
mScreenLifecycle);
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
mOverlayController = mOverlayCaptor.getValue();
verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
mScreenObserver = mScreenObserverCaptor.getValue();
assertEquals(TEST_UDFPS_SENSOR_ID, mUdfpsController.mSensorProps.sensorId);
}
@@ -233,9 +242,10 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Test
public void aodInterrupt() throws RemoteException {
// GIVEN that the overlay is showing
// GIVEN that the overlay is showing and screen is on
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady();
// WHEN fingerprint is requested because of AOD interrupt
mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
@@ -252,6 +262,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// GIVEN AOD interrupt
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady();
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
// WHEN it is cancelled
@@ -265,6 +276,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// GIVEN AOD interrupt
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady();
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
// WHEN it times out
@@ -273,4 +285,19 @@ public class UdfpsControllerTest extends SysuiTestCase {
// THEN the illumination is hidden
verify(mUdfpsView).stopIllumination();
}
@Test
public void aodInterruptScreenOff() throws RemoteException {
// GIVEN screen off
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
mScreenObserver.onScreenTurnedOff();
mFgExecutor.runAllReady();
// WHEN aod interrupt is received
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
// THEN no illumination because screen is off
verify(mUdfpsView, never()).startIllumination(any());
}
}