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

Commit 0cab3b42 authored by Joe Bolinger's avatar Joe Bolinger
Browse files

Invoke lifecycle callbacks while waiting for cookies.

Operations that wait for cookies (authentication) do not set their lifecycle callback until started. This leaves a small window when failures are not propogated to callers (i.e. fast/immediate failures).

This also adds some additional checking for stale UI events (point up/down) that are delivered after the operation has ended.

Fix: 216071532
Test: atest com.android.systemui.biometrics com.android.server.biometrics
Change-Id: I7f7500db0a42b2ea97e171e26148ee68b15f5ae8
parent 8987377b
Loading
Loading
Loading
Loading
+7 −6
Original line number Original line Diff line number Diff line
@@ -923,14 +923,15 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
     * @hide
     * @hide
     */
     */
    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
    public void onPointerDown(int sensorId, int x, int y, float minor, float major) {
    public void onPointerDown(long requestId, int sensorId, int x, int y,
            float minor, float major) {
        if (mService == null) {
        if (mService == null) {
            Slog.w(TAG, "onFingerDown: no fingerprint service");
            Slog.w(TAG, "onFingerDown: no fingerprint service");
            return;
            return;
        }
        }


        try {
        try {
            mService.onPointerDown(sensorId, x, y, minor, major);
            mService.onPointerDown(requestId, sensorId, x, y, minor, major);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
            throw e.rethrowFromSystemServer();
        }
        }
@@ -940,14 +941,14 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
     * @hide
     * @hide
     */
     */
    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
    public void onPointerUp(int sensorId) {
    public void onPointerUp(long requestId, int sensorId) {
        if (mService == null) {
        if (mService == null) {
            Slog.w(TAG, "onFingerDown: no fingerprint service");
            Slog.w(TAG, "onFingerDown: no fingerprint service");
            return;
            return;
        }
        }


        try {
        try {
            mService.onPointerUp(sensorId);
            mService.onPointerUp(requestId, sensorId);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
            throw e.rethrowFromSystemServer();
        }
        }
@@ -957,14 +958,14 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
     * @hide
     * @hide
     */
     */
    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
    public void onUiReady(int sensorId) {
    public void onUiReady(long requestId, int sensorId) {
        if (mService == null) {
        if (mService == null) {
            Slog.w(TAG, "onUiReady: no fingerprint service");
            Slog.w(TAG, "onUiReady: no fingerprint service");
            return;
            return;
        }
        }


        try {
        try {
            mService.onUiReady(sensorId);
            mService.onUiReady(requestId, sensorId);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
            throw e.rethrowFromSystemServer();
        }
        }
+3 −3
Original line number Original line Diff line number Diff line
@@ -155,13 +155,13 @@ interface IFingerprintService {
    void addAuthenticatorsRegisteredCallback(IFingerprintAuthenticatorsRegisteredCallback callback);
    void addAuthenticatorsRegisteredCallback(IFingerprintAuthenticatorsRegisteredCallback callback);


    // Notifies about a finger touching the sensor area.
    // Notifies about a finger touching the sensor area.
    void onPointerDown(int sensorId, int x, int y, float minor, float major);
    void onPointerDown(long requestId, int sensorId, int x, int y, float minor, float major);


    // Notifies about a finger leaving the sensor area.
    // Notifies about a finger leaving the sensor area.
    void onPointerUp(int sensorId);
    void onPointerUp(long requestId, int sensorId);


    // Notifies about the fingerprint UI being ready (e.g. HBM illumination is enabled).
    // Notifies about the fingerprint UI being ready (e.g. HBM illumination is enabled).
    void onUiReady(int sensorId);
    void onUiReady(long requestId, int sensorId);


    // Sets the controller for managing the UDFPS overlay.
    // Sets the controller for managing the UDFPS overlay.
    void setUdfpsOverlayController(in IUdfpsOverlayController controller);
    void setUdfpsOverlayController(in IUdfpsOverlayController controller);
+1 −1
Original line number Original line Diff line number Diff line
@@ -23,7 +23,7 @@ import android.hardware.fingerprint.IUdfpsOverlayControllerCallback;
 */
 */
oneway interface IUdfpsOverlayController {
oneway interface IUdfpsOverlayController {
    // Shows the overlay  for the given sensor with a reason from BiometricOverlayConstants.
    // Shows the overlay  for the given sensor with a reason from BiometricOverlayConstants.
    void showUdfpsOverlay(int sensorId, int reason, IUdfpsOverlayControllerCallback callback);
    void showUdfpsOverlay(long requestId, int sensorId, int reason, IUdfpsOverlayControllerCallback callback);


    // Hides the overlay.
    // Hides the overlay.
    void hideUdfpsOverlay(int sensorId);
    void hideUdfpsOverlay(int sensorId);
+39 −20
Original line number Original line Diff line number Diff line
@@ -49,7 +49,6 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.Surface;
import android.view.VelocityTracker;
import android.view.VelocityTracker;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager;


@@ -92,7 +91,7 @@ import kotlin.Unit;
 * Note that the current architecture is designed so that a single {@link UdfpsController}
 * Note that the current architecture is designed so that a single {@link UdfpsController}
 * controls/manages all UDFPS sensors. In other words, a single controller is registered with
 * controls/manages all UDFPS sensors. In other words, a single controller is registered with
 * {@link com.android.server.biometrics.sensors.fingerprint.FingerprintService}, and interfaces such
 * {@link com.android.server.biometrics.sensors.fingerprint.FingerprintService}, and interfaces such
 * as {@link FingerprintManager#onPointerDown(int, int, int, float, float)} or
 * as {@link FingerprintManager#onPointerDown(long, int, int, int, float, float)} or
 * {@link IUdfpsOverlayController#showUdfpsOverlay} should all have
 * {@link IUdfpsOverlayController#showUdfpsOverlay} should all have
 * {@code sensorId} parameters.
 * {@code sensorId} parameters.
 */
 */
@@ -193,7 +192,7 @@ public class UdfpsController implements DozeReceiver {


    public class UdfpsOverlayController extends IUdfpsOverlayController.Stub {
    public class UdfpsOverlayController extends IUdfpsOverlayController.Stub {
        @Override
        @Override
        public void showUdfpsOverlay(int sensorId, int reason,
        public void showUdfpsOverlay(long requestId, int sensorId, int reason,
                @NonNull IUdfpsOverlayControllerCallback callback) {
                @NonNull IUdfpsOverlayControllerCallback callback) {
            mFgExecutor.execute(
            mFgExecutor.execute(
                    () -> UdfpsController.this.showUdfpsOverlay(new UdfpsControllerOverlay(
                    () -> UdfpsController.this.showUdfpsOverlay(new UdfpsControllerOverlay(
@@ -203,8 +202,10 @@ public class UdfpsController implements DozeReceiver {
                            mKeyguardUpdateMonitor, mDialogManager, mDumpManager,
                            mKeyguardUpdateMonitor, mDialogManager, mDumpManager,
                            mLockscreenShadeTransitionController, mConfigurationController,
                            mLockscreenShadeTransitionController, mConfigurationController,
                            mSystemClock, mKeyguardStateController,
                            mSystemClock, mKeyguardStateController,
                            mUnlockedScreenOffAnimationController, mSensorProps, mHbmProvider,
                            mUnlockedScreenOffAnimationController, mSensorProps,
                            reason, callback, UdfpsController.this::onTouch,
                            mHbmProvider, requestId, reason, callback,
                            (view, event, fromUdfpsView) ->
                                   onTouch(requestId, event, fromUdfpsView),
                            mActivityLaunchAnimator)));
                            mActivityLaunchAnimator)));
        }
        }


@@ -318,7 +319,8 @@ public class UdfpsController implements DozeReceiver {
        if (mOverlay == null || mOverlay.isHiding()) {
        if (mOverlay == null || mOverlay.isHiding()) {
            return false;
            return false;
        }
        }
        return onTouch(mOverlay.getOverlayView(), event, false);
        // TODO(b/225068271): may not be correct but no way to get the id yet
        return onTouch(mOverlay.getRequestId(), event, false);
    }
    }


    /**
    /**
@@ -342,8 +344,18 @@ public class UdfpsController implements DozeReceiver {
                && getSensorLocation().contains(x, y);
                && getSensorLocation().contains(x, y);
    }
    }


    private boolean onTouch(@NonNull View view, @NonNull MotionEvent event, boolean fromUdfpsView) {
    private boolean onTouch(long requestId, @NonNull MotionEvent event, boolean fromUdfpsView) {
        UdfpsView udfpsView = (UdfpsView) view;
        if (mOverlay == null) {
            Log.w(TAG, "ignoring onTouch with null overlay");
            return false;
        }
        if (!mOverlay.matchesRequestId(requestId)) {
            Log.w(TAG, "ignoring stale touch event: " + requestId + " current: "
                    + mOverlay.getRequestId());
            return false;
        }

        final UdfpsView udfpsView = mOverlay.getOverlayView();
        final boolean isIlluminationRequested = udfpsView.isIlluminationRequested();
        final boolean isIlluminationRequested = udfpsView.isIlluminationRequested();
        boolean handled = false;
        boolean handled = false;
        switch (event.getActionMasked()) {
        switch (event.getActionMasked()) {
@@ -453,7 +465,7 @@ public class UdfpsController implements DozeReceiver {
                                    // Do nothing to stay in portrait mode.
                                    // Do nothing to stay in portrait mode.
                            }
                            }


                            onFingerDown(x, y, minor, major);
                            onFingerDown(requestId, x, y, minor, major);
                            Log.v(TAG, "onTouch | finger down: " + touchInfo);
                            Log.v(TAG, "onTouch | finger down: " + touchInfo);
                            mTouchLogTime = mSystemClock.elapsedRealtime();
                            mTouchLogTime = mSystemClock.elapsedRealtime();
                            mPowerManager.userActivity(mSystemClock.uptimeMillis(),
                            mPowerManager.userActivity(mSystemClock.uptimeMillis(),
@@ -465,7 +477,7 @@ public class UdfpsController implements DozeReceiver {
                        }
                        }
                    } else {
                    } else {
                        Log.v(TAG, "onTouch | finger outside");
                        Log.v(TAG, "onTouch | finger outside");
                        onFingerUp(udfpsView);
                        onFingerUp(requestId, udfpsView);
                    }
                    }
                }
                }
                Trace.endSection();
                Trace.endSection();
@@ -482,7 +494,7 @@ public class UdfpsController implements DozeReceiver {
                }
                }
                Log.v(TAG, "onTouch | finger up");
                Log.v(TAG, "onTouch | finger up");
                mAttemptedToDismissKeyguard = false;
                mAttemptedToDismissKeyguard = false;
                onFingerUp(udfpsView);
                onFingerUp(requestId, udfpsView);
                mFalsingManager.isFalseTouch(UDFPS_AUTHENTICATION);
                mFalsingManager.isFalseTouch(UDFPS_AUTHENTICATION);
                Trace.endSection();
                Trace.endSection();
                break;
                break;
@@ -679,7 +691,7 @@ public class UdfpsController implements DozeReceiver {
            // Reset the controller back to its starting state.
            // Reset the controller back to its starting state.
            final UdfpsView oldView = mOverlay.getOverlayView();
            final UdfpsView oldView = mOverlay.getOverlayView();
            if (oldView != null) {
            if (oldView != null) {
                onFingerUp(oldView);
                onFingerUp(mOverlay.getRequestId(), oldView);
            }
            }
            final boolean removed = mOverlay.hide();
            final boolean removed = mOverlay.hide();
            if (mKeyguardViewManager.isShowingAlternateAuth()) {
            if (mKeyguardViewManager.isShowingAlternateAuth()) {
@@ -710,6 +722,8 @@ public class UdfpsController implements DozeReceiver {
            return;
            return;
        }
        }


        // TODO(b/225068271): this may not be correct but there isn't a way to track it
        final long requestId = mOverlay != null ? mOverlay.getRequestId() : -1;
        mAodInterruptRunnable = () -> {
        mAodInterruptRunnable = () -> {
            mIsAodInterruptActive = true;
            mIsAodInterruptActive = true;
            // Since the sensor that triggers the AOD interrupt doesn't provide
            // Since the sensor that triggers the AOD interrupt doesn't provide
@@ -719,10 +733,10 @@ public class UdfpsController implements DozeReceiver {
            mCancelAodTimeoutAction = mFgExecutor.executeDelayed(this::onCancelUdfps,
            mCancelAodTimeoutAction = mFgExecutor.executeDelayed(this::onCancelUdfps,
                    AOD_INTERRUPT_TIMEOUT_MILLIS);
                    AOD_INTERRUPT_TIMEOUT_MILLIS);
            // using a hard-coded value for major and minor until it is available from the sensor
            // using a hard-coded value for major and minor until it is available from the sensor
            onFingerDown(screenX, screenY, minor, major);
            onFingerDown(requestId, screenX, screenY, minor, major);
        };
        };


        if (mScreenOn && mAodInterruptRunnable != null) {
        if (mScreenOn) {
            mAodInterruptRunnable.run();
            mAodInterruptRunnable.run();
            mAodInterruptRunnable = null;
            mAodInterruptRunnable = null;
        }
        }
@@ -755,7 +769,7 @@ public class UdfpsController implements DozeReceiver {
     */
     */
    void onCancelUdfps() {
    void onCancelUdfps() {
        if (mOverlay != null && mOverlay.getOverlayView() != null) {
        if (mOverlay != null && mOverlay.getOverlayView() != null) {
            onFingerUp(mOverlay.getOverlayView());
            onFingerUp(mOverlay.getRequestId(), mOverlay.getOverlayView());
        }
        }
        if (!mIsAodInterruptActive) {
        if (!mIsAodInterruptActive) {
            return;
            return;
@@ -771,12 +785,17 @@ public class UdfpsController implements DozeReceiver {
        return mOnFingerDown;
        return mOnFingerDown;
    }
    }


    private void onFingerDown(int x, int y, float minor, float major) {
    private void onFingerDown(long requestId, int x, int y, float minor, float major) {
        mExecution.assertIsMainThread();
        mExecution.assertIsMainThread();
        if (mOverlay == null) {
        if (mOverlay == null) {
            Log.w(TAG, "Null request in onFingerDown");
            Log.w(TAG, "Null request in onFingerDown");
            return;
            return;
        }
        }
        if (!mOverlay.matchesRequestId(requestId)) {
            Log.w(TAG, "Mismatched fingerDown: " + requestId
                    + " current: " + mOverlay.getRequestId());
            return;
        }


        if (mOverlay.getAnimationViewController() instanceof UdfpsKeyguardViewController
        if (mOverlay.getAnimationViewController() instanceof UdfpsKeyguardViewController
                && !mStatusBarStateController.isDozing()) {
                && !mStatusBarStateController.isDozing()) {
@@ -791,14 +810,14 @@ public class UdfpsController implements DozeReceiver {
            }
            }
        }
        }
        mOnFingerDown = true;
        mOnFingerDown = true;
        mFingerprintManager.onPointerDown(mSensorProps.sensorId, x, y, minor, major);
        mFingerprintManager.onPointerDown(requestId, mSensorProps.sensorId, x, y, minor, major);
        Trace.endAsyncSection("UdfpsController.e2e.onPointerDown", 0);
        Trace.endAsyncSection("UdfpsController.e2e.onPointerDown", 0);


        final UdfpsView view = mOverlay.getOverlayView();
        final UdfpsView view = mOverlay.getOverlayView();
        if (view != null) {
        if (view != null) {
            Trace.beginAsyncSection("UdfpsController.e2e.startIllumination", 0);
            Trace.beginAsyncSection("UdfpsController.e2e.startIllumination", 0);
            view.startIllumination(() -> {
            view.startIllumination(() -> {
                mFingerprintManager.onUiReady(mSensorProps.sensorId);
                mFingerprintManager.onUiReady(requestId, mSensorProps.sensorId);
                mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE);
                mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE);
                Trace.endAsyncSection("UdfpsController.e2e.startIllumination", 0);
                Trace.endAsyncSection("UdfpsController.e2e.startIllumination", 0);
            });
            });
@@ -809,12 +828,12 @@ public class UdfpsController implements DozeReceiver {
        }
        }
    }
    }


    private void onFingerUp(@NonNull UdfpsView view) {
    private void onFingerUp(long requestId, @NonNull UdfpsView view) {
        mExecution.assertIsMainThread();
        mExecution.assertIsMainThread();
        mActivePointerId = -1;
        mActivePointerId = -1;
        mAcquiredReceived = false;
        mAcquiredReceived = false;
        if (mOnFingerDown) {
        if (mOnFingerDown) {
            mFingerprintManager.onPointerUp(mSensorProps.sensorId);
            mFingerprintManager.onPointerUp(requestId, mSensorProps.sensorId);
            for (Callback cb : mCallbacks) {
            for (Callback cb : mCallbacks) {
                cb.onFingerUp();
                cb.onFingerUp();
            }
            }
+4 −0
Original line number Original line Diff line number Diff line
@@ -80,6 +80,7 @@ class UdfpsControllerOverlay(
    private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController,
    private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController,
    private val sensorProps: FingerprintSensorPropertiesInternal,
    private val sensorProps: FingerprintSensorPropertiesInternal,
    private var hbmProvider: UdfpsHbmProvider,
    private var hbmProvider: UdfpsHbmProvider,
    val requestId: Long,
    @ShowReason val requestReason: Int,
    @ShowReason val requestReason: Int,
    private val controllerCallback: IUdfpsOverlayControllerCallback,
    private val controllerCallback: IUdfpsOverlayControllerCallback,
    private val onTouch: (View, MotionEvent, Boolean) -> Boolean,
    private val onTouch: (View, MotionEvent, Boolean) -> Boolean,
@@ -276,6 +277,9 @@ class UdfpsControllerOverlay(
        }
        }
    }
    }


    /** Checks if the id is relevant for this overlay. */
    fun matchesRequestId(id: Long): Boolean = requestId == -1L || requestId == id

    private fun WindowManager.LayoutParams.updateForLocation(
    private fun WindowManager.LayoutParams.updateForLocation(
        location: SensorLocationInternal,
        location: SensorLocationInternal,
        animation: UdfpsAnimationViewController<*>?
        animation: UdfpsAnimationViewController<*>?
Loading