Provide API for accessing the current state of secure camera.
Secure camera refers to camera app launched over the lockscreen. This piece of information is required to control face auth behavior: 1. Face auth shouldn't run when secure camera is launched 2. Face auth should run when secure camera is launched but when UDFPS bouncer is shown. Bug: 262838215 Test: atest KeyguardRepositoryTest Test: atest SecureCameraInteractorTest Change-Id: I8d6d43b86c85152f6be8e7f9b0deb13a8a46cc1b
This commit is contained in:
@@ -24,8 +24,8 @@ import android.content.res.Resources
|
||||
import android.text.format.DateFormat
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.view.ViewTreeObserver
|
||||
import android.widget.FrameLayout
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
@@ -40,8 +40,8 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
|
||||
import com.android.systemui.keyguard.shared.model.TransitionState
|
||||
import com.android.systemui.lifecycle.repeatWhenAttached
|
||||
import com.android.systemui.log.dagger.KeyguardSmallClockLog
|
||||
import com.android.systemui.log.dagger.KeyguardLargeClockLog
|
||||
import com.android.systemui.log.dagger.KeyguardSmallClockLog
|
||||
import com.android.systemui.plugins.ClockController
|
||||
import com.android.systemui.plugins.ClockFaceController
|
||||
import com.android.systemui.plugins.ClockTickRate
|
||||
@@ -53,22 +53,24 @@ import com.android.systemui.statusbar.policy.BatteryController
|
||||
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor
|
||||
import java.util.Locale
|
||||
import java.util.TimeZone
|
||||
import java.util.concurrent.Executor
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.DisposableHandle
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.Locale
|
||||
import java.util.TimeZone
|
||||
import java.util.concurrent.Executor
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Controller for a Clock provided by the registry and used on the keyguard. Instantiated by
|
||||
* [KeyguardClockSwitchController]. Functionality is forked from [AnimatableClockController].
|
||||
*/
|
||||
open class ClockEventController @Inject constructor(
|
||||
open class ClockEventController
|
||||
@Inject
|
||||
constructor(
|
||||
private val keyguardInteractor: KeyguardInteractor,
|
||||
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
|
||||
private val broadcastDispatcher: BroadcastDispatcher,
|
||||
@@ -115,52 +117,59 @@ open class ClockEventController @Inject constructor(
|
||||
private var disposableHandle: DisposableHandle? = null
|
||||
private val regionSamplingEnabled = featureFlags.isEnabled(REGION_SAMPLING)
|
||||
|
||||
private val mLayoutChangedListener = object : View.OnLayoutChangeListener {
|
||||
private var currentSmallClockView: View? = null
|
||||
private var currentLargeClockView: View? = null
|
||||
private var currentSmallClockLocation = IntArray(2)
|
||||
private var currentLargeClockLocation = IntArray(2)
|
||||
private val mLayoutChangedListener =
|
||||
object : View.OnLayoutChangeListener {
|
||||
private var currentSmallClockView: View? = null
|
||||
private var currentLargeClockView: View? = null
|
||||
private var currentSmallClockLocation = IntArray(2)
|
||||
private var currentLargeClockLocation = IntArray(2)
|
||||
|
||||
override fun onLayoutChange(
|
||||
view: View?,
|
||||
left: Int,
|
||||
top: Int,
|
||||
right: Int,
|
||||
bottom: Int,
|
||||
oldLeft: Int,
|
||||
oldTop: Int,
|
||||
oldRight: Int,
|
||||
oldBottom: Int
|
||||
) {
|
||||
val parent = (view?.parent) as FrameLayout
|
||||
override fun onLayoutChange(
|
||||
view: View?,
|
||||
left: Int,
|
||||
top: Int,
|
||||
right: Int,
|
||||
bottom: Int,
|
||||
oldLeft: Int,
|
||||
oldTop: Int,
|
||||
oldRight: Int,
|
||||
oldBottom: Int
|
||||
) {
|
||||
val parent = (view?.parent) as FrameLayout
|
||||
|
||||
// don't pass in negative bounds when clocks are in transition state
|
||||
if (view.locationOnScreen[0] < 0 || view.locationOnScreen[1] < 0) {
|
||||
return
|
||||
}
|
||||
// don't pass in negative bounds when clocks are in transition state
|
||||
if (view.locationOnScreen[0] < 0 || view.locationOnScreen[1] < 0) {
|
||||
return
|
||||
}
|
||||
|
||||
// SMALL CLOCK
|
||||
if (parent.id == R.id.lockscreen_clock_view) {
|
||||
// view bounds have changed due to clock size changing (i.e. different character widths)
|
||||
// AND/OR the view has been translated when transitioning between small and large clock
|
||||
if (view != currentSmallClockView ||
|
||||
!view.locationOnScreen.contentEquals(currentSmallClockLocation)) {
|
||||
currentSmallClockView = view
|
||||
currentSmallClockLocation = view.locationOnScreen
|
||||
updateRegionSampler(view)
|
||||
// SMALL CLOCK
|
||||
if (parent.id == R.id.lockscreen_clock_view) {
|
||||
// view bounds have changed due to clock size changing (i.e. different character
|
||||
// widths)
|
||||
// AND/OR the view has been translated when transitioning between small and
|
||||
// large clock
|
||||
if (
|
||||
view != currentSmallClockView ||
|
||||
!view.locationOnScreen.contentEquals(currentSmallClockLocation)
|
||||
) {
|
||||
currentSmallClockView = view
|
||||
currentSmallClockLocation = view.locationOnScreen
|
||||
updateRegionSampler(view)
|
||||
}
|
||||
}
|
||||
// LARGE CLOCK
|
||||
else if (parent.id == R.id.lockscreen_clock_view_large) {
|
||||
if (
|
||||
view != currentLargeClockView ||
|
||||
!view.locationOnScreen.contentEquals(currentLargeClockLocation)
|
||||
) {
|
||||
currentLargeClockView = view
|
||||
currentLargeClockLocation = view.locationOnScreen
|
||||
updateRegionSampler(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// LARGE CLOCK
|
||||
else if (parent.id == R.id.lockscreen_clock_view_large) {
|
||||
if (view != currentLargeClockView ||
|
||||
!view.locationOnScreen.contentEquals(currentLargeClockLocation)) {
|
||||
currentLargeClockView = view
|
||||
currentLargeClockLocation = view.locationOnScreen
|
||||
updateRegionSampler(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateColors() {
|
||||
val wallpaperManager = WallpaperManager.getInstance(context)
|
||||
@@ -189,30 +198,33 @@ open class ClockEventController @Inject constructor(
|
||||
|
||||
private fun updateRegionSampler(sampledRegion: View) {
|
||||
regionSampler?.stopRegionSampler()
|
||||
regionSampler = createRegionSampler(
|
||||
sampledRegion,
|
||||
mainExecutor,
|
||||
bgExecutor,
|
||||
regionSamplingEnabled,
|
||||
::updateColors
|
||||
)?.apply { startRegionSampler() }
|
||||
regionSampler =
|
||||
createRegionSampler(
|
||||
sampledRegion,
|
||||
mainExecutor,
|
||||
bgExecutor,
|
||||
regionSamplingEnabled,
|
||||
::updateColors
|
||||
)
|
||||
?.apply { startRegionSampler() }
|
||||
|
||||
updateColors()
|
||||
}
|
||||
|
||||
protected open fun createRegionSampler(
|
||||
sampledView: View?,
|
||||
mainExecutor: Executor?,
|
||||
bgExecutor: Executor?,
|
||||
regionSamplingEnabled: Boolean,
|
||||
updateColors: () -> Unit
|
||||
sampledView: View?,
|
||||
mainExecutor: Executor?,
|
||||
bgExecutor: Executor?,
|
||||
regionSamplingEnabled: Boolean,
|
||||
updateColors: () -> Unit
|
||||
): RegionSampler? {
|
||||
return RegionSampler(
|
||||
sampledView,
|
||||
mainExecutor,
|
||||
bgExecutor,
|
||||
regionSamplingEnabled,
|
||||
updateColors)
|
||||
updateColors
|
||||
)
|
||||
}
|
||||
|
||||
var regionSampler: RegionSampler? = null
|
||||
@@ -224,64 +236,68 @@ open class ClockEventController @Inject constructor(
|
||||
private var smallClockIsDark = true
|
||||
private var largeClockIsDark = true
|
||||
|
||||
private val configListener = object : ConfigurationController.ConfigurationListener {
|
||||
override fun onThemeChanged() {
|
||||
clock?.events?.onColorPaletteChanged(resources)
|
||||
updateColors()
|
||||
}
|
||||
|
||||
override fun onDensityOrFontScaleChanged() {
|
||||
updateFontSizes()
|
||||
}
|
||||
}
|
||||
|
||||
private val batteryCallback = object : BatteryStateChangeCallback {
|
||||
override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) {
|
||||
if (isKeyguardVisible && !isCharging && charging) {
|
||||
clock?.animations?.charge()
|
||||
private val configListener =
|
||||
object : ConfigurationController.ConfigurationListener {
|
||||
override fun onThemeChanged() {
|
||||
clock?.events?.onColorPaletteChanged(resources)
|
||||
updateColors()
|
||||
}
|
||||
isCharging = charging
|
||||
}
|
||||
}
|
||||
|
||||
private val localeBroadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
clock?.events?.onLocaleChanged(Locale.getDefault())
|
||||
override fun onDensityOrFontScaleChanged() {
|
||||
updateFontSizes()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() {
|
||||
override fun onKeyguardVisibilityChanged(visible: Boolean) {
|
||||
isKeyguardVisible = visible
|
||||
if (!featureFlags.isEnabled(DOZING_MIGRATION_1)) {
|
||||
if (!isKeyguardVisible) {
|
||||
clock?.animations?.doze(if (isDozing) 1f else 0f)
|
||||
private val batteryCallback =
|
||||
object : BatteryStateChangeCallback {
|
||||
override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) {
|
||||
if (isKeyguardVisible && !isCharging && charging) {
|
||||
clock?.animations?.charge()
|
||||
}
|
||||
isCharging = charging
|
||||
}
|
||||
}
|
||||
|
||||
private val localeBroadcastReceiver =
|
||||
object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
clock?.events?.onLocaleChanged(Locale.getDefault())
|
||||
}
|
||||
}
|
||||
|
||||
private val keyguardUpdateMonitorCallback =
|
||||
object : KeyguardUpdateMonitorCallback() {
|
||||
override fun onKeyguardVisibilityChanged(visible: Boolean) {
|
||||
isKeyguardVisible = visible
|
||||
if (!featureFlags.isEnabled(DOZING_MIGRATION_1)) {
|
||||
if (!isKeyguardVisible) {
|
||||
clock?.animations?.doze(if (isDozing) 1f else 0f)
|
||||
}
|
||||
}
|
||||
|
||||
smallTimeListener?.update(shouldTimeListenerRun)
|
||||
largeTimeListener?.update(shouldTimeListenerRun)
|
||||
}
|
||||
|
||||
override fun onTimeFormatChanged(timeFormat: String) {
|
||||
clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context))
|
||||
}
|
||||
|
||||
override fun onTimeZoneChanged(timeZone: TimeZone) {
|
||||
clock?.events?.onTimeZoneChanged(timeZone)
|
||||
}
|
||||
|
||||
override fun onUserSwitchComplete(userId: Int) {
|
||||
clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context))
|
||||
}
|
||||
|
||||
override fun onWeatherDataChanged(data: Weather?) {
|
||||
if (data != null) {
|
||||
clock?.events?.onWeatherDataChanged(data)
|
||||
}
|
||||
}
|
||||
|
||||
smallTimeListener?.update(shouldTimeListenerRun)
|
||||
largeTimeListener?.update(shouldTimeListenerRun)
|
||||
}
|
||||
|
||||
override fun onTimeFormatChanged(timeFormat: String) {
|
||||
clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context))
|
||||
}
|
||||
|
||||
override fun onTimeZoneChanged(timeZone: TimeZone) {
|
||||
clock?.events?.onTimeZoneChanged(timeZone)
|
||||
}
|
||||
|
||||
override fun onUserSwitchComplete(userId: Int) {
|
||||
clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context))
|
||||
}
|
||||
|
||||
override fun onWeatherDataChanged(data: Weather?) {
|
||||
if (data != null) {
|
||||
clock?.events?.onWeatherDataChanged(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun registerListeners(parent: View) {
|
||||
if (isRegistered) {
|
||||
return
|
||||
@@ -295,17 +311,18 @@ open class ClockEventController @Inject constructor(
|
||||
configurationController.addCallback(configListener)
|
||||
batteryController.addCallback(batteryCallback)
|
||||
keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
|
||||
disposableHandle = parent.repeatWhenAttached {
|
||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
listenForDozing(this)
|
||||
if (featureFlags.isEnabled(DOZING_MIGRATION_1)) {
|
||||
listenForDozeAmountTransition(this)
|
||||
listenForAnyStateToAodTransition(this)
|
||||
} else {
|
||||
listenForDozeAmount(this)
|
||||
disposableHandle =
|
||||
parent.repeatWhenAttached {
|
||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
listenForDozing(this)
|
||||
if (featureFlags.isEnabled(DOZING_MIGRATION_1)) {
|
||||
listenForDozeAmountTransition(this)
|
||||
listenForAnyStateToAodTransition(this)
|
||||
} else {
|
||||
listenForDozeAmount(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
smallTimeListener?.update(shouldTimeListenerRun)
|
||||
largeTimeListener?.update(shouldTimeListenerRun)
|
||||
}
|
||||
@@ -344,10 +361,18 @@ open class ClockEventController @Inject constructor(
|
||||
}
|
||||
|
||||
private fun updateFontSizes() {
|
||||
clock?.smallClock?.events?.onFontSettingChanged(
|
||||
resources.getDimensionPixelSize(R.dimen.small_clock_text_size).toFloat())
|
||||
clock?.largeClock?.events?.onFontSettingChanged(
|
||||
resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat())
|
||||
clock
|
||||
?.smallClock
|
||||
?.events
|
||||
?.onFontSettingChanged(
|
||||
resources.getDimensionPixelSize(R.dimen.small_clock_text_size).toFloat()
|
||||
)
|
||||
clock
|
||||
?.largeClock
|
||||
?.events
|
||||
?.onFontSettingChanged(
|
||||
resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat()
|
||||
)
|
||||
}
|
||||
|
||||
private fun handleDoze(doze: Float) {
|
||||
@@ -359,68 +384,59 @@ open class ClockEventController @Inject constructor(
|
||||
|
||||
@VisibleForTesting
|
||||
internal fun listenForDozeAmount(scope: CoroutineScope): Job {
|
||||
return scope.launch {
|
||||
keyguardInteractor.dozeAmount.collect {
|
||||
handleDoze(it)
|
||||
}
|
||||
}
|
||||
return scope.launch { keyguardInteractor.dozeAmount.collect { handleDoze(it) } }
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
internal fun listenForDozeAmountTransition(scope: CoroutineScope): Job {
|
||||
return scope.launch {
|
||||
keyguardTransitionInteractor.dozeAmountTransition.collect {
|
||||
handleDoze(it.value)
|
||||
}
|
||||
keyguardTransitionInteractor.dozeAmountTransition.collect { handleDoze(it.value) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When keyguard is displayed again after being gone, the clock must be reset to full
|
||||
* dozing.
|
||||
* When keyguard is displayed again after being gone, the clock must be reset to full dozing.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
internal fun listenForAnyStateToAodTransition(scope: CoroutineScope): Job {
|
||||
return scope.launch {
|
||||
keyguardTransitionInteractor.anyStateToAodTransition.filter {
|
||||
it.transitionState == TransitionState.FINISHED
|
||||
}.collect {
|
||||
handleDoze(1f)
|
||||
}
|
||||
keyguardTransitionInteractor.anyStateToAodTransition
|
||||
.filter { it.transitionState == TransitionState.FINISHED }
|
||||
.collect { handleDoze(1f) }
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
internal fun listenForDozing(scope: CoroutineScope): Job {
|
||||
return scope.launch {
|
||||
combine (
|
||||
keyguardInteractor.dozeAmount,
|
||||
keyguardInteractor.isDozing,
|
||||
) { localDozeAmount, localIsDozing ->
|
||||
localDozeAmount > dozeAmount || localIsDozing
|
||||
}
|
||||
.collect { localIsDozing ->
|
||||
isDozing = localIsDozing
|
||||
}
|
||||
combine(
|
||||
keyguardInteractor.dozeAmount,
|
||||
keyguardInteractor.isDozing,
|
||||
) { localDozeAmount, localIsDozing ->
|
||||
localDozeAmount > dozeAmount || localIsDozing
|
||||
}
|
||||
.collect { localIsDozing -> isDozing = localIsDozing }
|
||||
}
|
||||
}
|
||||
|
||||
class TimeListener(val clockFace: ClockFaceController, val executor: DelayableExecutor) {
|
||||
val predrawListener = ViewTreeObserver.OnPreDrawListener {
|
||||
clockFace.events.onTimeTick()
|
||||
true
|
||||
}
|
||||
|
||||
val secondsRunnable = object : Runnable {
|
||||
override fun run() {
|
||||
if (!isRunning) {
|
||||
return
|
||||
}
|
||||
|
||||
executor.executeDelayed(this, 990)
|
||||
val predrawListener =
|
||||
ViewTreeObserver.OnPreDrawListener {
|
||||
clockFace.events.onTimeTick()
|
||||
true
|
||||
}
|
||||
|
||||
val secondsRunnable =
|
||||
object : Runnable {
|
||||
override fun run() {
|
||||
if (!isRunning) {
|
||||
return
|
||||
}
|
||||
|
||||
executor.executeDelayed(this, 990)
|
||||
clockFace.events.onTimeTick()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var isRunning: Boolean = false
|
||||
private set
|
||||
@@ -432,7 +448,9 @@ open class ClockEventController @Inject constructor(
|
||||
|
||||
isRunning = true
|
||||
when (clockFace.events.tickRate) {
|
||||
ClockTickRate.PER_MINUTE -> {/* Handled by KeyguardClockSwitchController */}
|
||||
ClockTickRate.PER_MINUTE -> {
|
||||
/* Handled by KeyguardClockSwitchController */
|
||||
}
|
||||
ClockTickRate.PER_SECOND -> executor.execute(secondsRunnable)
|
||||
ClockTickRate.PER_FRAME -> {
|
||||
clockFace.view.viewTreeObserver.addOnPreDrawListener(predrawListener)
|
||||
@@ -442,7 +460,9 @@ open class ClockEventController @Inject constructor(
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
if (!isRunning) { return }
|
||||
if (!isRunning) {
|
||||
return
|
||||
}
|
||||
|
||||
isRunning = false
|
||||
clockFace.view.viewTreeObserver.removeOnPreDrawListener(predrawListener)
|
||||
|
||||
@@ -22,6 +22,8 @@ import android.graphics.Point
|
||||
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.flags.FeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
|
||||
import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
|
||||
@@ -31,7 +33,6 @@ import com.android.systemui.keyguard.shared.model.DozeTransitionModel
|
||||
import com.android.systemui.keyguard.shared.model.StatusBarState
|
||||
import com.android.systemui.keyguard.shared.model.WakefulnessModel
|
||||
import com.android.systemui.statusbar.CommandQueue
|
||||
import com.android.systemui.statusbar.CommandQueue.Callbacks
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.delay
|
||||
@@ -41,7 +42,9 @@ import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.merge
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
|
||||
/**
|
||||
* Encapsulates business-logic related to the keyguard but not to a more specific part within it.
|
||||
@@ -52,6 +55,7 @@ class KeyguardInteractor
|
||||
constructor(
|
||||
private val repository: KeyguardRepository,
|
||||
private val commandQueue: CommandQueue,
|
||||
featureFlags: FeatureFlags,
|
||||
) {
|
||||
/**
|
||||
* The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at
|
||||
@@ -129,6 +133,29 @@ constructor(
|
||||
*/
|
||||
val biometricUnlockState: Flow<BiometricUnlockModel> = repository.biometricUnlockState
|
||||
|
||||
/** Keyguard is present and is not occluded. */
|
||||
val isKeyguardVisible: Flow<Boolean> =
|
||||
combine(isKeyguardShowing, isKeyguardOccluded) { showing, occluded -> showing && !occluded }
|
||||
|
||||
/** Whether camera is launched over keyguard. */
|
||||
var isSecureCameraActive =
|
||||
if (featureFlags.isEnabled(Flags.FACE_AUTH_REFACTOR)) {
|
||||
combine(
|
||||
isKeyguardVisible,
|
||||
repository.isBouncerShowing,
|
||||
onCameraLaunchDetected,
|
||||
) { isKeyguardVisible, isBouncerShowing, cameraLaunchEvent ->
|
||||
when {
|
||||
isKeyguardVisible -> false
|
||||
isBouncerShowing -> false
|
||||
else -> cameraLaunchEvent == CameraLaunchSourceModel.POWER_DOUBLE_TAP
|
||||
}
|
||||
}
|
||||
.onStart { emit(false) }
|
||||
} else {
|
||||
flowOf(false)
|
||||
}
|
||||
|
||||
/** The approximate location on the screen of the fingerprint sensor, if one is available. */
|
||||
val fingerprintSensorLocation: Flow<Point?> = repository.fingerprintSensorLocation
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.times
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import java.util.*
|
||||
import java.util.TimeZone
|
||||
import java.util.concurrent.Executor
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
@@ -105,7 +105,9 @@ class ClockEventControllerTest : SysuiTestCase() {
|
||||
repository = FakeKeyguardRepository()
|
||||
|
||||
underTest = ClockEventController(
|
||||
KeyguardInteractor(repository = repository, commandQueue = commandQueue),
|
||||
KeyguardInteractor(repository = repository,
|
||||
commandQueue = commandQueue,
|
||||
featureFlags = featureFlags),
|
||||
KeyguardTransitionInteractor(repository = transitionRepository),
|
||||
broadcastDispatcher,
|
||||
batteryController,
|
||||
|
||||
@@ -159,7 +159,9 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
|
||||
mAuthRippleController,
|
||||
mResources,
|
||||
new KeyguardTransitionInteractor(mTransitionRepository),
|
||||
new KeyguardInteractor(new FakeKeyguardRepository(), mCommandQueue),
|
||||
new KeyguardInteractor(new FakeKeyguardRepository(),
|
||||
mCommandQueue,
|
||||
mFeatureFlags),
|
||||
mFeatureFlags
|
||||
);
|
||||
}
|
||||
|
||||
@@ -157,25 +157,28 @@ class CustomizationProviderTest : SysuiTestCase() {
|
||||
dumpManager = mock(),
|
||||
userHandle = UserHandle.SYSTEM,
|
||||
)
|
||||
val featureFlags =
|
||||
FakeFeatureFlags().apply {
|
||||
set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
|
||||
set(Flags.LOCKSCREEN_CUSTOM_CLOCKS, true)
|
||||
set(Flags.REVAMPED_WALLPAPER_UI, true)
|
||||
set(Flags.WALLPAPER_FULLSCREEN_PREVIEW, true)
|
||||
set(Flags.FACE_AUTH_REFACTOR, true)
|
||||
}
|
||||
underTest.interactor =
|
||||
KeyguardQuickAffordanceInteractor(
|
||||
keyguardInteractor =
|
||||
KeyguardInteractor(
|
||||
repository = FakeKeyguardRepository(),
|
||||
commandQueue = commandQueue,
|
||||
featureFlags = featureFlags,
|
||||
),
|
||||
registry = mock(),
|
||||
lockPatternUtils = lockPatternUtils,
|
||||
keyguardStateController = keyguardStateController,
|
||||
userTracker = userTracker,
|
||||
activityStarter = activityStarter,
|
||||
featureFlags =
|
||||
FakeFeatureFlags().apply {
|
||||
set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
|
||||
set(Flags.LOCKSCREEN_CUSTOM_CLOCKS, true)
|
||||
set(Flags.REVAMPED_WALLPAPER_UI, true)
|
||||
set(Flags.WALLPAPER_FULLSCREEN_PREVIEW, true)
|
||||
},
|
||||
featureFlags = featureFlags,
|
||||
repository = { quickAffordanceRepository },
|
||||
launchAnimator = launchAnimator,
|
||||
)
|
||||
|
||||
@@ -18,30 +18,34 @@
|
||||
package com.android.systemui.keyguard.domain.interactor
|
||||
|
||||
import android.app.StatusBarManager
|
||||
import android.content.Context
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
import com.android.systemui.flags.FakeFeatureFlags
|
||||
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
|
||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
||||
import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
|
||||
import com.android.systemui.settings.DisplayTracker
|
||||
import com.android.systemui.statusbar.CommandQueue
|
||||
import com.android.systemui.statusbar.CommandQueue.Callbacks
|
||||
import com.android.systemui.util.mockito.argumentCaptor
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.flow.onCompletion
|
||||
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.junit.runners.JUnit4
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@SmallTest
|
||||
@RunWith(JUnit4::class)
|
||||
class KeyguardInteractorTest : SysuiTestCase() {
|
||||
@Mock private lateinit var commandQueue: CommandQueue
|
||||
private lateinit var commandQueue: FakeCommandQueue
|
||||
private lateinit var featureFlags: FakeFeatureFlags
|
||||
private lateinit var testScope: TestScope
|
||||
|
||||
private lateinit var underTest: KeyguardInteractor
|
||||
private lateinit var repository: FakeKeyguardRepository
|
||||
@@ -49,38 +53,134 @@ class KeyguardInteractorTest : SysuiTestCase() {
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) }
|
||||
commandQueue = FakeCommandQueue(mock(Context::class.java), mock(DisplayTracker::class.java))
|
||||
testScope = TestScope()
|
||||
repository = FakeKeyguardRepository()
|
||||
underTest = KeyguardInteractor(repository, commandQueue)
|
||||
underTest = KeyguardInteractor(repository, commandQueue, featureFlags)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onCameraLaunchDetected() = runTest {
|
||||
val flow = underTest.onCameraLaunchDetected
|
||||
var cameraLaunchSource = collectLastValue(flow)
|
||||
runCurrent()
|
||||
fun onCameraLaunchDetected() =
|
||||
testScope.runTest {
|
||||
val flow = underTest.onCameraLaunchDetected
|
||||
var cameraLaunchSource = collectLastValue(flow)
|
||||
runCurrent()
|
||||
|
||||
val captor = argumentCaptor<CommandQueue.Callbacks>()
|
||||
verify(commandQueue).addCallback(captor.capture())
|
||||
commandQueue.doForEachCallback {
|
||||
it.onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE)
|
||||
}
|
||||
assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.WIGGLE)
|
||||
|
||||
captor.value.onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE)
|
||||
assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.WIGGLE)
|
||||
commandQueue.doForEachCallback {
|
||||
it.onCameraLaunchGestureDetected(
|
||||
StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP
|
||||
)
|
||||
}
|
||||
assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.POWER_DOUBLE_TAP)
|
||||
|
||||
captor.value.onCameraLaunchGestureDetected(
|
||||
StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP
|
||||
)
|
||||
assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.POWER_DOUBLE_TAP)
|
||||
commandQueue.doForEachCallback {
|
||||
it.onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER)
|
||||
}
|
||||
assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.LIFT_TRIGGER)
|
||||
|
||||
captor.value.onCameraLaunchGestureDetected(
|
||||
StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER
|
||||
)
|
||||
assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.LIFT_TRIGGER)
|
||||
commandQueue.doForEachCallback {
|
||||
it.onCameraLaunchGestureDetected(
|
||||
StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE
|
||||
)
|
||||
}
|
||||
assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.QUICK_AFFORDANCE)
|
||||
|
||||
captor.value.onCameraLaunchGestureDetected(
|
||||
StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE
|
||||
)
|
||||
assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.QUICK_AFFORDANCE)
|
||||
flow.onCompletion { assertThat(commandQueue.callbackCount()).isEqualTo(0) }
|
||||
}
|
||||
|
||||
flow.onCompletion { verify(commandQueue).removeCallback(captor.value) }
|
||||
@Test
|
||||
fun testKeyguardGuardVisibilityStopsSecureCamera() =
|
||||
testScope.runTest {
|
||||
val secureCameraActive = collectLastValue(underTest.isSecureCameraActive)
|
||||
runCurrent()
|
||||
|
||||
commandQueue.doForEachCallback {
|
||||
it.onCameraLaunchGestureDetected(
|
||||
StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP
|
||||
)
|
||||
}
|
||||
|
||||
assertThat(secureCameraActive()).isTrue()
|
||||
|
||||
// Keyguard is showing but occluded
|
||||
repository.setKeyguardShowing(true)
|
||||
repository.setKeyguardOccluded(true)
|
||||
assertThat(secureCameraActive()).isTrue()
|
||||
|
||||
// Keyguard is showing and not occluded
|
||||
repository.setKeyguardOccluded(false)
|
||||
assertThat(secureCameraActive()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBouncerShowingResetsSecureCameraState() =
|
||||
testScope.runTest {
|
||||
val secureCameraActive = collectLastValue(underTest.isSecureCameraActive)
|
||||
runCurrent()
|
||||
|
||||
commandQueue.doForEachCallback {
|
||||
it.onCameraLaunchGestureDetected(
|
||||
StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP
|
||||
)
|
||||
}
|
||||
assertThat(secureCameraActive()).isTrue()
|
||||
|
||||
// Keyguard is showing and not occluded
|
||||
repository.setKeyguardShowing(true)
|
||||
repository.setKeyguardOccluded(true)
|
||||
assertThat(secureCameraActive()).isTrue()
|
||||
|
||||
repository.setBouncerShowing(true)
|
||||
assertThat(secureCameraActive()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun keyguardVisibilityIsDefinedAsKeyguardShowingButNotOccluded() = runTest {
|
||||
var isVisible = collectLastValue(underTest.isKeyguardVisible)
|
||||
repository.setKeyguardShowing(true)
|
||||
repository.setKeyguardOccluded(false)
|
||||
|
||||
assertThat(isVisible()).isTrue()
|
||||
|
||||
repository.setKeyguardOccluded(true)
|
||||
assertThat(isVisible()).isFalse()
|
||||
|
||||
repository.setKeyguardShowing(false)
|
||||
repository.setKeyguardOccluded(true)
|
||||
assertThat(isVisible()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun secureCameraIsNotActiveWhenNoCameraLaunchEventHasBeenFiredYet() =
|
||||
testScope.runTest {
|
||||
val secureCameraActive = collectLastValue(underTest.isSecureCameraActive)
|
||||
runCurrent()
|
||||
|
||||
assertThat(secureCameraActive()).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
class FakeCommandQueue(val context: Context, val displayTracker: DisplayTracker) :
|
||||
CommandQueue(context, displayTracker) {
|
||||
private val callbacks = mutableListOf<Callbacks>()
|
||||
|
||||
override fun addCallback(callback: Callbacks) {
|
||||
callbacks.add(callback)
|
||||
}
|
||||
|
||||
override fun removeCallback(callback: Callbacks) {
|
||||
callbacks.remove(callback)
|
||||
}
|
||||
|
||||
fun doForEachCallback(func: (callback: Callbacks) -> Unit) {
|
||||
callbacks.forEach { func(it) }
|
||||
}
|
||||
|
||||
fun callbackCount(): Int = callbacks.size
|
||||
}
|
||||
|
||||
@@ -286,12 +286,18 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
|
||||
dumpManager = mock(),
|
||||
userHandle = UserHandle.SYSTEM,
|
||||
)
|
||||
val featureFlags =
|
||||
FakeFeatureFlags().apply {
|
||||
set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
|
||||
set(Flags.FACE_AUTH_REFACTOR, true)
|
||||
}
|
||||
underTest =
|
||||
KeyguardQuickAffordanceInteractor(
|
||||
keyguardInteractor =
|
||||
KeyguardInteractor(
|
||||
repository = FakeKeyguardRepository(),
|
||||
commandQueue = commandQueue
|
||||
commandQueue = commandQueue,
|
||||
featureFlags = featureFlags,
|
||||
),
|
||||
registry =
|
||||
FakeKeyguardQuickAffordanceRegistry(
|
||||
@@ -311,10 +317,7 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
|
||||
keyguardStateController = keyguardStateController,
|
||||
userTracker = userTracker,
|
||||
activityStarter = activityStarter,
|
||||
featureFlags =
|
||||
FakeFeatureFlags().apply {
|
||||
set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
|
||||
},
|
||||
featureFlags = featureFlags,
|
||||
repository = { quickAffordanceRepository },
|
||||
launchAnimator = launchAnimator,
|
||||
)
|
||||
|
||||
@@ -150,12 +150,17 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
|
||||
featureFlags =
|
||||
FakeFeatureFlags().apply {
|
||||
set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
|
||||
set(Flags.FACE_AUTH_REFACTOR, true)
|
||||
}
|
||||
|
||||
underTest =
|
||||
KeyguardQuickAffordanceInteractor(
|
||||
keyguardInteractor =
|
||||
KeyguardInteractor(repository = repository, commandQueue = commandQueue),
|
||||
KeyguardInteractor(
|
||||
repository = repository,
|
||||
commandQueue = commandQueue,
|
||||
featureFlags = featureFlags
|
||||
),
|
||||
registry =
|
||||
FakeKeyguardQuickAffordanceRegistry(
|
||||
mapOf(
|
||||
|
||||
@@ -21,6 +21,8 @@ import androidx.test.filters.FlakyTest
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.animation.Interpolators
|
||||
import com.android.systemui.flags.FakeFeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositoryImpl
|
||||
@@ -92,10 +94,12 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
||||
transitionRepository = KeyguardTransitionRepositoryImpl()
|
||||
runner = KeyguardTransitionRunner(transitionRepository)
|
||||
|
||||
val featureFlags = FakeFeatureFlags().apply { set(Flags.FACE_AUTH_REFACTOR, true) }
|
||||
fromLockscreenTransitionInteractor =
|
||||
FromLockscreenTransitionInteractor(
|
||||
scope = testScope,
|
||||
keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
|
||||
keyguardInteractor =
|
||||
KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
|
||||
shadeRepository = shadeRepository,
|
||||
keyguardTransitionRepository = mockTransitionRepository,
|
||||
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
||||
@@ -105,7 +109,8 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
||||
fromDreamingTransitionInteractor =
|
||||
FromDreamingTransitionInteractor(
|
||||
scope = testScope,
|
||||
keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
|
||||
keyguardInteractor =
|
||||
KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
|
||||
keyguardTransitionRepository = mockTransitionRepository,
|
||||
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
||||
)
|
||||
@@ -114,7 +119,8 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
||||
fromAodTransitionInteractor =
|
||||
FromAodTransitionInteractor(
|
||||
scope = testScope,
|
||||
keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
|
||||
keyguardInteractor =
|
||||
KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
|
||||
keyguardTransitionRepository = mockTransitionRepository,
|
||||
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
||||
)
|
||||
@@ -123,7 +129,8 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
||||
fromGoneTransitionInteractor =
|
||||
FromGoneTransitionInteractor(
|
||||
scope = testScope,
|
||||
keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
|
||||
keyguardInteractor =
|
||||
KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
|
||||
keyguardTransitionRepository = mockTransitionRepository,
|
||||
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
||||
)
|
||||
@@ -132,7 +139,8 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
||||
fromDozingTransitionInteractor =
|
||||
FromDozingTransitionInteractor(
|
||||
scope = testScope,
|
||||
keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
|
||||
keyguardInteractor =
|
||||
KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
|
||||
keyguardTransitionRepository = mockTransitionRepository,
|
||||
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
||||
)
|
||||
@@ -141,7 +149,8 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
|
||||
fromOccludedTransitionInteractor =
|
||||
FromOccludedTransitionInteractor(
|
||||
scope = testScope,
|
||||
keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
|
||||
keyguardInteractor =
|
||||
KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
|
||||
keyguardTransitionRepository = mockTransitionRepository,
|
||||
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
|
||||
)
|
||||
|
||||
@@ -125,9 +125,18 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
),
|
||||
)
|
||||
repository = FakeKeyguardRepository()
|
||||
val featureFlags =
|
||||
FakeFeatureFlags().apply {
|
||||
set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
|
||||
set(Flags.FACE_AUTH_REFACTOR, true)
|
||||
}
|
||||
|
||||
val keyguardInteractor =
|
||||
KeyguardInteractor(repository = repository, commandQueue = commandQueue)
|
||||
KeyguardInteractor(
|
||||
repository = repository,
|
||||
commandQueue = commandQueue,
|
||||
featureFlags = featureFlags,
|
||||
)
|
||||
whenever(userTracker.userHandle).thenReturn(mock())
|
||||
whenever(lockPatternUtils.getStrongAuthForUser(anyInt()))
|
||||
.thenReturn(LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED)
|
||||
@@ -191,10 +200,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
keyguardStateController = keyguardStateController,
|
||||
userTracker = userTracker,
|
||||
activityStarter = activityStarter,
|
||||
featureFlags =
|
||||
FakeFeatureFlags().apply {
|
||||
set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
|
||||
},
|
||||
featureFlags = featureFlags,
|
||||
repository = { quickAffordanceRepository },
|
||||
launchAnimator = launchAnimator,
|
||||
),
|
||||
|
||||
@@ -25,6 +25,8 @@ import android.view.ViewTreeObserver
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.internal.util.LatencyTracker
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.flags.FakeFeatureFlags
|
||||
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
|
||||
import com.android.systemui.keyguard.WakefulnessLifecycle
|
||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
||||
@@ -105,8 +107,13 @@ class FoldAodAnimationControllerTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
keyguardRepository = FakeKeyguardRepository()
|
||||
val featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) }
|
||||
val keyguardInteractor =
|
||||
KeyguardInteractor(repository = keyguardRepository, commandQueue = commandQueue)
|
||||
KeyguardInteractor(
|
||||
repository = keyguardRepository,
|
||||
commandQueue = commandQueue,
|
||||
featureFlags = featureFlags
|
||||
)
|
||||
|
||||
// Needs to be run on the main thread
|
||||
runBlocking(IMMEDIATE) {
|
||||
|
||||
@@ -117,8 +117,11 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
SUPERVISED_USER_CREATION_APP_PACKAGE,
|
||||
)
|
||||
|
||||
featureFlags = FakeFeatureFlags()
|
||||
featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, false)
|
||||
featureFlags =
|
||||
FakeFeatureFlags().apply {
|
||||
set(Flags.FULL_SCREEN_USER_SWITCHER, false)
|
||||
set(Flags.FACE_AUTH_REFACTOR, true)
|
||||
}
|
||||
userRepository = FakeUserRepository()
|
||||
keyguardRepository = FakeKeyguardRepository()
|
||||
telephonyRepository = FakeTelephonyRepository()
|
||||
@@ -139,6 +142,7 @@ class UserInteractorTest : SysuiTestCase() {
|
||||
KeyguardInteractor(
|
||||
repository = keyguardRepository,
|
||||
commandQueue = commandQueue,
|
||||
featureFlags = featureFlags,
|
||||
),
|
||||
manager = manager,
|
||||
applicationScope = testScope.backgroundScope,
|
||||
|
||||
@@ -82,7 +82,6 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() {
|
||||
|
||||
private val userRepository = FakeUserRepository()
|
||||
private val keyguardRepository = FakeKeyguardRepository()
|
||||
private val featureFlags = FakeFeatureFlags()
|
||||
private lateinit var guestUserInteractor: GuestUserInteractor
|
||||
private lateinit var refreshUsersScheduler: RefreshUsersScheduler
|
||||
|
||||
@@ -233,6 +232,11 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
private fun viewModel(): StatusBarUserChipViewModel {
|
||||
val featureFlags =
|
||||
FakeFeatureFlags().apply {
|
||||
set(Flags.FULL_SCREEN_USER_SWITCHER, false)
|
||||
set(Flags.FACE_AUTH_REFACTOR, true)
|
||||
}
|
||||
return StatusBarUserChipViewModel(
|
||||
context = context,
|
||||
interactor =
|
||||
@@ -244,9 +248,9 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() {
|
||||
KeyguardInteractor(
|
||||
repository = keyguardRepository,
|
||||
commandQueue = commandQueue,
|
||||
featureFlags = featureFlags,
|
||||
),
|
||||
featureFlags =
|
||||
FakeFeatureFlags().apply { set(Flags.FULL_SCREEN_USER_SWITCHER, false) },
|
||||
featureFlags = featureFlags,
|
||||
manager = manager,
|
||||
applicationScope = testScope.backgroundScope,
|
||||
telephonyInteractor =
|
||||
|
||||
@@ -134,6 +134,11 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
||||
resetOrExitSessionReceiver = resetOrExitSessionReceiver,
|
||||
)
|
||||
|
||||
val featureFlags =
|
||||
FakeFeatureFlags().apply {
|
||||
set(Flags.FULL_SCREEN_USER_SWITCHER, false)
|
||||
set(Flags.FACE_AUTH_REFACTOR, true)
|
||||
}
|
||||
underTest =
|
||||
UserSwitcherViewModel.Factory(
|
||||
userInteractor =
|
||||
@@ -145,11 +150,9 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
|
||||
KeyguardInteractor(
|
||||
repository = keyguardRepository,
|
||||
commandQueue = commandQueue,
|
||||
featureFlags = featureFlags
|
||||
),
|
||||
featureFlags =
|
||||
FakeFeatureFlags().apply {
|
||||
set(Flags.FULL_SCREEN_USER_SWITCHER, false)
|
||||
},
|
||||
featureFlags = featureFlags,
|
||||
manager = manager,
|
||||
applicationScope = testScope.backgroundScope,
|
||||
telephonyInteractor =
|
||||
|
||||
Reference in New Issue
Block a user