diff options
9 files changed, 44 insertions, 229 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index f3de463e880e..fa79ea01cf51 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -256,8 +256,6 @@ public class UdfpsControllerTest extends SysuiTestCase { @Mock private ViewRootImpl mViewRootImpl; @Mock - private FpsUnlockTracker mFpsUnlockTracker; - @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor; @Mock private Lazy<DeviceEntryUdfpsTouchOverlayViewModel> mDeviceEntryUdfpsTouchOverlayViewModel; @@ -368,7 +366,6 @@ public class UdfpsControllerTest extends SysuiTestCase { mock(DeviceEntryFaceAuthInteractor.class), mUdfpsKeyguardAccessibilityDelegate, mSelectedUserInteractor, - mFpsUnlockTracker, mKeyguardTransitionInteractor, mDeviceEntryUdfpsTouchOverlayViewModel, mDefaultUdfpsTouchOverlayViewModel, diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FpsUnlockTracker.kt b/packages/SystemUI/src/com/android/systemui/biometrics/FpsUnlockTracker.kt deleted file mode 100644 index cf699a2ed349..000000000000 --- a/packages/SystemUI/src/com/android/systemui/biometrics/FpsUnlockTracker.kt +++ /dev/null @@ -1,208 +0,0 @@ -/* - * 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 -} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 85b5faf2d556..ad142a86fa03 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -184,7 +184,6 @@ 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; private final KeyguardTransitionInteractor mKeyguardTransitionInteractor; @@ -712,7 +711,6 @@ public class UdfpsController implements DozeReceiver, Dumpable { @NonNull DeviceEntryFaceAuthInteractor deviceEntryFaceAuthInteractor, @NonNull UdfpsKeyguardAccessibilityDelegate udfpsKeyguardAccessibilityDelegate, @NonNull SelectedUserInteractor selectedUserInteractor, - @NonNull FpsUnlockTracker fpsUnlockTracker, @NonNull KeyguardTransitionInteractor keyguardTransitionInteractor, Lazy<DeviceEntryUdfpsTouchOverlayViewModel> deviceEntryUdfpsTouchOverlayViewModel, Lazy<DefaultUdfpsTouchOverlayViewModel> defaultUdfpsTouchOverlayViewModel, @@ -765,8 +763,6 @@ public class UdfpsController implements DozeReceiver, Dumpable { mInputManager = inputManager; mUdfpsKeyguardAccessibilityDelegate = udfpsKeyguardAccessibilityDelegate; mSelectedUserInteractor = selectedUserInteractor; - mFpsUnlockTracker = fpsUnlockTracker; - mFpsUnlockTracker.startTracking(); mKeyguardTransitionInteractor = keyguardTransitionInteractor; mTouchProcessor = singlePointerTouchProcessor; @@ -1067,9 +1063,6 @@ public class UdfpsController implements DozeReceiver, Dumpable { if (isOptical()) { mLatencyTracker.onActionStart(ACTION_UDFPS_ILLUMINATE); } - if (getBiometricSessionType() == SESSION_KEYGUARD) { - mFpsUnlockTracker.onUiReadyStage(); - } // Refresh screen timeout and boost process priority if possible. mPowerManager.userActivity(mSystemClock.uptimeMillis(), PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt index 14d8caf2a5b7..e2a8a691b1fd 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt @@ -39,12 +39,14 @@ import com.android.systemui.biometrics.data.repository.PromptRepositoryImpl import com.android.systemui.biometrics.udfps.BoundingBoxOverlapDetector import com.android.systemui.biometrics.udfps.EllipseOverlapDetector import com.android.systemui.biometrics.udfps.OverlapDetector +import com.android.systemui.biometrics.ui.binder.DeviceEntryUnlockTrackerViewBinder import com.android.systemui.biometrics.ui.binder.SideFpsOverlayViewBinder import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.ui.binder.AlternateBouncerViewBinder import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener import com.android.systemui.util.concurrency.ThreadFactory import dagger.Binds +import dagger.BindsOptionalOf import dagger.Module import dagger.Provides import dagger.multibindings.ClassKey @@ -101,6 +103,9 @@ interface BiometricsModule { @SysUISingleton fun displayStateRepository(impl: DisplayStateRepositoryImpl): DisplayStateRepository + @BindsOptionalOf + fun deviceEntryUnlockTrackerViewBinder(): DeviceEntryUnlockTrackerViewBinder + companion object { /** Background [Executor] for HAL related operations. */ @Provides diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/DeviceEntryUnlockTrackerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/DeviceEntryUnlockTrackerViewBinder.kt new file mode 100644 index 000000000000..78eaab262370 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/DeviceEntryUnlockTrackerViewBinder.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 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.ui.binder + +import com.android.systemui.keyguard.ui.view.KeyguardRootView + +/** ViewBinder for device entry unlock tracker implemented in vendor */ +interface DeviceEntryUnlockTrackerViewBinder { + /** + * Allows vendor binds vendor's view model to the specified view. + * @param view the view to be bound + */ + fun bind(view: KeyguardRootView) {} +} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt index ff7ac35ba56b..9cc46506cefb 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt @@ -33,7 +33,6 @@ import com.airbnb.lottie.LottieProperty import com.android.app.animation.Interpolators import com.android.keyguard.KeyguardPINView import com.android.systemui.CoreStartable -import com.android.systemui.biometrics.FpsUnlockTracker import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractor import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.biometrics.domain.interactor.SideFpsSensorInteractor @@ -65,7 +64,6 @@ constructor( private val biometricStatusInteractor: Lazy<BiometricStatusInteractor>, private val displayStateInteractor: Lazy<DisplayStateInteractor>, private val deviceEntrySideFpsOverlayInteractor: Lazy<DeviceEntrySideFpsOverlayInteractor>, - private val fpsUnlockTracker: Lazy<FpsUnlockTracker>, private val layoutInflater: Lazy<LayoutInflater>, private val sideFpsProgressBarViewModel: Lazy<SideFpsProgressBarViewModel>, private val sfpsSensorInteractor: Lazy<SideFpsSensorInteractor>, @@ -114,7 +112,6 @@ constructor( } } } - .invokeOnCompletion { fpsUnlockTracker.get().stopTracking() } } private var overlayView: View? = null @@ -138,7 +135,7 @@ constructor( displayStateInteractor.get(), sfpsSensorInteractor.get(), ) - bind(overlayView!!, overlayViewModel, fpsUnlockTracker.get(), windowManager.get()) + bind(overlayView!!, overlayViewModel, windowManager.get()) overlayView!!.visibility = View.INVISIBLE Log.d(TAG, "show(): adding overlayView $overlayView") windowManager.get().addView(overlayView, overlayViewModel.defaultOverlayViewParams) @@ -163,12 +160,9 @@ constructor( fun bind( overlayView: View, viewModel: SideFpsOverlayViewModel, - fpsUnlockTracker: FpsUnlockTracker, windowManager: WindowManager ) { overlayView.repeatWhenAttached { - fpsUnlockTracker.startTracking() - val lottie = it.requireViewById<LottieAnimationView>(R.id.sidefps_animation) lottie.addLottieOnCompositionLoadedListener { composition: LottieComposition -> if (overlayView.visibility != View.VISIBLE) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt index 306f4ffa2a54..608e25a82eff 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt @@ -39,6 +39,7 @@ import com.android.keyguard.LegacyLockIconViewController import com.android.keyguard.LockIconView import com.android.keyguard.dagger.KeyguardStatusViewComponent import com.android.systemui.CoreStartable +import com.android.systemui.biometrics.ui.binder.DeviceEntryUnlockTrackerViewBinder import com.android.systemui.common.ui.ConfigurationState import com.android.systemui.dagger.SysUISingleton import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor @@ -70,6 +71,7 @@ import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator import dagger.Lazy +import java.util.Optional import javax.inject.Inject import kotlinx.coroutines.DisposableHandle import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -105,6 +107,7 @@ constructor( private val lockscreenSceneBlueprintsLazy: Lazy<Set<LockscreenSceneBlueprint>>, private val clockInteractor: KeyguardClockInteractor, private val keyguardViewMediator: KeyguardViewMediator, + private val deviceEntryUnlockTrackerViewBinder: Optional<DeviceEntryUnlockTrackerViewBinder>, ) : CoreStartable { private var rootViewHandle: DisposableHandle? = null @@ -157,6 +160,9 @@ constructor( ) } } + if (deviceEntryUnlockTrackerViewBinder.isPresent) { + deviceEntryUnlockTrackerViewBinder.get().bind(keyguardRootView) + } } fun bindIndicationArea() { diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/FpsUnlockTrackerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/keyguard/KeyguardUnlockAnimationControllerKosmos.kt index 6085a1f3353e..1fa681360070 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/FpsUnlockTrackerKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/keyguard/KeyguardUnlockAnimationControllerKosmos.kt @@ -14,9 +14,11 @@ * limitations under the License. */ -package com.android.systemui.biometrics +package com.android.keyguard +import com.android.systemui.keyguard.KeyguardUnlockAnimationController import com.android.systemui.kosmos.Kosmos import com.android.systemui.util.mockito.mock -val Kosmos.fpsUnlockTracker by Kosmos.Fixture { mock<FpsUnlockTracker>() } +val Kosmos.keyguardUnlockAnimationController by + Kosmos.Fixture { mock<KeyguardUnlockAnimationController>() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderKosmos.kt index 8281984d3b4f..79d58a1d4e40 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderKosmos.kt @@ -22,7 +22,6 @@ import android.view.windowManager import com.android.systemui.biometrics.domain.interactor.biometricStatusInteractor import com.android.systemui.biometrics.domain.interactor.displayStateInteractor import com.android.systemui.biometrics.domain.interactor.sideFpsSensorInteractor -import com.android.systemui.biometrics.fpsUnlockTracker import com.android.systemui.keyguard.domain.interactor.deviceEntrySideFpsOverlayInteractor import com.android.systemui.keyguard.ui.viewmodel.sideFpsProgressBarViewModel import com.android.systemui.kosmos.Kosmos @@ -38,7 +37,6 @@ val Kosmos.sideFpsOverlayViewBinder by Fixture { { biometricStatusInteractor }, { displayStateInteractor }, { deviceEntrySideFpsOverlayInteractor }, - { fpsUnlockTracker }, { layoutInflater }, { sideFpsProgressBarViewModel }, { sideFpsSensorInteractor }, |