Merge "Schedule UDFPS IPCs on the dedicated biometric thread" into tm-d1-dev

This commit is contained in:
Grace Cheng
2022-05-16 18:51:47 +00:00
committed by Android (Google) Code Review
2 changed files with 42 additions and 7 deletions

View File

@@ -53,6 +53,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.LatencyTracker; import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.biometrics.dagger.BiometricsBackground;
import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.Main;
@@ -76,6 +77,7 @@ import com.android.systemui.util.time.SystemClock;
import java.util.HashSet; import java.util.HashSet;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Executor;
import javax.inject.Inject; import javax.inject.Inject;
@@ -107,6 +109,7 @@ public class UdfpsController implements DozeReceiver {
@NonNull private final LayoutInflater mInflater; @NonNull private final LayoutInflater mInflater;
private final WindowManager mWindowManager; private final WindowManager mWindowManager;
private final DelayableExecutor mFgExecutor; private final DelayableExecutor mFgExecutor;
@NonNull private final Executor mBiometricExecutor;
@NonNull private final PanelExpansionStateManager mPanelExpansionStateManager; @NonNull private final PanelExpansionStateManager mPanelExpansionStateManager;
@NonNull private final StatusBarStateController mStatusBarStateController; @NonNull private final StatusBarStateController mStatusBarStateController;
@NonNull private final KeyguardStateController mKeyguardStateController; @NonNull private final KeyguardStateController mKeyguardStateController;
@@ -603,7 +606,8 @@ public class UdfpsController implements DozeReceiver {
@NonNull LatencyTracker latencyTracker, @NonNull LatencyTracker latencyTracker,
@NonNull ActivityLaunchAnimator activityLaunchAnimator, @NonNull ActivityLaunchAnimator activityLaunchAnimator,
@NonNull Optional<AlternateUdfpsTouchProvider> aternateTouchProvider, @NonNull Optional<AlternateUdfpsTouchProvider> aternateTouchProvider,
@NonNull BroadcastSender broadcastSender) { @NonNull BroadcastSender broadcastSender,
@BiometricsBackground Executor biometricsExecutor) {
mContext = context; mContext = context;
mExecution = execution; mExecution = execution;
mVibrator = vibrator; mVibrator = vibrator;
@@ -634,6 +638,7 @@ public class UdfpsController implements DozeReceiver {
mActivityLaunchAnimator = activityLaunchAnimator; mActivityLaunchAnimator = activityLaunchAnimator;
mAlternateTouchProvider = aternateTouchProvider.orElse(null); mAlternateTouchProvider = aternateTouchProvider.orElse(null);
mBroadcastSender = broadcastSender; mBroadcastSender = broadcastSender;
mBiometricExecutor = biometricsExecutor;
mOrientationListener = new BiometricDisplayListener( mOrientationListener = new BiometricDisplayListener(
context, context,
@@ -837,7 +842,9 @@ public class UdfpsController implements DozeReceiver {
} }
mOnFingerDown = true; mOnFingerDown = true;
if (mAlternateTouchProvider != null) { if (mAlternateTouchProvider != null) {
mAlternateTouchProvider.onPointerDown(requestId, x, y, minor, major); mBiometricExecutor.execute(() -> {
mAlternateTouchProvider.onPointerDown(requestId, x, y, minor, major);
});
mFgExecutor.execute(() -> { mFgExecutor.execute(() -> {
if (mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) { if (mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
mKeyguardUpdateMonitor.onUdfpsPointerDown((int) requestId); mKeyguardUpdateMonitor.onUdfpsPointerDown((int) requestId);
@@ -847,16 +854,18 @@ public class UdfpsController implements DozeReceiver {
mFingerprintManager.onPointerDown(requestId, mSensorId, x, y, minor, major); mFingerprintManager.onPointerDown(requestId, mSensorId, 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) {
view.startIllumination(() -> { view.startIllumination(() -> {
if (mAlternateTouchProvider != null) { if (mAlternateTouchProvider != null) {
mAlternateTouchProvider.onUiReady(); mBiometricExecutor.execute(() -> {
mAlternateTouchProvider.onUiReady();
mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE);
});
} else { } else {
mFingerprintManager.onUiReady(requestId, mSensorId); mFingerprintManager.onUiReady(requestId, mSensorId);
mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE);
} }
mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE);
}); });
} }
@@ -871,7 +880,9 @@ public class UdfpsController implements DozeReceiver {
mAcquiredReceived = false; mAcquiredReceived = false;
if (mOnFingerDown) { if (mOnFingerDown) {
if (mAlternateTouchProvider != null) { if (mAlternateTouchProvider != null) {
mAlternateTouchProvider.onPointerUp(requestId); mBiometricExecutor.execute(() -> {
mAlternateTouchProvider.onPointerUp(requestId);
});
mFgExecutor.execute(() -> { mFgExecutor.execute(() -> {
if (mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) { if (mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
mKeyguardUpdateMonitor.onUdfpsPointerUp((int) requestId); mKeyguardUpdateMonitor.onUdfpsPointerUp((int) requestId);

View File

@@ -117,6 +117,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
private UdfpsController mUdfpsController; private UdfpsController mUdfpsController;
// Dependencies // Dependencies
private FakeExecutor mBiometricsExecutor;
private Execution mExecution; private Execution mExecution;
@Mock @Mock
private LayoutInflater mLayoutInflater; private LayoutInflater mLayoutInflater;
@@ -234,6 +235,10 @@ public class UdfpsControllerTest extends SysuiTestCase {
true /* resetLockoutRequiresHardwareAuthToken */)); true /* resetLockoutRequiresHardwareAuthToken */));
when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props); when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props);
mFgExecutor = new FakeExecutor(new FakeSystemClock()); mFgExecutor = new FakeExecutor(new FakeSystemClock());
// Create a fake background executor.
mBiometricsExecutor = new FakeExecutor(new FakeSystemClock());
mUdfpsController = new UdfpsController( mUdfpsController = new UdfpsController(
mContext, mContext,
mExecution, mExecution,
@@ -265,7 +270,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
mLatencyTracker, mLatencyTracker,
mActivityLaunchAnimator, mActivityLaunchAnimator,
Optional.of(mAlternateTouchProvider), Optional.of(mAlternateTouchProvider),
mBroadcastSender); mBroadcastSender,
mBiometricsExecutor);
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture()); verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
mOverlayController = mOverlayCaptor.getValue(); mOverlayController = mOverlayCaptor.getValue();
verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture()); verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
@@ -298,6 +304,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0); MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
mBiometricsExecutor.runAllReady();
downEvent.recycle(); downEvent.recycle();
// THEN notify keyguard authenticate to dismiss the keyguard // THEN notify keyguard authenticate to dismiss the keyguard
@@ -336,6 +343,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
} }
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
mBiometricsExecutor.runAllReady();
moveEvent.recycle(); moveEvent.recycle();
// THEN notify keyguard authenticate to dismiss the keyguard // THEN notify keyguard authenticate to dismiss the keyguard
@@ -359,10 +367,12 @@ public class UdfpsControllerTest extends SysuiTestCase {
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0); MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
mBiometricsExecutor.runAllReady();
downEvent.recycle(); downEvent.recycle();
MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
mBiometricsExecutor.runAllReady();
moveEvent.recycle(); moveEvent.recycle();
// THEN notify keyguard authenticate to dismiss the keyguard // THEN notify keyguard authenticate to dismiss the keyguard
@@ -516,9 +526,11 @@ public class UdfpsControllerTest extends SysuiTestCase {
MotionEvent event = obtainMotionEvent(ACTION_DOWN, displayWidth, displayHeight, touchMinor, MotionEvent event = obtainMotionEvent(ACTION_DOWN, displayWidth, displayHeight, touchMinor,
touchMajor); touchMajor);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
mBiometricsExecutor.runAllReady();
event.recycle(); event.recycle();
event = obtainMotionEvent(ACTION_MOVE, displayWidth, displayHeight, touchMinor, touchMajor); event = obtainMotionEvent(ACTION_MOVE, displayWidth, displayHeight, touchMinor, touchMajor);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
mBiometricsExecutor.runAllReady();
event.recycle(); event.recycle();
verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(expectedX), verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(expectedX),
eq(expectedY), eq(expectedMinor), eq(expectedMajor)); eq(expectedY), eq(expectedMinor), eq(expectedMajor));
@@ -530,9 +542,11 @@ public class UdfpsControllerTest extends SysuiTestCase {
Surface.ROTATION_90)); Surface.ROTATION_90));
event = obtainMotionEvent(ACTION_DOWN, displayHeight, 0, touchMinor, touchMajor); event = obtainMotionEvent(ACTION_DOWN, displayHeight, 0, touchMinor, touchMajor);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
mBiometricsExecutor.runAllReady();
event.recycle(); event.recycle();
event = obtainMotionEvent(ACTION_MOVE, displayHeight, 0, touchMinor, touchMajor); event = obtainMotionEvent(ACTION_MOVE, displayHeight, 0, touchMinor, touchMajor);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
mBiometricsExecutor.runAllReady();
event.recycle(); event.recycle();
verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(expectedX), verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(expectedX),
eq(expectedY), eq(expectedMinor), eq(expectedMajor)); eq(expectedY), eq(expectedMinor), eq(expectedMajor));
@@ -544,9 +558,11 @@ public class UdfpsControllerTest extends SysuiTestCase {
Surface.ROTATION_270)); Surface.ROTATION_270));
event = obtainMotionEvent(ACTION_DOWN, 0, displayWidth, touchMinor, touchMajor); event = obtainMotionEvent(ACTION_DOWN, 0, displayWidth, touchMinor, touchMajor);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
mBiometricsExecutor.runAllReady();
event.recycle(); event.recycle();
event = obtainMotionEvent(ACTION_MOVE, 0, displayWidth, touchMinor, touchMajor); event = obtainMotionEvent(ACTION_MOVE, 0, displayWidth, touchMinor, touchMajor);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
mBiometricsExecutor.runAllReady();
event.recycle(); event.recycle();
verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(expectedX), verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(expectedX),
eq(expectedY), eq(expectedMinor), eq(expectedMajor)); eq(expectedY), eq(expectedMinor), eq(expectedMajor));
@@ -559,9 +575,11 @@ public class UdfpsControllerTest extends SysuiTestCase {
// ROTATION_180 is not supported. It should be treated like ROTATION_0. // ROTATION_180 is not supported. It should be treated like ROTATION_0.
event = obtainMotionEvent(ACTION_DOWN, displayWidth, displayHeight, touchMinor, touchMajor); event = obtainMotionEvent(ACTION_DOWN, displayWidth, displayHeight, touchMinor, touchMajor);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
mBiometricsExecutor.runAllReady();
event.recycle(); event.recycle();
event = obtainMotionEvent(ACTION_MOVE, displayWidth, displayHeight, touchMinor, touchMajor); event = obtainMotionEvent(ACTION_MOVE, displayWidth, displayHeight, touchMinor, touchMajor);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
mBiometricsExecutor.runAllReady();
event.recycle(); event.recycle();
verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(expectedX), verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(expectedX),
eq(expectedY), eq(expectedMinor), eq(expectedMajor)); eq(expectedY), eq(expectedMinor), eq(expectedMajor));
@@ -582,11 +600,13 @@ public class UdfpsControllerTest extends SysuiTestCase {
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0); MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
mBiometricsExecutor.runAllReady();
downEvent.recycle(); downEvent.recycle();
MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
// FIX THIS TEST // FIX THIS TEST
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
mBiometricsExecutor.runAllReady();
moveEvent.recycle(); moveEvent.recycle();
mFgExecutor.runAllReady(); mFgExecutor.runAllReady();
// THEN FingerprintManager is notified about onPointerDown // THEN FingerprintManager is notified about onPointerDown
@@ -601,6 +621,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
verify(mKeyguardUpdateMonitor).onUdfpsPointerDown(eq((int) TEST_REQUEST_ID)); verify(mKeyguardUpdateMonitor).onUdfpsPointerDown(eq((int) TEST_REQUEST_ID));
// AND onIlluminatedRunnable notifies FingerprintManager about onUiReady // AND onIlluminatedRunnable notifies FingerprintManager about onUiReady
mOnIlluminatedRunnableCaptor.getValue().run(); mOnIlluminatedRunnableCaptor.getValue().run();
mBiometricsExecutor.runAllReady();
InOrder inOrder = inOrder(mAlternateTouchProvider, mLatencyTracker); InOrder inOrder = inOrder(mAlternateTouchProvider, mLatencyTracker);
inOrder.verify(mAlternateTouchProvider).onUiReady(); inOrder.verify(mAlternateTouchProvider).onUiReady();
inOrder.verify(mLatencyTracker).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE)); inOrder.verify(mLatencyTracker).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
@@ -621,6 +642,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// AND onIlluminatedRunnable that notifies FingerprintManager is set // AND onIlluminatedRunnable that notifies FingerprintManager is set
verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture()); verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture());
mOnIlluminatedRunnableCaptor.getValue().run(); mOnIlluminatedRunnableCaptor.getValue().run();
mBiometricsExecutor.runAllReady();
verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID),
eq(0), eq(0), eq(3f) /* minor */, eq(2f) /* major */); eq(0), eq(0), eq(3f) /* minor */, eq(2f) /* major */);
verify(mFingerprintManager, never()).onPointerDown(anyLong(), anyInt(), anyInt(), anyInt(), verify(mFingerprintManager, never()).onPointerDown(anyLong(), anyInt(), anyInt(), anyInt(),
@@ -746,9 +768,11 @@ public class UdfpsControllerTest extends SysuiTestCase {
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0); MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
mBiometricsExecutor.runAllReady();
downEvent.recycle(); downEvent.recycle();
MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
mBiometricsExecutor.runAllReady();
moveEvent.recycle(); moveEvent.recycle();
// THEN NO haptic played // THEN NO haptic played