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.ExperimentalCoroutinesApi 32 import kotlinx.coroutines.test.TestScope 33 import kotlinx.coroutines.test.runCurrent 34 import kotlinx.coroutines.test.runTest 35 import org.junit.Before 36 import org.junit.Test 37 import org.junit.runner.RunWith 38 import org.mockito.ArgumentMatchers.anyInt 39 import org.mockito.Mock 40 import org.mockito.Mockito.mock 41 import org.mockito.Mockito.verify 42 import org.mockito.MockitoAnnotations 43 44 @ExperimentalCoroutinesApi 45 @SmallTest 46 @RunWith(AndroidJUnit4::class) 47 class ConfigurationRepositoryImplTest : SysuiTestCase() { 48 private var displaySizeRatio = 0f 49 @Mock private lateinit var configurationController: ConfigurationController 50 @Mock private lateinit var displayUtils: DisplayUtilsWrapper 51 52 private lateinit var testScope: TestScope 53 private lateinit var underTest: ConfigurationRepositoryImpl 54 55 @Before 56 fun setUp() { 57 MockitoAnnotations.initMocks(this) 58 setPhysicalPixelDisplaySizeRatio(displaySizeRatio) 59 60 testScope = TestScope() 61 underTest = 62 ConfigurationRepositoryImpl( 63 configurationController, 64 context, 65 testScope.backgroundScope, 66 displayUtils, 67 ) 68 } 69 70 @Test 71 fun onAnyConfigurationChange_updatesOnUiModeChanged() = 72 testScope.runTest { 73 val lastAnyConfigurationChange by collectLastValue(underTest.onAnyConfigurationChange) 74 assertThat(lastAnyConfigurationChange).isNull() 75 76 val configurationCallback = withArgCaptor { 77 verify(configurationController).addCallback(capture()) 78 } 79 80 configurationCallback.onUiModeChanged() 81 runCurrent() 82 assertThat(lastAnyConfigurationChange).isNotNull() 83 } 84 85 @Test 86 fun onAnyConfigurationChange_updatesOnThemeChanged() = 87 testScope.runTest { 88 val lastAnyConfigurationChange by collectLastValue(underTest.onAnyConfigurationChange) 89 assertThat(lastAnyConfigurationChange).isNull() 90 91 val configurationCallback = withArgCaptor { 92 verify(configurationController).addCallback(capture()) 93 } 94 95 configurationCallback.onThemeChanged() 96 runCurrent() 97 assertThat(lastAnyConfigurationChange).isNotNull() 98 } 99 100 @Test 101 fun onAnyConfigurationChange_updatesOnConfigChanged() = 102 testScope.runTest { 103 val lastAnyConfigurationChange by collectLastValue(underTest.onAnyConfigurationChange) 104 assertThat(lastAnyConfigurationChange).isNull() 105 106 val configurationCallback = withArgCaptor { 107 verify(configurationController).addCallback(capture()) 108 } 109 110 configurationCallback.onConfigChanged(mock(Configuration::class.java)) 111 runCurrent() 112 assertThat(lastAnyConfigurationChange).isNotNull() 113 } 114 115 @Test 116 fun onResolutionScale_updatesOnConfigurationChange() = 117 testScope.runTest { 118 val scaleForResolution by collectLastValue(underTest.scaleForResolution) 119 assertThat(scaleForResolution).isEqualTo(displaySizeRatio) 120 121 val configurationCallback = withArgCaptor { 122 verify(configurationController).addCallback(capture()) 123 } 124 125 setPhysicalPixelDisplaySizeRatio(2f) 126 configurationCallback.onConfigChanged(mock(Configuration::class.java)) 127 assertThat(scaleForResolution).isEqualTo(displaySizeRatio) 128 129 setPhysicalPixelDisplaySizeRatio(.21f) 130 configurationCallback.onConfigChanged(mock(Configuration::class.java)) 131 assertThat(scaleForResolution).isEqualTo(displaySizeRatio) 132 } 133 134 @Test 135 fun onResolutionScale_nullMaxResolution() = 136 testScope.runTest { 137 val scaleForResolution by collectLastValue(underTest.scaleForResolution) 138 runCurrent() 139 140 givenNullMaxResolutionDisplayMode() 141 val configurationCallback = withArgCaptor { 142 verify(configurationController).addCallback(capture()) 143 } 144 configurationCallback.onConfigChanged(mock(Configuration::class.java)) 145 assertThat(scaleForResolution).isEqualTo(1f) 146 } 147 148 @Test 149 fun getResolutionScale_nullMaxResolutionDisplayMode() { 150 givenNullMaxResolutionDisplayMode() 151 assertThat(underTest.getResolutionScale()).isEqualTo(1f) 152 } 153 154 @Test 155 fun getResolutionScale_infiniteDisplayRatios() { 156 setPhysicalPixelDisplaySizeRatio(Float.POSITIVE_INFINITY) 157 assertThat(underTest.getResolutionScale()).isEqualTo(1f) 158 } 159 160 @Test 161 fun getResolutionScale_differentDisplayRatios() { 162 setPhysicalPixelDisplaySizeRatio(.5f) 163 assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio) 164 165 setPhysicalPixelDisplaySizeRatio(.283f) 166 assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio) 167 168 setPhysicalPixelDisplaySizeRatio(3.58f) 169 assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio) 170 171 setPhysicalPixelDisplaySizeRatio(0f) 172 assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio) 173 174 setPhysicalPixelDisplaySizeRatio(1f) 175 assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio) 176 } 177 178 private fun givenNullMaxResolutionDisplayMode() { 179 whenever(displayUtils.getMaximumResolutionDisplayMode(any())).thenReturn(null) 180 } 181 182 private fun setPhysicalPixelDisplaySizeRatio(ratio: Float) { 183 displaySizeRatio = ratio 184 whenever(displayUtils.getMaximumResolutionDisplayMode(any())) 185 .thenReturn(Display.Mode(0, 0, 0, 90f)) 186 whenever( 187 displayUtils.getPhysicalPixelDisplaySizeRatio( 188 anyInt(), 189 anyInt(), 190 anyInt(), 191 anyInt() 192 ) 193 ) 194 .thenReturn(ratio) 195 } 196 } 197