From a8b581ae83f834224cce0ac5abac8c9002cf68eb Mon Sep 17 00:00:00 2001 From: Beverly Date: Tue, 16 Nov 2021 14:34:46 -0500 Subject: [PATCH] Update DozeSensors on fp enrollment changes In case the BiometricService takes a while to send its onEnrollmentsChanged callback (after AOD has begun and configures its sensors). Test: atest DozeSensorsTest Fixes: 205099649 Change-Id: I827b07941f4134854827414c6d2cf7b5779a578c --- .../android/systemui/doze/DozeSensors.java | 67 ++++++++++++++--- .../systemui/doze/DozeSensorsTest.java | 71 ++++++++++++++++++- 2 files changed, 129 insertions(+), 9 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index 5c3e07fbaea10..dd94a75c55c60 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -16,6 +16,8 @@ package com.android.systemui.doze; +import static com.android.systemui.doze.DozeLog.REASON_SENSOR_QUICK_PICKUP; +import static com.android.systemui.doze.DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS; import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_DISPLAY; import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_LOCK_SCREEN; @@ -98,6 +100,7 @@ public class DozeSensors { private final DozeLog mDozeLog; private final SecureSettings mSecureSettings; private final DevicePostureController mDevicePostureController; + private final AuthController mAuthController; private final boolean mScreenOffUdfpsEnabled; // Sensors @@ -115,6 +118,7 @@ public class DozeSensors { private boolean mListening; private boolean mListeningTouchScreenSensors; private boolean mListeningProxSensors; + private boolean mUdfpsEnrolled; @DevicePostureController.DevicePostureInt private int mDevicePosture; @@ -169,10 +173,11 @@ public class DozeSensors { config.screenOffUdfpsEnabled(KeyguardUpdateMonitor.getCurrentUser()); mDevicePostureController = devicePostureController; mDevicePosture = mDevicePostureController.getDevicePosture(); + mAuthController = authController; - boolean udfpsEnrolled = - authController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser()); - boolean alwaysOn = mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT); + mUdfpsEnrolled = + mAuthController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser()); + mAuthController.addCallback(mAuthControllerCallback); mTriggerSensors = new TriggerSensor[] { new TriggerSensor( mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION), @@ -221,7 +226,7 @@ public class DozeSensors { findSensor(config.udfpsLongPressSensorType()), "doze_pulse_on_auth", true /* settingDef */, - udfpsEnrolled && (alwaysOn || mScreenOffUdfpsEnabled), + udfpsLongPressConfigured(), DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS, true /* reports touch coordinates */, true /* touchscreen */, @@ -230,7 +235,8 @@ public class DozeSensors { new PluginSensor( new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY), Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE, - mConfig.wakeScreenGestureAvailable() && alwaysOn, + mConfig.wakeScreenGestureAvailable() + && mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT), DozeLog.REASON_SENSOR_WAKE_UP_PRESENCE, false /* reports touch coordinates */, false /* touchscreen */), @@ -246,8 +252,7 @@ public class DozeSensors { findSensor(config.quickPickupSensorType()), Settings.Secure.DOZE_QUICK_PICKUP_GESTURE, true /* setting default */, - config.quickPickupSensorEnabled(KeyguardUpdateMonitor.getCurrentUser()) - && udfpsEnrolled, + quickPickUpConfigured(), DozeLog.REASON_SENSOR_QUICK_PICKUP, false /* requiresTouchCoordinates */, false /* requiresTouchscreen */, @@ -265,6 +270,16 @@ public class DozeSensors { mDevicePostureController.addCallback(mDevicePostureCallback); } + private boolean udfpsLongPressConfigured() { + return mUdfpsEnrolled + && (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT) || mScreenOffUdfpsEnabled); + } + + private boolean quickPickUpConfigured() { + return mUdfpsEnrolled + && mConfig.quickPickupSensorEnabled(KeyguardUpdateMonitor.getCurrentUser()); + } + /** * Unregister all sensors and callbacks. */ @@ -276,6 +291,7 @@ public class DozeSensors { mProximitySensor.pause(); mDevicePostureController.removeCallback(mDevicePostureCallback); + mAuthController.removeCallback(mAuthControllerCallback); } /** @@ -450,6 +466,7 @@ public class DozeSensors { pw.println("mSelectivelyRegisterProxSensors=" + mSelectivelyRegisterProxSensors); pw.println("mListeningProxSensors=" + mListeningProxSensors); pw.println("mScreenOffUdfpsEnabled=" + mScreenOffUdfpsEnabled); + pw.println("mUdfpsEnrolled=" + mUdfpsEnrolled); IndentingPrintWriter idpw = new IndentingPrintWriter(pw); idpw.increaseIndent(); for (TriggerSensor s : mTriggerSensors) { @@ -468,7 +485,7 @@ public class DozeSensors { @VisibleForTesting class TriggerSensor extends TriggerEventListener { @NonNull final Sensor[] mSensors; // index = posture, value = sensor - final boolean mConfigured; + boolean mConfigured; final int mPulseReason; private final String mSetting; private final boolean mReportsTouchCoordinates; @@ -606,8 +623,18 @@ public class DozeSensors { updateListening(); } + /** + * Update configured state. + */ + public void setConfigured(boolean configured) { + if (mConfigured == configured) return; + mConfigured = configured; + updateListening(); + } + public void updateListening() { final Sensor sensor = mSensors[mPosture]; + if (!mConfigured || sensor == null) return; if (mRequested && !mDisabled && (enabledBySetting() || mIgnoresSetting)) { if (!mRegistered) { @@ -791,6 +818,30 @@ public class DozeSensors { } }; + private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() { + @Override + public void onAllAuthenticatorsRegistered() { + updateUdfpsEnrolled(); + } + + @Override + public void onEnrollmentsChanged() { + updateUdfpsEnrolled(); + } + + private void updateUdfpsEnrolled() { + mUdfpsEnrolled = mAuthController.isUdfpsEnrolled( + KeyguardUpdateMonitor.getCurrentUser()); + for (TriggerSensor sensor : mTriggerSensors) { + if (REASON_SENSOR_QUICK_PICKUP == sensor.mPulseReason) { + sensor.setConfigured(quickPickUpConfigured()); + } else if (REASON_SENSOR_UDFPS_LONG_PRESS == sensor.mPulseReason) { + sensor.setConfigured(udfpsLongPressConfigured()); + } + } + } + }; + public interface Callback { /** diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java index f525fee27e204..4ccb92609c77d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java @@ -17,6 +17,7 @@ package com.android.systemui.doze; import static com.android.systemui.doze.DozeLog.REASON_SENSOR_TAP; +import static com.android.systemui.doze.DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS; import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_LOCK_SCREEN; import static org.junit.Assert.assertEquals; @@ -37,6 +38,7 @@ import static org.mockito.Mockito.when; import android.database.ContentObserver; import android.hardware.Sensor; import android.hardware.display.AmbientDisplayConfiguration; +import android.os.UserHandle; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; @@ -57,6 +59,8 @@ import com.android.systemui.util.wakelock.WakeLock; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -94,6 +98,13 @@ public class DozeSensorsTest extends SysuiTestCase { private DevicePostureController mDevicePostureController; @Mock private ProximitySensor mProximitySensor; + + // Capture listeners so that they can be used to send events + @Captor + private ArgumentCaptor mAuthControllerCallbackCaptor = + ArgumentCaptor.forClass(AuthController.Callback.class); + private AuthController.Callback mAuthControllerCallback; + private FakeSettings mFakeSettings = new FakeSettings(); private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener; private TestableLooper mTestableLooper; @@ -105,14 +116,18 @@ public class DozeSensorsTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); mTestableLooper = TestableLooper.get(this); when(mAmbientDisplayConfiguration.tapSensorTypeMapping()) - .thenReturn(new String[]{"tapSEnsor"}); + .thenReturn(new String[]{"tapSensor"}); when(mAmbientDisplayConfiguration.getWakeLockScreenDebounce()).thenReturn(5000L); when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true); + when(mAmbientDisplayConfiguration.enabled(UserHandle.USER_CURRENT)).thenReturn(true); doAnswer(invocation -> { ((Runnable) invocation.getArgument(0)).run(); return null; }).when(mWakeLock).wrap(any(Runnable.class)); mDozeSensors = new TestableDozeSensors(); + + verify(mAuthController).addCallback(mAuthControllerCallbackCaptor.capture()); + mAuthControllerCallback = mAuthControllerCallbackCaptor.getValue(); } @Test @@ -375,6 +390,35 @@ public class DozeSensorsTest extends SysuiTestCase { "some other name")); } + @Test + public void testUdfpsEnrollmentChanged() throws Exception { + // GIVEN a UDFPS_LONG_PRESS trigger sensor that's not configured + Sensor mockSensor = mock(Sensor.class); + TriggerSensor triggerSensor = mDozeSensors.createDozeSensor( + mockSensor, + REASON_SENSOR_UDFPS_LONG_PRESS, + /* configured */ false); + mDozeSensors.addSensor(triggerSensor); + when(mSensorManager.requestTriggerSensor(eq(triggerSensor), eq(mockSensor))) + .thenReturn(true); + + // WHEN listening state is set to TRUE + mDozeSensors.setListening(true, true); + + // THEN mRegistered is still false b/c !mConfigured + assertFalse(triggerSensor.mConfigured); + assertFalse(triggerSensor.mRegistered); + + // WHEN enrollment changes to TRUE + when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(true); + mAuthControllerCallback.onEnrollmentsChanged(); + + // THEN mConfigured = TRUE + assertTrue(triggerSensor.mConfigured); + + // THEN mRegistered = TRUE + assertTrue(triggerSensor.mRegistered); + } private class TestableDozeSensors extends DozeSensors { TestableDozeSensors() { @@ -407,6 +451,22 @@ public class DozeSensorsTest extends SysuiTestCase { requiresTouchScreen); } + public TriggerSensor createDozeSensor( + Sensor sensor, + int pulseReason, + boolean configured + ) { + return new TriggerSensor(/* sensor */ sensor, + /* setting name */ "test_setting", + /* settingDefault */ true, + /* configured */ configured, + /* pulseReason*/ pulseReason, + /* reportsTouchCoordinate*/ false, + /* requiresTouchscreen */ false, + /* ignoresSetting */ false, + /* requiresTouchScreen */false); + } + /** * create a doze sensor that supports postures and is enabled */ @@ -422,6 +482,15 @@ public class DozeSensorsTest extends SysuiTestCase { /* requiresProx */false, posture); } + + public void addSensor(TriggerSensor sensor) { + TriggerSensor[] newArray = new TriggerSensor[mTriggerSensors.length + 1]; + for (int i = 0; i < mTriggerSensors.length; i++) { + newArray[i] = mTriggerSensors[i]; + } + newArray[mTriggerSensors.length] = sensor; + mTriggerSensors = newArray; + } } public static void setSensorType(Sensor sensor, int type, String strType) throws Exception {