Merge "Move sidefps bouncer logic into interactor." into tm-qpr-dev

This commit is contained in:
Aaron Liu
2023-02-22 04:41:42 +00:00
committed by Android (Google) Code Review
13 changed files with 311 additions and 268 deletions

View File

@@ -492,12 +492,14 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_MOVE:
mVelocityTracker.addMovement(event); mVelocityTracker.addMovement(event);
int pointerIndex = event.findPointerIndex(mActivePointerId); int pointerIndex = event.findPointerIndex(mActivePointerId);
float y = event.getY(pointerIndex); if (pointerIndex != -1) {
if (mLastTouchY != -1) { float y = event.getY(pointerIndex);
float dy = y - mLastTouchY; if (mLastTouchY != -1) {
setTranslationY(getTranslationY() + dy * TOUCH_Y_MULTIPLIER); float dy = y - mLastTouchY;
setTranslationY(getTranslationY() + dy * TOUCH_Y_MULTIPLIER);
}
mLastTouchY = y;
} }
mLastTouchY = y;
break; break;
case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_CANCEL:

View File

@@ -17,7 +17,6 @@
package com.android.keyguard; package com.android.keyguard;
import static android.app.StatusBarManager.SESSION_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_BIOMETRIC;
import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_EXTENDED_ACCESS; import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_EXTENDED_ACCESS;
@@ -36,7 +35,6 @@ import android.content.res.ColorStateList;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.hardware.biometrics.BiometricOverlayConstants; import android.hardware.biometrics.BiometricOverlayConstants;
import android.hardware.biometrics.BiometricSourceType;
import android.media.AudioManager; import android.media.AudioManager;
import android.metrics.LogMaker; import android.metrics.LogMaker;
import android.os.SystemClock; import android.os.SystemClock;
@@ -320,7 +318,6 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
KeyguardSecurityContainerController.this.onDensityOrFontScaleChanged(); KeyguardSecurityContainerController.this.onDensityOrFontScaleChanged();
} }
}; };
private boolean mBouncerVisible = false;
private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback = private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() { new KeyguardUpdateMonitorCallback() {
@Override @Override
@@ -355,19 +352,6 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
public void onDevicePolicyManagerStateChanged() { public void onDevicePolicyManagerStateChanged() {
showPrimarySecurityScreen(false); showPrimarySecurityScreen(false);
} }
@Override
public void onBiometricRunningStateChanged(boolean running,
BiometricSourceType biometricSourceType) {
if (biometricSourceType == FINGERPRINT) {
updateSideFpsVisibility();
}
}
@Override
public void onStrongAuthStateChanged(int userId) {
updateSideFpsVisibility();
}
}; };
@Inject @Inject
@@ -459,35 +443,24 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
getCurrentSecurityController().onPause(); getCurrentSecurityController().onPause();
} }
mView.onPause(); mView.onPause();
// It might happen that onStartingToHide is not called when the device is locked while on
// bouncer.
setBouncerVisible(false);
mView.clearFocus(); mView.clearFocus();
} }
private void updateSideFpsVisibility() { /**
* Shows and hides the side finger print sensor animation.
*
* @param isVisible sets whether we show or hide the side fps animation
*/
public void updateSideFpsVisibility(boolean isVisible) {
if (!mSideFpsController.isPresent()) { if (!mSideFpsController.isPresent()) {
return; return;
} }
final boolean sfpsEnabled = getResources().getBoolean(
R.bool.config_show_sidefps_hint_on_bouncer);
final boolean fpsDetectionRunning = mUpdateMonitor.isFingerprintDetectionRunning();
final boolean isUnlockingWithFpAllowed =
mUpdateMonitor.isUnlockingWithFingerprintAllowed();
boolean toShow = mBouncerVisible && sfpsEnabled && fpsDetectionRunning if (isVisible) {
&& isUnlockingWithFpAllowed; mSideFpsController.get().show(
SideFpsUiRequestSource.PRIMARY_BOUNCER,
if (DEBUG) { BiometricOverlayConstants.REASON_AUTH_KEYGUARD
Log.d(TAG, "sideFpsToShow=" + toShow + ", " );
+ "mBouncerVisible=" + mBouncerVisible + ", "
+ "configEnabled=" + sfpsEnabled + ", "
+ "fpsDetectionRunning=" + fpsDetectionRunning + ", "
+ "isUnlockingWithFpAllowed=" + isUnlockingWithFpAllowed);
}
if (toShow) {
mSideFpsController.get().show(SideFpsUiRequestSource.PRIMARY_BOUNCER,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD);
} else { } else {
mSideFpsController.get().hide(SideFpsUiRequestSource.PRIMARY_BOUNCER); mSideFpsController.get().hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
} }
@@ -636,7 +609,6 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED, state); SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED, state);
getCurrentSecurityController().onResume(reason); getCurrentSecurityController().onResume(reason);
updateSideFpsVisibility();
} }
mView.onResume( mView.onResume(
mSecurityModel.getSecurityMode(KeyguardUpdateMonitor.getCurrentUser()), mSecurityModel.getSecurityMode(KeyguardUpdateMonitor.getCurrentUser()),
@@ -690,22 +662,15 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
if (mCurrentSecurityMode != SecurityMode.None) { if (mCurrentSecurityMode != SecurityMode.None) {
getCurrentSecurityController().onStartingToHide(); getCurrentSecurityController().onStartingToHide();
} }
setBouncerVisible(false);
} }
/** Called when the bouncer changes visibility. */ /** Called when the bouncer changes visibility. */
public void onBouncerVisibilityChanged(@View.Visibility int visibility) { public void onBouncerVisibilityChanged(boolean isVisible) {
setBouncerVisible(visibility == View.VISIBLE); if (!isVisible) {
if (visibility == View.INVISIBLE) {
mView.resetScale(); mView.resetScale();
} }
} }
private void setBouncerVisible(boolean visible) {
mBouncerVisible = visible;
updateSideFpsVisibility();
}
/** /**
* Shows the next security screen if there is one. * Shows the next security screen if there is one.
* @param authenticated true if the user entered the correct authentication * @param authenticated true if the user entered the correct authentication

View File

@@ -60,7 +60,6 @@ interface KeyguardBouncerRepository {
*/ */
val panelExpansionAmount: StateFlow<Float> val panelExpansionAmount: StateFlow<Float>
val keyguardPosition: StateFlow<Float> val keyguardPosition: StateFlow<Float>
val onScreenTurnedOff: StateFlow<Boolean>
val isBackButtonEnabled: StateFlow<Boolean?> val isBackButtonEnabled: StateFlow<Boolean?>
/** Determines if user is already unlocked */ /** Determines if user is already unlocked */
val keyguardAuthenticated: StateFlow<Boolean?> val keyguardAuthenticated: StateFlow<Boolean?>
@@ -70,6 +69,8 @@ interface KeyguardBouncerRepository {
val bouncerErrorMessage: CharSequence? val bouncerErrorMessage: CharSequence?
val alternateBouncerVisible: StateFlow<Boolean> val alternateBouncerVisible: StateFlow<Boolean>
val alternateBouncerUIAvailable: StateFlow<Boolean> val alternateBouncerUIAvailable: StateFlow<Boolean>
val sideFpsShowing: StateFlow<Boolean>
var lastAlternateBouncerVisibleTime: Long var lastAlternateBouncerVisibleTime: Long
fun setPrimaryScrimmed(isScrimmed: Boolean) fun setPrimaryScrimmed(isScrimmed: Boolean)
@@ -98,11 +99,11 @@ interface KeyguardBouncerRepository {
fun setIsBackButtonEnabled(isBackButtonEnabled: Boolean) fun setIsBackButtonEnabled(isBackButtonEnabled: Boolean)
fun setOnScreenTurnedOff(onScreenTurnedOff: Boolean)
fun setAlternateVisible(isVisible: Boolean) fun setAlternateVisible(isVisible: Boolean)
fun setAlternateBouncerUIAvailable(isAvailable: Boolean) fun setAlternateBouncerUIAvailable(isAvailable: Boolean)
fun setSideFpsShowing(isShowing: Boolean)
} }
@SysUISingleton @SysUISingleton
@@ -142,8 +143,6 @@ constructor(
override val panelExpansionAmount = _panelExpansionAmount.asStateFlow() override val panelExpansionAmount = _panelExpansionAmount.asStateFlow()
private val _keyguardPosition = MutableStateFlow(0f) private val _keyguardPosition = MutableStateFlow(0f)
override val keyguardPosition = _keyguardPosition.asStateFlow() override val keyguardPosition = _keyguardPosition.asStateFlow()
private val _onScreenTurnedOff = MutableStateFlow(false)
override val onScreenTurnedOff = _onScreenTurnedOff.asStateFlow()
private val _isBackButtonEnabled = MutableStateFlow<Boolean?>(null) private val _isBackButtonEnabled = MutableStateFlow<Boolean?>(null)
override val isBackButtonEnabled = _isBackButtonEnabled.asStateFlow() override val isBackButtonEnabled = _isBackButtonEnabled.asStateFlow()
private val _keyguardAuthenticated = MutableStateFlow<Boolean?>(null) private val _keyguardAuthenticated = MutableStateFlow<Boolean?>(null)
@@ -165,6 +164,8 @@ constructor(
private val _alternateBouncerUIAvailable = MutableStateFlow(false) private val _alternateBouncerUIAvailable = MutableStateFlow(false)
override val alternateBouncerUIAvailable: StateFlow<Boolean> = override val alternateBouncerUIAvailable: StateFlow<Boolean> =
_alternateBouncerUIAvailable.asStateFlow() _alternateBouncerUIAvailable.asStateFlow()
private val _sideFpsShowing = MutableStateFlow(false)
override val sideFpsShowing: StateFlow<Boolean> = _sideFpsShowing.asStateFlow()
init { init {
setUpLogging() setUpLogging()
@@ -235,8 +236,8 @@ constructor(
_isBackButtonEnabled.value = isBackButtonEnabled _isBackButtonEnabled.value = isBackButtonEnabled
} }
override fun setOnScreenTurnedOff(onScreenTurnedOff: Boolean) { override fun setSideFpsShowing(isShowing: Boolean) {
_onScreenTurnedOff.value = onScreenTurnedOff _sideFpsShowing.value = isShowing
} }
/** Sets up logs for state flows. */ /** Sets up logs for state flows. */
@@ -276,9 +277,6 @@ constructor(
.map { it.toInt() } .map { it.toInt() }
.logDiffsForTable(buffer, "", "KeyguardPosition", -1) .logDiffsForTable(buffer, "", "KeyguardPosition", -1)
.launchIn(applicationScope) .launchIn(applicationScope)
onScreenTurnedOff
.logDiffsForTable(buffer, "", "OnScreenTurnedOff", false)
.launchIn(applicationScope)
isBackButtonEnabled isBackButtonEnabled
.filterNotNull() .filterNotNull()
.logDiffsForTable(buffer, "", "IsBackButtonEnabled", false) .logDiffsForTable(buffer, "", "IsBackButtonEnabled", false)
@@ -293,6 +291,9 @@ constructor(
alternateBouncerUIAvailable alternateBouncerUIAvailable
.logDiffsForTable(buffer, "", "IsAlternateBouncerUIAvailable", false) .logDiffsForTable(buffer, "", "IsAlternateBouncerUIAvailable", false)
.launchIn(applicationScope) .launchIn(applicationScope)
sideFpsShowing
.logDiffsForTable(buffer, "", "isSideFpsShowing", false)
.launchIn(applicationScope)
} }
companion object { companion object {

View File

@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.domain.interactor package com.android.systemui.keyguard.domain.interactor
import android.content.Context
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.hardware.biometrics.BiometricSourceType import android.hardware.biometrics.BiometricSourceType
import android.os.Handler import android.os.Handler
@@ -23,9 +24,13 @@ import android.os.Trace
import android.os.UserHandle import android.os.UserHandle
import android.os.UserManager import android.os.UserManager
import android.view.View import android.view.View
import android.util.Log
import com.android.keyguard.KeyguardConstants
import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardSecurityModel
import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.DejankUtils import com.android.systemui.DejankUtils
import com.android.systemui.R
import com.android.systemui.classifier.FalsingCollector import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dagger.qualifiers.Main
@@ -62,8 +67,9 @@ constructor(
private val primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor, private val primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor,
private val falsingCollector: FalsingCollector, private val falsingCollector: FalsingCollector,
private val dismissCallbackRegistry: DismissCallbackRegistry, private val dismissCallbackRegistry: DismissCallbackRegistry,
private val context: Context,
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
keyguardBypassController: KeyguardBypassController, keyguardBypassController: KeyguardBypassController,
keyguardUpdateMonitor: KeyguardUpdateMonitor,
) { ) {
/** Whether we want to wait for face auth. */ /** Whether we want to wait for face auth. */
private val primaryBouncerFaceDelay = private val primaryBouncerFaceDelay =
@@ -90,7 +96,6 @@ constructor(
} }
val keyguardAuthenticated: Flow<Boolean> = repository.keyguardAuthenticated.filterNotNull() val keyguardAuthenticated: Flow<Boolean> = repository.keyguardAuthenticated.filterNotNull()
val screenTurnedOff: Flow<Unit> = repository.onScreenTurnedOff.filter { it }.map {}
val show: Flow<KeyguardBouncerModel> = repository.primaryBouncerShow.filterNotNull() val show: Flow<KeyguardBouncerModel> = repository.primaryBouncerShow.filterNotNull()
val hide: Flow<Unit> = repository.primaryBouncerHide.filter { it }.map {} val hide: Flow<Unit> = repository.primaryBouncerHide.filter { it }.map {}
val startingToHide: Flow<Unit> = repository.primaryBouncerStartingToHide.filter { it }.map {} val startingToHide: Flow<Unit> = repository.primaryBouncerStartingToHide.filter { it }.map {}
@@ -115,6 +120,24 @@ constructor(
} }
/** Allow for interaction when just about fully visible */ /** Allow for interaction when just about fully visible */
val isInteractable: Flow<Boolean> = bouncerExpansion.map { it > 0.9 } val isInteractable: Flow<Boolean> = bouncerExpansion.map { it > 0.9 }
val sideFpsShowing: Flow<Boolean> = repository.sideFpsShowing
init {
keyguardUpdateMonitor.registerCallback(
object : KeyguardUpdateMonitorCallback() {
override fun onBiometricRunningStateChanged(
running: Boolean,
biometricSourceType: BiometricSourceType?
) {
updateSideFpsVisibility()
}
override fun onStrongAuthStateChanged(userId: Int) {
updateSideFpsVisibility()
}
}
)
}
// TODO(b/243685699): Move isScrimmed logic to data layer. // TODO(b/243685699): Move isScrimmed logic to data layer.
// TODO(b/243695312): Encapsulate all of the show logic for the bouncer. // TODO(b/243695312): Encapsulate all of the show logic for the bouncer.
@@ -122,7 +145,6 @@ constructor(
@JvmOverloads @JvmOverloads
fun show(isScrimmed: Boolean) { fun show(isScrimmed: Boolean) {
// Reset some states as we show the bouncer. // Reset some states as we show the bouncer.
repository.setOnScreenTurnedOff(false)
repository.setKeyguardAuthenticated(null) repository.setKeyguardAuthenticated(null)
repository.setPrimaryHide(false) repository.setPrimaryHide(false)
repository.setPrimaryStartingToHide(false) repository.setPrimaryStartingToHide(false)
@@ -262,11 +284,6 @@ constructor(
repository.setKeyguardAuthenticated(strongAuth) repository.setKeyguardAuthenticated(strongAuth)
} }
/** Tell the bouncer the screen has turned off. */
fun onScreenTurnedOff() {
repository.setOnScreenTurnedOff(true)
}
/** Update the position of the bouncer when showing. */ /** Update the position of the bouncer when showing. */
fun setKeyguardPosition(position: Float) { fun setKeyguardPosition(position: Float) {
repository.setKeyguardPosition(position) repository.setKeyguardPosition(position)
@@ -301,6 +318,35 @@ constructor(
repository.setPrimaryStartDisappearAnimation(finishRunnable) repository.setPrimaryStartDisappearAnimation(finishRunnable)
} }
/** Determine whether to show the side fps animation. */
fun updateSideFpsVisibility() {
val sfpsEnabled: Boolean =
context.resources.getBoolean(R.bool.config_show_sidefps_hint_on_bouncer)
val fpsDetectionRunning: Boolean = keyguardUpdateMonitor.isFingerprintDetectionRunning
val isUnlockingWithFpAllowed: Boolean =
keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed
val bouncerVisible = repository.primaryBouncerVisible.value
val toShow =
(repository.primaryBouncerVisible.value &&
sfpsEnabled &&
fpsDetectionRunning &&
isUnlockingWithFpAllowed &&
!isAnimatingAway())
if (KeyguardConstants.DEBUG) {
Log.d(
TAG,
("sideFpsToShow=$toShow\n" +
"bouncerVisible=$bouncerVisible\n" +
"configEnabled=$sfpsEnabled\n" +
"fpsDetectionRunning=$fpsDetectionRunning\n" +
"isUnlockingWithFpAllowed=$isUnlockingWithFpAllowed\n" +
"isAnimatingAway=${isAnimatingAway()}")
)
}
repository.setSideFpsShowing(toShow)
}
/** Returns whether bouncer is fully showing. */ /** Returns whether bouncer is fully showing. */
fun isFullyShowing(): Boolean { fun isFullyShowing(): Boolean {
return (repository.primaryBouncerShowingSoon.value || return (repository.primaryBouncerShowingSoon.value ||
@@ -344,4 +390,8 @@ constructor(
DejankUtils.removeCallbacks(showRunnable) DejankUtils.removeCallbacks(showRunnable)
mainHandler.removeCallbacks(showRunnable) mainHandler.removeCallbacks(showRunnable)
} }
companion object {
private const val TAG = "PrimaryBouncerInteractor"
}
} }

View File

@@ -34,6 +34,7 @@ import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -121,7 +122,6 @@ object KeyguardBouncerViewBinder {
launch { launch {
viewModel.hide.collect { viewModel.hide.collect {
securityContainerController.cancelDismissAction() securityContainerController.cancelDismissAction()
securityContainerController.onPause()
securityContainerController.reset() securityContainerController.reset()
} }
} }
@@ -155,12 +155,17 @@ object KeyguardBouncerViewBinder {
launch { launch {
viewModel.isBouncerVisible.collect { isVisible -> viewModel.isBouncerVisible.collect { isVisible ->
val visibility = if (isVisible) View.VISIBLE else View.INVISIBLE view.visibility = if (isVisible) View.VISIBLE else View.INVISIBLE
view.visibility = visibility securityContainerController.onBouncerVisibilityChanged(isVisible)
securityContainerController.onBouncerVisibilityChanged(visibility)
} }
} }
launch {
viewModel.isBouncerVisible
.filter { !it }
.collect { securityContainerController.onPause() }
}
launch { launch {
viewModel.isInteractable.collect { isInteractable -> viewModel.isInteractable.collect { isInteractable ->
securityContainerController.setInteractable(isInteractable) securityContainerController.setInteractable(isInteractable)
@@ -204,10 +209,14 @@ object KeyguardBouncerViewBinder {
} }
launch { launch {
viewModel.screenTurnedOff.collect { viewModel.shouldUpdateSideFps.collect {
if (view.visibility == View.VISIBLE) { viewModel.updateSideFpsVisibility()
securityContainerController.onPause() }
} }
launch {
viewModel.sideFpsShowing.collect {
securityContainerController.updateSideFpsVisibility(it)
} }
} }
awaitCancellation() awaitCancellation()

View File

@@ -24,7 +24,9 @@ import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
import com.android.systemui.keyguard.shared.model.KeyguardBouncerModel import com.android.systemui.keyguard.shared.model.KeyguardBouncerModel
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
/** Models UI state for the lock screen bouncer; handles user input. */ /** Models UI state for the lock screen bouncer; handles user input. */
class KeyguardBouncerViewModel class KeyguardBouncerViewModel
@@ -66,8 +68,16 @@ constructor(
/** Observe whether keyguard is authenticated already. */ /** Observe whether keyguard is authenticated already. */
val keyguardAuthenticated: Flow<Boolean> = interactor.keyguardAuthenticated val keyguardAuthenticated: Flow<Boolean> = interactor.keyguardAuthenticated
/** Observe whether screen is turned off. */ /** Observe whether the side fps is showing. */
val screenTurnedOff: Flow<Unit> = interactor.screenTurnedOff val sideFpsShowing: Flow<Boolean> = interactor.sideFpsShowing
/** Observe whether we should update fps is showing. */
val shouldUpdateSideFps: Flow<Unit> =
merge(
interactor.startingToHide,
interactor.isVisible.map {},
interactor.startingDisappearAnimation.filterNotNull().map {}
)
/** Observe whether we want to update resources. */ /** Observe whether we want to update resources. */
fun notifyUpdateResources() { fun notifyUpdateResources() {
@@ -84,6 +94,10 @@ constructor(
interactor.onMessageShown() interactor.onMessageShown()
} }
fun updateSideFpsVisibility() {
interactor.updateSideFpsVisibility()
}
/** Observe whether back button is enabled. */ /** Observe whether back button is enabled. */
fun observeOnIsBackButtonEnabled(systemUiVisibility: () -> Int): Flow<Int> { fun observeOnIsBackButtonEnabled(systemUiVisibility: () -> Int): Flow<Int> {
return interactor.isBackButtonEnabled.map { enabled -> return interactor.isBackButtonEnabled.map { enabled ->

View File

@@ -790,7 +790,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
@Override @Override
public void onFinishedGoingToSleep() { public void onFinishedGoingToSleep() {
mPrimaryBouncerInteractor.onScreenTurnedOff(); mPrimaryBouncerInteractor.hide();
} }
@Override @Override

View File

@@ -32,11 +32,9 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -44,7 +42,6 @@ import static org.mockito.Mockito.when;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.hardware.biometrics.BiometricOverlayConstants; import android.hardware.biometrics.BiometricOverlayConstants;
import android.hardware.biometrics.BiometricSourceType;
import android.media.AudioManager; import android.media.AudioManager;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner;
@@ -53,7 +50,6 @@ import android.testing.TestableResources;
import android.view.Gravity; import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View;
import android.view.WindowInsetsController; import android.view.WindowInsetsController;
import android.widget.FrameLayout; import android.widget.FrameLayout;
@@ -96,10 +92,8 @@ import java.util.Optional;
@TestableLooper.RunWithLooper() @TestableLooper.RunWithLooper()
public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
private static final int TARGET_USER_ID = 100; private static final int TARGET_USER_ID = 100;
@Rule @Rule
public MockitoRule mRule = MockitoJUnit.rule(); public MockitoRule mRule = MockitoJUnit.rule();
@Mock @Mock
private KeyguardSecurityContainer mView; private KeyguardSecurityContainer mView;
@Mock @Mock
@@ -367,134 +361,12 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
.removeUserSwitchCallback(any(UserSwitcherController.UserSwitchCallback.class)); .removeUserSwitchCallback(any(UserSwitcherController.UserSwitchCallback.class));
} }
@Test
public void onBouncerVisibilityChanged_allConditionsGood_sideFpsHintShown() {
setupConditionsToEnableSideFpsHint();
reset(mSideFpsController);
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
verify(mSideFpsController).show(SideFpsUiRequestSource.PRIMARY_BOUNCER,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD);
verify(mSideFpsController, never()).hide(any());
}
@Test
public void onBouncerVisibilityChanged_fpsSensorNotRunning_sideFpsHintHidden() {
setupConditionsToEnableSideFpsHint();
setFingerprintDetectionRunning(false);
reset(mSideFpsController);
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
verify(mSideFpsController, never()).show(any(), anyInt());
}
@Test
public void onBouncerVisibilityChanged_withoutSidedSecurity_sideFpsHintHidden() {
setupConditionsToEnableSideFpsHint();
setSideFpsHintEnabledFromResources(false);
reset(mSideFpsController);
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
verify(mSideFpsController, never()).show(any(), anyInt());
}
@Test
public void onBouncerVisibilityChanged_unlockingWithFingerprintNotAllowed_sideFpsHintHidden() {
setupConditionsToEnableSideFpsHint();
setUnlockingWithFingerprintAllowed(false);
reset(mSideFpsController);
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
verify(mSideFpsController, never()).show(any(), anyInt());
}
@Test
public void onBouncerVisibilityChanged_sideFpsHintShown_sideFpsHintHidden() {
setupGetSecurityView();
setupConditionsToEnableSideFpsHint();
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD);
reset(mSideFpsController);
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.INVISIBLE);
verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
verify(mSideFpsController, never()).show(any(), anyInt());
}
@Test @Test
public void onBouncerVisibilityChanged_resetsScale() { public void onBouncerVisibilityChanged_resetsScale() {
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.INVISIBLE); mKeyguardSecurityContainerController.onBouncerVisibilityChanged(false);
verify(mView).resetScale(); verify(mView).resetScale();
} }
@Test
public void onStartingToHide_sideFpsHintShown_sideFpsHintHidden() {
setupGetSecurityView();
setupConditionsToEnableSideFpsHint();
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD);
reset(mSideFpsController);
mKeyguardSecurityContainerController.onStartingToHide();
verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
verify(mSideFpsController, never()).show(any(), anyInt());
}
@Test
public void onPause_sideFpsHintShown_sideFpsHintHidden() {
setupGetSecurityView();
setupConditionsToEnableSideFpsHint();
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD);
reset(mSideFpsController);
mKeyguardSecurityContainerController.onPause();
verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
verify(mSideFpsController, never()).show(any(), anyInt());
}
@Test
public void onResume_sideFpsHintShouldBeShown_sideFpsHintShown() {
setupGetSecurityView();
setupConditionsToEnableSideFpsHint();
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
reset(mSideFpsController);
mKeyguardSecurityContainerController.onResume(0);
verify(mSideFpsController).show(SideFpsUiRequestSource.PRIMARY_BOUNCER,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD);
verify(mSideFpsController, never()).hide(any());
}
@Test
public void onResume_sideFpsHintShouldNotBeShown_sideFpsHintHidden() {
setupGetSecurityView();
setupConditionsToEnableSideFpsHint();
setSideFpsHintEnabledFromResources(false);
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
reset(mSideFpsController);
mKeyguardSecurityContainerController.onResume(0);
verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
verify(mSideFpsController, never()).show(any(), anyInt());
}
@Test @Test
public void showNextSecurityScreenOrFinish_setsSecurityScreenToPinAfterSimPinUnlock() { public void showNextSecurityScreenOrFinish_setsSecurityScreenToPinAfterSimPinUnlock() {
// GIVEN the current security method is SimPin // GIVEN the current security method is SimPin
@@ -719,39 +591,31 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
any(KeyguardSecurityCallback.class)); any(KeyguardSecurityCallback.class));
} }
@Test
public void testSideFpsControllerShow() {
mKeyguardSecurityContainerController.updateSideFpsVisibility(/* isVisible= */ true);
verify(mSideFpsController).show(
SideFpsUiRequestSource.PRIMARY_BOUNCER,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD);
}
@Test
public void testSideFpsControllerHide() {
mKeyguardSecurityContainerController.updateSideFpsVisibility(/* isVisible= */ false);
verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
}
private KeyguardSecurityContainer.SwipeListener getRegisteredSwipeListener() { private KeyguardSecurityContainer.SwipeListener getRegisteredSwipeListener() {
mKeyguardSecurityContainerController.onViewAttached(); mKeyguardSecurityContainerController.onViewAttached();
verify(mView).setSwipeListener(mSwipeListenerArgumentCaptor.capture()); verify(mView).setSwipeListener(mSwipeListenerArgumentCaptor.capture());
return mSwipeListenerArgumentCaptor.getValue(); return mSwipeListenerArgumentCaptor.getValue();
} }
private void setupConditionsToEnableSideFpsHint() {
attachView();
setSideFpsHintEnabledFromResources(true);
setFingerprintDetectionRunning(true);
setUnlockingWithFingerprintAllowed(true);
}
private void attachView() { private void attachView() {
mKeyguardSecurityContainerController.onViewAttached(); mKeyguardSecurityContainerController.onViewAttached();
verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallback.capture()); verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallback.capture());
} }
private void setFingerprintDetectionRunning(boolean running) {
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(running);
mKeyguardUpdateMonitorCallback.getValue().onBiometricRunningStateChanged(running,
BiometricSourceType.FINGERPRINT);
}
private void setSideFpsHintEnabledFromResources(boolean enabled) {
mTestableResources.addOverride(R.bool.config_show_sidefps_hint_on_bouncer,
enabled);
}
private void setUnlockingWithFingerprintAllowed(boolean allowed) {
when(mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed()).thenReturn(allowed);
}
private void setupGetSecurityView() { private void setupGetSecurityView() {
when(mKeyguardSecurityViewFlipperController.getSecurityView( when(mKeyguardSecurityViewFlipperController.getSecurityView(
any(), any(KeyguardSecurityCallback.class))) any(), any(KeyguardSecurityCallback.class)))

View File

@@ -86,8 +86,9 @@ class UdfpsKeyguardViewControllerWithCoroutinesTest : UdfpsKeyguardViewControlle
mock(PrimaryBouncerCallbackInteractor::class.java), mock(PrimaryBouncerCallbackInteractor::class.java),
mock(FalsingCollector::class.java), mock(FalsingCollector::class.java),
mock(DismissCallbackRegistry::class.java), mock(DismissCallbackRegistry::class.java),
context,
mKeyguardUpdateMonitor,
mock(KeyguardBypassController::class.java), mock(KeyguardBypassController::class.java),
mKeyguardUpdateMonitor
) )
mAlternateBouncerInteractor = mAlternateBouncerInteractor =
AlternateBouncerInteractor( AlternateBouncerInteractor(

View File

@@ -19,11 +19,13 @@ package com.android.systemui.keyguard.domain.interactor
import android.os.Looper import android.os.Looper
import android.testing.AndroidTestingRunner import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper import android.testing.TestableLooper.RunWithLooper
import android.testing.TestableResources
import android.view.View import android.view.View
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardSecurityModel
import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.DejankUtils import com.android.systemui.DejankUtils
import com.android.systemui.R
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.DismissCallbackRegistry
@@ -69,6 +71,7 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
private val mainHandler = FakeHandler(Looper.getMainLooper()) private val mainHandler = FakeHandler(Looper.getMainLooper())
private lateinit var underTest: PrimaryBouncerInteractor private lateinit var underTest: PrimaryBouncerInteractor
private lateinit var resources: TestableResources
@Before @Before
fun setUp() { fun setUp() {
@@ -84,18 +87,19 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
mPrimaryBouncerCallbackInteractor, mPrimaryBouncerCallbackInteractor,
falsingCollector, falsingCollector,
dismissCallbackRegistry, dismissCallbackRegistry,
keyguardBypassController, context,
keyguardUpdateMonitor, keyguardUpdateMonitor,
keyguardBypassController,
) )
`when`(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null) `when`(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
`when`(repository.primaryBouncerShow.value).thenReturn(null) `when`(repository.primaryBouncerShow.value).thenReturn(null)
`when`(bouncerView.delegate).thenReturn(bouncerViewDelegate) `when`(bouncerView.delegate).thenReturn(bouncerViewDelegate)
resources = context.orCreateTestableResources
} }
@Test @Test
fun testShow_isScrimmed() { fun testShow_isScrimmed() {
underTest.show(true) underTest.show(true)
verify(repository).setOnScreenTurnedOff(false)
verify(repository).setKeyguardAuthenticated(null) verify(repository).setKeyguardAuthenticated(null)
verify(repository).setPrimaryHide(false) verify(repository).setPrimaryHide(false)
verify(repository).setPrimaryStartingToHide(false) verify(repository).setPrimaryStartingToHide(false)
@@ -206,12 +210,6 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
verify(repository).setShowMessage(null) verify(repository).setShowMessage(null)
} }
@Test
fun testOnScreenTurnedOff() {
underTest.onScreenTurnedOff()
verify(repository).setOnScreenTurnedOff(true)
}
@Test @Test
fun testSetKeyguardPosition() { fun testSetKeyguardPosition() {
underTest.setKeyguardPosition(0f) underTest.setKeyguardPosition(0f)
@@ -286,4 +284,98 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() {
`when`(bouncerViewDelegate.willDismissWithActions()).thenReturn(false) `when`(bouncerViewDelegate.willDismissWithActions()).thenReturn(false)
assertThat(underTest.willDismissWithAction()).isFalse() assertThat(underTest.willDismissWithAction()).isFalse()
} }
@Test
fun testSideFpsVisibility() {
updateSideFpsVisibilityParameters(
isVisible = true,
sfpsEnabled = true,
fpsDetectionRunning = true,
isUnlockingWithFpAllowed = true,
isAnimatingAway = false
)
underTest.updateSideFpsVisibility()
verify(repository).setSideFpsShowing(true)
}
@Test
fun testSideFpsVisibility_notVisible() {
updateSideFpsVisibilityParameters(
isVisible = false,
sfpsEnabled = true,
fpsDetectionRunning = true,
isUnlockingWithFpAllowed = true,
isAnimatingAway = false
)
underTest.updateSideFpsVisibility()
verify(repository).setSideFpsShowing(false)
}
@Test
fun testSideFpsVisibility_sfpsNotEnabled() {
updateSideFpsVisibilityParameters(
isVisible = true,
sfpsEnabled = false,
fpsDetectionRunning = true,
isUnlockingWithFpAllowed = true,
isAnimatingAway = false
)
underTest.updateSideFpsVisibility()
verify(repository).setSideFpsShowing(false)
}
@Test
fun testSideFpsVisibility_fpsDetectionNotRunning() {
updateSideFpsVisibilityParameters(
isVisible = true,
sfpsEnabled = true,
fpsDetectionRunning = false,
isUnlockingWithFpAllowed = true,
isAnimatingAway = false
)
underTest.updateSideFpsVisibility()
verify(repository).setSideFpsShowing(false)
}
@Test
fun testSideFpsVisibility_UnlockingWithFpNotAllowed() {
updateSideFpsVisibilityParameters(
isVisible = true,
sfpsEnabled = true,
fpsDetectionRunning = true,
isUnlockingWithFpAllowed = false,
isAnimatingAway = false
)
underTest.updateSideFpsVisibility()
verify(repository).setSideFpsShowing(false)
}
@Test
fun testSideFpsVisibility_AnimatingAway() {
updateSideFpsVisibilityParameters(
isVisible = true,
sfpsEnabled = true,
fpsDetectionRunning = true,
isUnlockingWithFpAllowed = true,
isAnimatingAway = true
)
underTest.updateSideFpsVisibility()
verify(repository).setSideFpsShowing(false)
}
private fun updateSideFpsVisibilityParameters(
isVisible: Boolean,
sfpsEnabled: Boolean,
fpsDetectionRunning: Boolean,
isUnlockingWithFpAllowed: Boolean,
isAnimatingAway: Boolean
) {
`when`(repository.primaryBouncerVisible.value).thenReturn(isVisible)
resources.addOverride(R.bool.config_show_sidefps_hint_on_bouncer, sfpsEnabled)
`when`(keyguardUpdateMonitor.isFingerprintDetectionRunning).thenReturn(fpsDetectionRunning)
`when`(keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed)
.thenReturn(isUnlockingWithFpAllowed)
`when`(repository.primaryBouncerStartingDisappearAnimation.value)
.thenReturn(if (isAnimatingAway) Runnable {} else null)
}
} }

View File

@@ -26,7 +26,6 @@ import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.DismissCallbackRegistry
import com.android.systemui.keyguard.data.BouncerView import com.android.systemui.keyguard.data.BouncerView
import com.android.systemui.keyguard.data.BouncerViewDelegate
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -44,7 +43,6 @@ import org.mockito.MockitoAnnotations
class PrimaryBouncerInteractorWithCoroutinesTest : SysuiTestCase() { class PrimaryBouncerInteractorWithCoroutinesTest : SysuiTestCase() {
private lateinit var repository: FakeKeyguardBouncerRepository private lateinit var repository: FakeKeyguardBouncerRepository
@Mock private lateinit var bouncerView: BouncerView @Mock private lateinit var bouncerView: BouncerView
@Mock private lateinit var bouncerViewDelegate: BouncerViewDelegate
@Mock private lateinit var keyguardStateController: KeyguardStateController @Mock private lateinit var keyguardStateController: KeyguardStateController
@Mock private lateinit var keyguardSecurityModel: KeyguardSecurityModel @Mock private lateinit var keyguardSecurityModel: KeyguardSecurityModel
@Mock private lateinit var primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor @Mock private lateinit var primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor
@@ -69,8 +67,9 @@ class PrimaryBouncerInteractorWithCoroutinesTest : SysuiTestCase() {
primaryBouncerCallbackInteractor, primaryBouncerCallbackInteractor,
falsingCollector, falsingCollector,
dismissCallbackRegistry, dismissCallbackRegistry,
keyguardBypassController, context,
keyguardUpdateMonitor, keyguardUpdateMonitor,
keyguardBypassController,
) )
} }

View File

@@ -16,15 +16,23 @@
package com.android.systemui.keyguard.ui.viewmodel package com.android.systemui.keyguard.ui.viewmodel
import android.os.Looper
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardSecurityModel
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.keyguard.DismissCallbackRegistry
import com.android.systemui.keyguard.data.BouncerView import com.android.systemui.keyguard.data.BouncerView
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.utils.os.FakeHandler
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runCurrent
@@ -33,7 +41,6 @@ import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations import org.mockito.MockitoAnnotations
@SmallTest @SmallTest
@@ -41,31 +48,69 @@ import org.mockito.MockitoAnnotations
@kotlinx.coroutines.ExperimentalCoroutinesApi @kotlinx.coroutines.ExperimentalCoroutinesApi
class KeyguardBouncerViewModelTest : SysuiTestCase() { class KeyguardBouncerViewModelTest : SysuiTestCase() {
lateinit var underTest: KeyguardBouncerViewModel lateinit var underTest: KeyguardBouncerViewModel
lateinit var bouncerInteractor: PrimaryBouncerInteractor
@Mock lateinit var bouncerView: BouncerView @Mock lateinit var bouncerView: BouncerView
@Mock lateinit var bouncerInteractor: PrimaryBouncerInteractor @Mock private lateinit var keyguardStateController: KeyguardStateController
@Mock private lateinit var keyguardSecurityModel: KeyguardSecurityModel
@Mock private lateinit var primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor
@Mock private lateinit var falsingCollector: FalsingCollector
@Mock private lateinit var dismissCallbackRegistry: DismissCallbackRegistry
@Mock private lateinit var keyguardBypassController: KeyguardBypassController
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
private val mainHandler = FakeHandler(Looper.getMainLooper())
val repository = FakeKeyguardBouncerRepository()
@Before @Before
fun setup() { fun setup() {
MockitoAnnotations.initMocks(this) MockitoAnnotations.initMocks(this)
bouncerInteractor =
PrimaryBouncerInteractor(
repository,
bouncerView,
mainHandler,
keyguardStateController,
keyguardSecurityModel,
primaryBouncerCallbackInteractor,
falsingCollector,
dismissCallbackRegistry,
context,
keyguardUpdateMonitor,
keyguardBypassController,
)
underTest = KeyguardBouncerViewModel(bouncerView, bouncerInteractor) underTest = KeyguardBouncerViewModel(bouncerView, bouncerInteractor)
} }
@Test @Test
fun setMessage() = fun setMessage() = runTest {
runTest { var message: BouncerShowMessageModel? = null
val flow = MutableStateFlow<BouncerShowMessageModel?>(null) val job = underTest.bouncerShowMessage.onEach { message = it }.launchIn(this)
var message: BouncerShowMessageModel? = null
Mockito.`when`(bouncerInteractor.showMessage)
.thenReturn(flow as Flow<BouncerShowMessageModel>)
// Reinitialize the view model.
underTest = KeyguardBouncerViewModel(bouncerView, bouncerInteractor)
flow.value = BouncerShowMessageModel(message = "abc", colorStateList = null) repository.setShowMessage(BouncerShowMessageModel("abc", null))
// Run the tasks that are pending at this point of virtual time.
runCurrent()
assertThat(message?.message).isEqualTo("abc")
job.cancel()
}
val job = underTest.bouncerShowMessage.onEach { message = it }.launchIn(this) @Test
// Run the tasks that are pending at this point of virtual time. fun shouldUpdateSideFps() = runTest {
runCurrent() var count = 0
assertThat(message?.message).isEqualTo("abc") val job = underTest.shouldUpdateSideFps.onEach { count++ }.launchIn(this)
job.cancel() repository.setPrimaryVisible(true)
} // Run the tasks that are pending at this point of virtual time.
runCurrent()
assertThat(count).isEqualTo(1)
job.cancel()
}
@Test
fun sideFpsShowing() = runTest {
var sideFpsIsShowing = false
val job = underTest.sideFpsShowing.onEach { sideFpsIsShowing = it }.launchIn(this)
repository.setSideFpsShowing(true)
// Run the tasks that are pending at this point of virtual time.
runCurrent()
assertThat(sideFpsIsShowing).isEqualTo(true)
job.cancel()
}
} }

View File

@@ -21,6 +21,7 @@ import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.E
import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
import com.android.systemui.keyguard.shared.model.KeyguardBouncerModel import com.android.systemui.keyguard.shared.model.KeyguardBouncerModel
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
/** Fake implementation of [KeyguardRepository] */ /** Fake implementation of [KeyguardRepository] */
@@ -44,8 +45,6 @@ class FakeKeyguardBouncerRepository : KeyguardBouncerRepository {
override val panelExpansionAmount = _panelExpansionAmount.asStateFlow() override val panelExpansionAmount = _panelExpansionAmount.asStateFlow()
private val _keyguardPosition = MutableStateFlow(0f) private val _keyguardPosition = MutableStateFlow(0f)
override val keyguardPosition = _keyguardPosition.asStateFlow() override val keyguardPosition = _keyguardPosition.asStateFlow()
private val _onScreenTurnedOff = MutableStateFlow(false)
override val onScreenTurnedOff = _onScreenTurnedOff.asStateFlow()
private val _isBackButtonEnabled = MutableStateFlow<Boolean?>(null) private val _isBackButtonEnabled = MutableStateFlow<Boolean?>(null)
override val isBackButtonEnabled = _isBackButtonEnabled.asStateFlow() override val isBackButtonEnabled = _isBackButtonEnabled.asStateFlow()
private val _keyguardAuthenticated = MutableStateFlow<Boolean?>(null) private val _keyguardAuthenticated = MutableStateFlow<Boolean?>(null)
@@ -61,6 +60,8 @@ class FakeKeyguardBouncerRepository : KeyguardBouncerRepository {
override var lastAlternateBouncerVisibleTime: Long = 0L override var lastAlternateBouncerVisibleTime: Long = 0L
private val _isAlternateBouncerUIAvailable = MutableStateFlow<Boolean>(false) private val _isAlternateBouncerUIAvailable = MutableStateFlow<Boolean>(false)
override val alternateBouncerUIAvailable = _isAlternateBouncerUIAvailable.asStateFlow() override val alternateBouncerUIAvailable = _isAlternateBouncerUIAvailable.asStateFlow()
private val _sideFpsShowing: MutableStateFlow<Boolean> = MutableStateFlow(false)
override val sideFpsShowing: StateFlow<Boolean> = _sideFpsShowing.asStateFlow()
override fun setPrimaryScrimmed(isScrimmed: Boolean) { override fun setPrimaryScrimmed(isScrimmed: Boolean) {
_primaryBouncerScrimmed.value = isScrimmed _primaryBouncerScrimmed.value = isScrimmed
@@ -122,7 +123,7 @@ class FakeKeyguardBouncerRepository : KeyguardBouncerRepository {
_isBackButtonEnabled.value = isBackButtonEnabled _isBackButtonEnabled.value = isBackButtonEnabled
} }
override fun setOnScreenTurnedOff(onScreenTurnedOff: Boolean) { override fun setSideFpsShowing(isShowing: Boolean) {
_onScreenTurnedOff.value = onScreenTurnedOff _sideFpsShowing.value = isShowing
} }
} }