1 /* 2 * Copyright (C) 2023 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.common.ui.data.repository 18 19 import android.content.res.Configuration 20 import android.view.Display 21 import androidx.test.ext.junit.runners.AndroidJUnit4 22 import androidx.test.filters.SmallTest 23 import com.android.systemui.SysuiTestCase 24 import com.android.systemui.coroutines.collectLastValue 25 import com.android.systemui.statusbar.policy.ConfigurationController 26 import com.android.systemui.util.mockito.any 27 import com.android.systemui.util.mockito.whenever 28 import com.android.systemui.util.mockito.withArgCaptor 29 import com.android.systemui.util.wrapper.DisplayUtilsWrapper 30 import com.google.common.truth.Truth.assertThat 31 import kotlinx.coroutines.test.TestScope 32 import kotlinx.coroutines.test.runCurrent 33 import kotlinx.coroutines.test.runTest 34 import org.junit.Before 35 import org.junit.Test 36 import org.junit.runner.RunWith 37 import org.mockito.ArgumentMatchers.anyInt 38 import org.mockito.Mock 39 import org.mockito.Mockito.mock 40 import org.mockito.Mockito.verify 41 import org.mockito.MockitoAnnotations 42 import org.mockito.kotlin.clearInvocations 43 44 @SmallTest 45 @RunWith(AndroidJUnit4::class) 46 class ConfigurationRepositoryImplTest : SysuiTestCase() { 47 private var displaySizeRatio = 0f 48 @Mock private lateinit var configurationController: ConfigurationController 49 @Mock private lateinit var displayUtils: DisplayUtilsWrapper 50 51 private lateinit var testScope: TestScope 52 private lateinit var underTest: ConfigurationRepositoryImpl 53 54 @Before setUpnull55 fun setUp() { 56 MockitoAnnotations.initMocks(this) 57 setPhysicalPixelDisplaySizeRatio(displaySizeRatio) 58 59 testScope = TestScope() 60 underTest = 61 ConfigurationRepositoryImpl( 62 configurationController, 63 context, 64 testScope.backgroundScope, 65 displayUtils, 66 ) 67 testScope.runCurrent() 68 } 69 70 @Test onAnyConfigurationChange_updatesOnUiModeChangednull71 fun onAnyConfigurationChange_updatesOnUiModeChanged() = 72 testScope.runTest { 73 clearInvocations(configurationController) 74 val lastAnyConfigurationChange by collectLastValue(underTest.onAnyConfigurationChange) 75 assertThat(lastAnyConfigurationChange).isNull() 76 77 val configurationCallback = withArgCaptor { 78 verify(configurationController).addCallback(capture()) 79 } 80 81 configurationCallback.onUiModeChanged() 82 runCurrent() 83 assertThat(lastAnyConfigurationChange).isNotNull() 84 } 85 86 @Test onAnyConfigurationChange_updatesOnThemeChangednull87 fun onAnyConfigurationChange_updatesOnThemeChanged() = 88 testScope.runTest { 89 clearInvocations(configurationController) 90 val lastAnyConfigurationChange by collectLastValue(underTest.onAnyConfigurationChange) 91 assertThat(lastAnyConfigurationChange).isNull() 92 93 val configurationCallback = withArgCaptor { 94 verify(configurationController).addCallback(capture()) 95 } 96 97 configurationCallback.onThemeChanged() 98 runCurrent() 99 assertThat(lastAnyConfigurationChange).isNotNull() 100 } 101 102 @Test onMovedToDisplays_updatesOnMovedToDisplaynull103 fun onMovedToDisplays_updatesOnMovedToDisplay() = 104 testScope.runTest { 105 val lastOnMovedToDisplay by collectLastValue(underTest.onMovedToDisplay) 106 assertThat(lastOnMovedToDisplay).isEqualTo(Display.DEFAULT_DISPLAY) 107 108 val configurationCallback = withArgCaptor { 109 verify(configurationController).addCallback(capture()) 110 } 111 112 configurationCallback.onMovedToDisplay(1, Configuration()) 113 runCurrent() 114 assertThat(lastOnMovedToDisplay).isEqualTo(1) 115 } 116 117 @Test onAnyConfigurationChange_updatesOnConfigChangednull118 fun onAnyConfigurationChange_updatesOnConfigChanged() = 119 testScope.runTest { 120 clearInvocations(configurationController) 121 val lastAnyConfigurationChange by collectLastValue(underTest.onAnyConfigurationChange) 122 assertThat(lastAnyConfigurationChange).isNull() 123 124 val configurationCallback = withArgCaptor { 125 verify(configurationController).addCallback(capture()) 126 } 127 128 configurationCallback.onConfigChanged(mock(Configuration::class.java)) 129 runCurrent() 130 assertThat(lastAnyConfigurationChange).isNotNull() 131 } 132 133 @Test onResolutionScale_updatesOnConfigurationChangenull134 fun onResolutionScale_updatesOnConfigurationChange() = 135 testScope.runTest { 136 clearInvocations(configurationController) 137 val scaleForResolution by collectLastValue(underTest.scaleForResolution) 138 assertThat(scaleForResolution).isEqualTo(displaySizeRatio) 139 140 val configurationCallback = withArgCaptor { 141 verify(configurationController).addCallback(capture()) 142 } 143 144 setPhysicalPixelDisplaySizeRatio(2f) 145 configurationCallback.onConfigChanged(mock(Configuration::class.java)) 146 assertThat(scaleForResolution).isEqualTo(displaySizeRatio) 147 148 setPhysicalPixelDisplaySizeRatio(.21f) 149 configurationCallback.onConfigChanged(mock(Configuration::class.java)) 150 assertThat(scaleForResolution).isEqualTo(displaySizeRatio) 151 } 152 153 @Test onResolutionScale_nullMaxResolutionnull154 fun onResolutionScale_nullMaxResolution() = 155 testScope.runTest { 156 clearInvocations(configurationController) 157 val scaleForResolution by collectLastValue(underTest.scaleForResolution) 158 runCurrent() 159 160 givenNullMaxResolutionDisplayMode() 161 val configurationCallback = withArgCaptor { 162 verify(configurationController).addCallback(capture()) 163 } 164 configurationCallback.onConfigChanged(mock(Configuration::class.java)) 165 assertThat(scaleForResolution).isEqualTo(1f) 166 } 167 168 @Test getResolutionScale_nullMaxResolutionDisplayModenull169 fun getResolutionScale_nullMaxResolutionDisplayMode() { 170 givenNullMaxResolutionDisplayMode() 171 assertThat(underTest.getResolutionScale()).isEqualTo(1f) 172 } 173 174 @Test getResolutionScale_infiniteDisplayRatiosnull175 fun getResolutionScale_infiniteDisplayRatios() { 176 setPhysicalPixelDisplaySizeRatio(Float.POSITIVE_INFINITY) 177 assertThat(underTest.getResolutionScale()).isEqualTo(1f) 178 } 179 180 @Test getResolutionScale_differentDisplayRatiosnull181 fun getResolutionScale_differentDisplayRatios() { 182 setPhysicalPixelDisplaySizeRatio(.5f) 183 assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio) 184 185 setPhysicalPixelDisplaySizeRatio(.283f) 186 assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio) 187 188 setPhysicalPixelDisplaySizeRatio(3.58f) 189 assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio) 190 191 setPhysicalPixelDisplaySizeRatio(0f) 192 assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio) 193 194 setPhysicalPixelDisplaySizeRatio(1f) 195 assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio) 196 } 197 givenNullMaxResolutionDisplayModenull198 private fun givenNullMaxResolutionDisplayMode() { 199 whenever(displayUtils.getMaximumResolutionDisplayMode(any())).thenReturn(null) 200 } 201 setPhysicalPixelDisplaySizeRationull202 private fun setPhysicalPixelDisplaySizeRatio(ratio: Float) { 203 displaySizeRatio = ratio 204 whenever(displayUtils.getMaximumResolutionDisplayMode(any())) 205 .thenReturn(Display.Mode(0, 0, 0, 90f)) 206 whenever( 207 displayUtils.getPhysicalPixelDisplaySizeRatio( 208 anyInt(), 209 anyInt(), 210 anyInt(), 211 anyInt(), 212 ) 213 ) 214 .thenReturn(ratio) 215 } 216 } 217