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.qs.panels.data.repository 18 19 import android.content.Context 20 import android.content.SharedPreferences 21 import android.content.pm.UserInfo 22 import androidx.test.ext.junit.runners.AndroidJUnit4 23 import androidx.test.filters.SmallTest 24 import com.android.systemui.SysuiTestCase 25 import com.android.systemui.coroutines.collectLastValue 26 import com.android.systemui.kosmos.testScope 27 import com.android.systemui.qs.pipeline.shared.TileSpec 28 import com.android.systemui.qs.pipeline.shared.TilesUpgradePath 29 import com.android.systemui.settings.userFileManager 30 import com.android.systemui.testKosmos 31 import com.android.systemui.user.data.repository.fakeUserRepository 32 import com.android.systemui.user.data.repository.userRepository 33 import com.google.common.truth.Truth.assertThat 34 import kotlinx.coroutines.flow.first 35 import kotlinx.coroutines.test.runTest 36 import org.junit.Test 37 import org.junit.runner.RunWith 38 39 @SmallTest 40 @RunWith(AndroidJUnit4::class) 41 class QSPreferencesRepositoryTest : SysuiTestCase() { 42 private val kosmos = testKosmos() <lambda>null43 private val underTest = with(kosmos) { qsPreferencesRepository } 44 45 @Test largeTilesSpecs_updatesFromSharedPreferencesnull46 fun largeTilesSpecs_updatesFromSharedPreferences() = 47 with(kosmos) { 48 testScope.runTest { 49 val latest by collectLastValue(underTest.largeTilesSpecs) 50 assertThat(latest).isEqualTo(defaultLargeTilesRepository.defaultLargeTiles) 51 52 val newSet = setOf("tileA", "tileB") 53 setLargeTilesSpecsInSharedPreferences(newSet) 54 assertThat(latest).isEqualTo(newSet.toTileSpecs()) 55 } 56 } 57 58 @Test largeTilesSpecs_updatesFromUserChangenull59 fun largeTilesSpecs_updatesFromUserChange() = 60 with(kosmos) { 61 testScope.runTest { 62 fakeUserRepository.setUserInfos(USERS) 63 val latest by collectLastValue(underTest.largeTilesSpecs) 64 65 fakeUserRepository.setSelectedUserInfo(PRIMARY_USER) 66 val newSet = setOf("tileA", "tileB") 67 setLargeTilesSpecsInSharedPreferences(newSet) 68 69 fakeUserRepository.setSelectedUserInfo(ANOTHER_USER) 70 setLargeTilesSpecsInSharedPreferences(emptySet()) 71 72 fakeUserRepository.setSelectedUserInfo(PRIMARY_USER) 73 assertThat(latest).isEqualTo(newSet.toTileSpecs()) 74 } 75 } 76 77 @Test setLargeTilesSpecs_inSharedPreferencesnull78 fun setLargeTilesSpecs_inSharedPreferences() { 79 val setA = setOf("tileA", "tileB") 80 underTest.writeLargeTileSpecs(setA.toTileSpecs()) 81 assertThat(getLargeTilesSpecsFromSharedPreferences()).isEqualTo(setA) 82 83 val setB = setOf("tileA", "tileB") 84 underTest.writeLargeTileSpecs(setB.toTileSpecs()) 85 assertThat(getLargeTilesSpecsFromSharedPreferences()).isEqualTo(setB) 86 } 87 88 @Test setLargeTilesSpecs_forDifferentUsernull89 fun setLargeTilesSpecs_forDifferentUser() = 90 with(kosmos) { 91 testScope.runTest { 92 fakeUserRepository.setUserInfos(USERS) 93 94 fakeUserRepository.setSelectedUserInfo(PRIMARY_USER) 95 val setA = setOf("tileA", "tileB") 96 underTest.writeLargeTileSpecs(setA.toTileSpecs()) 97 assertThat(getLargeTilesSpecsFromSharedPreferences()).isEqualTo(setA) 98 99 fakeUserRepository.setSelectedUserInfo(ANOTHER_USER) 100 val setB = setOf("tileA", "tileB") 101 underTest.writeLargeTileSpecs(setB.toTileSpecs()) 102 assertThat(getLargeTilesSpecsFromSharedPreferences()).isEqualTo(setB) 103 104 fakeUserRepository.setSelectedUserInfo(PRIMARY_USER) 105 assertThat(getLargeTilesSpecsFromSharedPreferences()).isEqualTo(setA) 106 } 107 } 108 109 @Test setUpgradePathFromSettings_noLargeTiles_tilesSetnull110 fun setUpgradePathFromSettings_noLargeTiles_tilesSet() = 111 with(kosmos) { 112 testScope.runTest { 113 val largeTiles by collectLastValue(underTest.largeTilesSpecs) 114 115 fakeUserRepository.setUserInfos(USERS) 116 fakeUserRepository.setSelectedUserInfo(PRIMARY_USER) 117 val tiles = setOf("tileA", "tileB").toTileSpecs() 118 119 assertThat(getSharedPreferences().contains(LARGE_TILES_SPECS_KEY)).isFalse() 120 121 underTest.setInitialOrUpgradeLargeTiles( 122 TilesUpgradePath.ReadFromSettings(tiles), 123 PRIMARY_USER_ID, 124 ) 125 126 assertThat(largeTiles).isEqualTo(tiles) 127 } 128 } 129 130 @Test setUpgradePathFromSettings_alreadyLargeTiles_tilesNotSetnull131 fun setUpgradePathFromSettings_alreadyLargeTiles_tilesNotSet() = 132 with(kosmos) { 133 testScope.runTest { 134 val largeTiles by collectLastValue(underTest.largeTilesSpecs) 135 136 fakeUserRepository.setUserInfos(USERS) 137 fakeUserRepository.setSelectedUserInfo(ANOTHER_USER) 138 setLargeTilesSpecsInSharedPreferences(setOf("tileC")) 139 140 underTest.setInitialOrUpgradeLargeTiles( 141 TilesUpgradePath.ReadFromSettings(setOf("tileA").toTileSpecs()), 142 ANOTHER_USER_ID, 143 ) 144 145 assertThat(largeTiles).isEqualTo(setOf("tileC").toTileSpecs()) 146 } 147 } 148 149 @Test setUpgradePathFromSettings_emptyLargeTiles_tilesNotSetnull150 fun setUpgradePathFromSettings_emptyLargeTiles_tilesNotSet() = 151 with(kosmos) { 152 testScope.runTest { 153 val largeTiles by collectLastValue(underTest.largeTilesSpecs) 154 155 fakeUserRepository.setUserInfos(USERS) 156 fakeUserRepository.setSelectedUserInfo(ANOTHER_USER) 157 setLargeTilesSpecsInSharedPreferences(emptySet()) 158 159 underTest.setInitialOrUpgradeLargeTiles( 160 TilesUpgradePath.ReadFromSettings(setOf("tileA").toTileSpecs()), 161 ANOTHER_USER_ID, 162 ) 163 164 assertThat(largeTiles).isEmpty() 165 } 166 } 167 168 @Test setUpgradePathFromSettings_nonCurrentUser_tilesSetForCorrectUsernull169 fun setUpgradePathFromSettings_nonCurrentUser_tilesSetForCorrectUser() = 170 with(kosmos) { 171 testScope.runTest { 172 val largeTiles by collectLastValue(underTest.largeTilesSpecs) 173 174 fakeUserRepository.setUserInfos(USERS) 175 fakeUserRepository.setSelectedUserInfo(PRIMARY_USER) 176 177 underTest.setInitialOrUpgradeLargeTiles( 178 TilesUpgradePath.ReadFromSettings(setOf("tileA").toTileSpecs()), 179 ANOTHER_USER_ID, 180 ) 181 182 assertThat(largeTiles).isEqualTo(defaultLargeTilesRepository.defaultLargeTiles) 183 184 fakeUserRepository.setSelectedUserInfo(ANOTHER_USER) 185 assertThat(largeTiles).isEqualTo(setOf("tileA").toTileSpecs()) 186 } 187 } 188 189 @Test setUpgradePath_afterDefaultRead_noSetOnRepository_initialTilesCorrectnull190 fun setUpgradePath_afterDefaultRead_noSetOnRepository_initialTilesCorrect() = 191 with(kosmos) { 192 testScope.runTest { 193 val largeTiles by collectLastValue(underTest.largeTilesSpecs) 194 fakeUserRepository.setUserInfos(USERS) 195 fakeUserRepository.setSelectedUserInfo(PRIMARY_USER) 196 197 val currentLargeTiles = underTest.largeTilesSpecs.first() 198 199 assertThat(currentLargeTiles).isNotEmpty() 200 201 val tiles = setOf("tileA", "tileB") 202 underTest.setInitialOrUpgradeLargeTiles( 203 TilesUpgradePath.ReadFromSettings(tiles.toTileSpecs()), 204 PRIMARY_USER_ID, 205 ) 206 207 assertThat(largeTiles).isEqualTo(tiles.toTileSpecs()) 208 } 209 } 210 211 @Test setUpgradePath_afterDefaultRead_largeTilesSetOnRepository_initialTilesCorrectnull212 fun setUpgradePath_afterDefaultRead_largeTilesSetOnRepository_initialTilesCorrect() = 213 with(kosmos) { 214 testScope.runTest { 215 val largeTiles by collectLastValue(underTest.largeTilesSpecs) 216 fakeUserRepository.setUserInfos(USERS) 217 fakeUserRepository.setSelectedUserInfo(PRIMARY_USER) 218 219 val currentLargeTiles = underTest.largeTilesSpecs.first() 220 221 assertThat(currentLargeTiles).isNotEmpty() 222 223 underTest.writeLargeTileSpecs(setOf(TileSpec.create("tileC"))) 224 225 val tiles = setOf("tileA", "tileB") 226 underTest.setInitialOrUpgradeLargeTiles( 227 TilesUpgradePath.ReadFromSettings(tiles.toTileSpecs()), 228 PRIMARY_USER_ID, 229 ) 230 231 assertThat(largeTiles).isEqualTo(setOf(TileSpec.create("tileC"))) 232 } 233 } 234 235 @Test setTilesRestored_noLargeTiles_tilesSetnull236 fun setTilesRestored_noLargeTiles_tilesSet() = 237 with(kosmos) { 238 testScope.runTest { 239 val largeTiles by collectLastValue(underTest.largeTilesSpecs) 240 241 fakeUserRepository.setUserInfos(USERS) 242 fakeUserRepository.setSelectedUserInfo(PRIMARY_USER) 243 val tiles = setOf("tileA", "tileB").toTileSpecs() 244 245 assertThat(getSharedPreferences().contains(LARGE_TILES_SPECS_KEY)).isFalse() 246 247 underTest.setInitialOrUpgradeLargeTiles( 248 TilesUpgradePath.RestoreFromBackup(tiles), 249 PRIMARY_USER_ID, 250 ) 251 252 assertThat(largeTiles).isEqualTo(tiles) 253 } 254 } 255 256 @Test setDefaultTilesInitial_defaultSetLargenull257 fun setDefaultTilesInitial_defaultSetLarge() = 258 with(kosmos) { 259 testScope.runTest { 260 val largeTiles by collectLastValue(underTest.largeTilesSpecs) 261 262 fakeUserRepository.setUserInfos(USERS) 263 fakeUserRepository.setSelectedUserInfo(PRIMARY_USER) 264 265 underTest.setInitialOrUpgradeLargeTiles( 266 TilesUpgradePath.DefaultSet, 267 PRIMARY_USER_ID, 268 ) 269 270 assertThat(largeTiles).isEqualTo(defaultLargeTilesRepository.defaultLargeTiles) 271 } 272 } 273 274 @Test setTilesRestored_afterDefaultSet_tilesSetnull275 fun setTilesRestored_afterDefaultSet_tilesSet() = 276 with(kosmos) { 277 testScope.runTest { 278 underTest.setInitialOrUpgradeLargeTiles( 279 TilesUpgradePath.DefaultSet, 280 PRIMARY_USER_ID, 281 ) 282 val largeTiles by collectLastValue(underTest.largeTilesSpecs) 283 284 fakeUserRepository.setUserInfos(USERS) 285 fakeUserRepository.setSelectedUserInfo(PRIMARY_USER) 286 val tiles = setOf("tileA", "tileB").toTileSpecs() 287 288 underTest.setInitialOrUpgradeLargeTiles( 289 TilesUpgradePath.RestoreFromBackup(tiles), 290 PRIMARY_USER_ID, 291 ) 292 293 assertThat(largeTiles).isEqualTo(tiles) 294 } 295 } 296 getSharedPreferencesnull297 private fun getSharedPreferences(): SharedPreferences = 298 with(kosmos) { 299 return userFileManager.getSharedPreferences( 300 QSPreferencesRepository.FILE_NAME, 301 Context.MODE_PRIVATE, 302 userRepository.getSelectedUserInfo().id, 303 ) 304 } 305 setLargeTilesSpecsInSharedPreferencesnull306 private fun setLargeTilesSpecsInSharedPreferences(specs: Set<String>) { 307 getSharedPreferences().edit().putStringSet(LARGE_TILES_SPECS_KEY, specs).apply() 308 } 309 getLargeTilesSpecsFromSharedPreferencesnull310 private fun getLargeTilesSpecsFromSharedPreferences(): Set<String> { 311 return getSharedPreferences().getStringSet(LARGE_TILES_SPECS_KEY, emptySet())!! 312 } 313 Setnull314 private fun Set<String>.toTileSpecs(): Set<TileSpec> { 315 return map { TileSpec.create(it) }.toSet() 316 } 317 318 companion object { 319 private const val LARGE_TILES_SPECS_KEY = "large_tiles_specs" 320 private const val PRIMARY_USER_ID = 0 321 private val PRIMARY_USER = UserInfo(PRIMARY_USER_ID, "user 0", UserInfo.FLAG_MAIN) 322 private const val ANOTHER_USER_ID = 1 323 private val ANOTHER_USER = UserInfo(ANOTHER_USER_ID, "user 1", UserInfo.FLAG_FULL) 324 private val USERS = listOf(PRIMARY_USER, ANOTHER_USER) 325 } 326 } 327