Loading core/java/com/android/internal/util/LatencyTracker.java +11 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPOR import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOAD_SHARE_SHEET; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOCKSCREEN_UNLOCK; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_NOTIFICATION_BIG_PICTURE_LOADED; Loading Loading @@ -222,6 +223,11 @@ public class LatencyTracker { */ public static final int ACTION_NOTIFICATION_BIG_PICTURE_LOADED = 23; /** * Time it takes to unlock the device via udfps, until the whole launcher appears. */ public static final int ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME = 24; private static final int[] ACTIONS_ALL = { ACTION_EXPAND_PANEL, ACTION_TOGGLE_RECENTS, Loading @@ -247,6 +253,7 @@ public class LatencyTracker { ACTION_REQUEST_IME_HIDDEN, ACTION_SMARTSPACE_DOORBELL, ACTION_NOTIFICATION_BIG_PICTURE_LOADED, ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME, }; /** @hide */ Loading Loading @@ -275,6 +282,7 @@ public class LatencyTracker { ACTION_REQUEST_IME_HIDDEN, ACTION_SMARTSPACE_DOORBELL, ACTION_NOTIFICATION_BIG_PICTURE_LOADED, ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME, }) @Retention(RetentionPolicy.SOURCE) public @interface Action { Loading Loading @@ -306,6 +314,7 @@ public class LatencyTracker { UIACTION_LATENCY_REPORTED__ACTION__ACTION_REQUEST_IME_HIDDEN, UIACTION_LATENCY_REPORTED__ACTION__ACTION_SMARTSPACE_DOORBELL, UIACTION_LATENCY_REPORTED__ACTION__ACTION_NOTIFICATION_BIG_PICTURE_LOADED, UIACTION_LATENCY_REPORTED__ACTION__ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME, }; private final Object mLock = new Object(); Loading Loading @@ -492,6 +501,8 @@ public class LatencyTracker { return "ACTION_SMARTSPACE_DOORBELL"; case UIACTION_LATENCY_REPORTED__ACTION__ACTION_NOTIFICATION_BIG_PICTURE_LOADED: return "ACTION_NOTIFICATION_BIG_PICTURE_LOADED"; case UIACTION_LATENCY_REPORTED__ACTION__ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME: return "ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME"; default: throw new IllegalArgumentException("Invalid action"); } Loading packages/SystemUI/src/com/android/systemui/biometrics/FpsUnlockTracker.kt 0 → 100644 +208 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.biometrics import android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START import android.hardware.biometrics.BiometricSourceType import android.hardware.biometrics.BiometricSourceType.FINGERPRINT import android.util.Log import com.android.app.tracing.TraceStateLogger import com.android.internal.util.LatencyTracker import com.android.internal.util.LatencyTracker.ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.KeyguardUnlockAnimationController import com.android.systemui.keyguard.KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener import com.android.systemui.plugins.statusbar.StatusBarStateController import javax.inject.Inject private const val TAG = "FpsUnlockTracker" private const val TRACE_COUNTER_NAME = "FpsUnlockStage" private const val TRACE_TAG_AOD = "AOD" private const val TRACE_TAG_KEYGUARD = "KEYGUARD" private const val DEBUG = true /** This is a class for monitoring unlock latency of fps and logging stages in perfetto. */ @SysUISingleton class FpsUnlockTracker @Inject constructor( private val statusBarStateController: StatusBarStateController, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, private val keyguardUnlockAnimationController: KeyguardUnlockAnimationController, private val latencyTracker: LatencyTracker, ) { private val fpsTraceStateLogger = TraceStateLogger(TRACE_COUNTER_NAME) private var fpsAuthenticated: Boolean = false private val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() { override fun onBiometricAcquired( biometricSourceType: BiometricSourceType?, acquireInfo: Int ) { if (keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed) { onHalAuthenticationStage(acquireInfo) } } override fun onBiometricAuthenticated( userId: Int, biometricSourceType: BiometricSourceType?, isStrongBiometric: Boolean ) { if (biometricSourceType == FINGERPRINT) { fpsAuthenticated = true onExitKeyguard() } } override fun onBiometricError( msgId: Int, errString: String?, biometricSourceType: BiometricSourceType? ) { if (biometricSourceType == FINGERPRINT) { latencyTracker.onActionCancel(ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME) } } override fun onBiometricRunningStateChanged( running: Boolean, biometricSourceType: BiometricSourceType? ) { if (biometricSourceType != FINGERPRINT || !running) { return } onWaitForAuthenticationStage() } } private val keyguardUnlockAnimationListener = object : KeyguardUnlockAnimationListener { override fun onUnlockAnimationFinished() = onUnlockedStage() } /** Start tracking the fps unlock. */ fun startTracking() { keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback) keyguardUnlockAnimationController.addKeyguardUnlockAnimationListener( keyguardUnlockAnimationListener ) } /** Stop tracking the fps unlock. */ fun stopTracking() { keyguardUpdateMonitor.removeCallback(keyguardUpdateMonitorCallback) keyguardUnlockAnimationController.removeKeyguardUnlockAnimationListener( keyguardUnlockAnimationListener ) } /** * The stage when the devices is locked and is possible to be unlocked via fps. However, in some * situations, it might be unlocked only via bouncer. */ fun onWaitForAuthenticationStage() { val stage = if (keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed) FpsUnlockStage.WAIT_FOR_AUTHENTICATION.name else FpsUnlockStage.WAIT_FOR_AUTHENTICATION.name + "(Not allowed)" fpsTraceStateLogger.log(stage) if (DEBUG) { Log.d(TAG, "onWaitForAuthenticationStage: stage=$stage") } } /** * The stage dedicated to UDFPS, SFPS should not enter this stage. The only place where invokes * this function is UdfpsController#onFingerDown. */ fun onUiReadyStage() { if (!keyguardUpdateMonitor.isUdfpsSupported || !keyguardUpdateMonitor.isUdfpsEnrolled) { return } fpsTraceStateLogger.log(FpsUnlockStage.UI_READY.name) startLatencyTracker() if (DEBUG) { Log.d(TAG, "onUiReadyStage: dozing=${statusBarStateController.isDozing}") } } /** The stage when the HAL is authenticating the fingerprint. */ fun onHalAuthenticationStage(acquire: Int) { fpsTraceStateLogger.log("${FpsUnlockStage.HAL_AUTHENTICATION.name}($acquire)") // Start latency tracker here only for SFPS, UDFPS should start at onUiReadyStage. if ( keyguardUpdateMonitor.isSfpsSupported && keyguardUpdateMonitor.isSfpsEnrolled && acquire == FINGERPRINT_ACQUIRED_START ) { startLatencyTracker() } if (DEBUG) { Log.d( TAG, "onHalAuthenticationStage: acquire=$acquire" + ", sfpsSupported=${keyguardUpdateMonitor.isSfpsSupported}" + ", sfpsEnrolled=${keyguardUpdateMonitor.isSfpsEnrolled}" ) } } /** The stage when the authentication is succeeded and is going to exit keyguard. */ fun onExitKeyguard() { fpsTraceStateLogger.log(FpsUnlockStage.EXIT_KEYGUARD.name) if (DEBUG) { Log.d(TAG, "onExitKeyguard: fpsAuthenticated=$fpsAuthenticated") } } /** * The stage when the unlock animation is finished which means the user can start interacting * with the device. */ fun onUnlockedStage() { fpsTraceStateLogger.log(FpsUnlockStage.UNLOCKED.name) if (fpsAuthenticated) { // The device is unlocked successfully via fps, end the instrument. latencyTracker.onActionEnd(ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME) } else { // The device is unlocked but not via fps, maybe bouncer? Cancel the instrument. latencyTracker.onActionCancel(ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME) } if (DEBUG) { Log.d(TAG, "onUnlockedStage: fpsAuthenticated=$fpsAuthenticated") } fpsAuthenticated = false } private fun startLatencyTracker() { latencyTracker.onActionCancel(ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME) val tag = if (statusBarStateController.isDozing) TRACE_TAG_AOD else TRACE_TAG_KEYGUARD latencyTracker.onActionStart(ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME, tag) } } private enum class FpsUnlockStage { WAIT_FOR_AUTHENTICATION, UI_READY, HAL_AUTHENTICATION, EXIT_KEYGUARD, UNLOCKED } packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt +3 −1 Original line number Diff line number Diff line Loading @@ -91,7 +91,8 @@ constructor( @Main private val handler: Handler, private val alternateBouncerInteractor: AlternateBouncerInteractor, @Application private val scope: CoroutineScope, dumpManager: DumpManager dumpManager: DumpManager, fpsUnlockTracker: FpsUnlockTracker ) : Dumpable { private val requests: HashSet<SideFpsUiRequestSource> = HashSet() Loading Loading @@ -167,6 +168,7 @@ constructor( } init { fpsUnlockTracker.startTracking() fingerprintManager?.setSidefpsController( object : ISidefpsController.Stub() { override fun show( Loading packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +10 −2 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_ import static android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_ENROLLING; import static android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR; import static com.android.internal.util.LatencyTracker.ACTION_UDFPS_ILLUMINATE; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION; Loading Loading @@ -167,6 +168,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { @NonNull private final InputManager mInputManager; @NonNull private final UdfpsKeyguardAccessibilityDelegate mUdfpsKeyguardAccessibilityDelegate; @NonNull private final SelectedUserInteractor mSelectedUserInteractor; @NonNull private final FpsUnlockTracker mFpsUnlockTracker; private final boolean mIgnoreRefreshRate; // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple Loading Loading @@ -646,7 +648,8 @@ public class UdfpsController implements DozeReceiver, Dumpable { @NonNull KeyguardFaceAuthInteractor keyguardFaceAuthInteractor, @NonNull UdfpsKeyguardAccessibilityDelegate udfpsKeyguardAccessibilityDelegate, @NonNull Provider<UdfpsKeyguardViewModels> udfpsKeyguardViewModelsProvider, @NonNull SelectedUserInteractor selectedUserInteractor) { @NonNull SelectedUserInteractor selectedUserInteractor, @NonNull FpsUnlockTracker fpsUnlockTracker) { mContext = context; mExecution = execution; mVibrator = vibrator; Loading Loading @@ -690,6 +693,8 @@ public class UdfpsController implements DozeReceiver, Dumpable { mInputManager = inputManager; mUdfpsKeyguardAccessibilityDelegate = udfpsKeyguardAccessibilityDelegate; mSelectedUserInteractor = selectedUserInteractor; mFpsUnlockTracker = fpsUnlockTracker; mFpsUnlockTracker.startTracking(); mTouchProcessor = singlePointerTouchProcessor; mSessionTracker = sessionTracker; Loading Loading @@ -974,7 +979,10 @@ public class UdfpsController implements DozeReceiver, Dumpable { return; } if (isOptical()) { mLatencyTracker.onActionStart(LatencyTracker.ACTION_UDFPS_ILLUMINATE); mLatencyTracker.onActionStart(ACTION_UDFPS_ILLUMINATE); } if (getBiometricSessionType() == SESSION_KEYGUARD) { mFpsUnlockTracker.onUiReadyStage(); } // Refresh screen timeout and boost process priority if possible. mPowerManager.userActivity(mSystemClock.uptimeMillis(), Loading packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt +4 −2 Original line number Diff line number Diff line Loading @@ -52,7 +52,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.airbnb.lottie.LottieAnimationView import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestableContext import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository Loading @@ -64,6 +63,7 @@ import com.android.systemui.display.data.repository.FakeDisplayRepository import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.res.R import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.time.FakeSystemClock Loading Loading @@ -111,6 +111,7 @@ class SideFpsControllerTest : SysuiTestCase() { @Mock lateinit var displayManager: DisplayManager @Mock lateinit var handler: Handler @Mock lateinit var dumpManager: DumpManager @Mock lateinit var fpsUnlockTracker: FpsUnlockTracker @Captor lateinit var overlayCaptor: ArgumentCaptor<View> @Captor lateinit var overlayViewParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams> Loading Loading @@ -269,7 +270,8 @@ class SideFpsControllerTest : SysuiTestCase() { handler, alternateBouncerInteractor, TestCoroutineScope(), dumpManager dumpManager, fpsUnlockTracker ) displayStateRepository.setIsInRearDisplayMode(inRearDisplayMode) Loading Loading
core/java/com/android/internal/util/LatencyTracker.java +11 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPOR import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOAD_SHARE_SHEET; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOCKSCREEN_UNLOCK; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_NOTIFICATION_BIG_PICTURE_LOADED; Loading Loading @@ -222,6 +223,11 @@ public class LatencyTracker { */ public static final int ACTION_NOTIFICATION_BIG_PICTURE_LOADED = 23; /** * Time it takes to unlock the device via udfps, until the whole launcher appears. */ public static final int ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME = 24; private static final int[] ACTIONS_ALL = { ACTION_EXPAND_PANEL, ACTION_TOGGLE_RECENTS, Loading @@ -247,6 +253,7 @@ public class LatencyTracker { ACTION_REQUEST_IME_HIDDEN, ACTION_SMARTSPACE_DOORBELL, ACTION_NOTIFICATION_BIG_PICTURE_LOADED, ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME, }; /** @hide */ Loading Loading @@ -275,6 +282,7 @@ public class LatencyTracker { ACTION_REQUEST_IME_HIDDEN, ACTION_SMARTSPACE_DOORBELL, ACTION_NOTIFICATION_BIG_PICTURE_LOADED, ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME, }) @Retention(RetentionPolicy.SOURCE) public @interface Action { Loading Loading @@ -306,6 +314,7 @@ public class LatencyTracker { UIACTION_LATENCY_REPORTED__ACTION__ACTION_REQUEST_IME_HIDDEN, UIACTION_LATENCY_REPORTED__ACTION__ACTION_SMARTSPACE_DOORBELL, UIACTION_LATENCY_REPORTED__ACTION__ACTION_NOTIFICATION_BIG_PICTURE_LOADED, UIACTION_LATENCY_REPORTED__ACTION__ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME, }; private final Object mLock = new Object(); Loading Loading @@ -492,6 +501,8 @@ public class LatencyTracker { return "ACTION_SMARTSPACE_DOORBELL"; case UIACTION_LATENCY_REPORTED__ACTION__ACTION_NOTIFICATION_BIG_PICTURE_LOADED: return "ACTION_NOTIFICATION_BIG_PICTURE_LOADED"; case UIACTION_LATENCY_REPORTED__ACTION__ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME: return "ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME"; default: throw new IllegalArgumentException("Invalid action"); } Loading
packages/SystemUI/src/com/android/systemui/biometrics/FpsUnlockTracker.kt 0 → 100644 +208 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.biometrics import android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START import android.hardware.biometrics.BiometricSourceType import android.hardware.biometrics.BiometricSourceType.FINGERPRINT import android.util.Log import com.android.app.tracing.TraceStateLogger import com.android.internal.util.LatencyTracker import com.android.internal.util.LatencyTracker.ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.KeyguardUnlockAnimationController import com.android.systemui.keyguard.KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener import com.android.systemui.plugins.statusbar.StatusBarStateController import javax.inject.Inject private const val TAG = "FpsUnlockTracker" private const val TRACE_COUNTER_NAME = "FpsUnlockStage" private const val TRACE_TAG_AOD = "AOD" private const val TRACE_TAG_KEYGUARD = "KEYGUARD" private const val DEBUG = true /** This is a class for monitoring unlock latency of fps and logging stages in perfetto. */ @SysUISingleton class FpsUnlockTracker @Inject constructor( private val statusBarStateController: StatusBarStateController, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, private val keyguardUnlockAnimationController: KeyguardUnlockAnimationController, private val latencyTracker: LatencyTracker, ) { private val fpsTraceStateLogger = TraceStateLogger(TRACE_COUNTER_NAME) private var fpsAuthenticated: Boolean = false private val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() { override fun onBiometricAcquired( biometricSourceType: BiometricSourceType?, acquireInfo: Int ) { if (keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed) { onHalAuthenticationStage(acquireInfo) } } override fun onBiometricAuthenticated( userId: Int, biometricSourceType: BiometricSourceType?, isStrongBiometric: Boolean ) { if (biometricSourceType == FINGERPRINT) { fpsAuthenticated = true onExitKeyguard() } } override fun onBiometricError( msgId: Int, errString: String?, biometricSourceType: BiometricSourceType? ) { if (biometricSourceType == FINGERPRINT) { latencyTracker.onActionCancel(ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME) } } override fun onBiometricRunningStateChanged( running: Boolean, biometricSourceType: BiometricSourceType? ) { if (biometricSourceType != FINGERPRINT || !running) { return } onWaitForAuthenticationStage() } } private val keyguardUnlockAnimationListener = object : KeyguardUnlockAnimationListener { override fun onUnlockAnimationFinished() = onUnlockedStage() } /** Start tracking the fps unlock. */ fun startTracking() { keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback) keyguardUnlockAnimationController.addKeyguardUnlockAnimationListener( keyguardUnlockAnimationListener ) } /** Stop tracking the fps unlock. */ fun stopTracking() { keyguardUpdateMonitor.removeCallback(keyguardUpdateMonitorCallback) keyguardUnlockAnimationController.removeKeyguardUnlockAnimationListener( keyguardUnlockAnimationListener ) } /** * The stage when the devices is locked and is possible to be unlocked via fps. However, in some * situations, it might be unlocked only via bouncer. */ fun onWaitForAuthenticationStage() { val stage = if (keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed) FpsUnlockStage.WAIT_FOR_AUTHENTICATION.name else FpsUnlockStage.WAIT_FOR_AUTHENTICATION.name + "(Not allowed)" fpsTraceStateLogger.log(stage) if (DEBUG) { Log.d(TAG, "onWaitForAuthenticationStage: stage=$stage") } } /** * The stage dedicated to UDFPS, SFPS should not enter this stage. The only place where invokes * this function is UdfpsController#onFingerDown. */ fun onUiReadyStage() { if (!keyguardUpdateMonitor.isUdfpsSupported || !keyguardUpdateMonitor.isUdfpsEnrolled) { return } fpsTraceStateLogger.log(FpsUnlockStage.UI_READY.name) startLatencyTracker() if (DEBUG) { Log.d(TAG, "onUiReadyStage: dozing=${statusBarStateController.isDozing}") } } /** The stage when the HAL is authenticating the fingerprint. */ fun onHalAuthenticationStage(acquire: Int) { fpsTraceStateLogger.log("${FpsUnlockStage.HAL_AUTHENTICATION.name}($acquire)") // Start latency tracker here only for SFPS, UDFPS should start at onUiReadyStage. if ( keyguardUpdateMonitor.isSfpsSupported && keyguardUpdateMonitor.isSfpsEnrolled && acquire == FINGERPRINT_ACQUIRED_START ) { startLatencyTracker() } if (DEBUG) { Log.d( TAG, "onHalAuthenticationStage: acquire=$acquire" + ", sfpsSupported=${keyguardUpdateMonitor.isSfpsSupported}" + ", sfpsEnrolled=${keyguardUpdateMonitor.isSfpsEnrolled}" ) } } /** The stage when the authentication is succeeded and is going to exit keyguard. */ fun onExitKeyguard() { fpsTraceStateLogger.log(FpsUnlockStage.EXIT_KEYGUARD.name) if (DEBUG) { Log.d(TAG, "onExitKeyguard: fpsAuthenticated=$fpsAuthenticated") } } /** * The stage when the unlock animation is finished which means the user can start interacting * with the device. */ fun onUnlockedStage() { fpsTraceStateLogger.log(FpsUnlockStage.UNLOCKED.name) if (fpsAuthenticated) { // The device is unlocked successfully via fps, end the instrument. latencyTracker.onActionEnd(ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME) } else { // The device is unlocked but not via fps, maybe bouncer? Cancel the instrument. latencyTracker.onActionCancel(ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME) } if (DEBUG) { Log.d(TAG, "onUnlockedStage: fpsAuthenticated=$fpsAuthenticated") } fpsAuthenticated = false } private fun startLatencyTracker() { latencyTracker.onActionCancel(ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME) val tag = if (statusBarStateController.isDozing) TRACE_TAG_AOD else TRACE_TAG_KEYGUARD latencyTracker.onActionStart(ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME, tag) } } private enum class FpsUnlockStage { WAIT_FOR_AUTHENTICATION, UI_READY, HAL_AUTHENTICATION, EXIT_KEYGUARD, UNLOCKED }
packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt +3 −1 Original line number Diff line number Diff line Loading @@ -91,7 +91,8 @@ constructor( @Main private val handler: Handler, private val alternateBouncerInteractor: AlternateBouncerInteractor, @Application private val scope: CoroutineScope, dumpManager: DumpManager dumpManager: DumpManager, fpsUnlockTracker: FpsUnlockTracker ) : Dumpable { private val requests: HashSet<SideFpsUiRequestSource> = HashSet() Loading Loading @@ -167,6 +168,7 @@ constructor( } init { fpsUnlockTracker.startTracking() fingerprintManager?.setSidefpsController( object : ISidefpsController.Stub() { override fun show( Loading
packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +10 −2 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_ import static android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_ENROLLING; import static android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR; import static com.android.internal.util.LatencyTracker.ACTION_UDFPS_ILLUMINATE; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION; Loading Loading @@ -167,6 +168,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { @NonNull private final InputManager mInputManager; @NonNull private final UdfpsKeyguardAccessibilityDelegate mUdfpsKeyguardAccessibilityDelegate; @NonNull private final SelectedUserInteractor mSelectedUserInteractor; @NonNull private final FpsUnlockTracker mFpsUnlockTracker; private final boolean mIgnoreRefreshRate; // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple Loading Loading @@ -646,7 +648,8 @@ public class UdfpsController implements DozeReceiver, Dumpable { @NonNull KeyguardFaceAuthInteractor keyguardFaceAuthInteractor, @NonNull UdfpsKeyguardAccessibilityDelegate udfpsKeyguardAccessibilityDelegate, @NonNull Provider<UdfpsKeyguardViewModels> udfpsKeyguardViewModelsProvider, @NonNull SelectedUserInteractor selectedUserInteractor) { @NonNull SelectedUserInteractor selectedUserInteractor, @NonNull FpsUnlockTracker fpsUnlockTracker) { mContext = context; mExecution = execution; mVibrator = vibrator; Loading Loading @@ -690,6 +693,8 @@ public class UdfpsController implements DozeReceiver, Dumpable { mInputManager = inputManager; mUdfpsKeyguardAccessibilityDelegate = udfpsKeyguardAccessibilityDelegate; mSelectedUserInteractor = selectedUserInteractor; mFpsUnlockTracker = fpsUnlockTracker; mFpsUnlockTracker.startTracking(); mTouchProcessor = singlePointerTouchProcessor; mSessionTracker = sessionTracker; Loading Loading @@ -974,7 +979,10 @@ public class UdfpsController implements DozeReceiver, Dumpable { return; } if (isOptical()) { mLatencyTracker.onActionStart(LatencyTracker.ACTION_UDFPS_ILLUMINATE); mLatencyTracker.onActionStart(ACTION_UDFPS_ILLUMINATE); } if (getBiometricSessionType() == SESSION_KEYGUARD) { mFpsUnlockTracker.onUiReadyStage(); } // Refresh screen timeout and boost process priority if possible. mPowerManager.userActivity(mSystemClock.uptimeMillis(), Loading
packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt +4 −2 Original line number Diff line number Diff line Loading @@ -52,7 +52,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.airbnb.lottie.LottieAnimationView import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestableContext import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository Loading @@ -64,6 +63,7 @@ import com.android.systemui.display.data.repository.FakeDisplayRepository import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.res.R import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.time.FakeSystemClock Loading Loading @@ -111,6 +111,7 @@ class SideFpsControllerTest : SysuiTestCase() { @Mock lateinit var displayManager: DisplayManager @Mock lateinit var handler: Handler @Mock lateinit var dumpManager: DumpManager @Mock lateinit var fpsUnlockTracker: FpsUnlockTracker @Captor lateinit var overlayCaptor: ArgumentCaptor<View> @Captor lateinit var overlayViewParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams> Loading Loading @@ -269,7 +270,8 @@ class SideFpsControllerTest : SysuiTestCase() { handler, alternateBouncerInteractor, TestCoroutineScope(), dumpManager dumpManager, fpsUnlockTracker ) displayStateRepository.setIsInRearDisplayMode(inRearDisplayMode) Loading