Merge "Fixes quick affordance visibility bug." into tm-qpr-dev am: 7e09869954
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19485352 Change-Id: Ie32242d71691db07b324a61b763fd9d7b3cc038c Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
committed by
Automerger Merge Worker
commit
1846a65ace
@@ -17,14 +17,12 @@
|
||||
|
||||
package com.android.systemui.keyguard.data.quickaffordance
|
||||
|
||||
import android.content.Context
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
|
||||
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
||||
import com.android.systemui.containeddrawable.ContainedDrawable
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.qrcodescanner.controller.QRCodeScannerController
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
@@ -35,12 +33,9 @@ import kotlinx.coroutines.flow.Flow
|
||||
class QrCodeScannerKeyguardQuickAffordanceConfig
|
||||
@Inject
|
||||
constructor(
|
||||
@Application context: Context,
|
||||
private val controller: QRCodeScannerController,
|
||||
) : KeyguardQuickAffordanceConfig {
|
||||
|
||||
private val appContext = context.applicationContext
|
||||
|
||||
override val state: Flow<KeyguardQuickAffordanceConfig.State> = conflatedCallbackFlow {
|
||||
val callback =
|
||||
object : QRCodeScannerController.Callback {
|
||||
|
||||
@@ -29,32 +29,59 @@ import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCall
|
||||
import com.android.systemui.containeddrawable.ContainedDrawable
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.plugins.ActivityStarter
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateControllerExt.isKeyguardShowing
|
||||
import com.android.systemui.wallet.controller.QuickAccessWalletController
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
|
||||
/** Quick access wallet quick affordance data source. */
|
||||
@SysUISingleton
|
||||
class QuickAccessWalletKeyguardQuickAffordanceConfig
|
||||
@Inject
|
||||
constructor(
|
||||
private val keyguardStateController: KeyguardStateController,
|
||||
private val walletController: QuickAccessWalletController,
|
||||
private val activityStarter: ActivityStarter,
|
||||
) : KeyguardQuickAffordanceConfig {
|
||||
|
||||
override val state: Flow<KeyguardQuickAffordanceConfig.State> =
|
||||
keyguardStateController
|
||||
.isKeyguardShowing(TAG)
|
||||
.flatMapLatest { isKeyguardShowing ->
|
||||
stateInternal(isKeyguardShowing)
|
||||
override val state: Flow<KeyguardQuickAffordanceConfig.State> = conflatedCallbackFlow {
|
||||
val callback =
|
||||
object : QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
|
||||
override fun onWalletCardsRetrieved(response: GetWalletCardsResponse?) {
|
||||
trySendWithFailureLogging(
|
||||
state(
|
||||
isFeatureEnabled = walletController.isWalletEnabled,
|
||||
hasCard = response?.walletCards?.isNotEmpty() == true,
|
||||
tileIcon = walletController.walletClient.tileIcon,
|
||||
),
|
||||
TAG,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onWalletCardRetrievalError(error: GetWalletCardsError?) {
|
||||
Log.e(TAG, "Wallet card retrieval error, message: \"${error?.message}\"")
|
||||
trySendWithFailureLogging(
|
||||
KeyguardQuickAffordanceConfig.State.Hidden,
|
||||
TAG,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
walletController.setupWalletChangeObservers(
|
||||
callback,
|
||||
QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE,
|
||||
QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE
|
||||
)
|
||||
walletController.updateWalletPreference()
|
||||
walletController.queryWalletCards(callback)
|
||||
|
||||
awaitClose {
|
||||
walletController.unregisterWalletChangeObservers(
|
||||
QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE,
|
||||
QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onQuickAffordanceClicked(
|
||||
animationController: ActivityLaunchAnimator.Controller?,
|
||||
): KeyguardQuickAffordanceConfig.OnClickedResult {
|
||||
@@ -66,53 +93,6 @@ constructor(
|
||||
return KeyguardQuickAffordanceConfig.OnClickedResult.Handled
|
||||
}
|
||||
|
||||
private fun stateInternal(
|
||||
isKeyguardShowing: Boolean
|
||||
): Flow<KeyguardQuickAffordanceConfig.State> {
|
||||
if (!isKeyguardShowing) {
|
||||
return flowOf(KeyguardQuickAffordanceConfig.State.Hidden)
|
||||
}
|
||||
|
||||
return conflatedCallbackFlow {
|
||||
val callback =
|
||||
object : QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
|
||||
override fun onWalletCardsRetrieved(response: GetWalletCardsResponse?) {
|
||||
trySendWithFailureLogging(
|
||||
state(
|
||||
isFeatureEnabled = walletController.isWalletEnabled,
|
||||
hasCard = response?.walletCards?.isNotEmpty() == true,
|
||||
tileIcon = walletController.walletClient.tileIcon,
|
||||
),
|
||||
TAG,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onWalletCardRetrievalError(error: GetWalletCardsError?) {
|
||||
Log.e(TAG, "Wallet card retrieval error, message: \"${error?.message}\"")
|
||||
trySendWithFailureLogging(
|
||||
KeyguardQuickAffordanceConfig.State.Hidden,
|
||||
TAG,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
walletController.setupWalletChangeObservers(
|
||||
callback,
|
||||
QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE,
|
||||
QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE
|
||||
)
|
||||
walletController.updateWalletPreference()
|
||||
walletController.queryWalletCards(callback)
|
||||
|
||||
awaitClose {
|
||||
walletController.unregisterWalletChangeObservers(
|
||||
QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE,
|
||||
QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun state(
|
||||
isFeatureEnabled: Boolean,
|
||||
hasCard: Boolean,
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCall
|
||||
import com.android.systemui.common.data.model.Position
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -49,6 +50,15 @@ interface KeyguardRepository {
|
||||
*/
|
||||
val clockPosition: StateFlow<Position>
|
||||
|
||||
/**
|
||||
* Observable for whether the keyguard is showing.
|
||||
*
|
||||
* Note: this is also `true` when the lock-screen is occluded with an `Activity` "above" it in
|
||||
* the z-order (which is not really above the system UI window, but rather - the lock-screen
|
||||
* becomes invisible to reveal the "occluding activity").
|
||||
*/
|
||||
val isKeyguardShowing: Flow<Boolean>
|
||||
|
||||
/**
|
||||
* Observable for whether we are in doze state.
|
||||
*
|
||||
@@ -91,6 +101,7 @@ class KeyguardRepositoryImpl
|
||||
@Inject
|
||||
constructor(
|
||||
statusBarStateController: StatusBarStateController,
|
||||
keyguardStateController: KeyguardStateController,
|
||||
) : KeyguardRepository {
|
||||
private val _animateBottomAreaDozingTransitions = MutableStateFlow(false)
|
||||
override val animateBottomAreaDozingTransitions =
|
||||
@@ -102,6 +113,29 @@ constructor(
|
||||
private val _clockPosition = MutableStateFlow(Position(0, 0))
|
||||
override val clockPosition = _clockPosition.asStateFlow()
|
||||
|
||||
override val isKeyguardShowing: Flow<Boolean> = conflatedCallbackFlow {
|
||||
val callback =
|
||||
object : KeyguardStateController.Callback {
|
||||
override fun onKeyguardShowingChanged() {
|
||||
trySendWithFailureLogging(
|
||||
keyguardStateController.isShowing,
|
||||
TAG,
|
||||
"updated isKeyguardShowing"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
keyguardStateController.addCallback(callback)
|
||||
// Adding the callback does not send an initial update.
|
||||
trySendWithFailureLogging(
|
||||
keyguardStateController.isShowing,
|
||||
TAG,
|
||||
"initial isKeyguardShowing"
|
||||
)
|
||||
|
||||
awaitClose { keyguardStateController.removeCallback(callback) }
|
||||
}
|
||||
|
||||
override val isDozing: Flow<Boolean> = conflatedCallbackFlow {
|
||||
val callback =
|
||||
object : StatusBarStateController.StateListener {
|
||||
|
||||
@@ -30,7 +30,8 @@ interface KeyguardRepositoryModule {
|
||||
impl: KeyguardQuickAffordanceRepositoryImpl
|
||||
): KeyguardQuickAffordanceRepository
|
||||
|
||||
@Binds fun keyguardQuickAffordanceConfigs(
|
||||
@Binds
|
||||
fun keyguardQuickAffordanceConfigs(
|
||||
impl: KeyguardQuickAffordanceConfigsImpl
|
||||
): KeyguardQuickAffordanceConfigs
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.android.systemui.keyguard.domain.usecase
|
||||
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
* Use-case for observing whether the keyguard is currently being shown.
|
||||
*
|
||||
* Note: this is also `true` when the lock-screen is occluded with an `Activity` "above" it in the
|
||||
* z-order (which is not really above the system UI window, but rather - the lock-screen becomes
|
||||
* invisible to reveal the "occluding activity").
|
||||
*/
|
||||
class ObserveIsKeyguardShowingUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val repository: KeyguardRepository,
|
||||
) {
|
||||
operator fun invoke(): Flow<Boolean> {
|
||||
return repository.isKeyguardShowing
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ class ObserveKeyguardQuickAffordanceUseCase
|
||||
constructor(
|
||||
private val repository: KeyguardQuickAffordanceRepository,
|
||||
private val isDozingUseCase: ObserveIsDozingUseCase,
|
||||
private val dozeAmountUseCase: ObserveDozeAmountUseCase,
|
||||
private val isKeyguardShowingUseCase: ObserveIsKeyguardShowingUseCase,
|
||||
) {
|
||||
operator fun invoke(
|
||||
position: KeyguardQuickAffordancePosition
|
||||
@@ -37,9 +37,9 @@ constructor(
|
||||
return combine(
|
||||
repository.affordance(position),
|
||||
isDozingUseCase(),
|
||||
dozeAmountUseCase(),
|
||||
) { affordance, isDozing, dozeAmount ->
|
||||
if (!isDozing && dozeAmount == 0f) {
|
||||
isKeyguardShowingUseCase(),
|
||||
) { affordance, isDozing, isKeyguardShowing ->
|
||||
if (!isDozing && isKeyguardShowing) {
|
||||
affordance
|
||||
} else {
|
||||
KeyguardQuickAffordanceModel.Hidden
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.policy
|
||||
|
||||
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
|
||||
import com.android.systemui.common.coroutine.ConflatedCallbackFlow
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
object KeyguardStateControllerExt {
|
||||
/**
|
||||
* Returns an observable for whether the keyguard is currently shown or not.
|
||||
*/
|
||||
fun KeyguardStateController.isKeyguardShowing(loggingTag: String): Flow<Boolean> {
|
||||
return ConflatedCallbackFlow.conflatedCallbackFlow {
|
||||
val callback =
|
||||
object : KeyguardStateController.Callback {
|
||||
override fun onKeyguardShowingChanged() {
|
||||
trySendWithFailureLogging(
|
||||
isShowing, loggingTag, "updated isKeyguardShowing")
|
||||
}
|
||||
}
|
||||
|
||||
addCallback(callback)
|
||||
// Adding the callback does not send an initial update.
|
||||
trySendWithFailureLogging(isShowing, loggingTag, "initial isKeyguardShowing")
|
||||
|
||||
awaitClose { removeCallback(callback) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ class FakeKeyguardQuickAffordanceRepository : KeyguardQuickAffordanceRepository
|
||||
|
||||
private val modelByPosition =
|
||||
mutableMapOf<
|
||||
KeyguardQuickAffordancePosition, MutableStateFlow<KeyguardQuickAffordanceModel>>()
|
||||
KeyguardQuickAffordancePosition, MutableStateFlow<KeyguardQuickAffordanceModel>>()
|
||||
|
||||
init {
|
||||
KeyguardQuickAffordancePosition.values().forEach { value ->
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
package com.android.systemui.keyguard.data.repository
|
||||
|
||||
import com.android.systemui.common.data.model.Position
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
@@ -36,18 +34,13 @@ class FakeKeyguardRepository : KeyguardRepository {
|
||||
private val _clockPosition = MutableStateFlow(Position(0, 0))
|
||||
override val clockPosition: StateFlow<Position> = _clockPosition
|
||||
|
||||
private val _isDozing =
|
||||
MutableSharedFlow<Boolean>(
|
||||
replay = 1,
|
||||
onBufferOverflow = BufferOverflow.DROP_OLDEST,
|
||||
)
|
||||
private val _isKeyguardShowing = MutableStateFlow(false)
|
||||
override val isKeyguardShowing: Flow<Boolean> = _isKeyguardShowing
|
||||
|
||||
private val _isDozing = MutableStateFlow(false)
|
||||
override val isDozing: Flow<Boolean> = _isDozing
|
||||
|
||||
private val _dozeAmount =
|
||||
MutableSharedFlow<Float>(
|
||||
replay = 1,
|
||||
onBufferOverflow = BufferOverflow.DROP_OLDEST,
|
||||
)
|
||||
private val _dozeAmount = MutableStateFlow(0f)
|
||||
override val dozeAmount: Flow<Float> = _dozeAmount
|
||||
|
||||
init {
|
||||
@@ -67,11 +60,15 @@ class FakeKeyguardRepository : KeyguardRepository {
|
||||
_clockPosition.value = Position(x, y)
|
||||
}
|
||||
|
||||
fun setKeyguardShowing(isShowing: Boolean) {
|
||||
_isKeyguardShowing.value = isShowing
|
||||
}
|
||||
|
||||
fun setDozing(isDozing: Boolean) {
|
||||
_isDozing.tryEmit(isDozing)
|
||||
_isDozing.value = isDozing
|
||||
}
|
||||
|
||||
fun setDozeAmount(dozeAmount: Float) {
|
||||
_dozeAmount.tryEmit(dozeAmount)
|
||||
_dozeAmount.value = dozeAmount
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.common.data.model.Position
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.util.mockito.argumentCaptor
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
@@ -31,6 +32,7 @@ import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@SmallTest
|
||||
@@ -38,6 +40,7 @@ import org.mockito.MockitoAnnotations
|
||||
class KeyguardRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
@Mock private lateinit var statusBarStateController: StatusBarStateController
|
||||
@Mock private lateinit var keyguardStateController: KeyguardStateController
|
||||
|
||||
private lateinit var underTest: KeyguardRepositoryImpl
|
||||
|
||||
@@ -45,7 +48,7 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
underTest = KeyguardRepositoryImpl(statusBarStateController)
|
||||
underTest = KeyguardRepositoryImpl(statusBarStateController, keyguardStateController)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -99,6 +102,28 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
|
||||
assertThat(underTest.clockPosition.value).isEqualTo(Position(3, 1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isKeyguardShowing() = runBlockingTest {
|
||||
whenever(keyguardStateController.isShowing).thenReturn(false)
|
||||
var latest: Boolean? = null
|
||||
val job = underTest.isKeyguardShowing.onEach { latest = it }.launchIn(this)
|
||||
|
||||
assertThat(latest).isFalse()
|
||||
|
||||
val captor = argumentCaptor<KeyguardStateController.Callback>()
|
||||
verify(keyguardStateController).addCallback(captor.capture())
|
||||
|
||||
whenever(keyguardStateController.isShowing).thenReturn(true)
|
||||
captor.value.onKeyguardShowingChanged()
|
||||
assertThat(latest).isTrue()
|
||||
|
||||
whenever(keyguardStateController.isShowing).thenReturn(false)
|
||||
captor.value.onKeyguardShowingChanged()
|
||||
assertThat(latest).isFalse()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isDozing() = runBlockingTest {
|
||||
var latest: Boolean? = null
|
||||
|
||||
@@ -51,7 +51,7 @@ class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
whenever(controller.intent).thenReturn(INTENT_1)
|
||||
|
||||
underTest = QrCodeScannerKeyguardQuickAffordanceConfig(context, controller)
|
||||
underTest = QrCodeScannerKeyguardQuickAffordanceConfig(controller)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.android.systemui.containeddrawable.ContainedDrawable
|
||||
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
|
||||
import com.android.systemui.keyguard.data.quickaffordance.QuickAccessWalletKeyguardQuickAffordanceConfig
|
||||
import com.android.systemui.plugins.ActivityStarter
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import com.android.systemui.wallet.controller.QuickAccessWalletController
|
||||
@@ -48,7 +47,6 @@ import org.mockito.MockitoAnnotations
|
||||
class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
|
||||
@Mock private lateinit var walletController: QuickAccessWalletController
|
||||
@Mock private lateinit var keyguardStateController: KeyguardStateController
|
||||
@Mock private lateinit var activityStarter: ActivityStarter
|
||||
|
||||
private lateinit var underTest: QuickAccessWalletKeyguardQuickAffordanceConfig
|
||||
@@ -59,7 +57,6 @@ class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
|
||||
underTest =
|
||||
QuickAccessWalletKeyguardQuickAffordanceConfig(
|
||||
keyguardStateController,
|
||||
walletController,
|
||||
activityStarter,
|
||||
)
|
||||
@@ -67,7 +64,7 @@ class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `affordance - keyguard showing - has wallet card - visible model`() = runBlockingTest {
|
||||
val callback = setUpState()
|
||||
setUpState()
|
||||
var latest: KeyguardQuickAffordanceConfig.State? = null
|
||||
|
||||
val job = underTest.state.onEach { latest = it }.launchIn(this)
|
||||
@@ -76,25 +73,11 @@ class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
assertThat(visibleModel.icon).isEqualTo(ContainedDrawable.WithDrawable(ICON))
|
||||
assertThat(visibleModel.contentDescriptionResourceId).isNotNull()
|
||||
job.cancel()
|
||||
callback?.let { verify(keyguardStateController).removeCallback(it) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `affordance - keyguard not showing - model is none`() = runBlockingTest {
|
||||
val callback = setUpState(isKeyguardShowing = false)
|
||||
var latest: KeyguardQuickAffordanceConfig.State? = null
|
||||
|
||||
val job = underTest.state.onEach { latest = it }.launchIn(this)
|
||||
|
||||
assertThat(latest).isEqualTo(KeyguardQuickAffordanceConfig.State.Hidden)
|
||||
|
||||
job.cancel()
|
||||
callback?.let { verify(keyguardStateController).removeCallback(it) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `affordance - wallet not enabled - model is none`() = runBlockingTest {
|
||||
val callback = setUpState(isWalletEnabled = false)
|
||||
setUpState(isWalletEnabled = false)
|
||||
var latest: KeyguardQuickAffordanceConfig.State? = null
|
||||
|
||||
val job = underTest.state.onEach { latest = it }.launchIn(this)
|
||||
@@ -102,12 +85,11 @@ class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
assertThat(latest).isEqualTo(KeyguardQuickAffordanceConfig.State.Hidden)
|
||||
|
||||
job.cancel()
|
||||
callback?.let { verify(keyguardStateController).removeCallback(it) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `affordance - query not successful - model is none`() = runBlockingTest {
|
||||
val callback = setUpState(isWalletQuerySuccessful = false)
|
||||
setUpState(isWalletQuerySuccessful = false)
|
||||
var latest: KeyguardQuickAffordanceConfig.State? = null
|
||||
|
||||
val job = underTest.state.onEach { latest = it }.launchIn(this)
|
||||
@@ -115,12 +97,11 @@ class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
assertThat(latest).isEqualTo(KeyguardQuickAffordanceConfig.State.Hidden)
|
||||
|
||||
job.cancel()
|
||||
callback?.let { verify(keyguardStateController).removeCallback(it) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `affordance - missing icon - model is none`() = runBlockingTest {
|
||||
val callback = setUpState(hasWalletIcon = false)
|
||||
setUpState(hasWalletIcon = false)
|
||||
var latest: KeyguardQuickAffordanceConfig.State? = null
|
||||
|
||||
val job = underTest.state.onEach { latest = it }.launchIn(this)
|
||||
@@ -128,12 +109,11 @@ class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
assertThat(latest).isEqualTo(KeyguardQuickAffordanceConfig.State.Hidden)
|
||||
|
||||
job.cancel()
|
||||
callback?.let { verify(keyguardStateController).removeCallback(it) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `affordance - no selected card - model is none`() = runBlockingTest {
|
||||
val callback = setUpState(hasWalletIcon = false)
|
||||
setUpState(hasWalletIcon = false)
|
||||
var latest: KeyguardQuickAffordanceConfig.State? = null
|
||||
|
||||
val job = underTest.state.onEach { latest = it }.launchIn(this)
|
||||
@@ -141,7 +121,6 @@ class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
assertThat(latest).isEqualTo(KeyguardQuickAffordanceConfig.State.Hidden)
|
||||
|
||||
job.cancel()
|
||||
callback?.let { verify(keyguardStateController).removeCallback(it) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -159,21 +138,11 @@ class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
private fun setUpState(
|
||||
isKeyguardShowing: Boolean = true,
|
||||
isWalletEnabled: Boolean = true,
|
||||
isWalletQuerySuccessful: Boolean = true,
|
||||
hasWalletIcon: Boolean = true,
|
||||
hasSelectedCard: Boolean = true,
|
||||
): KeyguardStateController.Callback? {
|
||||
var returnedCallback: KeyguardStateController.Callback? = null
|
||||
whenever(keyguardStateController.isShowing).thenReturn(isKeyguardShowing)
|
||||
whenever(keyguardStateController.addCallback(any())).thenAnswer { invocation ->
|
||||
with(invocation.arguments[0] as KeyguardStateController.Callback) {
|
||||
returnedCallback = this
|
||||
onKeyguardShowingChanged()
|
||||
}
|
||||
}
|
||||
|
||||
) {
|
||||
whenever(walletController.isWalletEnabled).thenReturn(isWalletEnabled)
|
||||
|
||||
val walletClient: QuickAccessWalletClient = mock()
|
||||
@@ -203,8 +172,6 @@ class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnedCallback
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -43,20 +43,21 @@ class ObserveKeyguardQuickAffordanceUseCaseTest : SysuiTestCase() {
|
||||
private lateinit var repository: FakeKeyguardRepository
|
||||
private lateinit var quickAffordanceRepository: FakeKeyguardQuickAffordanceRepository
|
||||
private lateinit var isDozingUseCase: ObserveIsDozingUseCase
|
||||
private lateinit var dozeAmountUseCase: ObserveDozeAmountUseCase
|
||||
private lateinit var isKeyguardShowingUseCase: ObserveIsKeyguardShowingUseCase
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
repository = FakeKeyguardRepository()
|
||||
repository.setKeyguardShowing(true)
|
||||
isDozingUseCase = ObserveIsDozingUseCase(repository)
|
||||
dozeAmountUseCase = ObserveDozeAmountUseCase(repository)
|
||||
isKeyguardShowingUseCase = ObserveIsKeyguardShowingUseCase(repository)
|
||||
quickAffordanceRepository = FakeKeyguardQuickAffordanceRepository()
|
||||
|
||||
underTest =
|
||||
ObserveKeyguardQuickAffordanceUseCase(
|
||||
repository = quickAffordanceRepository,
|
||||
isDozingUseCase = isDozingUseCase,
|
||||
dozeAmountUseCase = dozeAmountUseCase,
|
||||
isKeyguardShowingUseCase = isKeyguardShowingUseCase,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -75,9 +76,10 @@ class ObserveKeyguardQuickAffordanceUseCaseTest : SysuiTestCase() {
|
||||
)
|
||||
|
||||
var latest: KeyguardQuickAffordanceModel? = null
|
||||
val job = underTest(KeyguardQuickAffordancePosition.BOTTOM_END)
|
||||
.onEach { latest = it }
|
||||
.launchIn(this)
|
||||
val job =
|
||||
underTest(KeyguardQuickAffordancePosition.BOTTOM_END)
|
||||
.onEach { latest = it }
|
||||
.launchIn(this)
|
||||
|
||||
assertThat(latest).isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java)
|
||||
val visibleModel = latest as KeyguardQuickAffordanceModel.Visible
|
||||
@@ -104,16 +106,17 @@ class ObserveKeyguardQuickAffordanceUseCaseTest : SysuiTestCase() {
|
||||
)
|
||||
|
||||
var latest: KeyguardQuickAffordanceModel? = null
|
||||
val job = underTest(KeyguardQuickAffordancePosition.BOTTOM_END)
|
||||
.onEach { latest = it }
|
||||
.launchIn(this)
|
||||
val job =
|
||||
underTest(KeyguardQuickAffordancePosition.BOTTOM_END)
|
||||
.onEach { latest = it }
|
||||
.launchIn(this)
|
||||
assertThat(latest).isEqualTo(KeyguardQuickAffordanceModel.Hidden)
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invoke - affordance not visible doze amount is not 0`() = runBlockingTest {
|
||||
repository.setDozeAmount(0.3f)
|
||||
fun `invoke - affordance not visible when lockscreen is not showing`() = runBlockingTest {
|
||||
repository.setKeyguardShowing(false)
|
||||
val configKey = HomeControlsKeyguardQuickAffordanceConfig::class
|
||||
val model =
|
||||
KeyguardQuickAffordanceModel.Visible(
|
||||
@@ -127,9 +130,10 @@ class ObserveKeyguardQuickAffordanceUseCaseTest : SysuiTestCase() {
|
||||
)
|
||||
|
||||
var latest: KeyguardQuickAffordanceModel? = null
|
||||
val job = underTest(KeyguardQuickAffordancePosition.BOTTOM_END)
|
||||
.onEach { latest = it }
|
||||
.launchIn(this)
|
||||
val job =
|
||||
underTest(KeyguardQuickAffordancePosition.BOTTOM_END)
|
||||
.onEach { latest = it }
|
||||
.launchIn(this)
|
||||
assertThat(latest).isEqualTo(KeyguardQuickAffordanceModel.Hidden)
|
||||
job.cancel()
|
||||
}
|
||||
@@ -142,9 +146,10 @@ class ObserveKeyguardQuickAffordanceUseCaseTest : SysuiTestCase() {
|
||||
)
|
||||
|
||||
var latest: KeyguardQuickAffordanceModel? = null
|
||||
val job = underTest(KeyguardQuickAffordancePosition.BOTTOM_START)
|
||||
.onEach { latest = it }
|
||||
.launchIn(this)
|
||||
val job =
|
||||
underTest(KeyguardQuickAffordancePosition.BOTTOM_START)
|
||||
.onEach { latest = it }
|
||||
.launchIn(this)
|
||||
assertThat(latest).isEqualTo(KeyguardQuickAffordanceModel.Hidden)
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.android.systemui.keyguard.domain.usecase.ObserveBottomAreaAlphaUseCas
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveClockPositionUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveDozeAmountUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveIsDozingUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveIsKeyguardShowingUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveKeyguardQuickAffordanceUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.OnKeyguardQuickAffordanceClickedUseCase
|
||||
import com.android.systemui.keyguard.shared.model.KeyguardQuickAffordanceModel
|
||||
@@ -65,7 +66,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
private lateinit var affordanceRepository: FakeKeyguardQuickAffordanceRepository
|
||||
private lateinit var repository: FakeKeyguardRepository
|
||||
private lateinit var isDozingUseCase: ObserveIsDozingUseCase
|
||||
private lateinit var dozeAmountUseCase: ObserveDozeAmountUseCase
|
||||
private lateinit var isKeyguardShowingUseCase: ObserveIsKeyguardShowingUseCase
|
||||
private lateinit var launchQuickAffordanceUseCase: FakeLaunchKeyguardQuickAffordanceUseCase
|
||||
private lateinit var homeControlsQuickAffordanceConfig: FakeKeyguardQuickAffordanceConfig
|
||||
private lateinit var quickAccessWalletAffordanceConfig: FakeKeyguardQuickAffordanceConfig
|
||||
@@ -83,8 +84,8 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
ObserveIsDozingUseCase(
|
||||
repository = repository,
|
||||
)
|
||||
dozeAmountUseCase =
|
||||
ObserveDozeAmountUseCase(
|
||||
isKeyguardShowingUseCase =
|
||||
ObserveIsKeyguardShowingUseCase(
|
||||
repository = repository,
|
||||
)
|
||||
launchQuickAffordanceUseCase = FakeLaunchKeyguardQuickAffordanceUseCase()
|
||||
@@ -98,7 +99,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
ObserveKeyguardQuickAffordanceUseCase(
|
||||
repository = affordanceRepository,
|
||||
isDozingUseCase = isDozingUseCase,
|
||||
dozeAmountUseCase = dozeAmountUseCase,
|
||||
isKeyguardShowingUseCase = isKeyguardShowingUseCase,
|
||||
),
|
||||
onQuickAffordanceClickedUseCase =
|
||||
OnKeyguardQuickAffordanceClickedUseCase(
|
||||
@@ -140,12 +141,13 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `startButton - present and not dozing - visible model - starts activity on click`() =
|
||||
fun `startButton - present - not dozing - lockscreen showing - visible model - starts activity on click`() = // ktlint-disable max-line-length
|
||||
runBlockingTest {
|
||||
var latest: KeyguardQuickAffordanceViewModel? = null
|
||||
val job = underTest.startButton.onEach { latest = it }.launchIn(this)
|
||||
|
||||
repository.setDozing(false)
|
||||
repository.setKeyguardShowing(true)
|
||||
val testConfig =
|
||||
TestConfig(
|
||||
isVisible = true,
|
||||
@@ -168,12 +170,13 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `endButton - present and not dozing - visible model - do nothing on click`() =
|
||||
fun `endButton - present - not dozing - lockscreen showing - visible model - do nothing on click`() = // ktlint-disable max-line-length
|
||||
runBlockingTest {
|
||||
var latest: KeyguardQuickAffordanceViewModel? = null
|
||||
val job = underTest.endButton.onEach { latest = it }.launchIn(this)
|
||||
|
||||
repository.setDozing(false)
|
||||
repository.setKeyguardShowing(true)
|
||||
val config =
|
||||
TestConfig(
|
||||
isVisible = true,
|
||||
@@ -197,35 +200,38 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `startButton - not present and not dozing - model is none`() = runBlockingTest {
|
||||
var latest: KeyguardQuickAffordanceViewModel? = null
|
||||
val job = underTest.startButton.onEach { latest = it }.launchIn(this)
|
||||
fun `startButton - not present - not dozing - lockscreen showing - model is none`() =
|
||||
runBlockingTest {
|
||||
var latest: KeyguardQuickAffordanceViewModel? = null
|
||||
val job = underTest.startButton.onEach { latest = it }.launchIn(this)
|
||||
|
||||
repository.setDozing(false)
|
||||
val config =
|
||||
TestConfig(
|
||||
isVisible = false,
|
||||
)
|
||||
val configKey =
|
||||
setUpQuickAffordanceModel(
|
||||
position = KeyguardQuickAffordancePosition.BOTTOM_START,
|
||||
repository.setDozing(false)
|
||||
repository.setKeyguardShowing(true)
|
||||
val config =
|
||||
TestConfig(
|
||||
isVisible = false,
|
||||
)
|
||||
val configKey =
|
||||
setUpQuickAffordanceModel(
|
||||
position = KeyguardQuickAffordancePosition.BOTTOM_START,
|
||||
testConfig = config,
|
||||
)
|
||||
|
||||
assertQuickAffordanceViewModel(
|
||||
viewModel = latest,
|
||||
testConfig = config,
|
||||
configKey = configKey,
|
||||
)
|
||||
|
||||
assertQuickAffordanceViewModel(
|
||||
viewModel = latest,
|
||||
testConfig = config,
|
||||
configKey = configKey,
|
||||
)
|
||||
job.cancel()
|
||||
}
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `startButton - present but dozing - model is none`() = runBlockingTest {
|
||||
fun `startButton - present - dozing - lockscreen showing - model is none`() = runBlockingTest {
|
||||
var latest: KeyguardQuickAffordanceViewModel? = null
|
||||
val job = underTest.startButton.onEach { latest = it }.launchIn(this)
|
||||
|
||||
repository.setDozing(true)
|
||||
repository.setKeyguardShowing(true)
|
||||
val config =
|
||||
TestConfig(
|
||||
isVisible = true,
|
||||
@@ -247,6 +253,35 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `startButton - present - not dozing - lockscreen not showing - model is none`() =
|
||||
runBlockingTest {
|
||||
var latest: KeyguardQuickAffordanceViewModel? = null
|
||||
val job = underTest.startButton.onEach { latest = it }.launchIn(this)
|
||||
|
||||
repository.setDozing(false)
|
||||
repository.setKeyguardShowing(false)
|
||||
val config =
|
||||
TestConfig(
|
||||
isVisible = true,
|
||||
icon = mock(),
|
||||
canShowWhileLocked = false,
|
||||
intent = Intent("action"),
|
||||
)
|
||||
val configKey =
|
||||
setUpQuickAffordanceModel(
|
||||
position = KeyguardQuickAffordancePosition.BOTTOM_START,
|
||||
testConfig = config,
|
||||
)
|
||||
|
||||
assertQuickAffordanceViewModel(
|
||||
viewModel = latest,
|
||||
testConfig = TestConfig(isVisible = false),
|
||||
configKey = configKey,
|
||||
)
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun animateButtonReveal() = runBlockingTest {
|
||||
val values = mutableListOf<Boolean>()
|
||||
@@ -287,6 +322,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun isIndicationAreaPadded() = runBlockingTest {
|
||||
repository.setKeyguardShowing(true)
|
||||
val values = mutableListOf<Boolean>()
|
||||
val job = underTest.isIndicationAreaPadded.onEach(values::add).launchIn(this)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user