Show side fps hint on large screen bouncer
This adds an hint regarding the possibility to unlock with the fingerprint while on bouncer, only when sided bouncer is enabled (so only on large screens). The hint is visible while the sensor is running. Bug: 226610828 Test: atest KeyguardSecurityContainerControllerTest Change-Id: I961ae6fe67e92620e955a5e297052e255fddd80d
This commit is contained in:
@@ -336,6 +336,11 @@ public class KeyguardHostViewController extends ViewController<KeyguardHostView>
|
||||
mKeyguardSecurityContainerController.onStartingToHide();
|
||||
}
|
||||
|
||||
/** Called when bouncer visibility changes. */
|
||||
public void onBouncerVisibilityChanged(@View.Visibility int visibility) {
|
||||
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(visibility);
|
||||
}
|
||||
|
||||
public boolean hasDismissActions() {
|
||||
return mDismissAction != null || mCancelAction != null;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.keyguard;
|
||||
|
||||
import static android.app.StatusBarManager.SESSION_KEYGUARD;
|
||||
import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
|
||||
|
||||
import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_BIOMETRIC;
|
||||
import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_EXTENDED_ACCESS;
|
||||
@@ -32,11 +33,13 @@ import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Configuration;
|
||||
import android.hardware.biometrics.BiometricSourceType;
|
||||
import android.metrics.LogMaker;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -55,6 +58,7 @@ import com.android.keyguard.dagger.KeyguardBouncerScope;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
import com.android.systemui.Gefingerpoken;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.biometrics.SidefpsController;
|
||||
import com.android.systemui.classifier.FalsingCollector;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.flags.Flags;
|
||||
@@ -67,6 +71,8 @@ import com.android.systemui.statusbar.policy.UserSwitcherController;
|
||||
import com.android.systemui.util.ViewController;
|
||||
import com.android.systemui.util.settings.GlobalSettings;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/** Controller for {@link KeyguardSecurityContainer} */
|
||||
@@ -93,6 +99,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
private final GlobalSettings mGlobalSettings;
|
||||
private final FeatureFlags mFeatureFlags;
|
||||
private final SessionTracker mSessionTracker;
|
||||
private final Optional<SidefpsController> mSidefpsController;
|
||||
|
||||
private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;
|
||||
|
||||
@@ -236,13 +243,27 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
reloadColors();
|
||||
}
|
||||
};
|
||||
private boolean mBouncerVisible = false;
|
||||
private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
|
||||
new KeyguardUpdateMonitorCallback() {
|
||||
@Override
|
||||
public void onDevicePolicyManagerStateChanged() {
|
||||
showPrimarySecurityScreen(false);
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public void onDevicePolicyManagerStateChanged() {
|
||||
showPrimarySecurityScreen(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBiometricRunningStateChanged(boolean running,
|
||||
BiometricSourceType biometricSourceType) {
|
||||
if (biometricSourceType == FINGERPRINT) {
|
||||
updateSideFpsVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStrongAuthStateChanged(int userId) {
|
||||
updateSideFpsVisibility();
|
||||
}
|
||||
};
|
||||
|
||||
private KeyguardSecurityContainerController(KeyguardSecurityContainer view,
|
||||
AdminSecondaryLockScreenController.Factory adminSecondaryLockScreenControllerFactory,
|
||||
@@ -260,7 +281,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
UserSwitcherController userSwitcherController,
|
||||
FeatureFlags featureFlags,
|
||||
GlobalSettings globalSettings,
|
||||
SessionTracker sessionTracker) {
|
||||
SessionTracker sessionTracker,
|
||||
Optional<SidefpsController> sidefpsController) {
|
||||
super(view);
|
||||
mLockPatternUtils = lockPatternUtils;
|
||||
mUpdateMonitor = keyguardUpdateMonitor;
|
||||
@@ -280,6 +302,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
mFeatureFlags = featureFlags;
|
||||
mGlobalSettings = globalSettings;
|
||||
mSessionTracker = sessionTracker;
|
||||
mSidefpsController = sidefpsController;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -311,8 +334,23 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
getCurrentSecurityController().onPause();
|
||||
}
|
||||
mView.onPause();
|
||||
// It might happen that onStartingToHide is not called when the device is locked while on
|
||||
// bouncer.
|
||||
setBouncerVisible(false);
|
||||
}
|
||||
|
||||
private void updateSideFpsVisibility() {
|
||||
if (!mSidefpsController.isPresent()) {
|
||||
return;
|
||||
}
|
||||
if (mBouncerVisible && mView.isSidedSecurityMode()
|
||||
&& mUpdateMonitor.isFingerprintDetectionRunning()
|
||||
&& !mUpdateMonitor.userNeedsStrongAuth()) {
|
||||
mSidefpsController.get().show();
|
||||
} else {
|
||||
mSidefpsController.get().hide();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the primary security screen for the user. This will be either the multi-selector
|
||||
@@ -397,6 +435,17 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
if (mCurrentSecurityMode != SecurityMode.None) {
|
||||
getCurrentSecurityController().onStartingToHide();
|
||||
}
|
||||
setBouncerVisible(false);
|
||||
}
|
||||
|
||||
/** Called when the bouncer changes visibility. */
|
||||
public void onBouncerVisibilityChanged(@View.Visibility int visibility) {
|
||||
setBouncerVisible(visibility == View.VISIBLE);
|
||||
}
|
||||
|
||||
private void setBouncerVisible(boolean visible) {
|
||||
mBouncerVisible = visible;
|
||||
updateSideFpsVisibility();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -655,6 +704,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
private final FeatureFlags mFeatureFlags;
|
||||
private final UserSwitcherController mUserSwitcherController;
|
||||
private final SessionTracker mSessionTracker;
|
||||
private final Optional<SidefpsController> mSidefpsController;
|
||||
|
||||
@Inject
|
||||
Factory(KeyguardSecurityContainer view,
|
||||
@@ -673,7 +723,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
UserSwitcherController userSwitcherController,
|
||||
FeatureFlags featureFlags,
|
||||
GlobalSettings globalSettings,
|
||||
SessionTracker sessionTracker) {
|
||||
SessionTracker sessionTracker,
|
||||
Optional<SidefpsController> sidefpsController) {
|
||||
mView = view;
|
||||
mAdminSecondaryLockScreenControllerFactory = adminSecondaryLockScreenControllerFactory;
|
||||
mLockPatternUtils = lockPatternUtils;
|
||||
@@ -690,6 +741,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
mGlobalSettings = globalSettings;
|
||||
mUserSwitcherController = userSwitcherController;
|
||||
mSessionTracker = sessionTracker;
|
||||
mSidefpsController = sidefpsController;
|
||||
}
|
||||
|
||||
public KeyguardSecurityContainerController create(
|
||||
@@ -699,7 +751,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
|
||||
mKeyguardStateController, securityCallback, mSecurityViewFlipperController,
|
||||
mConfigurationController, mFalsingCollector, mFalsingManager,
|
||||
mUserSwitcherController, mFeatureFlags, mGlobalSettings, mSessionTracker);
|
||||
mUserSwitcherController, mFeatureFlags, mGlobalSettings, mSessionTracker,
|
||||
mSidefpsController);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package com.android.keyguard.dagger;
|
||||
|
||||
import static com.android.systemui.biometrics.SidefpsControllerKt.hasSideFpsSensor;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
@@ -23,9 +27,14 @@ import com.android.keyguard.KeyguardHostView;
|
||||
import com.android.keyguard.KeyguardSecurityContainer;
|
||||
import com.android.keyguard.KeyguardSecurityViewFlipper;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.biometrics.SidefpsController;
|
||||
import com.android.systemui.dagger.qualifiers.RootView;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBouncer;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
@@ -60,4 +69,16 @@ public interface KeyguardBouncerModule {
|
||||
KeyguardSecurityContainer containerView) {
|
||||
return containerView.findViewById(R.id.view_flipper);
|
||||
}
|
||||
|
||||
/** Provides {@link SidefpsController} if the device has the side fingerprint sensor. */
|
||||
@Provides
|
||||
@KeyguardBouncerScope
|
||||
static Optional<SidefpsController> providesOptionalSidefpsController(
|
||||
@Nullable FingerprintManager fingerprintManager,
|
||||
Provider<SidefpsController> sidefpsControllerProvider) {
|
||||
if (!hasSideFpsSensor(fingerprintManager)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(sidefpsControllerProvider.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,16 +34,16 @@ import android.hardware.fingerprint.ISidefpsController
|
||||
import android.os.Handler
|
||||
import android.util.Log
|
||||
import android.util.RotationUtils
|
||||
import android.view.View.AccessibilityDelegate
|
||||
import android.view.accessibility.AccessibilityEvent
|
||||
import android.view.Display
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Surface
|
||||
import android.view.View
|
||||
import android.view.View.AccessibilityDelegate
|
||||
import android.view.ViewPropertyAnimator
|
||||
import android.view.WindowInsets
|
||||
import android.view.WindowManager
|
||||
import android.view.accessibility.AccessibilityEvent
|
||||
import androidx.annotation.RawRes
|
||||
import com.airbnb.lottie.LottieAnimationView
|
||||
import com.airbnb.lottie.LottieProperty
|
||||
@@ -70,13 +70,12 @@ class SidefpsController @Inject constructor(
|
||||
private val activityTaskManager: ActivityTaskManager,
|
||||
overviewProxyService: OverviewProxyService,
|
||||
displayManager: DisplayManager,
|
||||
@Main mainExecutor: DelayableExecutor,
|
||||
@Main private val mainExecutor: DelayableExecutor,
|
||||
@Main private val handler: Handler
|
||||
) {
|
||||
@VisibleForTesting
|
||||
val sensorProps: FingerprintSensorPropertiesInternal = fingerprintManager
|
||||
?.sensorPropertiesInternal
|
||||
?.firstOrNull { it.isAnySidefpsType }
|
||||
?.sideFpsSensorProperties
|
||||
?: throw IllegalStateException("no side fingerprint sensor")
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -135,25 +134,34 @@ class SidefpsController @Inject constructor(
|
||||
}
|
||||
|
||||
init {
|
||||
fingerprintManager?.setSidefpsController(object : ISidefpsController.Stub() {
|
||||
override fun show(
|
||||
sensorId: Int,
|
||||
@BiometricOverlayConstants.ShowReason reason: Int
|
||||
) = if (reason.isReasonToShow(activityTaskManager)) doShow() else hide(sensorId)
|
||||
fingerprintManager?.setSidefpsController(
|
||||
object : ISidefpsController.Stub() {
|
||||
override fun show(
|
||||
sensorId: Int,
|
||||
@BiometricOverlayConstants.ShowReason reason: Int
|
||||
) = if (reason.isReasonToShow(activityTaskManager)) show() else hide()
|
||||
|
||||
private fun doShow() = mainExecutor.execute {
|
||||
if (overlayView == null) {
|
||||
createOverlayForDisplay()
|
||||
} else {
|
||||
Log.v(TAG, "overlay already shown")
|
||||
}
|
||||
}
|
||||
|
||||
override fun hide(sensorId: Int) = mainExecutor.execute { overlayView = null }
|
||||
})
|
||||
override fun hide(sensorId: Int) = hide()
|
||||
})
|
||||
overviewProxyService.addCallback(overviewProxyListener)
|
||||
}
|
||||
|
||||
/** Shows the side fps overlay if not already shown. */
|
||||
fun show() {
|
||||
mainExecutor.execute {
|
||||
if (overlayView == null) {
|
||||
createOverlayForDisplay()
|
||||
} else {
|
||||
Log.v(TAG, "overlay already shown")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Hides the fps overlay if shown. */
|
||||
fun hide() {
|
||||
mainExecutor.execute { overlayView = null }
|
||||
}
|
||||
|
||||
private fun onOrientationChanged() {
|
||||
if (overlayView != null) {
|
||||
createOverlayForDisplay()
|
||||
@@ -266,6 +274,12 @@ class SidefpsController @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private val FingerprintManager?.sideFpsSensorProperties: FingerprintSensorPropertiesInternal?
|
||||
get() = this?.sensorPropertiesInternal?.firstOrNull { it.isAnySidefpsType }
|
||||
|
||||
/** Returns [True] when the device has a side fingerprint sensor. */
|
||||
fun FingerprintManager?.hasSideFpsSensor(): Boolean = this?.sideFpsSensorProperties != null
|
||||
|
||||
@BiometricOverlayConstants.ShowReason
|
||||
private fun Int.isReasonToShow(activityTaskManager: ActivityTaskManager): Boolean = when (this) {
|
||||
REASON_AUTH_KEYGUARD -> false
|
||||
|
||||
@@ -266,6 +266,9 @@ public class KeyguardBouncer {
|
||||
|
||||
private void setVisibility(@View.Visibility int visibility) {
|
||||
mContainer.setVisibility(visibility);
|
||||
if (mKeyguardViewController != null) {
|
||||
mKeyguardViewController.onBouncerVisibilityChanged(visibility);
|
||||
}
|
||||
dispatchVisibilityChanged();
|
||||
}
|
||||
|
||||
@@ -645,7 +648,7 @@ public class KeyguardBouncer {
|
||||
/**
|
||||
* Invoked when the bouncer expansion reaches {@link KeyguardBouncer#EXPANSION_VISIBLE}.
|
||||
* This is NOT called each time the bouncer is shown, but rather only when the fully
|
||||
* shown amount has changed based on the panel expansion. The bouncer is visibility
|
||||
* shown amount has changed based on the panel expansion. The bouncer's visibility
|
||||
* can still change when the expansion amount hasn't changed.
|
||||
* See {@link KeyguardBouncer#isShowing()} for the checks for the bouncer showing state.
|
||||
*/
|
||||
|
||||
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -31,6 +32,7 @@ import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.testing.TestableResources;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
@@ -42,6 +44,7 @@ import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
@@ -103,6 +106,17 @@ public class KeyguardHostViewControllerTest extends SysuiTestCase {
|
||||
verify(mKeyguardSecurityContainerController).onStartingToHide();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBouncerVisible_propagatesToKeyguardSecurityContainerController() {
|
||||
mKeyguardHostViewController.onBouncerVisibilityChanged(ViewGroup.VISIBLE);
|
||||
mKeyguardHostViewController.onBouncerVisibilityChanged(ViewGroup.INVISIBLE);
|
||||
|
||||
InOrder order = inOrder(mKeyguardSecurityContainerController);
|
||||
order.verify(mKeyguardSecurityContainerController).onBouncerVisibilityChanged(View.VISIBLE);
|
||||
order.verify(mKeyguardSecurityContainerController).onBouncerVisibilityChanged(
|
||||
View.INVISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGravityReappliedOnConfigurationChange() {
|
||||
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
|
||||
|
||||
@@ -25,17 +25,21 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.biometrics.BiometricSourceType;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowInsetsController;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
@@ -46,6 +50,7 @@ import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.biometrics.SidefpsController;
|
||||
import com.android.systemui.classifier.FalsingCollector;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.log.SessionTracker;
|
||||
@@ -59,10 +64,14 @@ import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper()
|
||||
@@ -124,6 +133,14 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
|
||||
private SessionTracker mSessionTracker;
|
||||
@Mock
|
||||
private KeyguardViewController mKeyguardViewController;
|
||||
@Mock
|
||||
private SidefpsController mSidefpsController;
|
||||
@Mock
|
||||
private KeyguardPasswordViewController mKeyguardPasswordViewControllerMock;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallback;
|
||||
|
||||
private Configuration mConfiguration;
|
||||
|
||||
private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
|
||||
@@ -160,7 +177,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
|
||||
mKeyguardStateController, mKeyguardSecurityViewFlipperController,
|
||||
mConfigurationController, mFalsingCollector, mFalsingManager,
|
||||
mUserSwitcherController, mFeatureFlags, mGlobalSettings,
|
||||
mSessionTracker).create(mSecurityCallback);
|
||||
mSessionTracker, Optional.of(mSidefpsController)).create(mSecurityCallback);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -258,9 +275,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void showSecurityScreen_twoHandedMode_flagEnabled_noOneHandedMode() {
|
||||
when(mResources.getBoolean(R.bool.can_use_one_handed_bouncer)).thenReturn(true);
|
||||
when(mKeyguardSecurityViewFlipperController.getSecurityView(
|
||||
eq(SecurityMode.Password), any(KeyguardSecurityCallback.class)))
|
||||
.thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);
|
||||
setupGetSecurityView();
|
||||
|
||||
mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Password);
|
||||
verify(mView).initMode(MODE_DEFAULT, mGlobalSettings, mFalsingManager,
|
||||
@@ -276,4 +291,126 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
|
||||
verify(mUserSwitcherController)
|
||||
.removeUserSwitchCallback(any(UserSwitcherController.UserSwitchCallback.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBouncerVisibilityChanged_allConditionsGood_sideFpsHintShown() {
|
||||
setupConditionsToEnableSideFpsHint();
|
||||
reset(mSidefpsController);
|
||||
|
||||
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
|
||||
|
||||
verify(mSidefpsController).show();
|
||||
verify(mSidefpsController, never()).hide();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBouncerVisibilityChanged_fpsSensorNotRunning_sideFpsHintHidden() {
|
||||
setupConditionsToEnableSideFpsHint();
|
||||
setFingerprintDetectionRunning(false);
|
||||
reset(mSidefpsController);
|
||||
|
||||
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
|
||||
|
||||
verify(mSidefpsController).hide();
|
||||
verify(mSidefpsController, never()).show();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBouncerVisibilityChanged_withoutSidedSecurity_sideFpsHintHidden() {
|
||||
setupConditionsToEnableSideFpsHint();
|
||||
setSidedSecurityMode(false);
|
||||
reset(mSidefpsController);
|
||||
|
||||
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
|
||||
|
||||
verify(mSidefpsController).hide();
|
||||
verify(mSidefpsController, never()).show();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBouncerVisibilityChanged_needsStrongAuth_sideFpsHintHidden() {
|
||||
setupConditionsToEnableSideFpsHint();
|
||||
setNeedsStrongAuth(true);
|
||||
reset(mSidefpsController);
|
||||
|
||||
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
|
||||
|
||||
verify(mSidefpsController).hide();
|
||||
verify(mSidefpsController, never()).show();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBouncerVisibilityChanged_sideFpsHintShown_sideFpsHintHidden() {
|
||||
setupGetSecurityView();
|
||||
setupConditionsToEnableSideFpsHint();
|
||||
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
|
||||
verify(mSidefpsController, atLeastOnce()).show();
|
||||
reset(mSidefpsController);
|
||||
|
||||
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.INVISIBLE);
|
||||
|
||||
verify(mSidefpsController).hide();
|
||||
verify(mSidefpsController, never()).show();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStartingToHide_sideFpsHintShown_sideFpsHintHidden() {
|
||||
setupGetSecurityView();
|
||||
setupConditionsToEnableSideFpsHint();
|
||||
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
|
||||
verify(mSidefpsController, atLeastOnce()).show();
|
||||
reset(mSidefpsController);
|
||||
|
||||
mKeyguardSecurityContainerController.onStartingToHide();
|
||||
|
||||
verify(mSidefpsController).hide();
|
||||
verify(mSidefpsController, never()).show();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPause_sideFpsHintShown_sideFpsHintHidden() {
|
||||
setupGetSecurityView();
|
||||
setupConditionsToEnableSideFpsHint();
|
||||
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
|
||||
verify(mSidefpsController, atLeastOnce()).show();
|
||||
reset(mSidefpsController);
|
||||
|
||||
mKeyguardSecurityContainerController.onPause();
|
||||
|
||||
verify(mSidefpsController).hide();
|
||||
verify(mSidefpsController, never()).show();
|
||||
}
|
||||
|
||||
private void setupConditionsToEnableSideFpsHint() {
|
||||
attachView();
|
||||
setSidedSecurityMode(true);
|
||||
setFingerprintDetectionRunning(true);
|
||||
setNeedsStrongAuth(false);
|
||||
}
|
||||
|
||||
private void attachView() {
|
||||
mKeyguardSecurityContainerController.onViewAttached();
|
||||
verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallback.capture());
|
||||
}
|
||||
|
||||
private void setFingerprintDetectionRunning(boolean running) {
|
||||
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(running);
|
||||
mKeyguardUpdateMonitorCallback.getValue().onBiometricRunningStateChanged(running,
|
||||
BiometricSourceType.FINGERPRINT);
|
||||
}
|
||||
|
||||
private void setSidedSecurityMode(boolean sided) {
|
||||
when(mView.isSidedSecurityMode()).thenReturn(sided);
|
||||
}
|
||||
|
||||
private void setNeedsStrongAuth(boolean needed) {
|
||||
when(mKeyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(needed);
|
||||
mKeyguardUpdateMonitorCallback.getValue().onStrongAuthStateChanged(/* userId= */ 0);
|
||||
}
|
||||
|
||||
private void setupGetSecurityView() {
|
||||
when(mKeyguardSecurityViewFlipperController.getSecurityView(
|
||||
any(), any(KeyguardSecurityCallback.class)))
|
||||
.thenReturn((KeyguardInputViewController) mKeyguardPasswordViewControllerMock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,6 @@ import org.mockito.ArgumentCaptor
|
||||
import org.mockito.ArgumentMatchers.eq
|
||||
import org.mockito.Captor
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.Mockito.any
|
||||
import org.mockito.Mockito.anyFloat
|
||||
import org.mockito.Mockito.anyInt
|
||||
@@ -72,6 +71,7 @@ import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.reset
|
||||
import org.mockito.Mockito.times
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when` as whenEver
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
|
||||
private const val DISPLAY_ID = 2
|
||||
@@ -126,15 +126,15 @@ class SidefpsControllerTest : SysuiTestCase() {
|
||||
context.addMockSystemService(DisplayManager::class.java, displayManager)
|
||||
context.addMockSystemService(WindowManager::class.java, windowManager)
|
||||
|
||||
`when`(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sidefpsView)
|
||||
`when`(sidefpsView.findViewById<LottieAnimationView>(eq(R.id.sidefps_animation)))
|
||||
whenEver(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sidefpsView)
|
||||
whenEver(sidefpsView.findViewById<LottieAnimationView>(eq(R.id.sidefps_animation)))
|
||||
.thenReturn(mock(LottieAnimationView::class.java))
|
||||
with(mock(ViewPropertyAnimator::class.java)) {
|
||||
`when`(sidefpsView.animate()).thenReturn(this)
|
||||
`when`(alpha(anyFloat())).thenReturn(this)
|
||||
`when`(setStartDelay(anyLong())).thenReturn(this)
|
||||
`when`(setDuration(anyLong())).thenReturn(this)
|
||||
`when`(setListener(any())).thenAnswer {
|
||||
whenEver(sidefpsView.animate()).thenReturn(this)
|
||||
whenEver(alpha(anyFloat())).thenReturn(this)
|
||||
whenEver(setStartDelay(anyLong())).thenReturn(this)
|
||||
whenEver(setDuration(anyLong())).thenReturn(this)
|
||||
whenEver(setListener(any())).thenAnswer {
|
||||
(it.arguments[0] as Animator.AnimatorListener)
|
||||
.onAnimationEnd(mock(Animator::class.java))
|
||||
this
|
||||
@@ -177,7 +177,7 @@ class SidefpsControllerTest : SysuiTestCase() {
|
||||
displayBounds = Rect(0, 0, displayWidth, displayHeight)
|
||||
var locations = listOf(sensorLocation)
|
||||
|
||||
`when`(fingerprintManager.sensorPropertiesInternal).thenReturn(
|
||||
whenEver(fingerprintManager.sensorPropertiesInternal).thenReturn(
|
||||
listOf(
|
||||
FingerprintSensorPropertiesInternal(
|
||||
SENSOR_ID,
|
||||
@@ -196,12 +196,12 @@ class SidefpsControllerTest : SysuiTestCase() {
|
||||
displayInfo.initInfo()
|
||||
val dmGlobal = mock(DisplayManagerGlobal::class.java)
|
||||
val display = Display(dmGlobal, DISPLAY_ID, displayInfo, DEFAULT_DISPLAY_ADJUSTMENTS)
|
||||
`when`(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo)
|
||||
`when`(windowManager.defaultDisplay).thenReturn(display)
|
||||
`when`(windowManager.maximumWindowMetrics).thenReturn(
|
||||
whenEver(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo)
|
||||
whenEver(windowManager.defaultDisplay).thenReturn(display)
|
||||
whenEver(windowManager.maximumWindowMetrics).thenReturn(
|
||||
WindowMetrics(displayBounds, WindowInsets.CONSUMED)
|
||||
)
|
||||
`when`(windowManager.currentWindowMetrics).thenReturn(
|
||||
whenEver(windowManager.currentWindowMetrics).thenReturn(
|
||||
WindowMetrics(displayBounds, windowInsets)
|
||||
)
|
||||
|
||||
@@ -277,13 +277,13 @@ class SidefpsControllerTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun testShowsForMostSettings() = testWithDisplay {
|
||||
`when`(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpEnrollTask()))
|
||||
whenEver(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpEnrollTask()))
|
||||
testIgnoredFor(REASON_AUTH_SETTINGS, ignored = false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIgnoredForVerySpecificSettings() = testWithDisplay {
|
||||
`when`(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpSettingsTask()))
|
||||
whenEver(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpSettingsTask()))
|
||||
testIgnoredFor(REASON_AUTH_SETTINGS)
|
||||
}
|
||||
|
||||
@@ -424,6 +424,20 @@ class SidefpsControllerTest : SysuiTestCase() {
|
||||
assertThat(overlayViewParamsCaptor.value.x).isEqualTo(displayWidth - boundsWidth)
|
||||
assertThat(overlayViewParamsCaptor.value.y).isEqualTo(sensorLocation.sensorLocationY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasSideFpsSensor_withSensorProps_returnsTrue() = testWithDisplay {
|
||||
// By default all those tests assume the side fps sensor is available.
|
||||
|
||||
assertThat(fingerprintManager.hasSideFpsSensor()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasSideFpsSensor_withoutSensorProps_returnsFalse() {
|
||||
whenEver(fingerprintManager.sensorPropertiesInternal).thenReturn(null)
|
||||
|
||||
assertThat(fingerprintManager.hasSideFpsSensor()).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
private fun insetsForSmallNavbar() = insetsWithBottom(60)
|
||||
|
||||
@@ -229,6 +229,15 @@ public class KeyguardBouncerTest extends SysuiTestCase {
|
||||
verify(mContainer).announceForAccessibility(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void show_notifiesKeyguardViewController() {
|
||||
mBouncer.ensureView();
|
||||
|
||||
mBouncer.show(/* resetSecuritySelection= */ false);
|
||||
|
||||
verify(mKeyguardHostViewController).onBouncerVisibilityChanged(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHide_notifiesFalsingManager() {
|
||||
mBouncer.hide(false);
|
||||
|
||||
Reference in New Issue
Block a user