Loading packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +6 −31 Original line number Diff line number Diff line Loading @@ -45,8 +45,6 @@ import android.os.RemoteException; import android.testing.TestableLooper.RunWithLooper; import android.view.LayoutInflater; import android.view.Surface; import android.view.View; import android.view.ViewRootImpl; import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; Loading @@ -63,13 +61,13 @@ import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams; import com.android.systemui.biometrics.udfps.SinglePointerTouchProcessor; import com.android.systemui.biometrics.ui.viewmodel.DefaultUdfpsTouchOverlayViewModel; import com.android.systemui.biometrics.ui.viewmodel.DeviceEntryUdfpsTouchOverlayViewModel; import com.android.systemui.biometrics.ui.viewmodel.PromptUdfpsTouchOverlayViewModel; import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor; import com.android.systemui.camera.CameraGestureHelper; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.UserActivityNotifierKosmosKt; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; Loading @@ -82,7 +80,6 @@ import com.android.systemui.power.domain.interactor.PowerInteractor; import com.android.systemui.power.shared.model.WakeSleepReason; import com.android.systemui.power.shared.model.WakefulnessState; import com.android.systemui.shade.domain.interactor.ShadeInteractor; import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.phone.ScreenOffAnimationController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; Loading @@ -98,8 +95,6 @@ import com.android.systemui.util.time.SystemClock; import dagger.Lazy; import javax.inject.Provider; import kotlinx.coroutines.CoroutineScope; import org.junit.Before; Loading @@ -115,6 +110,8 @@ import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; import javax.inject.Provider; @SmallTest @RunWith(AndroidJUnit4.class) @RunWithLooper(setAsMainLooper = true) Loading Loading @@ -151,8 +148,6 @@ public class UdfpsControllerTest extends SysuiTestCase { @Mock private AccessibilityManager mAccessibilityManager; @Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController; @Mock private ScreenLifecycle mScreenLifecycle; @Mock private VibratorHelper mVibrator; Loading @@ -178,9 +173,6 @@ public class UdfpsControllerTest extends SysuiTestCase { @Mock private UdfpsDisplayMode mUdfpsDisplayMode; @Mock private FeatureFlags mFeatureFlags; // Stuff for configuring mocks @Mock private SystemUIDialogManager mSystemUIDialogManager; @Mock private ActivityTransitionAnimator mActivityTransitionAnimator; Loading @@ -204,31 +196,21 @@ public class UdfpsControllerTest extends SysuiTestCase { private ArgumentCaptor<IUdfpsOverlayController> mOverlayCaptor; private IUdfpsOverlayController mOverlayController; @Captor private ArgumentCaptor<View> mViewCaptor; @Captor private ArgumentCaptor<View.OnHoverListener> mHoverListenerCaptor; @Captor private ArgumentCaptor<Runnable> mOnDisplayConfiguredCaptor; @Captor private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor; @Captor private ArgumentCaptor<UdfpsController.UdfpsOverlayController> mUdfpsOverlayControllerCaptor; private ScreenLifecycle.Observer mScreenObserver; private FingerprintSensorPropertiesInternal mOpticalProps; private FingerprintSensorPropertiesInternal mUltrasonicProps; private PowerInteractor mPowerInteractor; private FakePowerRepository mPowerRepository; @Mock private InputManager mInputManager; @Mock private ViewRootImpl mViewRootImpl; @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor; @Mock private Lazy<DeviceEntryUdfpsTouchOverlayViewModel> mDeviceEntryUdfpsTouchOverlayViewModel; @Mock private Lazy<DefaultUdfpsTouchOverlayViewModel> mDefaultUdfpsTouchOverlayViewModel; @Mock private Lazy<PromptUdfpsTouchOverlayViewModel> mPromptUdfpsTouchOverlayViewModel; @Mock private Provider<CameraGestureHelper> mCameraGestureHelper; @Before Loading Loading @@ -269,13 +251,6 @@ public class UdfpsControllerTest extends SysuiTestCase { FingerprintSensorProperties.TYPE_UDFPS_OPTICAL, true /* resetLockoutRequiresHardwareAuthToken */); mUltrasonicProps = new FingerprintSensorPropertiesInternal(2 /* sensorId */, SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */, componentInfo, FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC, true /* resetLockoutRequiresHardwareAuthToken */); mFgExecutor = new FakeExecutor(new FakeSystemClock()); // Create a fake background executor. Loading Loading @@ -327,6 +302,7 @@ public class UdfpsControllerTest extends SysuiTestCase { mKeyguardTransitionInteractor, mDeviceEntryUdfpsTouchOverlayViewModel, mDefaultUdfpsTouchOverlayViewModel, mPromptUdfpsTouchOverlayViewModel, mUdfpsOverlayInteractor, mPowerInteractor, mock(CoroutineScope.class), Loading @@ -335,7 +311,6 @@ public class UdfpsControllerTest extends SysuiTestCase { verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture()); mOverlayController = mOverlayCaptor.getValue(); verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture()); mScreenObserver = mScreenObserverCaptor.getValue(); mUdfpsController.updateOverlayParams(sensorProps, new UdfpsOverlayParams()); mUdfpsController.setUdfpsDisplayMode(mUdfpsDisplayMode); Loading packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +1 −1 Original line number Diff line number Diff line Loading @@ -741,7 +741,7 @@ public class AuthContainerView extends LinearLayout final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, windowFlags, PixelFormat.TRANSLUCENT); lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; Loading packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +7 −13 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ import com.android.systemui.biometrics.udfps.TouchProcessor; import com.android.systemui.biometrics.udfps.TouchProcessorResult; import com.android.systemui.biometrics.ui.viewmodel.DefaultUdfpsTouchOverlayViewModel; import com.android.systemui.biometrics.ui.viewmodel.DeviceEntryUdfpsTouchOverlayViewModel; import com.android.systemui.biometrics.ui.viewmodel.PromptUdfpsTouchOverlayViewModel; import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor; import com.android.systemui.dagger.SysUISingleton; Loading Loading @@ -178,6 +179,8 @@ public class UdfpsController implements DozeReceiver, Dumpable { mDeviceEntryUdfpsTouchOverlayViewModel; @NonNull private final Lazy<DefaultUdfpsTouchOverlayViewModel> mDefaultUdfpsTouchOverlayViewModel; @NonNull private final Lazy<PromptUdfpsTouchOverlayViewModel> mPromptUdfpsTouchOverlayViewModel; @NonNull private final AlternateBouncerInteractor mAlternateBouncerInteractor; @NonNull private final UdfpsOverlayInteractor mUdfpsOverlayInteractor; @NonNull private final PowerInteractor mPowerInteractor; Loading Loading @@ -272,18 +275,11 @@ public class UdfpsController implements DozeReceiver, Dumpable { mUdfpsOverlayInteractor.setRequestId(requestId); mFgExecutor.execute(() -> UdfpsController.this.showUdfpsOverlay( new UdfpsControllerOverlay( mContext, mInflater, mWindowManager, mAccessibilityManager, mStatusBarStateController, mKeyguardViewManager, mKeyguardUpdateMonitor, mDialogManager, mDumpManager, mConfigurationController, mKeyguardStateController, mUnlockedScreenOffAnimationController, mUdfpsDisplayMode, requestId, reason, Loading @@ -292,14 +288,10 @@ public class UdfpsController implements DozeReceiver, Dumpable { requestId, event ), mActivityTransitionAnimator, mPrimaryBouncerInteractor, mAlternateBouncerInteractor, mKeyguardTransitionInteractor, mSelectedUserInteractor, mDeviceEntryUdfpsTouchOverlayViewModel, mDefaultUdfpsTouchOverlayViewModel, mShadeInteractor, mPromptUdfpsTouchOverlayViewModel, mUdfpsOverlayInteractor, mPowerInteractor, mScope Loading Loading @@ -697,6 +689,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { @NonNull KeyguardTransitionInteractor keyguardTransitionInteractor, Lazy<DeviceEntryUdfpsTouchOverlayViewModel> deviceEntryUdfpsTouchOverlayViewModel, Lazy<DefaultUdfpsTouchOverlayViewModel> defaultUdfpsTouchOverlayViewModel, Lazy<PromptUdfpsTouchOverlayViewModel> promptUdfpsTouchOverlayViewModel, @NonNull UdfpsOverlayInteractor udfpsOverlayInteractor, @NonNull PowerInteractor powerInteractor, @Application CoroutineScope scope, Loading Loading @@ -752,6 +745,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { mSessionTracker = sessionTracker; mDeviceEntryUdfpsTouchOverlayViewModel = deviceEntryUdfpsTouchOverlayViewModel; mDefaultUdfpsTouchOverlayViewModel = defaultUdfpsTouchOverlayViewModel; mPromptUdfpsTouchOverlayViewModel = promptUdfpsTouchOverlayViewModel; mDumpManager.registerDumpable(TAG, this); Loading Loading @@ -827,7 +821,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { + " isn't running on keyguard. Skip show."); return; } if (overlay.show(this, mOverlayParams)) { if (overlay.show(mOverlayParams)) { Log.d(TAG, "showUdfpsOverlay | adding window reason=" + requestReason); mOnFingerDown = false; mAttemptedToDismissKeyguard = false; Loading packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt +12 −46 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.systemui.biometrics import android.annotation.SuppressLint import android.annotation.UiThread import android.content.Context import android.graphics.PixelFormat import android.graphics.Rect import android.hardware.biometrics.BiometricRequestConstants.REASON_AUTH_BP Loading @@ -27,10 +26,8 @@ import android.hardware.biometrics.BiometricRequestConstants.REASON_ENROLL_ENROL import android.hardware.biometrics.BiometricRequestConstants.REASON_ENROLL_FIND_SENSOR import android.hardware.biometrics.BiometricRequestConstants.RequestReason import android.hardware.fingerprint.IUdfpsOverlayControllerCallback import android.os.Build import android.os.RemoteException import android.os.Trace import android.provider.Settings import android.util.Log import android.util.RotationUtils import android.view.LayoutInflater Loading @@ -40,32 +37,21 @@ import android.view.View import android.view.WindowManager import android.view.accessibility.AccessibilityManager import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener import androidx.annotation.VisibleForTesting import com.android.app.tracing.coroutines.launchTraced as launch import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.animation.ActivityTransitionAnimator import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams import com.android.systemui.biometrics.ui.binder.UdfpsTouchOverlayBinder import com.android.systemui.biometrics.ui.view.UdfpsTouchOverlay import com.android.systemui.biometrics.ui.viewmodel.DefaultUdfpsTouchOverlayViewModel import com.android.systemui.biometrics.ui.viewmodel.DeviceEntryUdfpsTouchOverlayViewModel import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.biometrics.ui.viewmodel.PromptUdfpsTouchOverlayViewModel import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.res.R import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager import com.android.systemui.statusbar.phone.SystemUIDialogManager import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.user.domain.interactor.SelectedUserInteractor import dagger.Lazy import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job Loading @@ -75,42 +61,27 @@ import kotlinx.coroutines.flow.map private const val TAG = "UdfpsControllerOverlay" @VisibleForTesting const val SETTING_REMOVE_ENROLLMENT_UI = "udfps_overlay_remove_enrollment_ui" /** * Keeps track of the overlay state and UI resources associated with a single FingerprintService * request. This state can persist across configuration changes via the [show] and [hide] methods. */ @UiThread class UdfpsControllerOverlay @JvmOverloads constructor( private val context: Context, private val inflater: LayoutInflater, private val windowManager: WindowManager, private val accessibilityManager: AccessibilityManager, private val statusBarStateController: StatusBarStateController, private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, private val dialogManager: SystemUIDialogManager, private val dumpManager: DumpManager, private val configurationController: ConfigurationController, private val keyguardStateController: KeyguardStateController, private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController, private var udfpsDisplayModeProvider: UdfpsDisplayModeProvider, val requestId: Long, @RequestReason val requestReason: Int, private val controllerCallback: IUdfpsOverlayControllerCallback, private val onTouch: (View, MotionEvent) -> Boolean, private val activityTransitionAnimator: ActivityTransitionAnimator, private val primaryBouncerInteractor: PrimaryBouncerInteractor, private val alternateBouncerInteractor: AlternateBouncerInteractor, private val isDebuggable: Boolean = Build.IS_DEBUGGABLE, private val transitionInteractor: KeyguardTransitionInteractor, private val selectedUserInteractor: SelectedUserInteractor, transitionInteractor: KeyguardTransitionInteractor, private val deviceEntryUdfpsTouchOverlayViewModel: Lazy<DeviceEntryUdfpsTouchOverlayViewModel>, private val defaultUdfpsTouchOverlayViewModel: Lazy<DefaultUdfpsTouchOverlayViewModel>, private val shadeInteractor: ShadeInteractor, private val promptUdfpsTouchOverlayViewModel: Lazy<PromptUdfpsTouchOverlayViewModel>, private val udfpsOverlayInteractor: UdfpsOverlayInteractor, private val powerInteractor: PowerInteractor, @Application private val scope: CoroutineScope, Loading Loading @@ -170,20 +141,9 @@ constructor( private var touchExplorationEnabled = false private fun shouldRemoveEnrollmentUi(): Boolean { if (isDebuggable) { return Settings.Global.getInt( context.contentResolver, SETTING_REMOVE_ENROLLMENT_UI, 0, /* def */ ) != 0 } return false } /** Show the overlay or return false and do nothing if it is already showing. */ @SuppressLint("ClickableViewAccessibility") fun show(controller: UdfpsController, params: UdfpsOverlayParams): Boolean { fun show(params: UdfpsOverlayParams): Boolean { if (getTouchOverlay() == null) { overlayParams = params sensorBounds = Rect(params.sensorBounds) Loading @@ -206,6 +166,12 @@ constructor( viewModel = deviceEntryUdfpsTouchOverlayViewModel.get(), udfpsOverlayInteractor = udfpsOverlayInteractor, ) REASON_AUTH_BP -> UdfpsTouchOverlayBinder.bind( view = this, viewModel = promptUdfpsTouchOverlayViewModel.get(), udfpsOverlayInteractor = udfpsOverlayInteractor, ) else -> UdfpsTouchOverlayBinder.bind( view = this, Loading Loading @@ -340,7 +306,7 @@ constructor( val rot = overlayParams.rotation if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) { if (!shouldRotate(animation)) { if (!shouldRotate()) { Log.v( TAG, "Skip rotating UDFPS bounds " + Loading Loading @@ -375,7 +341,7 @@ constructor( return this } private fun shouldRotate(animation: UdfpsAnimationViewController<*>?): Boolean { private fun shouldRotate(): Boolean { if (!keyguardStateController.isShowing) { // always rotate view if we're not on the keyguard return true Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptUdfpsTouchOverlayViewModel.kt 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.viewmodel import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow class PromptUdfpsTouchOverlayViewModel @Inject constructor() : UdfpsTouchOverlayViewModel { // Biometric Prompt should always handle touches override val shouldHandleTouches: Flow<Boolean> = MutableStateFlow(true) } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +6 −31 Original line number Diff line number Diff line Loading @@ -45,8 +45,6 @@ import android.os.RemoteException; import android.testing.TestableLooper.RunWithLooper; import android.view.LayoutInflater; import android.view.Surface; import android.view.View; import android.view.ViewRootImpl; import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; Loading @@ -63,13 +61,13 @@ import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams; import com.android.systemui.biometrics.udfps.SinglePointerTouchProcessor; import com.android.systemui.biometrics.ui.viewmodel.DefaultUdfpsTouchOverlayViewModel; import com.android.systemui.biometrics.ui.viewmodel.DeviceEntryUdfpsTouchOverlayViewModel; import com.android.systemui.biometrics.ui.viewmodel.PromptUdfpsTouchOverlayViewModel; import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor; import com.android.systemui.camera.CameraGestureHelper; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.UserActivityNotifierKosmosKt; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; Loading @@ -82,7 +80,6 @@ import com.android.systemui.power.domain.interactor.PowerInteractor; import com.android.systemui.power.shared.model.WakeSleepReason; import com.android.systemui.power.shared.model.WakefulnessState; import com.android.systemui.shade.domain.interactor.ShadeInteractor; import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.phone.ScreenOffAnimationController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; Loading @@ -98,8 +95,6 @@ import com.android.systemui.util.time.SystemClock; import dagger.Lazy; import javax.inject.Provider; import kotlinx.coroutines.CoroutineScope; import org.junit.Before; Loading @@ -115,6 +110,8 @@ import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.List; import javax.inject.Provider; @SmallTest @RunWith(AndroidJUnit4.class) @RunWithLooper(setAsMainLooper = true) Loading Loading @@ -151,8 +148,6 @@ public class UdfpsControllerTest extends SysuiTestCase { @Mock private AccessibilityManager mAccessibilityManager; @Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController; @Mock private ScreenLifecycle mScreenLifecycle; @Mock private VibratorHelper mVibrator; Loading @@ -178,9 +173,6 @@ public class UdfpsControllerTest extends SysuiTestCase { @Mock private UdfpsDisplayMode mUdfpsDisplayMode; @Mock private FeatureFlags mFeatureFlags; // Stuff for configuring mocks @Mock private SystemUIDialogManager mSystemUIDialogManager; @Mock private ActivityTransitionAnimator mActivityTransitionAnimator; Loading @@ -204,31 +196,21 @@ public class UdfpsControllerTest extends SysuiTestCase { private ArgumentCaptor<IUdfpsOverlayController> mOverlayCaptor; private IUdfpsOverlayController mOverlayController; @Captor private ArgumentCaptor<View> mViewCaptor; @Captor private ArgumentCaptor<View.OnHoverListener> mHoverListenerCaptor; @Captor private ArgumentCaptor<Runnable> mOnDisplayConfiguredCaptor; @Captor private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor; @Captor private ArgumentCaptor<UdfpsController.UdfpsOverlayController> mUdfpsOverlayControllerCaptor; private ScreenLifecycle.Observer mScreenObserver; private FingerprintSensorPropertiesInternal mOpticalProps; private FingerprintSensorPropertiesInternal mUltrasonicProps; private PowerInteractor mPowerInteractor; private FakePowerRepository mPowerRepository; @Mock private InputManager mInputManager; @Mock private ViewRootImpl mViewRootImpl; @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor; @Mock private Lazy<DeviceEntryUdfpsTouchOverlayViewModel> mDeviceEntryUdfpsTouchOverlayViewModel; @Mock private Lazy<DefaultUdfpsTouchOverlayViewModel> mDefaultUdfpsTouchOverlayViewModel; @Mock private Lazy<PromptUdfpsTouchOverlayViewModel> mPromptUdfpsTouchOverlayViewModel; @Mock private Provider<CameraGestureHelper> mCameraGestureHelper; @Before Loading Loading @@ -269,13 +251,6 @@ public class UdfpsControllerTest extends SysuiTestCase { FingerprintSensorProperties.TYPE_UDFPS_OPTICAL, true /* resetLockoutRequiresHardwareAuthToken */); mUltrasonicProps = new FingerprintSensorPropertiesInternal(2 /* sensorId */, SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */, componentInfo, FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC, true /* resetLockoutRequiresHardwareAuthToken */); mFgExecutor = new FakeExecutor(new FakeSystemClock()); // Create a fake background executor. Loading Loading @@ -327,6 +302,7 @@ public class UdfpsControllerTest extends SysuiTestCase { mKeyguardTransitionInteractor, mDeviceEntryUdfpsTouchOverlayViewModel, mDefaultUdfpsTouchOverlayViewModel, mPromptUdfpsTouchOverlayViewModel, mUdfpsOverlayInteractor, mPowerInteractor, mock(CoroutineScope.class), Loading @@ -335,7 +311,6 @@ public class UdfpsControllerTest extends SysuiTestCase { verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture()); mOverlayController = mOverlayCaptor.getValue(); verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture()); mScreenObserver = mScreenObserverCaptor.getValue(); mUdfpsController.updateOverlayParams(sensorProps, new UdfpsOverlayParams()); mUdfpsController.setUdfpsDisplayMode(mUdfpsDisplayMode); Loading
packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +1 −1 Original line number Diff line number Diff line Loading @@ -741,7 +741,7 @@ public class AuthContainerView extends LinearLayout final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, windowFlags, PixelFormat.TRANSLUCENT); lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; Loading
packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +7 −13 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ import com.android.systemui.biometrics.udfps.TouchProcessor; import com.android.systemui.biometrics.udfps.TouchProcessorResult; import com.android.systemui.biometrics.ui.viewmodel.DefaultUdfpsTouchOverlayViewModel; import com.android.systemui.biometrics.ui.viewmodel.DeviceEntryUdfpsTouchOverlayViewModel; import com.android.systemui.biometrics.ui.viewmodel.PromptUdfpsTouchOverlayViewModel; import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor; import com.android.systemui.dagger.SysUISingleton; Loading Loading @@ -178,6 +179,8 @@ public class UdfpsController implements DozeReceiver, Dumpable { mDeviceEntryUdfpsTouchOverlayViewModel; @NonNull private final Lazy<DefaultUdfpsTouchOverlayViewModel> mDefaultUdfpsTouchOverlayViewModel; @NonNull private final Lazy<PromptUdfpsTouchOverlayViewModel> mPromptUdfpsTouchOverlayViewModel; @NonNull private final AlternateBouncerInteractor mAlternateBouncerInteractor; @NonNull private final UdfpsOverlayInteractor mUdfpsOverlayInteractor; @NonNull private final PowerInteractor mPowerInteractor; Loading Loading @@ -272,18 +275,11 @@ public class UdfpsController implements DozeReceiver, Dumpable { mUdfpsOverlayInteractor.setRequestId(requestId); mFgExecutor.execute(() -> UdfpsController.this.showUdfpsOverlay( new UdfpsControllerOverlay( mContext, mInflater, mWindowManager, mAccessibilityManager, mStatusBarStateController, mKeyguardViewManager, mKeyguardUpdateMonitor, mDialogManager, mDumpManager, mConfigurationController, mKeyguardStateController, mUnlockedScreenOffAnimationController, mUdfpsDisplayMode, requestId, reason, Loading @@ -292,14 +288,10 @@ public class UdfpsController implements DozeReceiver, Dumpable { requestId, event ), mActivityTransitionAnimator, mPrimaryBouncerInteractor, mAlternateBouncerInteractor, mKeyguardTransitionInteractor, mSelectedUserInteractor, mDeviceEntryUdfpsTouchOverlayViewModel, mDefaultUdfpsTouchOverlayViewModel, mShadeInteractor, mPromptUdfpsTouchOverlayViewModel, mUdfpsOverlayInteractor, mPowerInteractor, mScope Loading Loading @@ -697,6 +689,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { @NonNull KeyguardTransitionInteractor keyguardTransitionInteractor, Lazy<DeviceEntryUdfpsTouchOverlayViewModel> deviceEntryUdfpsTouchOverlayViewModel, Lazy<DefaultUdfpsTouchOverlayViewModel> defaultUdfpsTouchOverlayViewModel, Lazy<PromptUdfpsTouchOverlayViewModel> promptUdfpsTouchOverlayViewModel, @NonNull UdfpsOverlayInteractor udfpsOverlayInteractor, @NonNull PowerInteractor powerInteractor, @Application CoroutineScope scope, Loading Loading @@ -752,6 +745,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { mSessionTracker = sessionTracker; mDeviceEntryUdfpsTouchOverlayViewModel = deviceEntryUdfpsTouchOverlayViewModel; mDefaultUdfpsTouchOverlayViewModel = defaultUdfpsTouchOverlayViewModel; mPromptUdfpsTouchOverlayViewModel = promptUdfpsTouchOverlayViewModel; mDumpManager.registerDumpable(TAG, this); Loading Loading @@ -827,7 +821,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { + " isn't running on keyguard. Skip show."); return; } if (overlay.show(this, mOverlayParams)) { if (overlay.show(mOverlayParams)) { Log.d(TAG, "showUdfpsOverlay | adding window reason=" + requestReason); mOnFingerDown = false; mAttemptedToDismissKeyguard = false; Loading
packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt +12 −46 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.systemui.biometrics import android.annotation.SuppressLint import android.annotation.UiThread import android.content.Context import android.graphics.PixelFormat import android.graphics.Rect import android.hardware.biometrics.BiometricRequestConstants.REASON_AUTH_BP Loading @@ -27,10 +26,8 @@ import android.hardware.biometrics.BiometricRequestConstants.REASON_ENROLL_ENROL import android.hardware.biometrics.BiometricRequestConstants.REASON_ENROLL_FIND_SENSOR import android.hardware.biometrics.BiometricRequestConstants.RequestReason import android.hardware.fingerprint.IUdfpsOverlayControllerCallback import android.os.Build import android.os.RemoteException import android.os.Trace import android.provider.Settings import android.util.Log import android.util.RotationUtils import android.view.LayoutInflater Loading @@ -40,32 +37,21 @@ import android.view.View import android.view.WindowManager import android.view.accessibility.AccessibilityManager import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener import androidx.annotation.VisibleForTesting import com.android.app.tracing.coroutines.launchTraced as launch import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.animation.ActivityTransitionAnimator import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams import com.android.systemui.biometrics.ui.binder.UdfpsTouchOverlayBinder import com.android.systemui.biometrics.ui.view.UdfpsTouchOverlay import com.android.systemui.biometrics.ui.viewmodel.DefaultUdfpsTouchOverlayViewModel import com.android.systemui.biometrics.ui.viewmodel.DeviceEntryUdfpsTouchOverlayViewModel import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.biometrics.ui.viewmodel.PromptUdfpsTouchOverlayViewModel import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.res.R import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager import com.android.systemui.statusbar.phone.SystemUIDialogManager import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.user.domain.interactor.SelectedUserInteractor import dagger.Lazy import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job Loading @@ -75,42 +61,27 @@ import kotlinx.coroutines.flow.map private const val TAG = "UdfpsControllerOverlay" @VisibleForTesting const val SETTING_REMOVE_ENROLLMENT_UI = "udfps_overlay_remove_enrollment_ui" /** * Keeps track of the overlay state and UI resources associated with a single FingerprintService * request. This state can persist across configuration changes via the [show] and [hide] methods. */ @UiThread class UdfpsControllerOverlay @JvmOverloads constructor( private val context: Context, private val inflater: LayoutInflater, private val windowManager: WindowManager, private val accessibilityManager: AccessibilityManager, private val statusBarStateController: StatusBarStateController, private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, private val dialogManager: SystemUIDialogManager, private val dumpManager: DumpManager, private val configurationController: ConfigurationController, private val keyguardStateController: KeyguardStateController, private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController, private var udfpsDisplayModeProvider: UdfpsDisplayModeProvider, val requestId: Long, @RequestReason val requestReason: Int, private val controllerCallback: IUdfpsOverlayControllerCallback, private val onTouch: (View, MotionEvent) -> Boolean, private val activityTransitionAnimator: ActivityTransitionAnimator, private val primaryBouncerInteractor: PrimaryBouncerInteractor, private val alternateBouncerInteractor: AlternateBouncerInteractor, private val isDebuggable: Boolean = Build.IS_DEBUGGABLE, private val transitionInteractor: KeyguardTransitionInteractor, private val selectedUserInteractor: SelectedUserInteractor, transitionInteractor: KeyguardTransitionInteractor, private val deviceEntryUdfpsTouchOverlayViewModel: Lazy<DeviceEntryUdfpsTouchOverlayViewModel>, private val defaultUdfpsTouchOverlayViewModel: Lazy<DefaultUdfpsTouchOverlayViewModel>, private val shadeInteractor: ShadeInteractor, private val promptUdfpsTouchOverlayViewModel: Lazy<PromptUdfpsTouchOverlayViewModel>, private val udfpsOverlayInteractor: UdfpsOverlayInteractor, private val powerInteractor: PowerInteractor, @Application private val scope: CoroutineScope, Loading Loading @@ -170,20 +141,9 @@ constructor( private var touchExplorationEnabled = false private fun shouldRemoveEnrollmentUi(): Boolean { if (isDebuggable) { return Settings.Global.getInt( context.contentResolver, SETTING_REMOVE_ENROLLMENT_UI, 0, /* def */ ) != 0 } return false } /** Show the overlay or return false and do nothing if it is already showing. */ @SuppressLint("ClickableViewAccessibility") fun show(controller: UdfpsController, params: UdfpsOverlayParams): Boolean { fun show(params: UdfpsOverlayParams): Boolean { if (getTouchOverlay() == null) { overlayParams = params sensorBounds = Rect(params.sensorBounds) Loading @@ -206,6 +166,12 @@ constructor( viewModel = deviceEntryUdfpsTouchOverlayViewModel.get(), udfpsOverlayInteractor = udfpsOverlayInteractor, ) REASON_AUTH_BP -> UdfpsTouchOverlayBinder.bind( view = this, viewModel = promptUdfpsTouchOverlayViewModel.get(), udfpsOverlayInteractor = udfpsOverlayInteractor, ) else -> UdfpsTouchOverlayBinder.bind( view = this, Loading Loading @@ -340,7 +306,7 @@ constructor( val rot = overlayParams.rotation if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) { if (!shouldRotate(animation)) { if (!shouldRotate()) { Log.v( TAG, "Skip rotating UDFPS bounds " + Loading Loading @@ -375,7 +341,7 @@ constructor( return this } private fun shouldRotate(animation: UdfpsAnimationViewController<*>?): Boolean { private fun shouldRotate(): Boolean { if (!keyguardStateController.isShowing) { // always rotate view if we're not on the keyguard return true Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptUdfpsTouchOverlayViewModel.kt 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.viewmodel import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow class PromptUdfpsTouchOverlayViewModel @Inject constructor() : UdfpsTouchOverlayViewModel { // Biometric Prompt should always handle touches override val shouldHandleTouches: Flow<Boolean> = MutableStateFlow(true) }