1 /* 2 * Copyright (C) 2022 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 18 package com.android.systemui.controls.settings 19 20 import android.content.pm.UserInfo 21 import android.provider.Settings 22 import androidx.test.filters.SmallTest 23 import com.android.systemui.SysuiTestCase 24 import com.android.systemui.user.data.repository.FakeUserRepository 25 import com.android.systemui.util.settings.FakeSettings 26 import com.google.common.truth.Truth.assertThat 27 import kotlinx.coroutines.ExperimentalCoroutinesApi 28 import kotlinx.coroutines.flow.toList 29 import kotlinx.coroutines.launch 30 import kotlinx.coroutines.test.TestScope 31 import kotlinx.coroutines.test.UnconfinedTestDispatcher 32 import kotlinx.coroutines.test.runTest 33 import org.junit.Before 34 import org.junit.Test 35 import org.junit.runner.RunWith 36 import org.junit.runners.JUnit4 37 38 @SmallTest 39 @RunWith(JUnit4::class) 40 @OptIn(ExperimentalCoroutinesApi::class) 41 class ControlsSettingsRepositoryImplTest : SysuiTestCase() { 42 43 companion object { 44 private const val LOCKSCREEN_SHOW = Settings.Secure.LOCKSCREEN_SHOW_CONTROLS 45 private const val LOCKSCREEN_ACTION = Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS 46 47 private fun createUser(id: Int): UserInfo { 48 return UserInfo(id, "user_$id", 0) 49 } 50 51 private val ALL_USERS = (0..1).map { it to createUser(it) }.toMap() 52 } 53 54 private lateinit var underTest: ControlsSettingsRepository 55 56 private lateinit var testScope: TestScope 57 private lateinit var secureSettings: FakeSettings 58 private lateinit var userRepository: FakeUserRepository 59 60 @Before 61 fun setUp() { 62 secureSettings = FakeSettings() 63 userRepository = FakeUserRepository() 64 userRepository.setUserInfos(ALL_USERS.values.toList()) 65 66 val coroutineDispatcher = UnconfinedTestDispatcher() 67 testScope = TestScope(coroutineDispatcher) 68 69 underTest = 70 ControlsSettingsRepositoryImpl( 71 scope = testScope.backgroundScope, 72 backgroundDispatcher = coroutineDispatcher, 73 userRepository = userRepository, 74 secureSettings = secureSettings, 75 ) 76 } 77 78 @Test 79 fun showInLockScreen() = 80 testScope.runTest { 81 setUser(0) 82 val values = mutableListOf<Boolean>() 83 val job = 84 launch(UnconfinedTestDispatcher()) { 85 underTest.canShowControlsInLockscreen.toList(values) 86 } 87 assertThat(values.last()).isFalse() 88 89 secureSettings.putBool(LOCKSCREEN_SHOW, true) 90 assertThat(values.last()).isTrue() 91 92 secureSettings.putBool(LOCKSCREEN_SHOW, false) 93 assertThat(values.last()).isFalse() 94 95 secureSettings.putBoolForUser(LOCKSCREEN_SHOW, true, 1) 96 assertThat(values.last()).isFalse() 97 98 setUser(1) 99 assertThat(values.last()).isTrue() 100 101 job.cancel() 102 } 103 104 @Test 105 fun showInLockScreen_changesInOtherUsersAreNotQueued() = 106 testScope.runTest { 107 setUser(0) 108 109 val values = mutableListOf<Boolean>() 110 val job = 111 launch(UnconfinedTestDispatcher()) { 112 underTest.canShowControlsInLockscreen.toList(values) 113 } 114 115 secureSettings.putBoolForUser(LOCKSCREEN_SHOW, true, 1) 116 secureSettings.putBoolForUser(LOCKSCREEN_SHOW, false, 1) 117 118 setUser(1) 119 assertThat(values.last()).isFalse() 120 assertThat(values).containsNoneIn(listOf(true)) 121 122 job.cancel() 123 } 124 125 @Test 126 fun actionInLockScreen() = 127 testScope.runTest { 128 setUser(0) 129 val values = mutableListOf<Boolean>() 130 val job = 131 launch(UnconfinedTestDispatcher()) { 132 underTest.allowActionOnTrivialControlsInLockscreen.toList(values) 133 } 134 assertThat(values.last()).isFalse() 135 136 secureSettings.putBool(LOCKSCREEN_ACTION, true) 137 assertThat(values.last()).isTrue() 138 139 secureSettings.putBool(LOCKSCREEN_ACTION, false) 140 assertThat(values.last()).isFalse() 141 142 secureSettings.putBoolForUser(LOCKSCREEN_ACTION, true, 1) 143 assertThat(values.last()).isFalse() 144 145 setUser(1) 146 assertThat(values.last()).isTrue() 147 148 job.cancel() 149 } 150 151 @Test 152 fun actionInLockScreen_changesInOtherUsersAreNotQueued() = 153 testScope.runTest { 154 setUser(0) 155 156 val values = mutableListOf<Boolean>() 157 val job = 158 launch(UnconfinedTestDispatcher()) { 159 underTest.allowActionOnTrivialControlsInLockscreen.toList(values) 160 } 161 162 secureSettings.putBoolForUser(LOCKSCREEN_ACTION, true, 1) 163 secureSettings.putBoolForUser(LOCKSCREEN_ACTION, false, 1) 164 165 setUser(1) 166 assertThat(values.last()).isFalse() 167 assertThat(values).containsNoneIn(listOf(true)) 168 169 job.cancel() 170 } 171 172 @Test 173 fun valueIsUpdatedWhenNotSubscribed() = 174 testScope.runTest { 175 setUser(0) 176 assertThat(underTest.canShowControlsInLockscreen.value).isFalse() 177 178 secureSettings.putBool(LOCKSCREEN_SHOW, true) 179 180 assertThat(underTest.canShowControlsInLockscreen.value).isTrue() 181 } 182 183 private suspend fun setUser(id: Int) { 184 secureSettings.userId = id 185 userRepository.setSelectedUserInfo(ALL_USERS[id]!!) 186 } 187 } 188