Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt +125 −72 Original line number Diff line number Diff line Loading @@ -16,98 +16,108 @@ package com.android.systemui.keyguard.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import android.platform.test.annotations.DisableFlags import android.platform.test.flag.junit.FlagsParameterization import androidx.test.filters.SmallTest import com.android.systemui.Flags as AConfigFlags import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR import com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT import com.android.systemui.SysuiTestCase import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.common.ui.domain.interactor.configurationInteractor import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository import com.android.systemui.communal.domain.interactor.communalSceneInteractor import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.coroutines.collectLastValue import com.android.systemui.doze.util.BurnInHelperWrapper import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.BurnInInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory import com.android.systemui.keyguard.domain.interactor.keyguardBottomAreaInteractor import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.BurnInModel import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.MockitoAnnotations import org.mockito.kotlin.any import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) class KeyguardIndicationAreaViewModelTest : SysuiTestCase() { @RunWith(ParameterizedAndroidJunit4::class) class KeyguardIndicationAreaViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope @Mock private lateinit var burnInHelperWrapper: BurnInHelperWrapper @Mock private lateinit var shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel @Mock private lateinit var burnInInteractor: BurnInInteractor private val burnInFlow = MutableStateFlow(BurnInModel()) private lateinit var bottomAreaInteractor: KeyguardBottomAreaInteractor private val bottomAreaInteractor = kosmos.keyguardBottomAreaInteractor private lateinit var underTest: KeyguardIndicationAreaViewModel private lateinit var repository: FakeKeyguardRepository private val keyguardRepository = kosmos.fakeKeyguardRepository private val communalSceneRepository = kosmos.fakeCommunalSceneRepository private val startButtonFlow = MutableStateFlow<KeyguardQuickAffordanceViewModel>( MutableStateFlow( KeyguardQuickAffordanceViewModel( slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId() ) ) private val endButtonFlow = MutableStateFlow<KeyguardQuickAffordanceViewModel>( MutableStateFlow( KeyguardQuickAffordanceViewModel( slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId() ) ) private val alphaFlow = MutableStateFlow<Float>(1f) private val alphaFlow = MutableStateFlow(1f) init { mSetFlagsRule.setFlagsParameterization(flags) } @Before fun setUp() { MockitoAnnotations.initMocks(this) mSetFlagsRule.disableFlags(AConfigFlags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR) mSetFlagsRule.disableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) whenever(burnInHelperWrapper.burnInOffset(anyInt(), any())) .thenReturn(RETURNED_BURN_IN_OFFSET) whenever(burnInInteractor.burnIn(anyInt(), anyInt())).thenReturn(burnInFlow) val withDeps = KeyguardInteractorFactory.create() val keyguardInteractor = withDeps.keyguardInteractor repository = withDeps.repository val bottomAreaViewModel: KeyguardBottomAreaViewModel = mock() whenever(bottomAreaViewModel.startButton).thenReturn(startButtonFlow) whenever(bottomAreaViewModel.endButton).thenReturn(endButtonFlow) whenever(bottomAreaViewModel.alpha).thenReturn(alphaFlow) bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository) val bottomAreaViewModel = mock<KeyguardBottomAreaViewModel> { on { startButton } doReturn startButtonFlow on { endButton } doReturn endButtonFlow on { alpha } doReturn alphaFlow } val burnInInteractor = mock<BurnInInteractor> { on { burnIn(anyInt(), anyInt()) } doReturn flowOf(BurnInModel()) } val burnInHelperWrapper = mock<BurnInHelperWrapper> { on { burnInOffset(anyInt(), any()) } doReturn RETURNED_BURN_IN_OFFSET } val shortcutsCombinedViewModel = mock<KeyguardQuickAffordancesCombinedViewModel> { on { startButton } doReturn startButtonFlow on { endButton } doReturn endButtonFlow } underTest = KeyguardIndicationAreaViewModel( keyguardInteractor = keyguardInteractor, keyguardInteractor = kosmos.keyguardInteractor, bottomAreaInteractor = bottomAreaInteractor, keyguardBottomAreaViewModel = bottomAreaViewModel, burnInHelperWrapper = burnInHelperWrapper, burnInInteractor = burnInInteractor, shortcutsCombinedViewModel = shortcutsCombinedViewModel, configurationInteractor = ConfigurationInteractor(FakeConfigurationRepository()), configurationInteractor = kosmos.configurationInteractor, keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor, backgroundCoroutineContext = kosmos.testDispatcher, backgroundDispatcher = kosmos.testDispatcher, communalSceneInteractor = kosmos.communalSceneInteractor, mainDispatcher = kosmos.testDispatcher ) } Loading @@ -115,77 +125,120 @@ class KeyguardIndicationAreaViewModelTest : SysuiTestCase() { @Test fun alpha() = testScope.runTest { val value = collectLastValue(underTest.alpha) val alpha by collectLastValue(underTest.alpha) assertThat(value()).isEqualTo(1f) assertThat(alpha).isEqualTo(1f) alphaFlow.value = 0.1f assertThat(value()).isEqualTo(0.1f) assertThat(alpha).isEqualTo(0.1f) alphaFlow.value = 0.5f assertThat(value()).isEqualTo(0.5f) assertThat(alpha).isEqualTo(0.5f) alphaFlow.value = 0.2f assertThat(value()).isEqualTo(0.2f) assertThat(alpha).isEqualTo(0.2f) alphaFlow.value = 0f assertThat(value()).isEqualTo(0f) assertThat(alpha).isEqualTo(0f) } @Test @DisableFlags(FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR) fun isIndicationAreaPadded() = testScope.runTest { repository.setKeyguardShowing(true) val value = collectLastValue(underTest.isIndicationAreaPadded) keyguardRepository.setKeyguardShowing(true) val isIndicationAreaPadded by collectLastValue(underTest.isIndicationAreaPadded) assertThat(value()).isFalse() assertThat(isIndicationAreaPadded).isFalse() startButtonFlow.value = startButtonFlow.value.copy(isVisible = true) assertThat(value()).isTrue() assertThat(isIndicationAreaPadded).isTrue() endButtonFlow.value = endButtonFlow.value.copy(isVisible = true) assertThat(value()).isTrue() assertThat(isIndicationAreaPadded).isTrue() startButtonFlow.value = startButtonFlow.value.copy(isVisible = false) assertThat(value()).isTrue() assertThat(isIndicationAreaPadded).isTrue() endButtonFlow.value = endButtonFlow.value.copy(isVisible = false) assertThat(value()).isFalse() assertThat(isIndicationAreaPadded).isFalse() } @Test @DisableFlags(FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT, FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR) fun indicationAreaTranslationX() = testScope.runTest { val value = collectLastValue(underTest.indicationAreaTranslationX) val translationX by collectLastValue(underTest.indicationAreaTranslationX) assertThat(value()).isEqualTo(0f) assertThat(translationX).isEqualTo(0f) bottomAreaInteractor.setClockPosition(100, 100) assertThat(value()).isEqualTo(100f) assertThat(translationX).isEqualTo(100f) bottomAreaInteractor.setClockPosition(200, 100) assertThat(value()).isEqualTo(200f) assertThat(translationX).isEqualTo(200f) bottomAreaInteractor.setClockPosition(200, 200) assertThat(value()).isEqualTo(200f) assertThat(translationX).isEqualTo(200f) bottomAreaInteractor.setClockPosition(300, 100) assertThat(value()).isEqualTo(300f) assertThat(translationX).isEqualTo(300f) } @Test @DisableFlags(FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) fun indicationAreaTranslationY() = testScope.runTest { val value = val translationY by collectLastValue(underTest.indicationAreaTranslationY(DEFAULT_BURN_IN_OFFSET)) // Negative 0 - apparently there's a difference in floating point arithmetic - FML assertThat(value()).isEqualTo(-0f) assertThat(translationY).isEqualTo(-0f) val expected1 = setDozeAmountAndCalculateExpectedTranslationY(0.1f) assertThat(value()).isEqualTo(expected1) assertThat(translationY).isEqualTo(expected1) val expected2 = setDozeAmountAndCalculateExpectedTranslationY(0.2f) assertThat(value()).isEqualTo(expected2) assertThat(translationY).isEqualTo(expected2) val expected3 = setDozeAmountAndCalculateExpectedTranslationY(0.5f) assertThat(value()).isEqualTo(expected3) assertThat(translationY).isEqualTo(expected3) val expected4 = setDozeAmountAndCalculateExpectedTranslationY(1f) assertThat(value()).isEqualTo(expected4) assertThat(translationY).isEqualTo(expected4) } @Test fun visibilityWhenCommunalNotShowing() = testScope.runTest { keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD) val visible by collectLastValue(underTest.visible) assertThat(visible).isTrue() keyguardRepository.setStatusBarState(StatusBarState.SHADE) assertThat(visible).isFalse() } @Test fun visibilityWhenCommunalShowing() = testScope.runTest { keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD) communalSceneRepository.setTransitionState( flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal)) ) val visible by collectLastValue(underTest.visible) assertThat(visible).isTrue() keyguardRepository.setStatusBarState(StatusBarState.SHADE) assertThat(visible).isTrue() communalSceneRepository.setTransitionState( flowOf(ObservableTransitionState.Idle(CommunalScenes.Blank)) ) assertThat(visible).isFalse() } private fun setDozeAmountAndCalculateExpectedTranslationY(dozeAmount: Float): Float { repository.setDozeAmount(dozeAmount) keyguardRepository.setDozeAmount(dozeAmount) return dozeAmount * (RETURNED_BURN_IN_OFFSET - DEFAULT_BURN_IN_OFFSET) } companion object { private const val DEFAULT_BURN_IN_OFFSET = 5 private const val RETURNED_BURN_IN_OFFSET = 3 @JvmStatic @Parameters(name = "{0}") fun getParams(): List<FlagsParameterization> { return FlagsParameterization.allCombinationsOf( FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR, FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT, ) } } } packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt +6 −0 Original line number Diff line number Diff line Loading @@ -133,6 +133,12 @@ object KeyguardIndicationAreaBinder { configurationBasedDimensions.value = loadFromResources(view) } } launch("$TAG#viewModel.visible") { viewModel.visible.collect { visible -> indicationController.setVisible(visible) } } } } return disposables Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt +16 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.keyguard.ui.viewmodel import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.doze.util.BurnInHelperWrapper Loading @@ -28,9 +29,10 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.BurnInModel import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.res.R import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow Loading @@ -44,14 +46,15 @@ class KeyguardIndicationAreaViewModel @Inject constructor( private val keyguardInteractor: KeyguardInteractor, private val bottomAreaInteractor: KeyguardBottomAreaInteractor, bottomAreaInteractor: KeyguardBottomAreaInteractor, keyguardBottomAreaViewModel: KeyguardBottomAreaViewModel, private val burnInHelperWrapper: BurnInHelperWrapper, private val burnInInteractor: BurnInInteractor, private val shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel, burnInInteractor: BurnInInteractor, shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel, configurationInteractor: ConfigurationInteractor, keyguardTransitionInteractor: KeyguardTransitionInteractor, @Background private val backgroundCoroutineContext: CoroutineContext, communalSceneInteractor: CommunalSceneInteractor, @Background private val backgroundDispatcher: CoroutineDispatcher, @Main private val mainDispatcher: CoroutineDispatcher, ) { Loading @@ -61,6 +64,13 @@ constructor( /** An observable for the alpha level for the entire bottom area. */ val alpha: Flow<Float> = keyguardBottomAreaViewModel.alpha /** An observable for the visibility value for the indication area view. */ val visible: Flow<Boolean> = anyOf( keyguardInteractor.statusBarState.map { state -> state == StatusBarState.KEYGUARD }, communalSceneInteractor.isCommunalVisible ) /** An observable for whether the indication area should be padded. */ val isIndicationAreaPadded: Flow<Boolean> = if (KeyguardBottomAreaRefactor.isEnabled) { Loading Loading @@ -97,7 +107,7 @@ constructor( ) } .distinctUntilChanged() .flowOn(backgroundCoroutineContext) .flowOn(backgroundDispatcher) /** An observable for the x-offset by which the indication area should be translated. */ val indicationAreaTranslationX: Flow<Float> = Loading packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +0 −5 Original line number Diff line number Diff line Loading @@ -1669,11 +1669,6 @@ public class KeyguardIndicationController { private final StatusBarStateController.StateListener mStatusBarStateListener = new StatusBarStateController.StateListener() { @Override public void onStateChanged(int newState) { setVisible(newState == StatusBarState.KEYGUARD); } @Override public void onDozingChanged(boolean dozing) { if (mDozing == dozing) { Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt +125 −72 Original line number Diff line number Diff line Loading @@ -16,98 +16,108 @@ package com.android.systemui.keyguard.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import android.platform.test.annotations.DisableFlags import android.platform.test.flag.junit.FlagsParameterization import androidx.test.filters.SmallTest import com.android.systemui.Flags as AConfigFlags import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR import com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT import com.android.systemui.SysuiTestCase import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.common.ui.domain.interactor.configurationInteractor import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository import com.android.systemui.communal.domain.interactor.communalSceneInteractor import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.coroutines.collectLastValue import com.android.systemui.doze.util.BurnInHelperWrapper import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.BurnInInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory import com.android.systemui.keyguard.domain.interactor.keyguardBottomAreaInteractor import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.BurnInModel import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.MockitoAnnotations import org.mockito.kotlin.any import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) class KeyguardIndicationAreaViewModelTest : SysuiTestCase() { @RunWith(ParameterizedAndroidJunit4::class) class KeyguardIndicationAreaViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope @Mock private lateinit var burnInHelperWrapper: BurnInHelperWrapper @Mock private lateinit var shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel @Mock private lateinit var burnInInteractor: BurnInInteractor private val burnInFlow = MutableStateFlow(BurnInModel()) private lateinit var bottomAreaInteractor: KeyguardBottomAreaInteractor private val bottomAreaInteractor = kosmos.keyguardBottomAreaInteractor private lateinit var underTest: KeyguardIndicationAreaViewModel private lateinit var repository: FakeKeyguardRepository private val keyguardRepository = kosmos.fakeKeyguardRepository private val communalSceneRepository = kosmos.fakeCommunalSceneRepository private val startButtonFlow = MutableStateFlow<KeyguardQuickAffordanceViewModel>( MutableStateFlow( KeyguardQuickAffordanceViewModel( slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId() ) ) private val endButtonFlow = MutableStateFlow<KeyguardQuickAffordanceViewModel>( MutableStateFlow( KeyguardQuickAffordanceViewModel( slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId() ) ) private val alphaFlow = MutableStateFlow<Float>(1f) private val alphaFlow = MutableStateFlow(1f) init { mSetFlagsRule.setFlagsParameterization(flags) } @Before fun setUp() { MockitoAnnotations.initMocks(this) mSetFlagsRule.disableFlags(AConfigFlags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR) mSetFlagsRule.disableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) whenever(burnInHelperWrapper.burnInOffset(anyInt(), any())) .thenReturn(RETURNED_BURN_IN_OFFSET) whenever(burnInInteractor.burnIn(anyInt(), anyInt())).thenReturn(burnInFlow) val withDeps = KeyguardInteractorFactory.create() val keyguardInteractor = withDeps.keyguardInteractor repository = withDeps.repository val bottomAreaViewModel: KeyguardBottomAreaViewModel = mock() whenever(bottomAreaViewModel.startButton).thenReturn(startButtonFlow) whenever(bottomAreaViewModel.endButton).thenReturn(endButtonFlow) whenever(bottomAreaViewModel.alpha).thenReturn(alphaFlow) bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository) val bottomAreaViewModel = mock<KeyguardBottomAreaViewModel> { on { startButton } doReturn startButtonFlow on { endButton } doReturn endButtonFlow on { alpha } doReturn alphaFlow } val burnInInteractor = mock<BurnInInteractor> { on { burnIn(anyInt(), anyInt()) } doReturn flowOf(BurnInModel()) } val burnInHelperWrapper = mock<BurnInHelperWrapper> { on { burnInOffset(anyInt(), any()) } doReturn RETURNED_BURN_IN_OFFSET } val shortcutsCombinedViewModel = mock<KeyguardQuickAffordancesCombinedViewModel> { on { startButton } doReturn startButtonFlow on { endButton } doReturn endButtonFlow } underTest = KeyguardIndicationAreaViewModel( keyguardInteractor = keyguardInteractor, keyguardInteractor = kosmos.keyguardInteractor, bottomAreaInteractor = bottomAreaInteractor, keyguardBottomAreaViewModel = bottomAreaViewModel, burnInHelperWrapper = burnInHelperWrapper, burnInInteractor = burnInInteractor, shortcutsCombinedViewModel = shortcutsCombinedViewModel, configurationInteractor = ConfigurationInteractor(FakeConfigurationRepository()), configurationInteractor = kosmos.configurationInteractor, keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor, backgroundCoroutineContext = kosmos.testDispatcher, backgroundDispatcher = kosmos.testDispatcher, communalSceneInteractor = kosmos.communalSceneInteractor, mainDispatcher = kosmos.testDispatcher ) } Loading @@ -115,77 +125,120 @@ class KeyguardIndicationAreaViewModelTest : SysuiTestCase() { @Test fun alpha() = testScope.runTest { val value = collectLastValue(underTest.alpha) val alpha by collectLastValue(underTest.alpha) assertThat(value()).isEqualTo(1f) assertThat(alpha).isEqualTo(1f) alphaFlow.value = 0.1f assertThat(value()).isEqualTo(0.1f) assertThat(alpha).isEqualTo(0.1f) alphaFlow.value = 0.5f assertThat(value()).isEqualTo(0.5f) assertThat(alpha).isEqualTo(0.5f) alphaFlow.value = 0.2f assertThat(value()).isEqualTo(0.2f) assertThat(alpha).isEqualTo(0.2f) alphaFlow.value = 0f assertThat(value()).isEqualTo(0f) assertThat(alpha).isEqualTo(0f) } @Test @DisableFlags(FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR) fun isIndicationAreaPadded() = testScope.runTest { repository.setKeyguardShowing(true) val value = collectLastValue(underTest.isIndicationAreaPadded) keyguardRepository.setKeyguardShowing(true) val isIndicationAreaPadded by collectLastValue(underTest.isIndicationAreaPadded) assertThat(value()).isFalse() assertThat(isIndicationAreaPadded).isFalse() startButtonFlow.value = startButtonFlow.value.copy(isVisible = true) assertThat(value()).isTrue() assertThat(isIndicationAreaPadded).isTrue() endButtonFlow.value = endButtonFlow.value.copy(isVisible = true) assertThat(value()).isTrue() assertThat(isIndicationAreaPadded).isTrue() startButtonFlow.value = startButtonFlow.value.copy(isVisible = false) assertThat(value()).isTrue() assertThat(isIndicationAreaPadded).isTrue() endButtonFlow.value = endButtonFlow.value.copy(isVisible = false) assertThat(value()).isFalse() assertThat(isIndicationAreaPadded).isFalse() } @Test @DisableFlags(FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT, FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR) fun indicationAreaTranslationX() = testScope.runTest { val value = collectLastValue(underTest.indicationAreaTranslationX) val translationX by collectLastValue(underTest.indicationAreaTranslationX) assertThat(value()).isEqualTo(0f) assertThat(translationX).isEqualTo(0f) bottomAreaInteractor.setClockPosition(100, 100) assertThat(value()).isEqualTo(100f) assertThat(translationX).isEqualTo(100f) bottomAreaInteractor.setClockPosition(200, 100) assertThat(value()).isEqualTo(200f) assertThat(translationX).isEqualTo(200f) bottomAreaInteractor.setClockPosition(200, 200) assertThat(value()).isEqualTo(200f) assertThat(translationX).isEqualTo(200f) bottomAreaInteractor.setClockPosition(300, 100) assertThat(value()).isEqualTo(300f) assertThat(translationX).isEqualTo(300f) } @Test @DisableFlags(FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) fun indicationAreaTranslationY() = testScope.runTest { val value = val translationY by collectLastValue(underTest.indicationAreaTranslationY(DEFAULT_BURN_IN_OFFSET)) // Negative 0 - apparently there's a difference in floating point arithmetic - FML assertThat(value()).isEqualTo(-0f) assertThat(translationY).isEqualTo(-0f) val expected1 = setDozeAmountAndCalculateExpectedTranslationY(0.1f) assertThat(value()).isEqualTo(expected1) assertThat(translationY).isEqualTo(expected1) val expected2 = setDozeAmountAndCalculateExpectedTranslationY(0.2f) assertThat(value()).isEqualTo(expected2) assertThat(translationY).isEqualTo(expected2) val expected3 = setDozeAmountAndCalculateExpectedTranslationY(0.5f) assertThat(value()).isEqualTo(expected3) assertThat(translationY).isEqualTo(expected3) val expected4 = setDozeAmountAndCalculateExpectedTranslationY(1f) assertThat(value()).isEqualTo(expected4) assertThat(translationY).isEqualTo(expected4) } @Test fun visibilityWhenCommunalNotShowing() = testScope.runTest { keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD) val visible by collectLastValue(underTest.visible) assertThat(visible).isTrue() keyguardRepository.setStatusBarState(StatusBarState.SHADE) assertThat(visible).isFalse() } @Test fun visibilityWhenCommunalShowing() = testScope.runTest { keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD) communalSceneRepository.setTransitionState( flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal)) ) val visible by collectLastValue(underTest.visible) assertThat(visible).isTrue() keyguardRepository.setStatusBarState(StatusBarState.SHADE) assertThat(visible).isTrue() communalSceneRepository.setTransitionState( flowOf(ObservableTransitionState.Idle(CommunalScenes.Blank)) ) assertThat(visible).isFalse() } private fun setDozeAmountAndCalculateExpectedTranslationY(dozeAmount: Float): Float { repository.setDozeAmount(dozeAmount) keyguardRepository.setDozeAmount(dozeAmount) return dozeAmount * (RETURNED_BURN_IN_OFFSET - DEFAULT_BURN_IN_OFFSET) } companion object { private const val DEFAULT_BURN_IN_OFFSET = 5 private const val RETURNED_BURN_IN_OFFSET = 3 @JvmStatic @Parameters(name = "{0}") fun getParams(): List<FlagsParameterization> { return FlagsParameterization.allCombinationsOf( FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR, FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT, ) } } }
packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt +6 −0 Original line number Diff line number Diff line Loading @@ -133,6 +133,12 @@ object KeyguardIndicationAreaBinder { configurationBasedDimensions.value = loadFromResources(view) } } launch("$TAG#viewModel.visible") { viewModel.visible.collect { visible -> indicationController.setVisible(visible) } } } } return disposables Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt +16 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.keyguard.ui.viewmodel import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.doze.util.BurnInHelperWrapper Loading @@ -28,9 +29,10 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.BurnInModel import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.res.R import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow Loading @@ -44,14 +46,15 @@ class KeyguardIndicationAreaViewModel @Inject constructor( private val keyguardInteractor: KeyguardInteractor, private val bottomAreaInteractor: KeyguardBottomAreaInteractor, bottomAreaInteractor: KeyguardBottomAreaInteractor, keyguardBottomAreaViewModel: KeyguardBottomAreaViewModel, private val burnInHelperWrapper: BurnInHelperWrapper, private val burnInInteractor: BurnInInteractor, private val shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel, burnInInteractor: BurnInInteractor, shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel, configurationInteractor: ConfigurationInteractor, keyguardTransitionInteractor: KeyguardTransitionInteractor, @Background private val backgroundCoroutineContext: CoroutineContext, communalSceneInteractor: CommunalSceneInteractor, @Background private val backgroundDispatcher: CoroutineDispatcher, @Main private val mainDispatcher: CoroutineDispatcher, ) { Loading @@ -61,6 +64,13 @@ constructor( /** An observable for the alpha level for the entire bottom area. */ val alpha: Flow<Float> = keyguardBottomAreaViewModel.alpha /** An observable for the visibility value for the indication area view. */ val visible: Flow<Boolean> = anyOf( keyguardInteractor.statusBarState.map { state -> state == StatusBarState.KEYGUARD }, communalSceneInteractor.isCommunalVisible ) /** An observable for whether the indication area should be padded. */ val isIndicationAreaPadded: Flow<Boolean> = if (KeyguardBottomAreaRefactor.isEnabled) { Loading Loading @@ -97,7 +107,7 @@ constructor( ) } .distinctUntilChanged() .flowOn(backgroundCoroutineContext) .flowOn(backgroundDispatcher) /** An observable for the x-offset by which the indication area should be translated. */ val indicationAreaTranslationX: Flow<Float> = Loading
packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +0 −5 Original line number Diff line number Diff line Loading @@ -1669,11 +1669,6 @@ public class KeyguardIndicationController { private final StatusBarStateController.StateListener mStatusBarStateListener = new StatusBarStateController.StateListener() { @Override public void onStateChanged(int newState) { setVisible(newState == StatusBarState.KEYGUARD); } @Override public void onDozingChanged(boolean dozing) { if (mDozing == dozing) { Loading