Files
lawnchair/tests/src/com/android/launcher3/LauncherPrefsTest.kt
Stefan Andonian 956b88e561 Stop enabling the Boot Aware Launcher prefs code during Tests after
running LauncherPref unit tests.

There is something in the LauncherPrefs code that interacts with the
boot aware shared preference data that is not compatible with the
Widgets.Reorder tests. A todo has been added to fix that before
releasing that feature. For now, implementing a simple fix to stop
enabling this feature for while doing post submit testing.

Bug: 271434610
Test: Used go/abdt to verify that this CL fixes the post submit tests.
They no longer fail like they did before this was pushed.

Change-Id: Id6bd94f5d0e0ee9afc2ccea3a4808cf723a4e688
2023-03-20 20:59:50 +00:00

332 lines
12 KiB
Kotlin

/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3
import android.content.Context
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.launcher3.LauncherPrefs.Companion.BOOT_AWARE_PREFS_KEY
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import org.junit.AfterClass
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
private val TEST_BOOLEAN_ITEM = LauncherPrefs.nonRestorableItem("1", false)
private val TEST_STRING_ITEM = LauncherPrefs.nonRestorableItem("2", "( ͡❛ ͜ʖ ͡❛)")
private val TEST_INT_ITEM = LauncherPrefs.nonRestorableItem("3", -1)
private val TEST_CONTEXTUAL_ITEM = ContextualItem("4", true, { true }, false, Boolean::class.java)
private const val TEST_DEFAULT_VALUE = "default"
private const val TEST_PREF_KEY = "test_pref_key"
private const val WAIT_TIME_IN_SECONDS = 3L
@SmallTest
@RunWith(AndroidJUnit4::class)
class LauncherPrefsTest {
private val context by lazy { InstrumentationRegistry.getInstrumentation().targetContext }
private val launcherPrefs by lazy { LauncherPrefs.get(context) }
companion object {
@BeforeClass
@JvmStatic
fun setup() {
isBootAwareStartupDataEnabled = true
}
@AfterClass
@JvmStatic
fun teardown() {
isBootAwareStartupDataEnabled = false
}
}
@Test
fun has_keyMissingFromLauncherPrefs_returnsFalse() {
assertThat(launcherPrefs.has(TEST_BOOLEAN_ITEM)).isFalse()
}
@Test
fun has_keyPresentInLauncherPrefs_returnsTrue() {
with(launcherPrefs) {
putSync(TEST_BOOLEAN_ITEM.to(TEST_BOOLEAN_ITEM.defaultValue))
assertThat(has(TEST_BOOLEAN_ITEM)).isTrue()
remove(TEST_BOOLEAN_ITEM)
}
}
@Test
fun addListener_listeningForStringItemUpdates_isCorrectlyNotifiedOfUpdates() {
val latch = CountDownLatch(1)
val listener = OnSharedPreferenceChangeListener { _, _ -> latch.countDown() }
with(launcherPrefs) {
putSync(TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue))
addListener(listener, TEST_STRING_ITEM)
putSync(TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue + "abc"))
assertThat(latch.await(WAIT_TIME_IN_SECONDS, TimeUnit.SECONDS)).isTrue()
remove(TEST_STRING_ITEM)
}
}
@Test
fun removeListener_previouslyListeningForStringItemUpdates_isNoLongerNotifiedOfUpdates() {
val latch = CountDownLatch(1)
val listener = OnSharedPreferenceChangeListener { _, _ -> latch.countDown() }
with(launcherPrefs) {
addListener(listener, TEST_STRING_ITEM)
removeListener(listener, TEST_STRING_ITEM)
putSync(TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue + "hello."))
// latch will be still be 1 (and await will return false) if the listener was not called
assertThat(latch.await(WAIT_TIME_IN_SECONDS, TimeUnit.SECONDS)).isFalse()
remove(TEST_STRING_ITEM)
}
}
@Test
fun addListenerAndRemoveListener_forMultipleItems_bothWorkProperly() {
var latch = CountDownLatch(3)
val listener = OnSharedPreferenceChangeListener { _, _ -> latch.countDown() }
with(launcherPrefs) {
addListener(listener, TEST_INT_ITEM, TEST_STRING_ITEM, TEST_BOOLEAN_ITEM)
putSync(
TEST_INT_ITEM.to(TEST_INT_ITEM.defaultValue + 123),
TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue + "abc"),
TEST_BOOLEAN_ITEM.to(!TEST_BOOLEAN_ITEM.defaultValue)
)
assertThat(latch.await(WAIT_TIME_IN_SECONDS, TimeUnit.SECONDS)).isTrue()
removeListener(listener, TEST_INT_ITEM, TEST_STRING_ITEM, TEST_BOOLEAN_ITEM)
latch = CountDownLatch(1)
putSync(
TEST_INT_ITEM.to(TEST_INT_ITEM.defaultValue),
TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue),
TEST_BOOLEAN_ITEM.to(TEST_BOOLEAN_ITEM.defaultValue)
)
remove(TEST_INT_ITEM, TEST_STRING_ITEM, TEST_BOOLEAN_ITEM)
assertThat(latch.await(WAIT_TIME_IN_SECONDS, TimeUnit.SECONDS)).isFalse()
}
}
@Test
fun get_booleanItemNotInLauncherprefs_returnsDefaultValue() {
assertThat(launcherPrefs.get(TEST_BOOLEAN_ITEM)).isEqualTo(TEST_BOOLEAN_ITEM.defaultValue)
}
@Test
fun get_stringItemNotInLauncherPrefs_returnsDefaultValue() {
assertThat(launcherPrefs.get(TEST_STRING_ITEM)).isEqualTo(TEST_STRING_ITEM.defaultValue)
}
@Test
fun get_intItemNotInLauncherprefs_returnsDefaultValue() {
assertThat(launcherPrefs.get(TEST_INT_ITEM)).isEqualTo(TEST_INT_ITEM.defaultValue)
}
@Test
fun put_storesItemInLauncherPrefs_successfully() {
val notDefaultValue = !TEST_BOOLEAN_ITEM.defaultValue
with(launcherPrefs) {
putSync(TEST_BOOLEAN_ITEM.to(notDefaultValue))
assertThat(get(TEST_BOOLEAN_ITEM)).isEqualTo(notDefaultValue)
remove(TEST_BOOLEAN_ITEM)
}
}
@Test
fun put_storesListOfItemsInLauncherPrefs_successfully() {
with(launcherPrefs) {
putSync(
TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue),
TEST_INT_ITEM.to(TEST_INT_ITEM.defaultValue),
TEST_BOOLEAN_ITEM.to(TEST_BOOLEAN_ITEM.defaultValue)
)
assertThat(has(TEST_BOOLEAN_ITEM, TEST_INT_ITEM, TEST_STRING_ITEM)).isTrue()
remove(TEST_STRING_ITEM, TEST_INT_ITEM, TEST_BOOLEAN_ITEM)
}
}
@Test
fun remove_deletesItemFromLauncherPrefs_successfully() {
val notDefaultValue = !TEST_BOOLEAN_ITEM.defaultValue
with(launcherPrefs) {
putSync(TEST_BOOLEAN_ITEM.to(notDefaultValue))
remove(TEST_BOOLEAN_ITEM)
assertThat(get(TEST_BOOLEAN_ITEM)).isEqualTo(TEST_BOOLEAN_ITEM.defaultValue)
}
}
@Test
fun get_contextualItem_returnsCorrectDefault() {
assertThat(launcherPrefs.get(TEST_CONTEXTUAL_ITEM)).isTrue()
}
@Test
fun getItemSharedPrefFile_forNonRestorableItem_isCorrect() {
val nonRestorableItem = LauncherPrefs.nonRestorableItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE)
assertThat(nonRestorableItem.sharedPrefFile).isEqualTo(LauncherFiles.DEVICE_PREFERENCES_KEY)
}
@Test
fun getItemSharedPrefFile_forBackedUpItem_isCorrect() {
val backedUpItem = LauncherPrefs.backedUpItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE)
assertThat(backedUpItem.sharedPrefFile).isEqualTo(LauncherFiles.SHARED_PREFERENCES_KEY)
}
@Test
fun put_bootAwareItem_updatesDeviceProtectedStorage() {
val bootAwareItem =
LauncherPrefs.backedUpItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE, isBootAware = true)
val bootAwarePrefs: SharedPreferences =
context
.createDeviceProtectedStorageContext()
.getSharedPreferences(BOOT_AWARE_PREFS_KEY, Context.MODE_PRIVATE)
bootAwarePrefs.edit().remove(bootAwareItem.sharedPrefKey).commit()
launcherPrefs.putSync(bootAwareItem.to(bootAwareItem.defaultValue))
assertThat(bootAwarePrefs.contains(bootAwareItem.sharedPrefKey)).isTrue()
launcherPrefs.removeSync(bootAwareItem)
}
@Test
fun put_bootAwareItem_updatesEncryptedStorage() {
val bootAwareItem =
LauncherPrefs.backedUpItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE, isBootAware = true)
val encryptedPrefs: SharedPreferences =
context.getSharedPreferences(bootAwareItem.sharedPrefFile, Context.MODE_PRIVATE)
encryptedPrefs.edit().remove(bootAwareItem.sharedPrefKey).commit()
launcherPrefs.putSync(bootAwareItem.to(TEST_STRING_ITEM.defaultValue))
assertThat(encryptedPrefs.contains(bootAwareItem.sharedPrefKey)).isTrue()
launcherPrefs.removeSync(bootAwareItem)
}
@Test
fun remove_bootAwareItem_removesFromDeviceProtectedStorage() {
val bootAwareItem =
LauncherPrefs.backedUpItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE, isBootAware = true)
val bootAwarePrefs: SharedPreferences =
context
.createDeviceProtectedStorageContext()
.getSharedPreferences(BOOT_AWARE_PREFS_KEY, Context.MODE_PRIVATE)
bootAwarePrefs
.edit()
.putString(bootAwareItem.sharedPrefKey, bootAwareItem.defaultValue)
.commit()
launcherPrefs.removeSync(bootAwareItem)
assertThat(bootAwarePrefs.contains(bootAwareItem.sharedPrefKey)).isFalse()
}
@Test
fun remove_bootAwareItem_removesFromEncryptedStorage() {
val bootAwareItem =
LauncherPrefs.backedUpItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE, isBootAware = true)
val encryptedPrefs: SharedPreferences =
context.getSharedPreferences(bootAwareItem.sharedPrefFile, Context.MODE_PRIVATE)
encryptedPrefs
.edit()
.putString(bootAwareItem.sharedPrefKey, bootAwareItem.defaultValue)
.commit()
launcherPrefs.removeSync(bootAwareItem)
assertThat(encryptedPrefs.contains(bootAwareItem.sharedPrefKey)).isFalse()
}
@Test
fun migrate_bootAwareItemsToDeviceProtectedStorage_worksAsIntended() {
val bootAwareItem =
LauncherPrefs.backedUpItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE, isBootAware = true)
launcherPrefs.removeSync(bootAwareItem)
val bootAwarePrefs: SharedPreferences =
context
.createDeviceProtectedStorageContext()
.getSharedPreferences(BOOT_AWARE_PREFS_KEY, Context.MODE_PRIVATE)
if (bootAwarePrefs.contains(bootAwareItem.sharedPrefKey)) {
bootAwarePrefs.edit().remove(bootAwareItem.sharedPrefKey).commit()
}
val encryptedPrefs: SharedPreferences =
context.getSharedPreferences(bootAwareItem.sharedPrefFile, Context.MODE_PRIVATE)
encryptedPrefs
.edit()
.putString(bootAwareItem.sharedPrefKey, bootAwareItem.defaultValue)
.commit()
launcherPrefs.migrateStartupDataToDeviceProtectedStorage()
assertThat(bootAwarePrefs.contains(bootAwareItem.sharedPrefKey)).isTrue()
launcherPrefs.removeSync(bootAwareItem)
}
@Test
fun migrate_onlyEncryptedItemsToDeviceProtectedStorage_doesNotHappen() {
val onlyEncryptedItem =
LauncherPrefs.backedUpItem(
TEST_PREF_KEY + "_",
TEST_DEFAULT_VALUE + "_",
isBootAware = false
)
val bootAwarePrefs: SharedPreferences =
context
.createDeviceProtectedStorageContext()
.getSharedPreferences(BOOT_AWARE_PREFS_KEY, Context.MODE_PRIVATE)
if (bootAwarePrefs.contains(onlyEncryptedItem.sharedPrefKey)) {
bootAwarePrefs.edit().remove(onlyEncryptedItem.sharedPrefKey).commit()
}
val encryptedPrefs: SharedPreferences =
context.getSharedPreferences(onlyEncryptedItem.sharedPrefFile, Context.MODE_PRIVATE)
encryptedPrefs
.edit()
.putString(onlyEncryptedItem.sharedPrefKey, onlyEncryptedItem.defaultValue)
.commit()
launcherPrefs.migrateStartupDataToDeviceProtectedStorage()
assertThat(bootAwarePrefs.contains(onlyEncryptedItem.sharedPrefKey)).isFalse()
encryptedPrefs.edit().remove(onlyEncryptedItem.sharedPrefKey).commit()
}
}