1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.keyguard.ui.viewmodel 18 19 import androidx.test.filters.SmallTest 20 import com.android.compose.animation.scene.ObservableTransitionState 21 import com.android.systemui.SysuiTestCase 22 import com.android.systemui.common.ui.domain.interactor.configurationInteractor 23 import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository 24 import com.android.systemui.communal.domain.interactor.communalSceneInteractor 25 import com.android.systemui.communal.shared.model.CommunalScenes 26 import com.android.systemui.coroutines.collectLastValue 27 import com.android.systemui.doze.util.BurnInHelperWrapper 28 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository 29 import com.android.systemui.keyguard.domain.interactor.BurnInInteractor 30 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor 31 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor 32 import com.android.systemui.keyguard.shared.model.BurnInModel 33 import com.android.systemui.keyguard.shared.model.StatusBarState 34 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition 35 import com.android.systemui.kosmos.testDispatcher 36 import com.android.systemui.kosmos.testScope 37 import com.android.systemui.testKosmos 38 import com.google.common.truth.Truth.assertThat 39 import kotlinx.coroutines.flow.MutableStateFlow 40 import kotlinx.coroutines.flow.flowOf 41 import kotlinx.coroutines.test.runTest 42 import org.junit.Before 43 import org.junit.Test 44 import org.mockito.ArgumentMatchers.anyInt 45 import org.mockito.kotlin.any 46 import org.mockito.kotlin.doReturn 47 import org.mockito.kotlin.mock 48 49 @SmallTest 50 class KeyguardIndicationAreaViewModelTest() : SysuiTestCase() { 51 private val kosmos = testKosmos() 52 private val testScope = kosmos.testScope 53 private lateinit var underTest: KeyguardIndicationAreaViewModel 54 private val keyguardRepository = kosmos.fakeKeyguardRepository 55 private val communalSceneRepository = kosmos.fakeCommunalSceneRepository 56 57 private val startButtonFlow = 58 MutableStateFlow( 59 KeyguardQuickAffordanceViewModel( 60 slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId() 61 ) 62 ) 63 private val endButtonFlow = 64 MutableStateFlow( 65 KeyguardQuickAffordanceViewModel( 66 slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId() 67 ) 68 ) 69 70 @Before setUpnull71 fun setUp() { 72 val burnInInteractor = 73 mock<BurnInInteractor> { 74 on { burnIn(anyInt(), anyInt()) } doReturn flowOf(BurnInModel()) 75 } 76 val burnInHelperWrapper = 77 mock<BurnInHelperWrapper> { 78 on { burnInOffset(anyInt(), any()) } doReturn RETURNED_BURN_IN_OFFSET 79 } 80 val shortcutsCombinedViewModel = 81 mock<KeyguardQuickAffordancesCombinedViewModel> { 82 on { startButton } doReturn startButtonFlow 83 on { endButton } doReturn endButtonFlow 84 } 85 underTest = 86 KeyguardIndicationAreaViewModel( 87 keyguardInteractor = kosmos.keyguardInteractor, 88 burnInHelperWrapper = burnInHelperWrapper, 89 burnInInteractor = burnInInteractor, 90 shortcutsCombinedViewModel = shortcutsCombinedViewModel, 91 configurationInteractor = kosmos.configurationInteractor, 92 keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor, 93 backgroundDispatcher = kosmos.testDispatcher, 94 communalSceneInteractor = kosmos.communalSceneInteractor, 95 mainDispatcher = kosmos.testDispatcher, 96 ) 97 } 98 99 @Test visibilityWhenCommunalNotShowingnull100 fun visibilityWhenCommunalNotShowing() = 101 testScope.runTest { 102 keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD) 103 val visible by collectLastValue(underTest.visible) 104 105 assertThat(visible).isTrue() 106 keyguardRepository.setStatusBarState(StatusBarState.SHADE) 107 assertThat(visible).isFalse() 108 } 109 110 @Test visibilityWhenCommunalShowingnull111 fun visibilityWhenCommunalShowing() = 112 testScope.runTest { 113 keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD) 114 communalSceneRepository.setTransitionState( 115 flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal)) 116 ) 117 118 val visible by collectLastValue(underTest.visible) 119 120 assertThat(visible).isTrue() 121 keyguardRepository.setStatusBarState(StatusBarState.SHADE) 122 assertThat(visible).isTrue() 123 124 communalSceneRepository.setTransitionState( 125 flowOf(ObservableTransitionState.Idle(CommunalScenes.Blank)) 126 ) 127 assertThat(visible).isFalse() 128 } 129 setDozeAmountAndCalculateExpectedTranslationYnull130 private fun setDozeAmountAndCalculateExpectedTranslationY(dozeAmount: Float): Float { 131 keyguardRepository.setDozeAmount(dozeAmount) 132 return dozeAmount * (RETURNED_BURN_IN_OFFSET - DEFAULT_BURN_IN_OFFSET) 133 } 134 135 companion object { 136 private const val DEFAULT_BURN_IN_OFFSET = 5 137 private const val RETURNED_BURN_IN_OFFSET = 3 138 } 139 } 140