Merge changes from topic "revert-20691780-cherrypick-modernize_alt_bouncer-2av1xvqe7q-EXOZAWOBTI"
* changes: Revert "Modernize alternate bouncer logic" Revert "Remove ScrimController from BiometricUnlockController"
This commit is contained in:
@@ -366,7 +366,7 @@ constructor(
|
||||
val dialog = animatedDialog.dialog
|
||||
|
||||
// Don't animate if the dialog is not showing or if we are locked and going to show the
|
||||
// primary bouncer.
|
||||
// bouncer.
|
||||
if (
|
||||
!dialog.isShowing ||
|
||||
(!callback.isUnlocked() && !callback.isShowingAlternateAuthOnUnlock())
|
||||
|
||||
@@ -691,13 +691,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
updateBiometricListeningState(BIOMETRIC_ACTION_STOP, FACE_AUTH_STOPPED_KEYGUARD_GOING_AWAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether keyguard is going away due to screen off or device entry.
|
||||
*/
|
||||
public boolean isKeyguardGoingAway() {
|
||||
return mKeyguardGoingAway;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates KeyguardUpdateMonitor's internal state to know if keyguard is showing and if
|
||||
* its occluded. The keyguard is considered visible if its showing and NOT occluded.
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.systemui.biometrics;
|
||||
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR;
|
||||
|
||||
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
|
||||
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
|
||||
@@ -80,7 +79,6 @@ import com.android.systemui.dagger.qualifiers.Background;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.doze.DozeReceiver;
|
||||
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
||||
import com.android.systemui.keyguard.data.repository.BiometricType;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.VibratorHelper;
|
||||
@@ -90,10 +88,8 @@ import com.android.systemui.util.concurrency.Execution;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -162,7 +158,6 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
@Nullable private List<FingerprintSensorPropertiesInternal> mUdfpsProps;
|
||||
@Nullable private List<FingerprintSensorPropertiesInternal> mSidefpsProps;
|
||||
|
||||
@NonNull private final Map<Integer, Boolean> mFpEnrolledForUser = new HashMap<>();
|
||||
@NonNull private final SparseBooleanArray mUdfpsEnrolledForUser;
|
||||
@NonNull private final SparseBooleanArray mFaceEnrolledForUser;
|
||||
@NonNull private final SparseBooleanArray mSfpsEnrolledForUser;
|
||||
@@ -175,6 +170,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
private final @Background DelayableExecutor mBackgroundExecutor;
|
||||
private final DisplayInfo mCachedDisplayInfo = new DisplayInfo();
|
||||
|
||||
|
||||
private final VibratorHelper mVibratorHelper;
|
||||
|
||||
private void vibrateSuccess(int modality) {
|
||||
@@ -352,21 +348,12 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
mExecution.assertIsMainThread();
|
||||
Log.d(TAG, "handleEnrollmentsChanged, userId: " + userId + ", sensorId: " + sensorId
|
||||
+ ", hasEnrollments: " + hasEnrollments);
|
||||
BiometricType sensorBiometricType = BiometricType.UNKNOWN;
|
||||
if (mFpProps != null) {
|
||||
for (FingerprintSensorPropertiesInternal prop: mFpProps) {
|
||||
if (mUdfpsProps == null) {
|
||||
Log.d(TAG, "handleEnrollmentsChanged, mUdfpsProps is null");
|
||||
} else {
|
||||
for (FingerprintSensorPropertiesInternal prop : mUdfpsProps) {
|
||||
if (prop.sensorId == sensorId) {
|
||||
mFpEnrolledForUser.put(userId, hasEnrollments);
|
||||
if (prop.isAnyUdfpsType()) {
|
||||
sensorBiometricType = BiometricType.UNDER_DISPLAY_FINGERPRINT;
|
||||
mUdfpsEnrolledForUser.put(userId, hasEnrollments);
|
||||
} else if (prop.isAnySidefpsType()) {
|
||||
sensorBiometricType = BiometricType.SIDE_FINGERPRINT;
|
||||
mSfpsEnrolledForUser.put(userId, hasEnrollments);
|
||||
} else if (prop.sensorType == TYPE_REAR) {
|
||||
sensorBiometricType = BiometricType.REAR_FINGERPRINT;
|
||||
}
|
||||
break;
|
||||
mUdfpsEnrolledForUser.put(userId, hasEnrollments);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -376,14 +363,20 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
for (FaceSensorPropertiesInternal prop : mFaceProps) {
|
||||
if (prop.sensorId == sensorId) {
|
||||
mFaceEnrolledForUser.put(userId, hasEnrollments);
|
||||
sensorBiometricType = BiometricType.FACE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mSidefpsProps == null) {
|
||||
Log.d(TAG, "handleEnrollmentsChanged, mSidefpsProps is null");
|
||||
} else {
|
||||
for (FingerprintSensorPropertiesInternal prop : mSidefpsProps) {
|
||||
if (prop.sensorId == sensorId) {
|
||||
mSfpsEnrolledForUser.put(userId, hasEnrollments);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Callback cb : mCallbacks) {
|
||||
cb.onEnrollmentsChanged(modality);
|
||||
cb.onEnrollmentsChanged(sensorBiometricType, userId, hasEnrollments);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -636,11 +629,6 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
}
|
||||
}
|
||||
|
||||
/** Get FP sensor properties */
|
||||
public @Nullable List<FingerprintSensorPropertiesInternal> getFingerprintProperties() {
|
||||
return mFpProps;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return where the face sensor exists in pixels in the current device orientation. Returns
|
||||
* null if no face sensor exists.
|
||||
@@ -893,7 +881,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiometricContextListener(IBiometricContextListener listener) {
|
||||
public void setBiometicContextListener(IBiometricContextListener listener) {
|
||||
mBiometricContextListener = listener;
|
||||
notifyDozeChanged(mStatusBarStateController.isDozing(),
|
||||
mWakefulnessLifecycle.getWakefulness());
|
||||
@@ -1152,13 +1140,6 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
return mCurrentDialog != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the passed userId has enrolled at least one fingerprint.
|
||||
*/
|
||||
public boolean isFingerprintEnrolled(int userId) {
|
||||
return mFpEnrolledForUser.getOrDefault(userId, false);
|
||||
}
|
||||
|
||||
private void showDialog(SomeArgs args, boolean skipAnimation, Bundle savedState) {
|
||||
mCurrentDialogArgs = args;
|
||||
|
||||
@@ -1341,16 +1322,6 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
|
||||
*/
|
||||
default void onEnrollmentsChanged(@Modality int modality) {}
|
||||
|
||||
/**
|
||||
* Called when UDFPS enrollments have changed. This is called after boot and on changes to
|
||||
* enrollment.
|
||||
*/
|
||||
default void onEnrollmentsChanged(
|
||||
@NonNull BiometricType biometricType,
|
||||
int userId,
|
||||
boolean hasEnrollments
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Called when the biometric prompt starts showing.
|
||||
*/
|
||||
|
||||
@@ -189,6 +189,11 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>(
|
||||
*/
|
||||
open fun listenForTouchesOutsideView(): Boolean = false
|
||||
|
||||
/**
|
||||
* Called on touches outside of the view if listenForTouchesOutsideView returns true
|
||||
*/
|
||||
open fun onTouchOutsideView() {}
|
||||
|
||||
/**
|
||||
* Called when a view should announce an accessibility event.
|
||||
*/
|
||||
|
||||
@@ -74,7 +74,6 @@ import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.flags.Flags;
|
||||
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
|
||||
import com.android.systemui.plugins.FalsingManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
@@ -151,7 +150,6 @@ public class UdfpsController implements DozeReceiver, Dumpable {
|
||||
@NonNull private final ActivityLaunchAnimator mActivityLaunchAnimator;
|
||||
@NonNull private final PrimaryBouncerInteractor mPrimaryBouncerInteractor;
|
||||
@Nullable private final TouchProcessor mTouchProcessor;
|
||||
@NonNull private final AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
|
||||
// Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
|
||||
// sensors, this, in addition to a lot of the code here, will be updated.
|
||||
@@ -239,12 +237,12 @@ public class UdfpsController implements DozeReceiver, Dumpable {
|
||||
mShadeExpansionStateManager, mKeyguardViewManager,
|
||||
mKeyguardUpdateMonitor, mDialogManager, mDumpManager,
|
||||
mLockscreenShadeTransitionController, mConfigurationController,
|
||||
mKeyguardStateController,
|
||||
mSystemClock, mKeyguardStateController,
|
||||
mUnlockedScreenOffAnimationController,
|
||||
mUdfpsDisplayMode, requestId, reason, callback,
|
||||
(view, event, fromUdfpsView) -> onTouch(requestId, event,
|
||||
fromUdfpsView), mActivityLaunchAnimator, mFeatureFlags,
|
||||
mPrimaryBouncerInteractor, mAlternateBouncerInteractor)));
|
||||
mPrimaryBouncerInteractor)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -363,13 +361,13 @@ public class UdfpsController implements DozeReceiver, Dumpable {
|
||||
if (!mOverlayParams.equals(overlayParams)) {
|
||||
mOverlayParams = overlayParams;
|
||||
|
||||
final boolean wasShowingAlternateBouncer = mAlternateBouncerInteractor.isVisibleState();
|
||||
final boolean wasShowingAltAuth = mKeyguardViewManager.isShowingAlternateBouncer();
|
||||
|
||||
// When the bounds change it's always necessary to re-create the overlay's window with
|
||||
// new LayoutParams. If the overlay needs to be shown, this will re-create and show the
|
||||
// overlay with the updated LayoutParams. Otherwise, the overlay will remain hidden.
|
||||
redrawOverlay();
|
||||
if (wasShowingAlternateBouncer) {
|
||||
if (wasShowingAltAuth) {
|
||||
mKeyguardViewManager.showBouncer(true);
|
||||
}
|
||||
}
|
||||
@@ -577,6 +575,9 @@ public class UdfpsController implements DozeReceiver, Dumpable {
|
||||
final UdfpsView udfpsView = mOverlay.getOverlayView();
|
||||
boolean handled = false;
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_OUTSIDE:
|
||||
udfpsView.onTouchOutsideView();
|
||||
return true;
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_HOVER_ENTER:
|
||||
Trace.beginSection("UdfpsController.onTouch.ACTION_DOWN");
|
||||
@@ -750,8 +751,7 @@ public class UdfpsController implements DozeReceiver, Dumpable {
|
||||
@NonNull Optional<Provider<AlternateUdfpsTouchProvider>> alternateTouchProvider,
|
||||
@NonNull @BiometricsBackground Executor biometricsExecutor,
|
||||
@NonNull PrimaryBouncerInteractor primaryBouncerInteractor,
|
||||
@NonNull SinglePointerTouchProcessor singlePointerTouchProcessor,
|
||||
@NonNull AlternateBouncerInteractor alternateBouncerInteractor) {
|
||||
@NonNull SinglePointerTouchProcessor singlePointerTouchProcessor) {
|
||||
mContext = context;
|
||||
mExecution = execution;
|
||||
mVibrator = vibrator;
|
||||
@@ -791,7 +791,6 @@ public class UdfpsController implements DozeReceiver, Dumpable {
|
||||
|
||||
mBiometricExecutor = biometricsExecutor;
|
||||
mPrimaryBouncerInteractor = primaryBouncerInteractor;
|
||||
mAlternateBouncerInteractor = alternateBouncerInteractor;
|
||||
|
||||
mTouchProcessor = mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)
|
||||
? singlePointerTouchProcessor : null;
|
||||
@@ -886,7 +885,9 @@ public class UdfpsController implements DozeReceiver, Dumpable {
|
||||
onFingerUp(mOverlay.getRequestId(), oldView);
|
||||
}
|
||||
final boolean removed = mOverlay.hide();
|
||||
mKeyguardViewManager.hideAlternateBouncer(true);
|
||||
if (mKeyguardViewManager.isShowingAlternateBouncer()) {
|
||||
mKeyguardViewManager.hideAlternateBouncer(true);
|
||||
}
|
||||
Log.v(TAG, "hideUdfpsOverlay | removing window: " + removed);
|
||||
} else {
|
||||
Log.v(TAG, "hideUdfpsOverlay | the overlay is already hidden");
|
||||
|
||||
@@ -50,7 +50,6 @@ import com.android.systemui.animation.ActivityLaunchAnimator
|
||||
import com.android.systemui.dump.DumpManager
|
||||
import com.android.systemui.flags.FeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||
import com.android.systemui.shade.ShadeExpansionStateManager
|
||||
@@ -60,6 +59,7 @@ 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.util.time.SystemClock
|
||||
|
||||
private const val TAG = "UdfpsControllerOverlay"
|
||||
|
||||
@@ -86,6 +86,7 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
|
||||
private val dumpManager: DumpManager,
|
||||
private val transitionController: LockscreenShadeTransitionController,
|
||||
private val configurationController: ConfigurationController,
|
||||
private val systemClock: SystemClock,
|
||||
private val keyguardStateController: KeyguardStateController,
|
||||
private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController,
|
||||
private var udfpsDisplayModeProvider: UdfpsDisplayModeProvider,
|
||||
@@ -96,8 +97,7 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
|
||||
private val activityLaunchAnimator: ActivityLaunchAnimator,
|
||||
private val featureFlags: FeatureFlags,
|
||||
private val primaryBouncerInteractor: PrimaryBouncerInteractor,
|
||||
private val alternateBouncerInteractor: AlternateBouncerInteractor,
|
||||
private val isDebuggable: Boolean = Build.IS_DEBUGGABLE,
|
||||
private val isDebuggable: Boolean = Build.IS_DEBUGGABLE
|
||||
) {
|
||||
/** The view, when [isShowing], or null. */
|
||||
var overlayView: UdfpsView? = null
|
||||
@@ -255,14 +255,14 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
|
||||
dumpManager,
|
||||
transitionController,
|
||||
configurationController,
|
||||
systemClock,
|
||||
keyguardStateController,
|
||||
unlockedScreenOffAnimationController,
|
||||
dialogManager,
|
||||
controller,
|
||||
activityLaunchAnimator,
|
||||
featureFlags,
|
||||
primaryBouncerInteractor,
|
||||
alternateBouncerInteractor,
|
||||
primaryBouncerInteractor
|
||||
)
|
||||
}
|
||||
REASON_AUTH_BP -> {
|
||||
|
||||
@@ -31,7 +31,6 @@ import com.android.systemui.animation.Interpolators
|
||||
import com.android.systemui.dump.DumpManager
|
||||
import com.android.systemui.flags.FeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
|
||||
import com.android.systemui.lifecycle.repeatWhenAttached
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||
@@ -43,13 +42,13 @@ import com.android.systemui.statusbar.notification.stack.StackStateAnimator
|
||||
import com.android.systemui.statusbar.phone.KeyguardBouncer
|
||||
import com.android.systemui.statusbar.phone.KeyguardBouncer.PrimaryBouncerExpansionCallback
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager.AlternateBouncer
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager.KeyguardViewManagerCallback
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager.LegacyAlternateBouncer
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager.OccludingAppBiometricUI
|
||||
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.util.time.SystemClock
|
||||
import java.io.PrintWriter
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
@@ -66,27 +65,25 @@ constructor(
|
||||
dumpManager: DumpManager,
|
||||
private val lockScreenShadeTransitionController: LockscreenShadeTransitionController,
|
||||
private val configurationController: ConfigurationController,
|
||||
private val systemClock: SystemClock,
|
||||
private val keyguardStateController: KeyguardStateController,
|
||||
private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController,
|
||||
systemUIDialogManager: SystemUIDialogManager,
|
||||
private val udfpsController: UdfpsController,
|
||||
private val activityLaunchAnimator: ActivityLaunchAnimator,
|
||||
featureFlags: FeatureFlags,
|
||||
private val primaryBouncerInteractor: PrimaryBouncerInteractor,
|
||||
private val alternateBouncerInteractor: AlternateBouncerInteractor,
|
||||
private val primaryBouncerInteractor: PrimaryBouncerInteractor
|
||||
) :
|
||||
UdfpsAnimationViewController<UdfpsKeyguardView>(
|
||||
view,
|
||||
statusBarStateController,
|
||||
shadeExpansionStateManager,
|
||||
systemUIDialogManager,
|
||||
dumpManager,
|
||||
dumpManager
|
||||
) {
|
||||
private val useExpandedOverlay: Boolean =
|
||||
featureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)
|
||||
private val isModernBouncerEnabled: Boolean = featureFlags.isEnabled(Flags.MODERN_BOUNCER)
|
||||
private val isModernAlternateBouncerEnabled: Boolean =
|
||||
featureFlags.isEnabled(Flags.MODERN_ALTERNATE_BOUNCER)
|
||||
private var showingUdfpsBouncer = false
|
||||
private var udfpsRequested = false
|
||||
private var qsExpansion = 0f
|
||||
@@ -94,6 +91,7 @@ constructor(
|
||||
private var statusBarState = 0
|
||||
private var transitionToFullShadeProgress = 0f
|
||||
private var lastDozeAmount = 0f
|
||||
private var lastUdfpsBouncerShowTime: Long = -1
|
||||
private var panelExpansionFraction = 0f
|
||||
private var launchTransitionFadingAway = false
|
||||
private var isLaunchingActivity = false
|
||||
@@ -246,8 +244,20 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private val occludingAppBiometricUI: OccludingAppBiometricUI =
|
||||
object : OccludingAppBiometricUI {
|
||||
private val mAlternateBouncer: AlternateBouncer =
|
||||
object : AlternateBouncer {
|
||||
override fun showAlternateBouncer(): Boolean {
|
||||
return showUdfpsBouncer(true)
|
||||
}
|
||||
|
||||
override fun hideAlternateBouncer(): Boolean {
|
||||
return showUdfpsBouncer(false)
|
||||
}
|
||||
|
||||
override fun isShowingAlternateBouncer(): Boolean {
|
||||
return showingUdfpsBouncer
|
||||
}
|
||||
|
||||
override fun requestUdfps(request: Boolean, color: Int) {
|
||||
udfpsRequested = request
|
||||
view.requestUdfps(request, color)
|
||||
@@ -265,19 +275,16 @@ constructor(
|
||||
|
||||
override fun onInit() {
|
||||
super.onInit()
|
||||
keyguardViewManager.setOccludingAppBiometricUI(occludingAppBiometricUI)
|
||||
keyguardViewManager.setAlternateBouncer(mAlternateBouncer)
|
||||
}
|
||||
|
||||
init {
|
||||
if (isModernBouncerEnabled || isModernAlternateBouncerEnabled) {
|
||||
if (isModernBouncerEnabled) {
|
||||
view.repeatWhenAttached {
|
||||
// repeatOnLifecycle CREATED (as opposed to STARTED) because the Bouncer expansion
|
||||
// can make the view not visible; and we still want to listen for events
|
||||
// that may make the view visible again.
|
||||
repeatOnLifecycle(Lifecycle.State.CREATED) {
|
||||
if (isModernBouncerEnabled) listenForBouncerExpansion(this)
|
||||
if (isModernAlternateBouncerEnabled) listenForAlternateBouncerVisibility(this)
|
||||
}
|
||||
repeatOnLifecycle(Lifecycle.State.CREATED) { listenForBouncerExpansion(this) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,18 +300,8 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
internal suspend fun listenForAlternateBouncerVisibility(scope: CoroutineScope): Job {
|
||||
return scope.launch {
|
||||
alternateBouncerInteractor.isVisible.collect { isVisible: Boolean ->
|
||||
showUdfpsBouncer(isVisible)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override fun onViewAttached() {
|
||||
super.onViewAttached()
|
||||
alternateBouncerInteractor.setAlternateBouncerUIAvailable(true)
|
||||
val dozeAmount = statusBarStateController.dozeAmount
|
||||
lastDozeAmount = dozeAmount
|
||||
stateListener.onDozeAmountChanged(dozeAmount, dozeAmount)
|
||||
@@ -329,8 +326,7 @@ constructor(
|
||||
view.updatePadding()
|
||||
updateAlpha()
|
||||
updatePauseAuth()
|
||||
keyguardViewManager.setLegacyAlternateBouncer(legacyAlternateBouncer)
|
||||
keyguardViewManager.setOccludingAppBiometricUI(occludingAppBiometricUI)
|
||||
keyguardViewManager.setAlternateBouncer(mAlternateBouncer)
|
||||
lockScreenShadeTransitionController.udfpsKeyguardViewController = this
|
||||
activityLaunchAnimator.addListener(activityLaunchAnimatorListener)
|
||||
view.mUseExpandedOverlay = useExpandedOverlay
|
||||
@@ -338,12 +334,10 @@ constructor(
|
||||
|
||||
override fun onViewDetached() {
|
||||
super.onViewDetached()
|
||||
alternateBouncerInteractor.setAlternateBouncerUIAvailable(false)
|
||||
faceDetectRunning = false
|
||||
keyguardStateController.removeCallback(keyguardStateControllerCallback)
|
||||
statusBarStateController.removeCallback(stateListener)
|
||||
keyguardViewManager.removeLegacyAlternateBouncer(legacyAlternateBouncer)
|
||||
keyguardViewManager.removeOccludingAppBiometricUI(occludingAppBiometricUI)
|
||||
keyguardViewManager.removeAlternateAuthInterceptor(mAlternateBouncer)
|
||||
keyguardUpdateMonitor.requestFaceAuthOnOccludingApp(false)
|
||||
configurationController.removeCallback(configurationListener)
|
||||
shadeExpansionStateManager.removeExpansionListener(shadeExpansionListener)
|
||||
@@ -362,16 +356,7 @@ constructor(
|
||||
override fun dump(pw: PrintWriter, args: Array<String>) {
|
||||
super.dump(pw, args)
|
||||
pw.println("isModernBouncerEnabled=$isModernBouncerEnabled")
|
||||
pw.println("isModernAlternateBouncerEnabled=$isModernAlternateBouncerEnabled")
|
||||
pw.println("showingUdfpsAltBouncer=$showingUdfpsBouncer")
|
||||
pw.println(
|
||||
"altBouncerInteractor#isAlternateBouncerVisible=" +
|
||||
"${alternateBouncerInteractor.isVisibleState()}"
|
||||
)
|
||||
pw.println(
|
||||
"altBouncerInteractor#canShowAlternateBouncerForFingerprint=" +
|
||||
"${alternateBouncerInteractor.canShowAlternateBouncerForFingerprint()}"
|
||||
)
|
||||
pw.println("faceDetectRunning=$faceDetectRunning")
|
||||
pw.println("statusBarState=" + StatusBarState.toString(statusBarState))
|
||||
pw.println("transitionToFullShadeProgress=$transitionToFullShadeProgress")
|
||||
@@ -399,6 +384,9 @@ constructor(
|
||||
}
|
||||
val udfpsAffordanceWasNotShowing = shouldPauseAuth()
|
||||
showingUdfpsBouncer = show
|
||||
if (showingUdfpsBouncer) {
|
||||
lastUdfpsBouncerShowTime = systemClock.uptimeMillis()
|
||||
}
|
||||
if (showingUdfpsBouncer) {
|
||||
if (udfpsAffordanceWasNotShowing) {
|
||||
view.animateInUdfpsBouncer(null)
|
||||
@@ -464,7 +452,7 @@ constructor(
|
||||
return if (isModernBouncerEnabled) {
|
||||
inputBouncerExpansion == 1f
|
||||
} else {
|
||||
keyguardViewManager.isBouncerShowing && !alternateBouncerInteractor.isVisibleState()
|
||||
keyguardViewManager.isBouncerShowing && !keyguardViewManager.isShowingAlternateBouncer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,6 +460,30 @@ constructor(
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onTouchOutsideView() {
|
||||
maybeShowInputBouncer()
|
||||
}
|
||||
|
||||
/**
|
||||
* If we were previously showing the udfps bouncer, hide it and instead show the regular
|
||||
* (pin/pattern/password) bouncer.
|
||||
*
|
||||
* Does nothing if we weren't previously showing the UDFPS bouncer.
|
||||
*/
|
||||
private fun maybeShowInputBouncer() {
|
||||
if (showingUdfpsBouncer && hasUdfpsBouncerShownWithMinTime()) {
|
||||
keyguardViewManager.showPrimaryBouncer(true)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the udfps bouncer has shown for at least 200ms before allowing touches outside of the
|
||||
* udfps icon area to dismiss the udfps bouncer and show the pin/pattern/password bouncer.
|
||||
*/
|
||||
private fun hasUdfpsBouncerShownWithMinTime(): Boolean {
|
||||
return systemClock.uptimeMillis() - lastUdfpsBouncerShowTime > 200
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the progress we're currently transitioning to the full shade. 0.0f means we're not
|
||||
* transitioning yet, while 1.0f means we've fully dragged down. For example, start swiping down
|
||||
@@ -533,7 +545,7 @@ constructor(
|
||||
if (isModernBouncerEnabled) {
|
||||
return
|
||||
}
|
||||
val altBouncerShowing = alternateBouncerInteractor.isVisibleState()
|
||||
val altBouncerShowing = keyguardViewManager.isShowingAlternateBouncer
|
||||
if (altBouncerShowing || !keyguardViewManager.primaryBouncerIsOrWillBeShowing()) {
|
||||
inputBouncerHiddenAmount = 1f
|
||||
} else if (keyguardViewManager.isBouncerShowing) {
|
||||
@@ -542,21 +554,6 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private val legacyAlternateBouncer: LegacyAlternateBouncer =
|
||||
object : LegacyAlternateBouncer {
|
||||
override fun showAlternateBouncer(): Boolean {
|
||||
return showUdfpsBouncer(true)
|
||||
}
|
||||
|
||||
override fun hideAlternateBouncer(): Boolean {
|
||||
return showUdfpsBouncer(false)
|
||||
}
|
||||
|
||||
override fun isShowingAlternateBouncer(): Boolean {
|
||||
return showingUdfpsBouncer
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = "UdfpsKeyguardViewController"
|
||||
}
|
||||
|
||||
@@ -111,6 +111,10 @@ class UdfpsView(
|
||||
}
|
||||
}
|
||||
|
||||
fun onTouchOutsideView() {
|
||||
animationViewController?.onTouchOutsideView()
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
Log.v(TAG, "onAttachedToWindow")
|
||||
|
||||
@@ -175,13 +175,6 @@ object Flags {
|
||||
@JvmField
|
||||
val LIGHT_REVEAL_MIGRATION = unreleasedFlag(218, "light_reveal_migration", teamfood = true)
|
||||
|
||||
/**
|
||||
* Whether to use the new alternate bouncer architecture, a refactor of and eventual replacement
|
||||
* of the Alternate/Authentication Bouncer. No visual UI changes.
|
||||
*/
|
||||
// TODO(b/260619425): Tracking Bug
|
||||
@JvmField val MODERN_ALTERNATE_BOUNCER = unreleasedFlag(219, "modern_alternate_bouncer")
|
||||
|
||||
// 300 - power menu
|
||||
// TODO(b/254512600): Tracking Bug
|
||||
@JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite")
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.keyguard.data.repository
|
||||
|
||||
import android.app.admin.DevicePolicyManager
|
||||
import android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
|
||||
import android.content.Context
|
||||
import android.content.IntentFilter
|
||||
import android.os.Looper
|
||||
import android.os.UserHandle
|
||||
import com.android.internal.widget.LockPatternUtils
|
||||
import com.android.systemui.biometrics.AuthController
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher
|
||||
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
|
||||
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.dagger.qualifiers.Background
|
||||
import com.android.systemui.dagger.qualifiers.Main
|
||||
import com.android.systemui.user.data.repository.UserRepository
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.transformLatest
|
||||
|
||||
/**
|
||||
* Acts as source of truth for biometric features.
|
||||
*
|
||||
* Abstracts-away data sources and their schemas so the rest of the app doesn't need to worry about
|
||||
* upstream changes.
|
||||
*/
|
||||
interface BiometricRepository {
|
||||
/** Whether any fingerprints are enrolled for the current user. */
|
||||
val isFingerprintEnrolled: StateFlow<Boolean>
|
||||
|
||||
/**
|
||||
* Whether the current user is allowed to use a strong biometric for device entry based on
|
||||
* Android Security policies. If false, the user may be able to use primary authentication for
|
||||
* device entry.
|
||||
*/
|
||||
val isStrongBiometricAllowed: StateFlow<Boolean>
|
||||
|
||||
/** Whether fingerprint feature is enabled for the current user by the DevicePolicy */
|
||||
val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean>
|
||||
}
|
||||
|
||||
@SysUISingleton
|
||||
class BiometricRepositoryImpl
|
||||
@Inject
|
||||
constructor(
|
||||
context: Context,
|
||||
lockPatternUtils: LockPatternUtils,
|
||||
broadcastDispatcher: BroadcastDispatcher,
|
||||
authController: AuthController,
|
||||
userRepository: UserRepository,
|
||||
devicePolicyManager: DevicePolicyManager,
|
||||
@Application scope: CoroutineScope,
|
||||
@Background backgroundDispatcher: CoroutineDispatcher,
|
||||
@Main looper: Looper,
|
||||
) : BiometricRepository {
|
||||
|
||||
/** UserId of the current selected user. */
|
||||
private val selectedUserId: Flow<Int> =
|
||||
userRepository.selectedUserInfo.map { it.id }.distinctUntilChanged()
|
||||
|
||||
override val isFingerprintEnrolled: StateFlow<Boolean> =
|
||||
selectedUserId
|
||||
.flatMapLatest { userId ->
|
||||
conflatedCallbackFlow {
|
||||
val callback =
|
||||
object : AuthController.Callback {
|
||||
override fun onEnrollmentsChanged(
|
||||
sensorBiometricType: BiometricType,
|
||||
userId: Int,
|
||||
hasEnrollments: Boolean
|
||||
) {
|
||||
if (sensorBiometricType.isFingerprint) {
|
||||
trySendWithFailureLogging(
|
||||
hasEnrollments,
|
||||
TAG,
|
||||
"update fpEnrollment"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
authController.addCallback(callback)
|
||||
awaitClose { authController.removeCallback(callback) }
|
||||
}
|
||||
}
|
||||
.stateIn(
|
||||
scope,
|
||||
started = SharingStarted.Eagerly,
|
||||
initialValue =
|
||||
authController.isFingerprintEnrolled(userRepository.getSelectedUserInfo().id)
|
||||
)
|
||||
|
||||
override val isStrongBiometricAllowed: StateFlow<Boolean> =
|
||||
selectedUserId
|
||||
.flatMapLatest { currUserId ->
|
||||
conflatedCallbackFlow {
|
||||
val callback =
|
||||
object : LockPatternUtils.StrongAuthTracker(context, looper) {
|
||||
override fun onStrongAuthRequiredChanged(userId: Int) {
|
||||
if (currUserId != userId) {
|
||||
return
|
||||
}
|
||||
|
||||
trySendWithFailureLogging(
|
||||
isBiometricAllowedForUser(true, currUserId),
|
||||
TAG
|
||||
)
|
||||
}
|
||||
|
||||
override fun onIsNonStrongBiometricAllowedChanged(userId: Int) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
lockPatternUtils.registerStrongAuthTracker(callback)
|
||||
awaitClose { lockPatternUtils.unregisterStrongAuthTracker(callback) }
|
||||
}
|
||||
}
|
||||
.stateIn(
|
||||
scope,
|
||||
started = SharingStarted.Eagerly,
|
||||
initialValue =
|
||||
lockPatternUtils.isBiometricAllowedForUser(
|
||||
userRepository.getSelectedUserInfo().id
|
||||
)
|
||||
)
|
||||
|
||||
override val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean> =
|
||||
selectedUserId
|
||||
.flatMapLatest { userId ->
|
||||
broadcastDispatcher
|
||||
.broadcastFlow(
|
||||
filter = IntentFilter(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
|
||||
user = UserHandle.ALL
|
||||
)
|
||||
.transformLatest {
|
||||
emit(
|
||||
(devicePolicyManager.getKeyguardDisabledFeatures(null, userId) and
|
||||
DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) == 0
|
||||
)
|
||||
}
|
||||
.flowOn(backgroundDispatcher)
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
.stateIn(
|
||||
scope,
|
||||
started = SharingStarted.Eagerly,
|
||||
initialValue =
|
||||
devicePolicyManager.getKeyguardDisabledFeatures(
|
||||
null,
|
||||
userRepository.getSelectedUserInfo().id
|
||||
) and DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT == 0
|
||||
)
|
||||
|
||||
companion object {
|
||||
private const val TAG = "BiometricsRepositoryImpl"
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.keyguard.data.repository
|
||||
|
||||
enum class BiometricType(val isFingerprint: Boolean) {
|
||||
// An unsupported biometric type
|
||||
UNKNOWN(false),
|
||||
|
||||
// Fingerprint sensor that is located on the back (opposite side of the display) of the device
|
||||
REAR_FINGERPRINT(true),
|
||||
|
||||
// Fingerprint sensor that is located under the display
|
||||
UNDER_DISPLAY_FINGERPRINT(true),
|
||||
|
||||
// Fingerprint sensor that is located on the side of the device, typically on the power button
|
||||
SIDE_FINGERPRINT(true),
|
||||
FACE(false),
|
||||
}
|
||||
@@ -16,15 +16,14 @@
|
||||
|
||||
package com.android.systemui.keyguard.data.repository
|
||||
|
||||
import com.android.keyguard.KeyguardUpdateMonitor
|
||||
import com.android.keyguard.ViewMediatorCallback
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
|
||||
import com.android.systemui.keyguard.shared.model.KeyguardBouncerModel
|
||||
import com.android.systemui.statusbar.phone.KeyguardBouncer
|
||||
import com.android.systemui.util.time.SystemClock
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
/** Encapsulates app state for the lock screen primary and alternate bouncer. */
|
||||
@@ -33,7 +32,7 @@ class KeyguardBouncerRepository
|
||||
@Inject
|
||||
constructor(
|
||||
private val viewMediatorCallback: ViewMediatorCallback,
|
||||
private val clock: SystemClock,
|
||||
keyguardUpdateMonitor: KeyguardUpdateMonitor,
|
||||
) {
|
||||
/** Values associated with the PrimaryBouncer (pin/pattern/password) input. */
|
||||
private val _primaryBouncerVisible = MutableStateFlow(false)
|
||||
@@ -78,14 +77,6 @@ constructor(
|
||||
val bouncerErrorMessage: CharSequence?
|
||||
get() = viewMediatorCallback.consumeCustomMessage()
|
||||
|
||||
/** Values associated with the AlternateBouncer */
|
||||
private val _isAlternateBouncerVisible = MutableStateFlow(false)
|
||||
val isAlternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow()
|
||||
var lastAlternateBouncerVisibleTime: Long = NOT_VISIBLE
|
||||
private val _isAlternateBouncerUIAvailable = MutableStateFlow<Boolean>(false)
|
||||
val isAlternateBouncerUIAvailable: StateFlow<Boolean> =
|
||||
_isAlternateBouncerUIAvailable.asStateFlow()
|
||||
|
||||
fun setPrimaryScrimmed(isScrimmed: Boolean) {
|
||||
_primaryBouncerScrimmed.value = isScrimmed
|
||||
}
|
||||
@@ -94,19 +85,6 @@ constructor(
|
||||
_primaryBouncerVisible.value = isVisible
|
||||
}
|
||||
|
||||
fun setAlternateVisible(isVisible: Boolean) {
|
||||
if (isVisible && !_isAlternateBouncerVisible.value) {
|
||||
lastAlternateBouncerVisibleTime = clock.uptimeMillis()
|
||||
} else if (!isVisible) {
|
||||
lastAlternateBouncerVisibleTime = NOT_VISIBLE
|
||||
}
|
||||
_isAlternateBouncerVisible.value = isVisible
|
||||
}
|
||||
|
||||
fun setAlternateBouncerUIAvailable(isAvailable: Boolean) {
|
||||
_isAlternateBouncerUIAvailable.value = isAvailable
|
||||
}
|
||||
|
||||
fun setPrimaryShow(keyguardBouncerModel: KeyguardBouncerModel?) {
|
||||
_primaryBouncerShow.value = keyguardBouncerModel
|
||||
}
|
||||
@@ -154,8 +132,4 @@ constructor(
|
||||
fun setOnScreenTurnedOff(onScreenTurnedOff: Boolean) {
|
||||
_onScreenTurnedOff.value = onScreenTurnedOff
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val NOT_VISIBLE = -1L
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,4 @@ interface KeyguardRepositoryModule {
|
||||
|
||||
@Binds
|
||||
fun lightRevealScrimRepository(impl: LightRevealScrimRepositoryImpl): LightRevealScrimRepository
|
||||
|
||||
@Binds fun biometricRepository(impl: BiometricRepositoryImpl): BiometricRepository
|
||||
}
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.keyguard.domain.interactor
|
||||
|
||||
import com.android.keyguard.KeyguardUpdateMonitor
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.flags.FeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.keyguard.data.repository.BiometricRepository
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager.LegacyAlternateBouncer
|
||||
import com.android.systemui.util.time.SystemClock
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/** Encapsulates business logic for interacting with the lock-screen alternate bouncer. */
|
||||
@SysUISingleton
|
||||
class AlternateBouncerInteractor
|
||||
@Inject
|
||||
constructor(
|
||||
private val bouncerRepository: KeyguardBouncerRepository,
|
||||
private val biometricRepository: BiometricRepository,
|
||||
private val systemClock: SystemClock,
|
||||
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
|
||||
featureFlags: FeatureFlags,
|
||||
) {
|
||||
val isModernAlternateBouncerEnabled = featureFlags.isEnabled(Flags.MODERN_ALTERNATE_BOUNCER)
|
||||
var legacyAlternateBouncer: LegacyAlternateBouncer? = null
|
||||
var legacyAlternateBouncerVisibleTime: Long = NOT_VISIBLE
|
||||
|
||||
val isVisible: Flow<Boolean> = bouncerRepository.isAlternateBouncerVisible
|
||||
|
||||
/**
|
||||
* Sets the correct bouncer states to show the alternate bouncer if it can show.
|
||||
* @return whether alternateBouncer is visible
|
||||
*/
|
||||
fun show(): Boolean {
|
||||
return when {
|
||||
isModernAlternateBouncerEnabled -> {
|
||||
bouncerRepository.setAlternateVisible(canShowAlternateBouncerForFingerprint())
|
||||
isVisibleState()
|
||||
}
|
||||
canShowAlternateBouncerForFingerprint() -> {
|
||||
if (legacyAlternateBouncer?.showAlternateBouncer() == true) {
|
||||
legacyAlternateBouncerVisibleTime = systemClock.uptimeMillis()
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the correct bouncer states to hide the bouncer. Should only be called through
|
||||
* StatusBarKeyguardViewManager until ScrimController is refactored to use
|
||||
* alternateBouncerInteractor.
|
||||
* @return true if the alternate bouncer was newly hidden, else false.
|
||||
*/
|
||||
fun hide(): Boolean {
|
||||
return if (isModernAlternateBouncerEnabled) {
|
||||
val wasAlternateBouncerVisible = isVisibleState()
|
||||
bouncerRepository.setAlternateVisible(false)
|
||||
wasAlternateBouncerVisible && !isVisibleState()
|
||||
} else {
|
||||
legacyAlternateBouncer?.hideAlternateBouncer() ?: false
|
||||
}
|
||||
}
|
||||
|
||||
fun isVisibleState(): Boolean {
|
||||
return if (isModernAlternateBouncerEnabled) {
|
||||
bouncerRepository.isAlternateBouncerVisible.value
|
||||
} else {
|
||||
legacyAlternateBouncer?.isShowingAlternateBouncer ?: false
|
||||
}
|
||||
}
|
||||
|
||||
fun setAlternateBouncerUIAvailable(isAvailable: Boolean) {
|
||||
bouncerRepository.setAlternateBouncerUIAvailable(isAvailable)
|
||||
}
|
||||
|
||||
fun canShowAlternateBouncerForFingerprint(): Boolean {
|
||||
return if (isModernAlternateBouncerEnabled) {
|
||||
bouncerRepository.isAlternateBouncerUIAvailable.value &&
|
||||
biometricRepository.isFingerprintEnrolled.value &&
|
||||
biometricRepository.isStrongBiometricAllowed.value &&
|
||||
biometricRepository.isFingerprintEnabledByDevicePolicy.value
|
||||
} else {
|
||||
legacyAlternateBouncer != null &&
|
||||
keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(true)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the alt bouncer has shown for a minimum time before allowing touches to dismiss the
|
||||
* alternate bouncer and show the primary bouncer.
|
||||
*/
|
||||
fun hasAlternateBouncerShownWithMinTime(): Boolean {
|
||||
return if (isModernAlternateBouncerEnabled) {
|
||||
(systemClock.uptimeMillis() - bouncerRepository.lastAlternateBouncerVisibleTime) >
|
||||
MIN_VISIBILITY_DURATION_UNTIL_TOUCHES_DISMISS_ALTERNATE_BOUNCER_MS
|
||||
} else {
|
||||
systemClock.uptimeMillis() - legacyAlternateBouncerVisibleTime > 200
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val MIN_VISIBILITY_DURATION_UNTIL_TOUCHES_DISMISS_ALTERNATE_BOUNCER_MS = 200L
|
||||
private const val NOT_VISIBLE = -1L
|
||||
}
|
||||
}
|
||||
@@ -136,7 +136,6 @@ import com.android.systemui.flags.Flags;
|
||||
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
|
||||
import com.android.systemui.fragments.FragmentService;
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor;
|
||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
|
||||
import com.android.systemui.media.controls.pipeline.MediaDataManager;
|
||||
@@ -352,7 +351,6 @@ public final class NotificationPanelViewController implements Dumpable {
|
||||
private final FragmentListener mQsFragmentListener = new QsFragmentListener();
|
||||
private final AccessibilityDelegate mAccessibilityDelegate = new ShadeAccessibilityDelegate();
|
||||
private final NotificationGutsManager mGutsManager;
|
||||
private final AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
|
||||
private long mDownTime;
|
||||
private boolean mTouchSlopExceededBeforeDown;
|
||||
@@ -759,7 +757,6 @@ public final class NotificationPanelViewController implements Dumpable {
|
||||
SystemClock systemClock,
|
||||
KeyguardBottomAreaViewModel keyguardBottomAreaViewModel,
|
||||
KeyguardBottomAreaInteractor keyguardBottomAreaInteractor,
|
||||
AlternateBouncerInteractor alternateBouncerInteractor,
|
||||
DumpManager dumpManager) {
|
||||
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
|
||||
@Override
|
||||
@@ -940,7 +937,6 @@ public final class NotificationPanelViewController implements Dumpable {
|
||||
unlockAnimationStarted(playingCannedAnimation, isWakeAndUnlock, startDelay);
|
||||
}
|
||||
});
|
||||
mAlternateBouncerInteractor = alternateBouncerInteractor;
|
||||
dumpManager.registerDumpable(this);
|
||||
}
|
||||
|
||||
@@ -4814,7 +4810,7 @@ public final class NotificationPanelViewController implements Dumpable {
|
||||
mUpdateFlingVelocity = vel;
|
||||
}
|
||||
} else if (!mCentralSurfaces.isBouncerShowing()
|
||||
&& !mAlternateBouncerInteractor.isVisibleState()
|
||||
&& !mStatusBarKeyguardViewManager.isShowingAlternateBouncer()
|
||||
&& !mKeyguardStateController.isKeyguardGoingAway()) {
|
||||
onEmptySpaceClick();
|
||||
onTrackingStopped(true);
|
||||
|
||||
@@ -38,7 +38,6 @@ import com.android.systemui.dock.DockManager;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.flags.Flags;
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.keyguard.ui.binder.KeyguardBouncerViewBinder;
|
||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
|
||||
import com.android.systemui.statusbar.DragDownHelper;
|
||||
@@ -79,7 +78,6 @@ public class NotificationShadeWindowViewController {
|
||||
private final AmbientState mAmbientState;
|
||||
private final PulsingGestureListener mPulsingGestureListener;
|
||||
private final NotificationInsetsController mNotificationInsetsController;
|
||||
private final AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
|
||||
private GestureDetector mPulsingWakeupGestureHandler;
|
||||
private View mBrightnessMirror;
|
||||
@@ -120,8 +118,7 @@ public class NotificationShadeWindowViewController {
|
||||
PulsingGestureListener pulsingGestureListener,
|
||||
FeatureFlags featureFlags,
|
||||
KeyguardBouncerViewModel keyguardBouncerViewModel,
|
||||
KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory,
|
||||
AlternateBouncerInteractor alternateBouncerInteractor
|
||||
KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory
|
||||
) {
|
||||
mLockscreenShadeTransitionController = transitionController;
|
||||
mFalsingCollector = falsingCollector;
|
||||
@@ -141,7 +138,6 @@ public class NotificationShadeWindowViewController {
|
||||
mAmbientState = ambientState;
|
||||
mPulsingGestureListener = pulsingGestureListener;
|
||||
mNotificationInsetsController = notificationInsetsController;
|
||||
mAlternateBouncerInteractor = alternateBouncerInteractor;
|
||||
|
||||
// This view is not part of the newly inflated expanded status bar.
|
||||
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
|
||||
@@ -293,7 +289,7 @@ public class NotificationShadeWindowViewController {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mAlternateBouncerInteractor.isVisibleState()) {
|
||||
if (mStatusBarKeyguardViewManager.isShowingAlternateBouncer()) {
|
||||
// capture all touches if the alt auth bouncer is showing
|
||||
return true;
|
||||
}
|
||||
@@ -331,7 +327,7 @@ public class NotificationShadeWindowViewController {
|
||||
handled = !mService.isPulsing();
|
||||
}
|
||||
|
||||
if (mAlternateBouncerInteractor.isVisibleState()) {
|
||||
if (mStatusBarKeyguardViewManager.isShowingAlternateBouncer()) {
|
||||
// eat the touch
|
||||
handled = true;
|
||||
}
|
||||
|
||||
@@ -332,7 +332,7 @@ public class CommandQueue extends IStatusBar.Stub implements
|
||||
/**
|
||||
* @see IStatusBar#setBiometicContextListener(IBiometricContextListener)
|
||||
*/
|
||||
default void setBiometricContextListener(IBiometricContextListener listener) {
|
||||
default void setBiometicContextListener(IBiometricContextListener listener) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1580,7 +1580,7 @@ public class CommandQueue extends IStatusBar.Stub implements
|
||||
}
|
||||
case MSG_SET_BIOMETRICS_LISTENER:
|
||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||
mCallbacks.get(i).setBiometricContextListener(
|
||||
mCallbacks.get(i).setBiometicContextListener(
|
||||
(IBiometricContextListener) msg.obj);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -90,7 +90,6 @@ import com.android.systemui.dock.DockManager;
|
||||
import com.android.systemui.keyguard.KeyguardIndication;
|
||||
import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
|
||||
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.plugins.FalsingManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
||||
@@ -156,7 +155,6 @@ public class KeyguardIndicationController {
|
||||
private final KeyguardBypassController mKeyguardBypassController;
|
||||
private final AccessibilityManager mAccessibilityManager;
|
||||
private final Handler mHandler;
|
||||
private final AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
|
||||
@VisibleForTesting
|
||||
public KeyguardIndicationRotateTextViewController mRotateTextViewController;
|
||||
@@ -236,8 +234,7 @@ public class KeyguardIndicationController {
|
||||
KeyguardBypassController keyguardBypassController,
|
||||
AccessibilityManager accessibilityManager,
|
||||
FaceHelpMessageDeferral faceHelpMessageDeferral,
|
||||
KeyguardLogger keyguardLogger,
|
||||
AlternateBouncerInteractor alternateBouncerInteractor) {
|
||||
KeyguardLogger keyguardLogger) {
|
||||
mContext = context;
|
||||
mBroadcastDispatcher = broadcastDispatcher;
|
||||
mDevicePolicyManager = devicePolicyManager;
|
||||
@@ -259,7 +256,6 @@ public class KeyguardIndicationController {
|
||||
mScreenLifecycle = screenLifecycle;
|
||||
mKeyguardLogger = keyguardLogger;
|
||||
mScreenLifecycle.addObserver(mScreenObserver);
|
||||
mAlternateBouncerInteractor = alternateBouncerInteractor;
|
||||
|
||||
mFaceAcquiredMessageDeferral = faceHelpMessageDeferral;
|
||||
mCoExFaceAcquisitionMsgIdsToShow = new HashSet<>();
|
||||
@@ -932,7 +928,7 @@ public class KeyguardIndicationController {
|
||||
}
|
||||
|
||||
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
|
||||
if (mAlternateBouncerInteractor.isVisibleState()) {
|
||||
if (mStatusBarKeyguardViewManager.isShowingAlternateBouncer()) {
|
||||
return; // udfps affordance is highlighted, no need to show action to unlock
|
||||
} else if (mKeyguardUpdateMonitor.isFaceEnrolled()) {
|
||||
String message = mContext.getString(R.string.keyguard_retry);
|
||||
|
||||
@@ -31,7 +31,6 @@ import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.dump.DumpHandler;
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.media.controls.pipeline.MediaDataManager;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
@@ -62,6 +61,7 @@ import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconList;
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
|
||||
import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback;
|
||||
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
|
||||
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallFlags;
|
||||
@@ -280,7 +280,7 @@ public interface CentralSurfacesDependenciesModule {
|
||||
@SysUISingleton
|
||||
static DialogLaunchAnimator provideDialogLaunchAnimator(IDreamManager dreamManager,
|
||||
KeyguardStateController keyguardStateController,
|
||||
Lazy<AlternateBouncerInteractor> alternateBouncerInteractor,
|
||||
Lazy<StatusBarKeyguardViewManager> statusBarKeyguardViewManager,
|
||||
InteractionJankMonitor interactionJankMonitor) {
|
||||
DialogLaunchAnimator.Callback callback = new DialogLaunchAnimator.Callback() {
|
||||
@Override
|
||||
@@ -300,7 +300,7 @@ public interface CentralSurfacesDependenciesModule {
|
||||
|
||||
@Override
|
||||
public boolean isShowingAlternateAuthOnUnlock() {
|
||||
return alternateBouncerInteractor.get().canShowAlternateBouncerForFingerprint();
|
||||
return statusBarKeyguardViewManager.get().canShowAlternateBouncer();
|
||||
}
|
||||
};
|
||||
return new DialogLaunchAnimator(callback, interactionJankMonitor);
|
||||
|
||||
@@ -157,6 +157,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
private KeyguardViewController mKeyguardViewController;
|
||||
private DozeScrimController mDozeScrimController;
|
||||
private KeyguardViewMediator mKeyguardViewMediator;
|
||||
private ScrimController mScrimController;
|
||||
private PendingAuthenticated mPendingAuthenticated = null;
|
||||
private boolean mHasScreenTurnedOnSinceAuthenticating;
|
||||
private boolean mFadedAwayAfterWakeAndUnlock;
|
||||
@@ -255,7 +256,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
@Inject
|
||||
public BiometricUnlockController(
|
||||
DozeScrimController dozeScrimController,
|
||||
KeyguardViewMediator keyguardViewMediator,
|
||||
KeyguardViewMediator keyguardViewMediator, ScrimController scrimController,
|
||||
NotificationShadeWindowController notificationShadeWindowController,
|
||||
KeyguardStateController keyguardStateController, Handler handler,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||
@@ -284,6 +285,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
mNotificationShadeWindowController = notificationShadeWindowController;
|
||||
mDozeScrimController = dozeScrimController;
|
||||
mKeyguardViewMediator = keyguardViewMediator;
|
||||
mScrimController = scrimController;
|
||||
mKeyguardStateController = keyguardStateController;
|
||||
mHandler = handler;
|
||||
mConsecutiveFpFailureThreshold = resources.getInteger(
|
||||
@@ -364,6 +366,12 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
Trace.endSection();
|
||||
}
|
||||
|
||||
private boolean pulsingOrAod() {
|
||||
final ScrimState scrimState = mScrimController.getState();
|
||||
return scrimState == ScrimState.AOD
|
||||
|| scrimState == ScrimState.PULSING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
|
||||
boolean isStrongBiometric) {
|
||||
@@ -408,7 +416,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
|
||||
mMode = mode;
|
||||
mHasScreenTurnedOnSinceAuthenticating = false;
|
||||
if (mMode == MODE_WAKE_AND_UNLOCK_PULSING) {
|
||||
if (mMode == MODE_WAKE_AND_UNLOCK_PULSING && pulsingOrAod()) {
|
||||
// If we are waking the device up while we are pulsing the clock and the
|
||||
// notifications would light up first, creating an unpleasant animation.
|
||||
// Defer changing the screen brightness by forcing doze brightness on our window
|
||||
|
||||
@@ -157,7 +157,6 @@ import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
import com.android.systemui.keyguard.KeyguardViewMediator;
|
||||
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.keyguard.ui.binder.LightRevealScrimViewBinder;
|
||||
import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel;
|
||||
import com.android.systemui.navigationbar.NavigationBarController;
|
||||
@@ -466,7 +465,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|
||||
private final ShadeController mShadeController;
|
||||
private final InitController mInitController;
|
||||
private final Lazy<CameraLauncher> mCameraLauncherLazy;
|
||||
private final AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
|
||||
private final PluginDependencyProvider mPluginDependencyProvider;
|
||||
private final KeyguardDismissUtil mKeyguardDismissUtil;
|
||||
@@ -745,9 +743,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|
||||
WiredChargingRippleController wiredChargingRippleController,
|
||||
IDreamManager dreamManager,
|
||||
Lazy<CameraLauncher> cameraLauncherLazy,
|
||||
Lazy<LightRevealScrimViewModel> lightRevealScrimViewModelLazy,
|
||||
AlternateBouncerInteractor alternateBouncerInteractor
|
||||
) {
|
||||
Lazy<LightRevealScrimViewModel> lightRevealScrimViewModelLazy) {
|
||||
mContext = context;
|
||||
mNotificationsController = notificationsController;
|
||||
mFragmentService = fragmentService;
|
||||
@@ -825,7 +821,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|
||||
mWallpaperManager = wallpaperManager;
|
||||
mJankMonitor = jankMonitor;
|
||||
mCameraLauncherLazy = cameraLauncherLazy;
|
||||
mAlternateBouncerInteractor = alternateBouncerInteractor;
|
||||
|
||||
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
|
||||
mStartingSurfaceOptional = startingSurfaceOptional;
|
||||
@@ -3227,7 +3222,8 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|
||||
private void showBouncerOrLockScreenIfKeyguard() {
|
||||
// If the keyguard is animating away, we aren't really the keyguard anymore and should not
|
||||
// show the bouncer/lockscreen.
|
||||
if (!mKeyguardViewMediator.isHiding() && !mKeyguardUpdateMonitor.isKeyguardGoingAway()) {
|
||||
if (!mKeyguardViewMediator.isHiding()
|
||||
&& !mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
|
||||
if (mState == StatusBarState.SHADE_LOCKED) {
|
||||
// shade is showing while locked on the keyguard, so go back to showing the
|
||||
// lock screen where users can use the UDFPS affordance to enter the device
|
||||
@@ -3706,7 +3702,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|
||||
boolean launchingAffordanceWithPreview = mLaunchingAffordance;
|
||||
mScrimController.setLaunchingAffordanceWithPreview(launchingAffordanceWithPreview);
|
||||
|
||||
if (mAlternateBouncerInteractor.isVisibleState()) {
|
||||
if (mStatusBarKeyguardViewManager.isShowingAlternateBouncer()) {
|
||||
if (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED
|
||||
|| mTransitionToFullShadeProgress > 0f) {
|
||||
mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED_SHADE);
|
||||
|
||||
@@ -58,7 +58,6 @@ import com.android.systemui.dreams.DreamOverlayStateController;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.flags.Flags;
|
||||
import com.android.systemui.keyguard.data.BouncerView;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor;
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
|
||||
import com.android.systemui.navigationbar.NavigationBarView;
|
||||
@@ -135,7 +134,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
private KeyguardMessageAreaController<AuthKeyguardMessageArea> mKeyguardMessageAreaController;
|
||||
private final PrimaryBouncerCallbackInteractor mPrimaryBouncerCallbackInteractor;
|
||||
private final PrimaryBouncerInteractor mPrimaryBouncerInteractor;
|
||||
private final AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
private final BouncerView mPrimaryBouncerView;
|
||||
private final Lazy<com.android.systemui.shade.ShadeController> mShadeController;
|
||||
|
||||
@@ -254,7 +252,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
private float mQsExpansion;
|
||||
final Set<KeyguardViewManagerCallback> mCallbacks = new HashSet<>();
|
||||
private boolean mIsModernBouncerEnabled;
|
||||
private boolean mIsModernAlternateBouncerEnabled;
|
||||
|
||||
private OnDismissAction mAfterKeyguardGoneAction;
|
||||
private Runnable mKeyguardGoneCancelAction;
|
||||
@@ -271,7 +268,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
private final LatencyTracker mLatencyTracker;
|
||||
private final KeyguardSecurityModel mKeyguardSecurityModel;
|
||||
@Nullable private KeyguardBypassController mBypassController;
|
||||
@Nullable private OccludingAppBiometricUI mOccludingAppBiometricUI;
|
||||
@Nullable private AlternateBouncer mAlternateBouncer;
|
||||
|
||||
private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
|
||||
new KeyguardUpdateMonitorCallback() {
|
||||
@@ -308,8 +305,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
FeatureFlags featureFlags,
|
||||
PrimaryBouncerCallbackInteractor primaryBouncerCallbackInteractor,
|
||||
PrimaryBouncerInteractor primaryBouncerInteractor,
|
||||
BouncerView primaryBouncerView,
|
||||
AlternateBouncerInteractor alternateBouncerInteractor) {
|
||||
BouncerView primaryBouncerView) {
|
||||
mContext = context;
|
||||
mViewMediatorCallback = callback;
|
||||
mLockPatternUtils = lockPatternUtils;
|
||||
@@ -333,8 +329,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
mFoldAodAnimationController = sysUIUnfoldComponent
|
||||
.map(SysUIUnfoldComponent::getFoldAodAnimationController).orElse(null);
|
||||
mIsModernBouncerEnabled = featureFlags.isEnabled(Flags.MODERN_BOUNCER);
|
||||
mIsModernAlternateBouncerEnabled = featureFlags.isEnabled(Flags.MODERN_ALTERNATE_BOUNCER);
|
||||
mAlternateBouncerInteractor = alternateBouncerInteractor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -367,51 +361,23 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given legacy alternate bouncer to null if it's the current alternate bouncer. Else,
|
||||
* does nothing. Only used if modern alternate bouncer is NOT enabled.
|
||||
*/
|
||||
public void removeLegacyAlternateBouncer(
|
||||
@NonNull LegacyAlternateBouncer alternateBouncerLegacy) {
|
||||
if (!mIsModernAlternateBouncerEnabled) {
|
||||
if (Objects.equals(mAlternateBouncerInteractor.getLegacyAlternateBouncer(),
|
||||
alternateBouncerLegacy)) {
|
||||
mAlternateBouncerInteractor.setLegacyAlternateBouncer(null);
|
||||
hideAlternateBouncer(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new legacy alternate bouncer. Only used if mdoern alternate bouncer is NOT enable.
|
||||
*/
|
||||
public void setLegacyAlternateBouncer(@NonNull LegacyAlternateBouncer alternateBouncerLegacy) {
|
||||
if (!mIsModernAlternateBouncerEnabled) {
|
||||
if (!Objects.equals(mAlternateBouncerInteractor.getLegacyAlternateBouncer(),
|
||||
alternateBouncerLegacy)) {
|
||||
mAlternateBouncerInteractor.setLegacyAlternateBouncer(alternateBouncerLegacy);
|
||||
hideAlternateBouncer(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the given OccludingAppBiometricUI to null if it's the current auth interceptor. Else,
|
||||
* Sets the given alt auth interceptor to null if it's the current auth interceptor. Else,
|
||||
* does nothing.
|
||||
*/
|
||||
public void removeOccludingAppBiometricUI(@NonNull OccludingAppBiometricUI biometricUI) {
|
||||
if (Objects.equals(mOccludingAppBiometricUI, biometricUI)) {
|
||||
mOccludingAppBiometricUI = null;
|
||||
public void removeAlternateAuthInterceptor(@NonNull AlternateBouncer authInterceptor) {
|
||||
if (Objects.equals(mAlternateBouncer, authInterceptor)) {
|
||||
mAlternateBouncer = null;
|
||||
hideAlternateBouncer(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new OccludingAppBiometricUI.
|
||||
* Sets a new alt auth interceptor.
|
||||
*/
|
||||
public void setOccludingAppBiometricUI(@NonNull OccludingAppBiometricUI biometricUI) {
|
||||
if (!Objects.equals(mOccludingAppBiometricUI, biometricUI)) {
|
||||
mOccludingAppBiometricUI = biometricUI;
|
||||
public void setAlternateBouncer(@NonNull AlternateBouncer authInterceptor) {
|
||||
if (!Objects.equals(mAlternateBouncer, authInterceptor)) {
|
||||
mAlternateBouncer = authInterceptor;
|
||||
hideAlternateBouncer(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,11 +564,18 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
* {@see KeyguardBouncer#show(boolean, boolean)}
|
||||
*/
|
||||
public void showBouncer(boolean scrimmed) {
|
||||
if (!mAlternateBouncerInteractor.show()) {
|
||||
showPrimaryBouncer(scrimmed);
|
||||
} else {
|
||||
updateAlternateBouncerShowing(mAlternateBouncerInteractor.isVisibleState());
|
||||
if (canShowAlternateBouncer()) {
|
||||
updateAlternateBouncerShowing(mAlternateBouncer.showAlternateBouncer());
|
||||
return;
|
||||
}
|
||||
|
||||
showPrimaryBouncer(scrimmed);
|
||||
}
|
||||
|
||||
/** Whether we can show the alternate bouncer instead of the primary bouncer. */
|
||||
public boolean canShowAlternateBouncer() {
|
||||
return mAlternateBouncer != null
|
||||
&& mKeyguardUpdateManager.isUnlockingWithBiometricAllowed(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -666,9 +639,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
mKeyguardGoneCancelAction = cancelAction;
|
||||
mDismissActionWillAnimateOnKeyguard = r != null && r.willRunAnimationOnKeyguard();
|
||||
|
||||
// If there is an alternate auth interceptor (like the UDFPS), show that one
|
||||
// If there is an an alternate auth interceptor (like the UDFPS), show that one
|
||||
// instead of the bouncer.
|
||||
if (mAlternateBouncerInteractor.canShowAlternateBouncerForFingerprint()) {
|
||||
if (canShowAlternateBouncer()) {
|
||||
if (!afterKeyguardGone) {
|
||||
if (mPrimaryBouncer != null) {
|
||||
mPrimaryBouncer.setDismissAction(mAfterKeyguardGoneAction,
|
||||
@@ -681,7 +654,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
mKeyguardGoneCancelAction = null;
|
||||
}
|
||||
|
||||
updateAlternateBouncerShowing(mAlternateBouncerInteractor.show());
|
||||
updateAlternateBouncerShowing(mAlternateBouncer.showAlternateBouncer());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -750,7 +723,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
|
||||
@Override
|
||||
public void hideAlternateBouncer(boolean forceUpdateScrim) {
|
||||
updateAlternateBouncerShowing(mAlternateBouncerInteractor.hide() || forceUpdateScrim);
|
||||
final boolean updateScrim = (mAlternateBouncer != null
|
||||
&& mAlternateBouncer.hideAlternateBouncer())
|
||||
|| forceUpdateScrim;
|
||||
updateAlternateBouncerShowing(updateScrim);
|
||||
}
|
||||
|
||||
private void updateAlternateBouncerShowing(boolean updateScrim) {
|
||||
@@ -760,7 +736,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean isShowingAlternateBouncer = mAlternateBouncerInteractor.isVisibleState();
|
||||
final boolean isShowingAlternateBouncer = isShowingAlternateBouncer();
|
||||
if (mKeyguardMessageAreaController != null) {
|
||||
mKeyguardMessageAreaController.setIsVisible(isShowingAlternateBouncer);
|
||||
mKeyguardMessageAreaController.setMessage("");
|
||||
@@ -1114,7 +1090,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
|
||||
@Override
|
||||
public boolean isBouncerShowing() {
|
||||
return primaryBouncerIsShowing() || mAlternateBouncerInteractor.isVisibleState();
|
||||
return primaryBouncerIsShowing() || isShowingAlternateBouncer();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1358,7 +1334,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
mPrimaryBouncerInteractor.notifyKeyguardAuthenticated(strongAuth);
|
||||
}
|
||||
|
||||
if (mAlternateBouncerInteractor.isVisibleState()) {
|
||||
if (mAlternateBouncer != null && isShowingAlternateBouncer()) {
|
||||
hideAlternateBouncer(false);
|
||||
executeAfterKeyguardGoneAction();
|
||||
}
|
||||
@@ -1366,7 +1342,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
|
||||
/** Display security message to relevant KeyguardMessageArea. */
|
||||
public void setKeyguardMessage(String message, ColorStateList colorState) {
|
||||
if (mAlternateBouncerInteractor.isVisibleState()) {
|
||||
if (isShowingAlternateBouncer()) {
|
||||
if (mKeyguardMessageAreaController != null) {
|
||||
mKeyguardMessageAreaController.setMessage(message);
|
||||
}
|
||||
@@ -1440,7 +1416,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.println("StatusBarKeyguardViewManager:");
|
||||
pw.println(" mIsModernAlternateBouncerEnabled: " + mIsModernAlternateBouncerEnabled);
|
||||
pw.println(" mRemoteInputActive: " + mRemoteInputActive);
|
||||
pw.println(" mDozing: " + mDozing);
|
||||
pw.println(" mAfterKeyguardGoneAction: " + mAfterKeyguardGoneAction);
|
||||
@@ -1458,9 +1433,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
mPrimaryBouncer.dump(pw);
|
||||
}
|
||||
|
||||
if (mOccludingAppBiometricUI != null) {
|
||||
pw.println("mOccludingAppBiometricUI:");
|
||||
mOccludingAppBiometricUI.dump(pw);
|
||||
if (mAlternateBouncer != null) {
|
||||
pw.println("AlternateBouncer:");
|
||||
mAlternateBouncer.dump(pw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1512,17 +1487,14 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
return mPrimaryBouncer;
|
||||
}
|
||||
|
||||
public boolean isShowingAlternateBouncer() {
|
||||
return mAlternateBouncer != null && mAlternateBouncer.isShowingAlternateBouncer();
|
||||
}
|
||||
|
||||
/**
|
||||
* For any touches on the NPVC, show the primary bouncer if the alternate bouncer is currently
|
||||
* showing.
|
||||
* Forward touches to callbacks.
|
||||
*/
|
||||
public void onTouch(MotionEvent event) {
|
||||
if (mAlternateBouncerInteractor.isVisibleState()
|
||||
&& mAlternateBouncerInteractor.hasAlternateBouncerShownWithMinTime()) {
|
||||
showPrimaryBouncer(true);
|
||||
}
|
||||
|
||||
// Forward NPVC touches to callbacks in case they want to respond to touches
|
||||
for (KeyguardViewManagerCallback callback: mCallbacks) {
|
||||
callback.onTouch(event);
|
||||
}
|
||||
@@ -1565,8 +1537,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
*/
|
||||
public void requestFp(boolean request, int udfpsColor) {
|
||||
mKeyguardUpdateManager.requestFingerprintAuthOnOccludingApp(request);
|
||||
if (mOccludingAppBiometricUI != null) {
|
||||
mOccludingAppBiometricUI.requestUdfps(request, udfpsColor);
|
||||
if (mAlternateBouncer != null) {
|
||||
mAlternateBouncer.requestUdfps(request, udfpsColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1637,9 +1609,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
}
|
||||
|
||||
/**
|
||||
* @Deprecated Delegate used to send show and hide events to an alternate bouncer.
|
||||
* Delegate used to send show and hide events to an alternate authentication method instead of
|
||||
* the regular pin/pattern/password bouncer.
|
||||
*/
|
||||
public interface LegacyAlternateBouncer {
|
||||
public interface AlternateBouncer {
|
||||
/**
|
||||
* Show alternate authentication bouncer.
|
||||
* @return whether alternate auth method was newly shown
|
||||
@@ -1656,13 +1629,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
* @return true if the alternate auth bouncer is showing
|
||||
*/
|
||||
boolean isShowingAlternateBouncer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate used to send show and hide events to an alternate authentication method instead of
|
||||
* the regular pin/pattern/password bouncer.
|
||||
*/
|
||||
public interface OccludingAppBiometricUI {
|
||||
/**
|
||||
* Use when an app occluding the keyguard would like to give the user ability to
|
||||
* unlock the device using udfps.
|
||||
|
||||
@@ -812,7 +812,7 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
public void testForwardsDozeEvents() throws RemoteException {
|
||||
when(mStatusBarStateController.isDozing()).thenReturn(true);
|
||||
when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
|
||||
mAuthController.setBiometricContextListener(mContextListener);
|
||||
mAuthController.setBiometicContextListener(mContextListener);
|
||||
|
||||
mStatusBarStateListenerCaptor.getValue().onDozingChanged(true);
|
||||
mStatusBarStateListenerCaptor.getValue().onDozingChanged(false);
|
||||
@@ -827,7 +827,7 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
public void testForwardsWakeEvents() throws RemoteException {
|
||||
when(mStatusBarStateController.isDozing()).thenReturn(false);
|
||||
when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
|
||||
mAuthController.setBiometricContextListener(mContextListener);
|
||||
mAuthController.setBiometicContextListener(mContextListener);
|
||||
|
||||
mWakefullnessObserverCaptor.getValue().onStartedGoingToSleep();
|
||||
mWakefullnessObserverCaptor.getValue().onFinishedGoingToSleep();
|
||||
|
||||
@@ -43,7 +43,6 @@ import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||
import com.android.systemui.dump.DumpManager
|
||||
import com.android.systemui.flags.FeatureFlags
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||
import com.android.systemui.shade.ShadeExpansionStateManager
|
||||
@@ -53,6 +52,7 @@ 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.util.time.SystemClock
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
@@ -95,6 +95,7 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
|
||||
@Mock private lateinit var dumpManager: DumpManager
|
||||
@Mock private lateinit var transitionController: LockscreenShadeTransitionController
|
||||
@Mock private lateinit var configurationController: ConfigurationController
|
||||
@Mock private lateinit var systemClock: SystemClock
|
||||
@Mock private lateinit var keyguardStateController: KeyguardStateController
|
||||
@Mock private lateinit var unlockedScreenOffAnimationController:
|
||||
UnlockedScreenOffAnimationController
|
||||
@@ -105,8 +106,7 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
|
||||
@Mock private lateinit var udfpsEnrollView: UdfpsEnrollView
|
||||
@Mock private lateinit var activityLaunchAnimator: ActivityLaunchAnimator
|
||||
@Mock private lateinit var featureFlags: FeatureFlags
|
||||
@Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
|
||||
@Mock private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
|
||||
@Mock private lateinit var mPrimaryBouncerInteractor: PrimaryBouncerInteractor
|
||||
@Captor private lateinit var layoutParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams>
|
||||
|
||||
private val onTouch = { _: View, _: MotionEvent, _: Boolean -> true }
|
||||
@@ -138,10 +138,10 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
|
||||
context, fingerprintManager, inflater, windowManager, accessibilityManager,
|
||||
statusBarStateController, shadeExpansionStateManager, statusBarKeyguardViewManager,
|
||||
keyguardUpdateMonitor, dialogManager, dumpManager, transitionController,
|
||||
configurationController, keyguardStateController,
|
||||
configurationController, systemClock, keyguardStateController,
|
||||
unlockedScreenOffAnimationController, udfpsDisplayMode, REQUEST_ID, reason,
|
||||
controllerCallback, onTouch, activityLaunchAnimator, featureFlags,
|
||||
primaryBouncerInteractor, alternateBouncerInteractor, isDebuggable,
|
||||
mPrimaryBouncerInteractor, isDebuggable
|
||||
)
|
||||
block()
|
||||
}
|
||||
|
||||
@@ -78,7 +78,6 @@ import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.flags.Flags;
|
||||
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
|
||||
import com.android.systemui.plugins.FalsingManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
@@ -200,8 +199,6 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
private PrimaryBouncerInteractor mPrimaryBouncerInteractor;
|
||||
@Mock
|
||||
private SinglePointerTouchProcessor mSinglePointerTouchProcessor;
|
||||
@Mock
|
||||
private AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
|
||||
// Capture listeners so that they can be used to send events
|
||||
@Captor
|
||||
@@ -290,8 +287,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
mDisplayManager, mHandler, mConfigurationController, mSystemClock,
|
||||
mUnlockedScreenOffAnimationController, mSystemUIDialogManager, mLatencyTracker,
|
||||
mActivityLaunchAnimator, alternateTouchProvider, mBiometricsExecutor,
|
||||
mPrimaryBouncerInteractor, mSinglePointerTouchProcessor,
|
||||
mAlternateBouncerInteractor);
|
||||
mPrimaryBouncerInteractor, mSinglePointerTouchProcessor);
|
||||
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
|
||||
mOverlayController = mOverlayCaptor.getValue();
|
||||
verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
|
||||
@@ -405,7 +401,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
// GIVEN overlay was showing and the udfps bouncer is showing
|
||||
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
|
||||
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
|
||||
when(mStatusBarKeyguardViewManager.isShowingAlternateBouncer()).thenReturn(true);
|
||||
|
||||
// WHEN the overlay is hidden
|
||||
mOverlayController.hideUdfpsOverlay(mOpticalProps.sensorId);
|
||||
|
||||
@@ -30,7 +30,6 @@ import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.flags.FakeFeatureFlags;
|
||||
import com.android.systemui.flags.Flags;
|
||||
import com.android.systemui.keyguard.KeyguardViewMediator;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.shade.ShadeExpansionChangeEvent;
|
||||
@@ -44,6 +43,7 @@ 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.util.concurrency.DelayableExecutor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
@@ -73,9 +73,9 @@ public class UdfpsKeyguardViewControllerBaseTest extends SysuiTestCase {
|
||||
protected @Mock ActivityLaunchAnimator mActivityLaunchAnimator;
|
||||
protected @Mock KeyguardBouncer mBouncer;
|
||||
protected @Mock PrimaryBouncerInteractor mPrimaryBouncerInteractor;
|
||||
protected @Mock AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
|
||||
protected FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
|
||||
protected FakeSystemClock mSystemClock = new FakeSystemClock();
|
||||
|
||||
protected UdfpsKeyguardViewController mController;
|
||||
|
||||
@@ -86,6 +86,10 @@ public class UdfpsKeyguardViewControllerBaseTest extends SysuiTestCase {
|
||||
private @Captor ArgumentCaptor<ShadeExpansionListener> mExpansionListenerCaptor;
|
||||
protected List<ShadeExpansionListener> mExpansionListeners;
|
||||
|
||||
private @Captor ArgumentCaptor<StatusBarKeyguardViewManager.AlternateBouncer>
|
||||
mAlternateBouncerCaptor;
|
||||
protected StatusBarKeyguardViewManager.AlternateBouncer mAlternateBouncer;
|
||||
|
||||
private @Captor ArgumentCaptor<KeyguardStateController.Callback>
|
||||
mKeyguardStateControllerCallbackCaptor;
|
||||
protected KeyguardStateController.Callback mKeyguardStateControllerCallback;
|
||||
@@ -131,6 +135,12 @@ public class UdfpsKeyguardViewControllerBaseTest extends SysuiTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
protected void captureAltAuthInterceptor() {
|
||||
verify(mStatusBarKeyguardViewManager).setAlternateBouncer(
|
||||
mAlternateBouncerCaptor.capture());
|
||||
mAlternateBouncer = mAlternateBouncerCaptor.getValue();
|
||||
}
|
||||
|
||||
protected void captureKeyguardStateControllerCallback() {
|
||||
verify(mKeyguardStateController).addCallback(
|
||||
mKeyguardStateControllerCallbackCaptor.capture());
|
||||
@@ -150,7 +160,6 @@ public class UdfpsKeyguardViewControllerBaseTest extends SysuiTestCase {
|
||||
protected UdfpsKeyguardViewController createUdfpsKeyguardViewController(
|
||||
boolean useModernBouncer, boolean useExpandedOverlay) {
|
||||
mFeatureFlags.set(Flags.MODERN_BOUNCER, useModernBouncer);
|
||||
mFeatureFlags.set(Flags.MODERN_ALTERNATE_BOUNCER, useModernBouncer);
|
||||
mFeatureFlags.set(Flags.UDFPS_NEW_TOUCH_DETECTION, useExpandedOverlay);
|
||||
when(mStatusBarKeyguardViewManager.getPrimaryBouncer()).thenReturn(
|
||||
useModernBouncer ? null : mBouncer);
|
||||
@@ -163,14 +172,14 @@ public class UdfpsKeyguardViewControllerBaseTest extends SysuiTestCase {
|
||||
mDumpManager,
|
||||
mLockscreenShadeTransitionController,
|
||||
mConfigurationController,
|
||||
mSystemClock,
|
||||
mKeyguardStateController,
|
||||
mUnlockedScreenOffAnimationController,
|
||||
mDialogManager,
|
||||
mUdfpsController,
|
||||
mActivityLaunchAnimator,
|
||||
mFeatureFlags,
|
||||
mPrimaryBouncerInteractor,
|
||||
mAlternateBouncerInteractor);
|
||||
mPrimaryBouncerInteractor);
|
||||
return controller;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,15 +19,18 @@ package com.android.systemui.biometrics;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.atLeast;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.testing.TestableLooper.RunWithLooper;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
@@ -43,8 +46,7 @@ import org.mockito.Captor;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
|
||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||
@RunWithLooper
|
||||
public class UdfpsKeyguardViewControllerTest extends UdfpsKeyguardViewControllerBaseTest {
|
||||
private @Captor ArgumentCaptor<KeyguardBouncer.PrimaryBouncerExpansionCallback>
|
||||
mBouncerExpansionCallbackCaptor;
|
||||
@@ -70,6 +72,8 @@ public class UdfpsKeyguardViewControllerTest extends UdfpsKeyguardViewController
|
||||
assertTrue(mController.shouldPauseAuth());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testRegistersExpansionChangedListenerOnAttached() {
|
||||
mController.onViewAttached();
|
||||
@@ -233,9 +237,85 @@ public class UdfpsKeyguardViewControllerTest extends UdfpsKeyguardViewController
|
||||
public void testOverrideShouldPauseAuthOnShadeLocked() {
|
||||
mController.onViewAttached();
|
||||
captureStatusBarStateListeners();
|
||||
captureAltAuthInterceptor();
|
||||
|
||||
sendStatusBarStateChanged(StatusBarState.SHADE_LOCKED);
|
||||
assertTrue(mController.shouldPauseAuth());
|
||||
|
||||
mAlternateBouncer.showAlternateBouncer(); // force show
|
||||
assertFalse(mController.shouldPauseAuth());
|
||||
assertTrue(mAlternateBouncer.isShowingAlternateBouncer());
|
||||
|
||||
mAlternateBouncer.hideAlternateBouncer(); // stop force show
|
||||
assertTrue(mController.shouldPauseAuth());
|
||||
assertFalse(mAlternateBouncer.isShowingAlternateBouncer());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnDetachedStateReset() {
|
||||
// GIVEN view is attached
|
||||
mController.onViewAttached();
|
||||
captureAltAuthInterceptor();
|
||||
|
||||
// WHEN view is detached
|
||||
mController.onViewDetached();
|
||||
|
||||
// THEN remove alternate auth interceptor
|
||||
verify(mStatusBarKeyguardViewManager).removeAlternateAuthInterceptor(mAlternateBouncer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHiddenUdfpsBouncerOnTouchOutside_nothingHappens() {
|
||||
// GIVEN view is attached
|
||||
mController.onViewAttached();
|
||||
captureAltAuthInterceptor();
|
||||
|
||||
// GIVEN udfps bouncer isn't showing
|
||||
mAlternateBouncer.hideAlternateBouncer();
|
||||
|
||||
// WHEN touch is observed outside the view
|
||||
mController.onTouchOutsideView();
|
||||
|
||||
// THEN bouncer / alt auth methods are never called
|
||||
verify(mStatusBarKeyguardViewManager, never()).showPrimaryBouncer(anyBoolean());
|
||||
verify(mStatusBarKeyguardViewManager, never()).showBouncer(anyBoolean());
|
||||
verify(mStatusBarKeyguardViewManager, never()).hideAlternateBouncer(anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowingUdfpsBouncerOnTouchOutsideWithinThreshold_nothingHappens() {
|
||||
// GIVEN view is attached
|
||||
mController.onViewAttached();
|
||||
captureAltAuthInterceptor();
|
||||
|
||||
// GIVEN udfps bouncer is showing
|
||||
mAlternateBouncer.showAlternateBouncer();
|
||||
|
||||
// WHEN touch is observed outside the view 200ms later (just within threshold)
|
||||
mSystemClock.advanceTime(200);
|
||||
mController.onTouchOutsideView();
|
||||
|
||||
// THEN bouncer / alt auth methods are never called because not enough time has passed
|
||||
verify(mStatusBarKeyguardViewManager, never()).showPrimaryBouncer(anyBoolean());
|
||||
verify(mStatusBarKeyguardViewManager, never()).showBouncer(anyBoolean());
|
||||
verify(mStatusBarKeyguardViewManager, never()).hideAlternateBouncer(anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowingUdfpsBouncerOnTouchOutsideAboveThreshold_showPrimaryBouncer() {
|
||||
// GIVEN view is attached
|
||||
mController.onViewAttached();
|
||||
captureAltAuthInterceptor();
|
||||
|
||||
// GIVEN udfps bouncer is showing
|
||||
mAlternateBouncer.showAlternateBouncer();
|
||||
|
||||
// WHEN touch is observed outside the view 205ms later
|
||||
mSystemClock.advanceTime(205);
|
||||
mController.onTouchOutsideView();
|
||||
|
||||
// THEN show the bouncer
|
||||
verify(mStatusBarKeyguardViewManager).showPrimaryBouncer(eq(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -253,6 +333,25 @@ public class UdfpsKeyguardViewControllerTest extends UdfpsKeyguardViewController
|
||||
verify(mView).setUnpausedAlpha(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowUdfpsBouncer() {
|
||||
// GIVEN view is attached and status bar expansion is 0
|
||||
mController.onViewAttached();
|
||||
captureStatusBarExpansionListeners();
|
||||
captureKeyguardStateControllerCallback();
|
||||
captureAltAuthInterceptor();
|
||||
updateStatusBarExpansion(0, true);
|
||||
reset(mView);
|
||||
when(mView.getContext()).thenReturn(mResourceContext);
|
||||
when(mResourceContext.getString(anyInt())).thenReturn("test string");
|
||||
|
||||
// WHEN status bar expansion is 0 but udfps bouncer is requested
|
||||
mAlternateBouncer.showAlternateBouncer();
|
||||
|
||||
// THEN alpha is 255
|
||||
verify(mView).setUnpausedAlpha(255);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransitionToFullShadeProgress() {
|
||||
// GIVEN view is attached and status bar expansion is 1f
|
||||
@@ -270,6 +369,24 @@ public class UdfpsKeyguardViewControllerTest extends UdfpsKeyguardViewController
|
||||
verify(mView).setUnpausedAlpha((int) ((1f - transitionProgress) * 255));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowUdfpsBouncer_transitionToFullShadeProgress() {
|
||||
// GIVEN view is attached and status bar expansion is 1f
|
||||
mController.onViewAttached();
|
||||
captureStatusBarExpansionListeners();
|
||||
captureKeyguardStateControllerCallback();
|
||||
captureAltAuthInterceptor();
|
||||
updateStatusBarExpansion(1f, true);
|
||||
mAlternateBouncer.showAlternateBouncer();
|
||||
reset(mView);
|
||||
|
||||
// WHEN we're transitioning to the full shade
|
||||
mController.setTransitionToFullShadeProgress(1.0f);
|
||||
|
||||
// THEN alpha is 255 (b/c udfps bouncer is requested)
|
||||
verify(mView).setUnpausedAlpha(255);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdatePanelExpansion_pauseAuth() {
|
||||
// GIVEN view is attached + on the keyguard
|
||||
|
||||
@@ -21,32 +21,23 @@ import android.testing.AndroidTestingRunner
|
||||
import android.testing.TestableLooper
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.keyguard.KeyguardSecurityModel
|
||||
import com.android.keyguard.KeyguardUpdateMonitor
|
||||
import com.android.systemui.classifier.FalsingCollector
|
||||
import com.android.systemui.flags.FeatureFlags
|
||||
import com.android.systemui.keyguard.DismissCallbackRegistry
|
||||
import com.android.systemui.keyguard.data.BouncerView
|
||||
import com.android.systemui.keyguard.data.repository.BiometricRepository
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
|
||||
import com.android.systemui.statusbar.StatusBarState
|
||||
import com.android.systemui.statusbar.phone.KeyguardBouncer
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController
|
||||
import com.android.systemui.util.time.FakeSystemClock
|
||||
import com.android.systemui.util.time.SystemClock
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.yield
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentMatchers.any
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@@ -62,7 +53,7 @@ class UdfpsKeyguardViewControllerWithCoroutinesTest : UdfpsKeyguardViewControlle
|
||||
keyguardBouncerRepository =
|
||||
KeyguardBouncerRepository(
|
||||
mock(com.android.keyguard.ViewMediatorCallback::class.java),
|
||||
FakeSystemClock()
|
||||
mKeyguardUpdateMonitor
|
||||
)
|
||||
super.setUp()
|
||||
}
|
||||
@@ -81,43 +72,15 @@ class UdfpsKeyguardViewControllerWithCoroutinesTest : UdfpsKeyguardViewControlle
|
||||
mock(KeyguardBypassController::class.java),
|
||||
mKeyguardUpdateMonitor
|
||||
)
|
||||
mAlternateBouncerInteractor =
|
||||
AlternateBouncerInteractor(
|
||||
keyguardBouncerRepository,
|
||||
mock(BiometricRepository::class.java),
|
||||
mock(SystemClock::class.java),
|
||||
mock(KeyguardUpdateMonitor::class.java),
|
||||
mock(FeatureFlags::class.java)
|
||||
)
|
||||
return createUdfpsKeyguardViewController(
|
||||
/* useModernBouncer */ true, /* useExpandedOverlay */
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
/** After migration, replaces LockIconViewControllerTest version */
|
||||
@Test
|
||||
fun shadeLocked_showAlternateBouncer_unpauseAuth() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
// GIVEN view is attached + on the SHADE_LOCKED (udfps view not showing)
|
||||
mController.onViewAttached()
|
||||
captureStatusBarStateListeners()
|
||||
sendStatusBarStateChanged(StatusBarState.SHADE_LOCKED)
|
||||
|
||||
// WHEN alternate bouncer is requested
|
||||
val job = mController.listenForAlternateBouncerVisibility(this)
|
||||
keyguardBouncerRepository.setAlternateVisible(true)
|
||||
yield()
|
||||
|
||||
// THEN udfps view will animate in & pause auth is updated to NOT pause
|
||||
verify(mView).animateInUdfpsBouncer(any())
|
||||
assertFalse(mController.shouldPauseAuth())
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
/** After migration to MODERN_BOUNCER, replaces UdfpsKeyguardViewControllerTest version */
|
||||
@Test
|
||||
fun shouldPauseAuthBouncerShowing() =
|
||||
fun testShouldPauseAuthBouncerShowing() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
// GIVEN view attached and we're on the keyguard
|
||||
mController.onViewAttached()
|
||||
|
||||
@@ -79,6 +79,15 @@ class UdfpsViewTest : SysuiTestCase() {
|
||||
ViewUtils.detachView(view)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun forwardsEvents() {
|
||||
view.dozeTimeTick()
|
||||
verify(animationViewController).dozeTimeTick()
|
||||
|
||||
view.onTouchOutsideView()
|
||||
verify(animationViewController).onTouchOutsideView()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun layoutSizeFitsSensor() {
|
||||
val params = withArgCaptor<RectF> {
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.keyguard.data.repository
|
||||
|
||||
import android.app.admin.DevicePolicyManager
|
||||
import android.content.Intent
|
||||
import android.content.pm.UserInfo
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.testing.TestableLooper
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.internal.widget.LockPatternUtils
|
||||
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED
|
||||
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.biometrics.AuthController
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
import com.android.systemui.user.data.repository.FakeUserRepository
|
||||
import com.android.systemui.util.mockito.argumentCaptor
|
||||
import com.android.systemui.util.mockito.whenever
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentMatchers.any
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@SmallTest
|
||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
class BiometricRepositoryTest : SysuiTestCase() {
|
||||
private lateinit var underTest: BiometricRepository
|
||||
|
||||
@Mock private lateinit var authController: AuthController
|
||||
@Mock private lateinit var lockPatternUtils: LockPatternUtils
|
||||
@Mock private lateinit var devicePolicyManager: DevicePolicyManager
|
||||
private lateinit var userRepository: FakeUserRepository
|
||||
|
||||
private lateinit var testDispatcher: TestDispatcher
|
||||
private lateinit var testScope: TestScope
|
||||
private var testableLooper: TestableLooper? = null
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
testableLooper = TestableLooper.get(this)
|
||||
testDispatcher = StandardTestDispatcher()
|
||||
testScope = TestScope(testDispatcher)
|
||||
userRepository = FakeUserRepository()
|
||||
}
|
||||
|
||||
private suspend fun createBiometricRepository() {
|
||||
userRepository.setUserInfos(listOf(PRIMARY_USER))
|
||||
userRepository.setSelectedUserInfo(PRIMARY_USER)
|
||||
underTest =
|
||||
BiometricRepositoryImpl(
|
||||
context = context,
|
||||
lockPatternUtils = lockPatternUtils,
|
||||
broadcastDispatcher = fakeBroadcastDispatcher,
|
||||
authController = authController,
|
||||
userRepository = userRepository,
|
||||
devicePolicyManager = devicePolicyManager,
|
||||
scope = testScope.backgroundScope,
|
||||
backgroundDispatcher = testDispatcher,
|
||||
looper = testableLooper!!.looper,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fingerprintEnrollmentChange() =
|
||||
testScope.runTest {
|
||||
createBiometricRepository()
|
||||
val fingerprintEnabledByDevicePolicy = collectLastValue(underTest.isFingerprintEnrolled)
|
||||
runCurrent()
|
||||
|
||||
val captor = argumentCaptor<AuthController.Callback>()
|
||||
verify(authController).addCallback(captor.capture())
|
||||
whenever(authController.isFingerprintEnrolled(anyInt())).thenReturn(true)
|
||||
captor.value.onEnrollmentsChanged(
|
||||
BiometricType.UNDER_DISPLAY_FINGERPRINT,
|
||||
PRIMARY_USER_ID,
|
||||
true
|
||||
)
|
||||
assertThat(fingerprintEnabledByDevicePolicy()).isTrue()
|
||||
|
||||
whenever(authController.isFingerprintEnrolled(anyInt())).thenReturn(false)
|
||||
captor.value.onEnrollmentsChanged(
|
||||
BiometricType.UNDER_DISPLAY_FINGERPRINT,
|
||||
PRIMARY_USER_ID,
|
||||
false
|
||||
)
|
||||
assertThat(fingerprintEnabledByDevicePolicy()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun strongBiometricAllowedChange() =
|
||||
testScope.runTest {
|
||||
createBiometricRepository()
|
||||
val strongBiometricAllowed = collectLastValue(underTest.isStrongBiometricAllowed)
|
||||
runCurrent()
|
||||
|
||||
val captor = argumentCaptor<LockPatternUtils.StrongAuthTracker>()
|
||||
verify(lockPatternUtils).registerStrongAuthTracker(captor.capture())
|
||||
|
||||
captor.value
|
||||
.getStub()
|
||||
.onStrongAuthRequiredChanged(STRONG_AUTH_NOT_REQUIRED, PRIMARY_USER_ID)
|
||||
testableLooper?.processAllMessages() // StrongAuthTracker uses the TestableLooper
|
||||
assertThat(strongBiometricAllowed()).isTrue()
|
||||
|
||||
captor.value
|
||||
.getStub()
|
||||
.onStrongAuthRequiredChanged(STRONG_AUTH_REQUIRED_AFTER_BOOT, PRIMARY_USER_ID)
|
||||
testableLooper?.processAllMessages() // StrongAuthTracker uses the TestableLooper
|
||||
assertThat(strongBiometricAllowed()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fingerprintDisabledByDpmChange() =
|
||||
testScope.runTest {
|
||||
createBiometricRepository()
|
||||
val fingerprintEnabledByDevicePolicy =
|
||||
collectLastValue(underTest.isFingerprintEnabledByDevicePolicy)
|
||||
runCurrent()
|
||||
|
||||
whenever(devicePolicyManager.getKeyguardDisabledFeatures(any(), anyInt()))
|
||||
.thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT)
|
||||
broadcastDPMStateChange()
|
||||
assertThat(fingerprintEnabledByDevicePolicy()).isFalse()
|
||||
|
||||
whenever(devicePolicyManager.getKeyguardDisabledFeatures(any(), anyInt())).thenReturn(0)
|
||||
broadcastDPMStateChange()
|
||||
assertThat(fingerprintEnabledByDevicePolicy()).isTrue()
|
||||
}
|
||||
|
||||
private fun broadcastDPMStateChange() {
|
||||
fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
|
||||
receiver.onReceive(
|
||||
context,
|
||||
Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val PRIMARY_USER_ID = 0
|
||||
private val PRIMARY_USER =
|
||||
UserInfo(
|
||||
/* id= */ PRIMARY_USER_ID,
|
||||
/* name= */ "primary user",
|
||||
/* flags= */ UserInfo.FLAG_PRIMARY
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.keyguard.domain.interactor
|
||||
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.keyguard.KeyguardUpdateMonitor
|
||||
import com.android.keyguard.ViewMediatorCallback
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.flags.FakeFeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.keyguard.data.repository.FakeBiometricRepository
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
|
||||
import com.android.systemui.util.time.FakeSystemClock
|
||||
import com.android.systemui.util.time.SystemClock
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@SmallTest
|
||||
@RunWith(JUnit4::class)
|
||||
class AlternateBouncerInteractorTest : SysuiTestCase() {
|
||||
private lateinit var underTest: AlternateBouncerInteractor
|
||||
private lateinit var bouncerRepository: KeyguardBouncerRepository
|
||||
private lateinit var biometricRepository: FakeBiometricRepository
|
||||
@Mock private lateinit var systemClock: SystemClock
|
||||
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
|
||||
private lateinit var featureFlags: FakeFeatureFlags
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
bouncerRepository =
|
||||
KeyguardBouncerRepository(mock(ViewMediatorCallback::class.java), FakeSystemClock())
|
||||
biometricRepository = FakeBiometricRepository()
|
||||
featureFlags = FakeFeatureFlags().apply { this.set(Flags.MODERN_ALTERNATE_BOUNCER, true) }
|
||||
underTest =
|
||||
AlternateBouncerInteractor(
|
||||
bouncerRepository,
|
||||
biometricRepository,
|
||||
systemClock,
|
||||
keyguardUpdateMonitor,
|
||||
featureFlags,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canShowAlternateBouncerForFingerprint_givenCanShow() {
|
||||
givenCanShowAlternateBouncer()
|
||||
assertTrue(underTest.canShowAlternateBouncerForFingerprint())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canShowAlternateBouncerForFingerprint_alternateBouncerUIUnavailable() {
|
||||
givenCanShowAlternateBouncer()
|
||||
bouncerRepository.setAlternateBouncerUIAvailable(false)
|
||||
|
||||
assertFalse(underTest.canShowAlternateBouncerForFingerprint())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canShowAlternateBouncerForFingerprint_noFingerprintsEnrolled() {
|
||||
givenCanShowAlternateBouncer()
|
||||
biometricRepository.setFingerprintEnrolled(false)
|
||||
|
||||
assertFalse(underTest.canShowAlternateBouncerForFingerprint())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canShowAlternateBouncerForFingerprint_strongBiometricNotAllowed() {
|
||||
givenCanShowAlternateBouncer()
|
||||
biometricRepository.setStrongBiometricAllowed(false)
|
||||
|
||||
assertFalse(underTest.canShowAlternateBouncerForFingerprint())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canShowAlternateBouncerForFingerprint_devicePolicyDoesNotAllowFingerprint() {
|
||||
givenCanShowAlternateBouncer()
|
||||
biometricRepository.setFingerprintEnabledByDevicePolicy(false)
|
||||
|
||||
assertFalse(underTest.canShowAlternateBouncerForFingerprint())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun show_whenCanShow() {
|
||||
givenCanShowAlternateBouncer()
|
||||
|
||||
assertTrue(underTest.show())
|
||||
assertTrue(bouncerRepository.isAlternateBouncerVisible.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun show_whenCannotShow() {
|
||||
givenCannotShowAlternateBouncer()
|
||||
|
||||
assertFalse(underTest.show())
|
||||
assertFalse(bouncerRepository.isAlternateBouncerVisible.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hide_wasPreviouslyShowing() {
|
||||
bouncerRepository.setAlternateVisible(true)
|
||||
|
||||
assertTrue(underTest.hide())
|
||||
assertFalse(bouncerRepository.isAlternateBouncerVisible.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hide_wasNotPreviouslyShowing() {
|
||||
bouncerRepository.setAlternateVisible(false)
|
||||
|
||||
assertFalse(underTest.hide())
|
||||
assertFalse(bouncerRepository.isAlternateBouncerVisible.value)
|
||||
}
|
||||
|
||||
private fun givenCanShowAlternateBouncer() {
|
||||
bouncerRepository.setAlternateBouncerUIAvailable(true)
|
||||
biometricRepository.setFingerprintEnrolled(true)
|
||||
biometricRepository.setStrongBiometricAllowed(true)
|
||||
biometricRepository.setFingerprintEnabledByDevicePolicy(true)
|
||||
}
|
||||
|
||||
private fun givenCannotShowAlternateBouncer() {
|
||||
biometricRepository.setFingerprintEnrolled(false)
|
||||
}
|
||||
}
|
||||
@@ -103,7 +103,6 @@ import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.fragments.FragmentHostManager;
|
||||
import com.android.systemui.fragments.FragmentService;
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor;
|
||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
|
||||
import com.android.systemui.media.controls.pipeline.MediaDataManager;
|
||||
@@ -286,7 +285,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
@Mock private ViewTreeObserver mViewTreeObserver;
|
||||
@Mock private KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel;
|
||||
@Mock private KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
|
||||
@Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
@Mock private MotionEvent mDownMotionEvent;
|
||||
@Captor
|
||||
private ArgumentCaptor<NotificationStackScrollLayout.OnEmptySpaceClickListener>
|
||||
@@ -502,7 +500,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
systemClock,
|
||||
mKeyguardBottomAreaViewModel,
|
||||
mKeyguardBottomAreaInteractor,
|
||||
mAlternateBouncerInteractor,
|
||||
mDumpManager);
|
||||
mNotificationPanelViewController.initDependencies(
|
||||
mCentralSurfaces,
|
||||
|
||||
@@ -30,7 +30,6 @@ import com.android.systemui.classifier.FalsingCollectorFake
|
||||
import com.android.systemui.dock.DockManager
|
||||
import com.android.systemui.flags.FeatureFlags
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
|
||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
|
||||
import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
|
||||
import com.android.systemui.statusbar.LockscreenShadeTransitionController
|
||||
@@ -98,8 +97,6 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
|
||||
private lateinit var pulsingGestureListener: PulsingGestureListener
|
||||
@Mock
|
||||
private lateinit var notificationInsetsController: NotificationInsetsController
|
||||
@Mock
|
||||
private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
|
||||
@Mock lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory
|
||||
@Mock lateinit var keyguardBouncerContainer: ViewGroup
|
||||
@Mock lateinit var keyguardBouncerComponent: KeyguardBouncerComponent
|
||||
@@ -135,8 +132,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
|
||||
pulsingGestureListener,
|
||||
featureFlags,
|
||||
keyguardBouncerViewModel,
|
||||
keyguardBouncerComponentFactory,
|
||||
alternateBouncerInteractor
|
||||
keyguardBouncerComponentFactory
|
||||
)
|
||||
underTest.setupExpandedStatusBar()
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ import com.android.systemui.classifier.FalsingCollectorFake;
|
||||
import com.android.systemui.dock.DockManager;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
|
||||
import com.android.systemui.statusbar.DragDownHelper;
|
||||
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
|
||||
@@ -94,7 +93,6 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
||||
@Mock private KeyguardBouncerViewModel mKeyguardBouncerViewModel;
|
||||
@Mock private KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
|
||||
@Mock private NotificationInsetsController mNotificationInsetsController;
|
||||
@Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
|
||||
@Captor private ArgumentCaptor<NotificationShadeWindowView.InteractionEventHandler>
|
||||
mInteractionEventHandlerCaptor;
|
||||
@@ -134,8 +132,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
||||
mPulsingGestureListener,
|
||||
mFeatureFlags,
|
||||
mKeyguardBouncerViewModel,
|
||||
mKeyguardBouncerComponentFactory,
|
||||
mAlternateBouncerInteractor
|
||||
mKeyguardBouncerComponentFactory
|
||||
);
|
||||
mController.setupExpandedStatusBar();
|
||||
mController.setDragDownHelper(mDragDownHelper);
|
||||
@@ -158,7 +155,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
||||
|
||||
// WHEN showing alt auth, not dozing, drag down helper doesn't want to intercept
|
||||
when(mStatusBarStateController.isDozing()).thenReturn(false);
|
||||
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
|
||||
when(mStatusBarKeyguardViewManager.isShowingAlternateBouncer()).thenReturn(true);
|
||||
when(mDragDownHelper.onInterceptTouchEvent(any())).thenReturn(false);
|
||||
|
||||
// THEN we should intercept touch
|
||||
@@ -171,7 +168,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
||||
|
||||
// WHEN not showing alt auth, not dozing, drag down helper doesn't want to intercept
|
||||
when(mStatusBarStateController.isDozing()).thenReturn(false);
|
||||
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false);
|
||||
when(mStatusBarKeyguardViewManager.isShowingAlternateBouncer()).thenReturn(false);
|
||||
when(mDragDownHelper.onInterceptTouchEvent(any())).thenReturn(false);
|
||||
|
||||
// THEN we shouldn't intercept touch
|
||||
@@ -184,7 +181,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
|
||||
|
||||
// WHEN showing alt auth, not dozing, drag down helper doesn't want to intercept
|
||||
when(mStatusBarStateController.isDozing()).thenReturn(false);
|
||||
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
|
||||
when(mStatusBarKeyguardViewManager.isShowingAlternateBouncer()).thenReturn(true);
|
||||
when(mDragDownHelper.onInterceptTouchEvent(any())).thenReturn(false);
|
||||
|
||||
// THEN we should handle the touch
|
||||
|
||||
@@ -99,7 +99,6 @@ import com.android.systemui.dock.DockManager;
|
||||
import com.android.systemui.keyguard.KeyguardIndication;
|
||||
import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
|
||||
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.plugins.FalsingManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
||||
@@ -178,8 +177,6 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private FaceHelpMessageDeferral mFaceHelpMessageDeferral;
|
||||
@Mock
|
||||
private AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
@Mock
|
||||
private ScreenLifecycle mScreenLifecycle;
|
||||
@Mock
|
||||
private AuthController mAuthController;
|
||||
@@ -276,8 +273,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
||||
mUserManager, mExecutor, mExecutor, mFalsingManager,
|
||||
mAuthController, mLockPatternUtils, mScreenLifecycle,
|
||||
mKeyguardBypassController, mAccessibilityManager,
|
||||
mFaceHelpMessageDeferral, mock(KeyguardLogger.class),
|
||||
mAlternateBouncerInteractor);
|
||||
mFaceHelpMessageDeferral, mock(KeyguardLogger.class));
|
||||
mController.init();
|
||||
mController.setIndicationArea(mIndicationArea);
|
||||
verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
|
||||
|
||||
@@ -86,6 +86,8 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private KeyguardViewMediator mKeyguardViewMediator;
|
||||
@Mock
|
||||
private ScrimController mScrimController;
|
||||
@Mock
|
||||
private BiometricUnlockController.BiometricModeListener mBiometricModeListener;
|
||||
@Mock
|
||||
private KeyguardStateController mKeyguardStateController;
|
||||
@@ -131,7 +133,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
|
||||
when(mVibratorHelper.hasVibrator()).thenReturn(true);
|
||||
mDependency.injectTestDependency(NotificationMediaManager.class, mMediaManager);
|
||||
mBiometricUnlockController = new BiometricUnlockController(mDozeScrimController,
|
||||
mKeyguardViewMediator,
|
||||
mKeyguardViewMediator, mScrimController,
|
||||
mNotificationShadeWindowController, mKeyguardStateController, mHandler,
|
||||
mUpdateMonitor, res.getResources(), mKeyguardBypassController,
|
||||
mMetricsLogger, mDumpManager, mPowerManager, mLogger,
|
||||
|
||||
@@ -106,7 +106,6 @@ import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
import com.android.systemui.keyguard.KeyguardViewMediator;
|
||||
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel;
|
||||
import com.android.systemui.navigationbar.NavigationBarController;
|
||||
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
|
||||
@@ -294,7 +293,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
||||
@Mock private WiredChargingRippleController mWiredChargingRippleController;
|
||||
@Mock private Lazy<CameraLauncher> mCameraLauncherLazy;
|
||||
@Mock private CameraLauncher mCameraLauncher;
|
||||
@Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
/**
|
||||
* The process of registering/unregistering a predictive back callback requires a
|
||||
* ViewRootImpl, which is present IRL, but may be missing during a Mockito unit test.
|
||||
@@ -502,9 +500,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
||||
mWiredChargingRippleController,
|
||||
mDreamManager,
|
||||
mCameraLauncherLazy,
|
||||
() -> mLightRevealScrimViewModel,
|
||||
mAlternateBouncerInteractor
|
||||
) {
|
||||
() -> mLightRevealScrimViewModel) {
|
||||
@Override
|
||||
protected ViewRootImpl getViewRootImpl() {
|
||||
return mViewRootImpl;
|
||||
|
||||
@@ -56,7 +56,6 @@ import com.android.systemui.dreams.DreamOverlayStateController;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.keyguard.data.BouncerView;
|
||||
import com.android.systemui.keyguard.data.BouncerViewDelegate;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor;
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
|
||||
import com.android.systemui.navigationbar.NavigationModeController;
|
||||
@@ -106,6 +105,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
|
||||
@Mock private KeyguardBouncer.Factory mKeyguardBouncerFactory;
|
||||
@Mock private KeyguardMessageAreaController.Factory mKeyguardMessageAreaFactory;
|
||||
@Mock private KeyguardMessageAreaController mKeyguardMessageAreaController;
|
||||
@Mock private StatusBarKeyguardViewManager.AlternateBouncer mAlternateBouncer;
|
||||
@Mock private KeyguardMessageArea mKeyguardMessageArea;
|
||||
@Mock private ShadeController mShadeController;
|
||||
@Mock private SysUIUnfoldComponent mSysUiUnfoldComponent;
|
||||
@@ -115,7 +115,6 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
|
||||
@Mock private KeyguardSecurityModel mKeyguardSecurityModel;
|
||||
@Mock private PrimaryBouncerCallbackInteractor mPrimaryBouncerCallbackInteractor;
|
||||
@Mock private PrimaryBouncerInteractor mPrimaryBouncerInteractor;
|
||||
@Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
@Mock private BouncerView mBouncerView;
|
||||
@Mock private BouncerViewDelegate mBouncerViewDelegate;
|
||||
|
||||
@@ -164,8 +163,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
|
||||
mFeatureFlags,
|
||||
mPrimaryBouncerCallbackInteractor,
|
||||
mPrimaryBouncerInteractor,
|
||||
mBouncerView,
|
||||
mAlternateBouncerInteractor) {
|
||||
mBouncerView) {
|
||||
@Override
|
||||
public ViewRootImpl getViewRootImpl() {
|
||||
return mViewRootImpl;
|
||||
@@ -436,35 +434,37 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testShowing_whenAlternateAuthShowing() {
|
||||
mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
|
||||
when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(false);
|
||||
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
|
||||
when(mAlternateBouncer.isShowingAlternateBouncer()).thenReturn(true);
|
||||
assertTrue(
|
||||
"Is showing not accurate when alternative bouncer is visible",
|
||||
"Is showing not accurate when alternative auth showing",
|
||||
mStatusBarKeyguardViewManager.isBouncerShowing());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWillBeShowing_whenAlternateAuthShowing() {
|
||||
mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
|
||||
when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(false);
|
||||
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
|
||||
when(mAlternateBouncer.isShowingAlternateBouncer()).thenReturn(true);
|
||||
assertTrue(
|
||||
"Is or will be showing not accurate when alternate bouncer is visible",
|
||||
"Is or will be showing not accurate when alternative auth showing",
|
||||
mStatusBarKeyguardViewManager.primaryBouncerIsOrWillBeShowing());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHideAlternateBouncer_onShowPrimaryBouncer() {
|
||||
reset(mAlternateBouncerInteractor);
|
||||
|
||||
// GIVEN alt bouncer is showing
|
||||
public void testHideAlternateBouncer_onShowBouncer() {
|
||||
// GIVEN alt auth is showing
|
||||
mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
|
||||
when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(false);
|
||||
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
|
||||
when(mAlternateBouncer.isShowingAlternateBouncer()).thenReturn(true);
|
||||
reset(mAlternateBouncer);
|
||||
|
||||
// WHEN showBouncer is called
|
||||
mStatusBarKeyguardViewManager.showPrimaryBouncer(true);
|
||||
|
||||
// THEN alt bouncer should be hidden
|
||||
verify(mAlternateBouncerInteractor).hide();
|
||||
verify(mAlternateBouncer).hideAlternateBouncer();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -479,9 +479,11 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testShowAltAuth_unlockingWithBiometricNotAllowed() {
|
||||
// GIVEN cannot use alternate bouncer
|
||||
// GIVEN alt auth exists, unlocking with biometric isn't allowed
|
||||
mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
|
||||
when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(false);
|
||||
when(mAlternateBouncerInteractor.canShowAlternateBouncerForFingerprint()).thenReturn(false);
|
||||
when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean()))
|
||||
.thenReturn(false);
|
||||
|
||||
// WHEN showGenericBouncer is called
|
||||
final boolean scrimmed = true;
|
||||
@@ -489,19 +491,21 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
|
||||
|
||||
// THEN regular bouncer is shown
|
||||
verify(mPrimaryBouncerInteractor).show(eq(scrimmed));
|
||||
verify(mAlternateBouncer, never()).showAlternateBouncer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowAlternateBouncer_unlockingWithBiometricAllowed() {
|
||||
// GIVEN will show alternate bouncer
|
||||
// GIVEN alt auth exists, unlocking with biometric is allowed
|
||||
mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
|
||||
when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(false);
|
||||
when(mAlternateBouncerInteractor.show()).thenReturn(true);
|
||||
when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
|
||||
|
||||
// WHEN showGenericBouncer is called
|
||||
mStatusBarKeyguardViewManager.showBouncer(true);
|
||||
|
||||
// THEN alt auth bouncer is shown
|
||||
verify(mAlternateBouncerInteractor).show();
|
||||
verify(mAlternateBouncer).showAlternateBouncer();
|
||||
verify(mPrimaryBouncerInteractor, never()).show(anyBoolean());
|
||||
}
|
||||
|
||||
@@ -609,8 +613,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
|
||||
mFeatureFlags,
|
||||
mPrimaryBouncerCallbackInteractor,
|
||||
mPrimaryBouncerInteractor,
|
||||
mBouncerView,
|
||||
mAlternateBouncerInteractor) {
|
||||
mBouncerView) {
|
||||
@Override
|
||||
public ViewRootImpl getViewRootImpl() {
|
||||
return mViewRootImpl;
|
||||
|
||||
@@ -56,7 +56,6 @@ import com.android.systemui.dreams.DreamOverlayStateController;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.keyguard.data.BouncerView;
|
||||
import com.android.systemui.keyguard.data.BouncerViewDelegate;
|
||||
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor;
|
||||
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
|
||||
import com.android.systemui.navigationbar.NavigationModeController;
|
||||
@@ -110,6 +109,7 @@ public class StatusBarKeyguardViewManagerTest_Old extends SysuiTestCase {
|
||||
@Mock private KeyguardMessageAreaController.Factory mKeyguardMessageAreaFactory;
|
||||
@Mock private KeyguardMessageAreaController mKeyguardMessageAreaController;
|
||||
@Mock private KeyguardBouncer mPrimaryBouncer;
|
||||
@Mock private StatusBarKeyguardViewManager.AlternateBouncer mAlternateBouncer;
|
||||
@Mock private KeyguardMessageArea mKeyguardMessageArea;
|
||||
@Mock private ShadeController mShadeController;
|
||||
@Mock private SysUIUnfoldComponent mSysUiUnfoldComponent;
|
||||
@@ -119,7 +119,6 @@ public class StatusBarKeyguardViewManagerTest_Old extends SysuiTestCase {
|
||||
@Mock private KeyguardSecurityModel mKeyguardSecurityModel;
|
||||
@Mock private PrimaryBouncerCallbackInteractor mPrimaryBouncerCallbackInteractor;
|
||||
@Mock private PrimaryBouncerInteractor mPrimaryBouncerInteractor;
|
||||
@Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
@Mock private BouncerView mBouncerView;
|
||||
@Mock private BouncerViewDelegate mBouncerViewDelegate;
|
||||
|
||||
@@ -170,8 +169,7 @@ public class StatusBarKeyguardViewManagerTest_Old extends SysuiTestCase {
|
||||
mFeatureFlags,
|
||||
mPrimaryBouncerCallbackInteractor,
|
||||
mPrimaryBouncerInteractor,
|
||||
mBouncerView,
|
||||
mAlternateBouncerInteractor) {
|
||||
mBouncerView) {
|
||||
@Override
|
||||
public ViewRootImpl getViewRootImpl() {
|
||||
return mViewRootImpl;
|
||||
@@ -440,6 +438,41 @@ public class StatusBarKeyguardViewManagerTest_Old extends SysuiTestCase {
|
||||
verify(cancelAction, never()).run();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowing_whenAlternateAuthShowing() {
|
||||
mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
|
||||
when(mPrimaryBouncer.isShowing()).thenReturn(false);
|
||||
when(mAlternateBouncer.isShowingAlternateBouncer()).thenReturn(true);
|
||||
assertTrue(
|
||||
"Is showing not accurate when alternative auth showing",
|
||||
mStatusBarKeyguardViewManager.isBouncerShowing());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWillBeShowing_whenAlternateAuthShowing() {
|
||||
mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
|
||||
when(mPrimaryBouncer.isShowing()).thenReturn(false);
|
||||
when(mAlternateBouncer.isShowingAlternateBouncer()).thenReturn(true);
|
||||
assertTrue(
|
||||
"Is or will be showing not accurate when alternative auth showing",
|
||||
mStatusBarKeyguardViewManager.primaryBouncerIsOrWillBeShowing());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHideAlternateBouncer_onShowBouncer() {
|
||||
// GIVEN alt auth is showing
|
||||
mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
|
||||
when(mPrimaryBouncer.isShowing()).thenReturn(false);
|
||||
when(mAlternateBouncer.isShowingAlternateBouncer()).thenReturn(true);
|
||||
reset(mAlternateBouncer);
|
||||
|
||||
// WHEN showBouncer is called
|
||||
mStatusBarKeyguardViewManager.showPrimaryBouncer(true);
|
||||
|
||||
// THEN alt bouncer should be hidden
|
||||
verify(mAlternateBouncer).hideAlternateBouncer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBouncerIsOrWillBeShowing_whenBouncerIsInTransit() {
|
||||
when(mPrimaryBouncer.isShowing()).thenReturn(false);
|
||||
@@ -450,6 +483,38 @@ public class StatusBarKeyguardViewManagerTest_Old extends SysuiTestCase {
|
||||
mStatusBarKeyguardViewManager.primaryBouncerIsOrWillBeShowing());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowAltAuth_unlockingWithBiometricNotAllowed() {
|
||||
// GIVEN alt auth exists, unlocking with biometric isn't allowed
|
||||
mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
|
||||
when(mPrimaryBouncer.isShowing()).thenReturn(false);
|
||||
when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean()))
|
||||
.thenReturn(false);
|
||||
|
||||
// WHEN showGenericBouncer is called
|
||||
final boolean scrimmed = true;
|
||||
mStatusBarKeyguardViewManager.showBouncer(scrimmed);
|
||||
|
||||
// THEN regular bouncer is shown
|
||||
verify(mPrimaryBouncer).show(anyBoolean(), eq(scrimmed));
|
||||
verify(mAlternateBouncer, never()).showAlternateBouncer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowAlternateBouncer_unlockingWithBiometricAllowed() {
|
||||
// GIVEN alt auth exists, unlocking with biometric is allowed
|
||||
mStatusBarKeyguardViewManager.setAlternateBouncer(mAlternateBouncer);
|
||||
when(mPrimaryBouncer.isShowing()).thenReturn(false);
|
||||
when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
|
||||
|
||||
// WHEN showGenericBouncer is called
|
||||
mStatusBarKeyguardViewManager.showBouncer(true);
|
||||
|
||||
// THEN alt auth bouncer is shown
|
||||
verify(mAlternateBouncer).showAlternateBouncer();
|
||||
verify(mPrimaryBouncer, never()).show(anyBoolean(), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateResources_delegatesToBouncer() {
|
||||
mStatusBarKeyguardViewManager.updateResources();
|
||||
@@ -563,8 +628,7 @@ public class StatusBarKeyguardViewManagerTest_Old extends SysuiTestCase {
|
||||
mFeatureFlags,
|
||||
mPrimaryBouncerCallbackInteractor,
|
||||
mPrimaryBouncerInteractor,
|
||||
mBouncerView,
|
||||
mAlternateBouncerInteractor) {
|
||||
mBouncerView) {
|
||||
@Override
|
||||
public ViewRootImpl getViewRootImpl() {
|
||||
return mViewRootImpl;
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.keyguard.data.repository
|
||||
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
class FakeBiometricRepository : BiometricRepository {
|
||||
|
||||
private val _isFingerprintEnrolled = MutableStateFlow<Boolean>(false)
|
||||
override val isFingerprintEnrolled: StateFlow<Boolean> = _isFingerprintEnrolled.asStateFlow()
|
||||
|
||||
private val _isStrongBiometricAllowed = MutableStateFlow(false)
|
||||
override val isStrongBiometricAllowed = _isStrongBiometricAllowed.asStateFlow()
|
||||
|
||||
private val _isFingerprintEnabledByDevicePolicy = MutableStateFlow(false)
|
||||
override val isFingerprintEnabledByDevicePolicy =
|
||||
_isFingerprintEnabledByDevicePolicy.asStateFlow()
|
||||
|
||||
fun setFingerprintEnrolled(isFingerprintEnrolled: Boolean) {
|
||||
_isFingerprintEnrolled.value = isFingerprintEnrolled
|
||||
}
|
||||
|
||||
fun setStrongBiometricAllowed(isStrongBiometricAllowed: Boolean) {
|
||||
_isStrongBiometricAllowed.value = isStrongBiometricAllowed
|
||||
}
|
||||
|
||||
fun setFingerprintEnabledByDevicePolicy(isFingerprintEnabledByDevicePolicy: Boolean) {
|
||||
_isFingerprintEnabledByDevicePolicy.value = isFingerprintEnabledByDevicePolicy
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user