Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt +10 −1 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import javax.inject.Inject import kotlin.reflect.KClass import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.onStart @SysUISingleton class KeyguardQuickAffordanceInteractor Loading Loading @@ -88,7 +89,15 @@ constructor( position: KeyguardQuickAffordancePosition ): Flow<KeyguardQuickAffordanceModel> { val configs = registry.getAll(position) return combine(configs.map { config -> config.state }) { states -> return combine( configs.map { config -> // We emit an initial "Hidden" value to make sure that there's always an initial // value and avoid subtle bugs where the downstream isn't receiving any values // because one config implementation is not emitting an initial value. For example, // see b/244296596. config.state.onStart { emit(KeyguardQuickAffordanceConfig.State.Hidden) } } ) { states -> val index = states.indexOfFirst { it is KeyguardQuickAffordanceConfig.State.Visible } if (index != -1) { val visibleState = states[index] as KeyguardQuickAffordanceConfig.State.Visible Loading packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/usecase/KeyguardQuickAffordanceInteractorTest.kt +9 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.yield import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading Loading @@ -110,6 +111,10 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() { .quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START) .onEach { latest = it } .launchIn(this) // The interactor has an onStart { emit(Hidden) } to cover for upstream configs that don't // produce an initial value. We yield to give the coroutine time to emit the first real // value from our config. yield() assertThat(latest).isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java) val visibleModel = latest as KeyguardQuickAffordanceModel.Visible Loading @@ -136,6 +141,10 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() { .quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_END) .onEach { latest = it } .launchIn(this) // The interactor has an onStart { emit(Hidden) } to cover for upstream configs that don't // produce an initial value. We yield to give the coroutine time to emit the first real // value from our config. yield() assertThat(latest).isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java) val visibleModel = latest as KeyguardQuickAffordanceModel.Visible Loading packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt +8 −1 Original line number Diff line number Diff line Loading @@ -224,7 +224,10 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() { repository.setAnimateDozingTransitions(false) yield() assertThat(values).isEqualTo(listOf(false, true, false)) // Note the extra false value in the beginning. This is to cover for the initial value // inserted by the quick affordance interactor which it does to cover for config // implementations that don't emit an initial value. assertThat(values).isEqualTo(listOf(false, false, true, false)) job.cancel() } Loading Loading @@ -372,6 +375,10 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() { var latest: KeyguardQuickAffordanceViewModel? = null val job = underTest.startButton.onEach { latest = it }.launchIn(this) // The interactor has an onStart { emit(Hidden) } to cover for upstream configs that don't // produce an initial value. We yield to give the coroutine time to emit the first real // value from our config. yield() assertQuickAffordanceViewModel( viewModel = latest, Loading Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt +10 −1 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import javax.inject.Inject import kotlin.reflect.KClass import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.onStart @SysUISingleton class KeyguardQuickAffordanceInteractor Loading Loading @@ -88,7 +89,15 @@ constructor( position: KeyguardQuickAffordancePosition ): Flow<KeyguardQuickAffordanceModel> { val configs = registry.getAll(position) return combine(configs.map { config -> config.state }) { states -> return combine( configs.map { config -> // We emit an initial "Hidden" value to make sure that there's always an initial // value and avoid subtle bugs where the downstream isn't receiving any values // because one config implementation is not emitting an initial value. For example, // see b/244296596. config.state.onStart { emit(KeyguardQuickAffordanceConfig.State.Hidden) } } ) { states -> val index = states.indexOfFirst { it is KeyguardQuickAffordanceConfig.State.Visible } if (index != -1) { val visibleState = states[index] as KeyguardQuickAffordanceConfig.State.Visible Loading
packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/usecase/KeyguardQuickAffordanceInteractorTest.kt +9 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.yield import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading Loading @@ -110,6 +111,10 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() { .quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START) .onEach { latest = it } .launchIn(this) // The interactor has an onStart { emit(Hidden) } to cover for upstream configs that don't // produce an initial value. We yield to give the coroutine time to emit the first real // value from our config. yield() assertThat(latest).isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java) val visibleModel = latest as KeyguardQuickAffordanceModel.Visible Loading @@ -136,6 +141,10 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() { .quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_END) .onEach { latest = it } .launchIn(this) // The interactor has an onStart { emit(Hidden) } to cover for upstream configs that don't // produce an initial value. We yield to give the coroutine time to emit the first real // value from our config. yield() assertThat(latest).isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java) val visibleModel = latest as KeyguardQuickAffordanceModel.Visible Loading
packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt +8 −1 Original line number Diff line number Diff line Loading @@ -224,7 +224,10 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() { repository.setAnimateDozingTransitions(false) yield() assertThat(values).isEqualTo(listOf(false, true, false)) // Note the extra false value in the beginning. This is to cover for the initial value // inserted by the quick affordance interactor which it does to cover for config // implementations that don't emit an initial value. assertThat(values).isEqualTo(listOf(false, false, true, false)) job.cancel() } Loading Loading @@ -372,6 +375,10 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() { var latest: KeyguardQuickAffordanceViewModel? = null val job = underTest.startButton.onEach { latest = it }.launchIn(this) // The interactor has an onStart { emit(Hidden) } to cover for upstream configs that don't // produce an initial value. We yield to give the coroutine time to emit the first real // value from our config. yield() assertQuickAffordanceViewModel( viewModel = latest, Loading