Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d75bedac authored by Beverly's avatar Beverly Committed by android-build-team Robot
Browse files

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
(cherry picked from commit 56e8540e)
parent 4940402b
Loading
Loading
Loading
Loading
+40 −9
Original line number Diff line number Diff line
@@ -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;
        }

        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;
        }
    }

    /**
+29 −2
Original line number Diff line number Diff line
@@ -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());
    }
}