Loading packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +40 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() Loading @@ -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. Loading Loading @@ -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()); Loading @@ -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 Loading Loading @@ -691,14 +713,23 @@ public class UdfpsController implements DozeReceiver, HbmCallback { if (mIsAodInterruptActive) { return; } 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. // 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; } } /** Loading packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +29 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -110,6 +112,8 @@ public class UdfpsControllerTest extends SysuiTestCase { private PowerManager mPowerManager; @Mock private AccessibilityManager mAccessibilityManager; @Mock private ScreenLifecycle mScreenLifecycle; private FakeExecutor mFgExecutor; Loading @@ -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() { Loading Loading @@ -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); } Loading Loading @@ -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); Loading @@ -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 Loading @@ -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 Loading @@ -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()); } } Loading
packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +40 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() Loading @@ -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. Loading Loading @@ -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()); Loading @@ -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 Loading Loading @@ -691,14 +713,23 @@ public class UdfpsController implements DozeReceiver, HbmCallback { if (mIsAodInterruptActive) { return; } 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. // 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; } } /** Loading
packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +29 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -110,6 +112,8 @@ public class UdfpsControllerTest extends SysuiTestCase { private PowerManager mPowerManager; @Mock private AccessibilityManager mAccessibilityManager; @Mock private ScreenLifecycle mScreenLifecycle; private FakeExecutor mFgExecutor; Loading @@ -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() { Loading Loading @@ -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); } Loading Loading @@ -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); Loading @@ -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 Loading @@ -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 Loading @@ -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()); } }