1 /* <lambda>null2 * 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 package com.android.launcher3 17 18 import android.content.Context 19 import android.content.SharedPreferences 20 import android.content.SharedPreferences.OnSharedPreferenceChangeListener 21 import androidx.test.ext.junit.runners.AndroidJUnit4 22 import androidx.test.filters.SmallTest 23 import androidx.test.platform.app.InstrumentationRegistry 24 import com.android.launcher3.LauncherPrefs.Companion.BOOT_AWARE_PREFS_KEY 25 import com.google.common.truth.Truth.assertThat 26 import java.util.concurrent.CountDownLatch 27 import java.util.concurrent.TimeUnit 28 import org.junit.Test 29 import org.junit.runner.RunWith 30 31 private val TEST_BOOLEAN_ITEM = LauncherPrefs.nonRestorableItem("1", false) 32 private val TEST_STRING_ITEM = LauncherPrefs.nonRestorableItem("2", "( ͡❛ ͜ʖ ͡❛)") 33 private val TEST_INT_ITEM = LauncherPrefs.nonRestorableItem("3", -1) 34 private val TEST_CONTEXTUAL_ITEM = 35 ContextualItem("4", true, { true }, EncryptionType.ENCRYPTED, Boolean::class.java) 36 37 private const val TEST_DEFAULT_VALUE = "default" 38 private const val TEST_PREF_KEY = "test_pref_key" 39 40 private const val WAIT_TIME_IN_SECONDS = 3L 41 42 @SmallTest 43 @RunWith(AndroidJUnit4::class) 44 class LauncherPrefsTest { 45 <lambda>null46 private val context by lazy { InstrumentationRegistry.getInstrumentation().targetContext } <lambda>null47 private val launcherPrefs by lazy { LauncherPrefs.get(context) } 48 49 @Test has_keyMissingFromLauncherPrefs_returnsFalsenull50 fun has_keyMissingFromLauncherPrefs_returnsFalse() { 51 assertThat(launcherPrefs.has(TEST_BOOLEAN_ITEM)).isFalse() 52 } 53 54 @Test has_keyPresentInLauncherPrefs_returnsTruenull55 fun has_keyPresentInLauncherPrefs_returnsTrue() { 56 with(launcherPrefs) { 57 putSync(TEST_BOOLEAN_ITEM.to(TEST_BOOLEAN_ITEM.defaultValue)) 58 assertThat(has(TEST_BOOLEAN_ITEM)).isTrue() 59 remove(TEST_BOOLEAN_ITEM) 60 } 61 } 62 63 @Test addListener_listeningForStringItemUpdates_isCorrectlyNotifiedOfUpdatesnull64 fun addListener_listeningForStringItemUpdates_isCorrectlyNotifiedOfUpdates() { 65 val latch = CountDownLatch(1) 66 val listener = OnSharedPreferenceChangeListener { _, _ -> latch.countDown() } 67 68 with(launcherPrefs) { 69 putSync(TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue)) 70 addListener(listener, TEST_STRING_ITEM) 71 putSync(TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue + "abc")) 72 73 assertThat(latch.await(WAIT_TIME_IN_SECONDS, TimeUnit.SECONDS)).isTrue() 74 remove(TEST_STRING_ITEM) 75 } 76 } 77 78 @Test removeListener_previouslyListeningForStringItemUpdates_isNoLongerNotifiedOfUpdatesnull79 fun removeListener_previouslyListeningForStringItemUpdates_isNoLongerNotifiedOfUpdates() { 80 val latch = CountDownLatch(1) 81 val listener = OnSharedPreferenceChangeListener { _, _ -> latch.countDown() } 82 83 with(launcherPrefs) { 84 addListener(listener, TEST_STRING_ITEM) 85 removeListener(listener, TEST_STRING_ITEM) 86 putSync(TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue + "hello.")) 87 88 // latch will be still be 1 (and await will return false) if the listener was not called 89 assertThat(latch.await(WAIT_TIME_IN_SECONDS, TimeUnit.SECONDS)).isFalse() 90 remove(TEST_STRING_ITEM) 91 } 92 } 93 94 @Test addListenerAndRemoveListener_forMultipleItems_bothWorkProperlynull95 fun addListenerAndRemoveListener_forMultipleItems_bothWorkProperly() { 96 var latch = CountDownLatch(3) 97 val listener = OnSharedPreferenceChangeListener { _, _ -> latch.countDown() } 98 99 with(launcherPrefs) { 100 addListener(listener, TEST_INT_ITEM, TEST_STRING_ITEM, TEST_BOOLEAN_ITEM) 101 putSync( 102 TEST_INT_ITEM.to(TEST_INT_ITEM.defaultValue + 123), 103 TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue + "abc"), 104 TEST_BOOLEAN_ITEM.to(!TEST_BOOLEAN_ITEM.defaultValue) 105 ) 106 assertThat(latch.await(WAIT_TIME_IN_SECONDS, TimeUnit.SECONDS)).isTrue() 107 108 removeListener(listener, TEST_INT_ITEM, TEST_STRING_ITEM, TEST_BOOLEAN_ITEM) 109 latch = CountDownLatch(1) 110 putSync( 111 TEST_INT_ITEM.to(TEST_INT_ITEM.defaultValue), 112 TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue), 113 TEST_BOOLEAN_ITEM.to(TEST_BOOLEAN_ITEM.defaultValue) 114 ) 115 remove(TEST_INT_ITEM, TEST_STRING_ITEM, TEST_BOOLEAN_ITEM) 116 117 assertThat(latch.await(WAIT_TIME_IN_SECONDS, TimeUnit.SECONDS)).isFalse() 118 } 119 } 120 121 @Test get_booleanItemNotInLauncherprefs_returnsDefaultValuenull122 fun get_booleanItemNotInLauncherprefs_returnsDefaultValue() { 123 assertThat(launcherPrefs.get(TEST_BOOLEAN_ITEM)).isEqualTo(TEST_BOOLEAN_ITEM.defaultValue) 124 } 125 126 @Test get_stringItemNotInLauncherPrefs_returnsDefaultValuenull127 fun get_stringItemNotInLauncherPrefs_returnsDefaultValue() { 128 assertThat(launcherPrefs.get(TEST_STRING_ITEM)).isEqualTo(TEST_STRING_ITEM.defaultValue) 129 } 130 131 @Test get_intItemNotInLauncherprefs_returnsDefaultValuenull132 fun get_intItemNotInLauncherprefs_returnsDefaultValue() { 133 assertThat(launcherPrefs.get(TEST_INT_ITEM)).isEqualTo(TEST_INT_ITEM.defaultValue) 134 } 135 136 @Test put_storesItemInLauncherPrefs_successfullynull137 fun put_storesItemInLauncherPrefs_successfully() { 138 val notDefaultValue = !TEST_BOOLEAN_ITEM.defaultValue 139 140 with(launcherPrefs) { 141 putSync(TEST_BOOLEAN_ITEM.to(notDefaultValue)) 142 assertThat(get(TEST_BOOLEAN_ITEM)).isEqualTo(notDefaultValue) 143 remove(TEST_BOOLEAN_ITEM) 144 } 145 } 146 147 @Test put_storesListOfItemsInLauncherPrefs_successfullynull148 fun put_storesListOfItemsInLauncherPrefs_successfully() { 149 with(launcherPrefs) { 150 putSync( 151 TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue), 152 TEST_INT_ITEM.to(TEST_INT_ITEM.defaultValue), 153 TEST_BOOLEAN_ITEM.to(TEST_BOOLEAN_ITEM.defaultValue) 154 ) 155 assertThat(has(TEST_BOOLEAN_ITEM, TEST_INT_ITEM, TEST_STRING_ITEM)).isTrue() 156 remove(TEST_STRING_ITEM, TEST_INT_ITEM, TEST_BOOLEAN_ITEM) 157 } 158 } 159 160 @Test remove_deletesItemFromLauncherPrefs_successfullynull161 fun remove_deletesItemFromLauncherPrefs_successfully() { 162 val notDefaultValue = !TEST_BOOLEAN_ITEM.defaultValue 163 164 with(launcherPrefs) { 165 putSync(TEST_BOOLEAN_ITEM.to(notDefaultValue)) 166 remove(TEST_BOOLEAN_ITEM) 167 assertThat(get(TEST_BOOLEAN_ITEM)).isEqualTo(TEST_BOOLEAN_ITEM.defaultValue) 168 } 169 } 170 171 @Test get_contextualItem_returnsCorrectDefaultnull172 fun get_contextualItem_returnsCorrectDefault() { 173 assertThat(launcherPrefs.get(TEST_CONTEXTUAL_ITEM)).isTrue() 174 } 175 176 @Test getItemSharedPrefFile_forNonRestorableItem_isCorrectnull177 fun getItemSharedPrefFile_forNonRestorableItem_isCorrect() { 178 val nonRestorableItem = LauncherPrefs.nonRestorableItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE) 179 assertThat(nonRestorableItem.sharedPrefFile).isEqualTo(LauncherFiles.DEVICE_PREFERENCES_KEY) 180 } 181 182 @Test getItemSharedPrefFile_forBackedUpItem_isCorrectnull183 fun getItemSharedPrefFile_forBackedUpItem_isCorrect() { 184 val backedUpItem = LauncherPrefs.backedUpItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE) 185 assertThat(backedUpItem.sharedPrefFile).isEqualTo(LauncherFiles.SHARED_PREFERENCES_KEY) 186 } 187 188 @Test put_bootAwareItem_updatesDeviceProtectedStoragenull189 fun put_bootAwareItem_updatesDeviceProtectedStorage() { 190 val bootAwareItem = 191 LauncherPrefs.backedUpItem( 192 TEST_PREF_KEY, 193 TEST_DEFAULT_VALUE, 194 EncryptionType.DEVICE_PROTECTED 195 ) 196 197 val bootAwarePrefs: SharedPreferences = 198 context 199 .createDeviceProtectedStorageContext() 200 .getSharedPreferences(BOOT_AWARE_PREFS_KEY, Context.MODE_PRIVATE) 201 bootAwarePrefs.edit().remove(bootAwareItem.sharedPrefKey).commit() 202 203 launcherPrefs.putSync(bootAwareItem.to(bootAwareItem.defaultValue)) 204 assertThat(bootAwarePrefs.contains(bootAwareItem.sharedPrefKey)).isTrue() 205 206 launcherPrefs.removeSync(bootAwareItem) 207 } 208 209 @Test remove_bootAwareItem_removesFromDeviceProtectedStoragenull210 fun remove_bootAwareItem_removesFromDeviceProtectedStorage() { 211 val bootAwareItem = 212 LauncherPrefs.backedUpItem( 213 TEST_PREF_KEY, 214 TEST_DEFAULT_VALUE, 215 EncryptionType.DEVICE_PROTECTED 216 ) 217 218 val bootAwarePrefs: SharedPreferences = 219 context 220 .createDeviceProtectedStorageContext() 221 .getSharedPreferences(BOOT_AWARE_PREFS_KEY, Context.MODE_PRIVATE) 222 223 bootAwarePrefs 224 .edit() 225 .putString(bootAwareItem.sharedPrefKey, bootAwareItem.defaultValue) 226 .commit() 227 228 launcherPrefs.removeSync(bootAwareItem) 229 assertThat(bootAwarePrefs.contains(bootAwareItem.sharedPrefKey)).isFalse() 230 } 231 } 232