diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java index 9335e7e475..a5be89af19 100644 --- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java +++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java @@ -30,7 +30,6 @@ import static com.android.quickstep.BaseActivityInterface.getTaskDimension; import static java.lang.annotation.RetentionPolicy.SOURCE; import android.content.Context; -import android.content.SharedPreferences; import android.graphics.Matrix; import android.graphics.Point; import android.graphics.PointF; @@ -45,6 +44,7 @@ import androidx.annotation.NonNull; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; +import com.android.launcher3.LauncherPrefChangeListener; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.testing.shared.TestProtocol; import com.android.launcher3.touch.PagedOrientationHandler; @@ -66,8 +66,7 @@ import java.util.function.IntConsumer; * This class has initial default state assuming the device and foreground app have * no ({@link Surface#ROTATION_0} rotation. */ -public class RecentsOrientedState implements - SharedPreferences.OnSharedPreferenceChangeListener { +public class RecentsOrientedState implements LauncherPrefChangeListener { private static final String TAG = "RecentsOrientedState"; private static final boolean DEBUG = false; @@ -283,7 +282,7 @@ public class RecentsOrientedState implements } @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { + public void onPrefChanged(String s) { if (LauncherPrefs.ALLOW_ROTATION.getSharedPrefKey().equals(s)) { updateHomeRotationSetting(); } diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java index 15641ab516..05a3a52463 100644 --- a/src/com/android/launcher3/LauncherAppState.java +++ b/src/com/android/launcher3/LauncherAppState.java @@ -266,7 +266,7 @@ public class LauncherAppState implements SafeCloseable { } private class IconObserver - implements IconProvider.IconChangeListener, OnSharedPreferenceChangeListener { + implements IconProvider.IconChangeListener, LauncherPrefChangeListener { @Override public void onAppIconChanged(String packageName, UserHandle user) { @@ -288,7 +288,7 @@ public class LauncherAppState implements SafeCloseable { } @Override - public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + public void onPrefChanged(String key) { if (Themes.KEY_THEMED_ICONS.equals(key)) { mIconProvider.setIconThemeSupported(Themes.isThemedIconEnabled(mContext)); verifyIconChanged(); diff --git a/src/com/android/launcher3/LauncherPrefChangeListener.java b/src/com/android/launcher3/LauncherPrefChangeListener.java new file mode 100644 index 0000000000..3e9a8464d9 --- /dev/null +++ b/src/com/android/launcher3/LauncherPrefChangeListener.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2024 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.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; + +/** + * Listener for changes in [LauncherPrefs]. + *

+ * The listener also serves as an [OnSharedPreferenceChangeListener] where + * [onSharedPreferenceChanged] delegates to [onPrefChanged]. Overriding [onSharedPreferenceChanged] + * breaks compatibility with [SharedPreferences]. + */ +public interface LauncherPrefChangeListener extends OnSharedPreferenceChangeListener { + + /** Callback invoked when the preference for [key] has changed. */ + void onPrefChanged(String key); + + @Override + default void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + onPrefChanged(key); + } +} diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt index 13181e87f2..7ebfc1818a 100644 --- a/src/com/android/launcher3/LauncherPrefs.kt +++ b/src/com/android/launcher3/LauncherPrefs.kt @@ -18,7 +18,6 @@ package com.android.launcher3 import android.content.Context import android.content.Context.MODE_PRIVATE import android.content.SharedPreferences -import android.content.SharedPreferences.OnSharedPreferenceChangeListener import androidx.annotation.VisibleForTesting import com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN import com.android.launcher3.LauncherFiles.DEVICE_PREFERENCES_KEY @@ -34,11 +33,177 @@ import com.android.launcher3.util.SafeCloseable import com.android.launcher3.util.Themes /** - * Use same context for shared preferences, so that we use a single cached instance + * Manages Launcher [SharedPreferences] through [Item] instances. * * TODO(b/262721340): Replace all direct SharedPreference refs with LauncherPrefs / Item methods. */ -class LauncherPrefs(private val encryptedContext: Context) : SafeCloseable { +abstract class LauncherPrefs : SafeCloseable { + + /** Returns the value with type [T] for [item]. */ + abstract fun get(item: ContextualItem): T + + /** Returns the value with type [T] for [item]. */ + abstract fun get(item: ConstantItem): T + + /** Stores the values for each item in preferences. */ + abstract fun put(vararg itemsToValues: Pair) + + /** Stores the [value] with type [T] for [item] in preferences. */ + abstract fun put(item: Item, value: T) + + /** Synchronous version of [put]. */ + abstract fun putSync(vararg itemsToValues: Pair) + + /** Registers [listener] for [items]. */ + abstract fun addListener(listener: LauncherPrefChangeListener, vararg items: Item) + + /** Unregisters [listener] for [items]. */ + abstract fun removeListener(listener: LauncherPrefChangeListener, vararg items: Item) + + /** Returns `true` iff all [items] have a value. */ + abstract fun has(vararg items: Item): Boolean + + /** Removes the value for each item in [items]. */ + abstract fun remove(vararg items: Item) + + /** Synchronous version of [remove]. */ + abstract fun removeSync(vararg items: Item) + + companion object { + @VisibleForTesting const val BOOT_AWARE_PREFS_KEY = "boot_aware_prefs" + + @JvmField + var INSTANCE = MainThreadInitializedObject { LauncherPrefsImpl(it) } + + @JvmStatic fun get(context: Context): LauncherPrefs = INSTANCE.get(context) + + const val TASKBAR_PINNING_KEY = "TASKBAR_PINNING_KEY" + const val TASKBAR_PINNING_DESKTOP_MODE_KEY = "TASKBAR_PINNING_DESKTOP_MODE_KEY" + const val SHOULD_SHOW_SMARTSPACE_KEY = "SHOULD_SHOW_SMARTSPACE_KEY" + @JvmField + val ICON_STATE = nonRestorableItem("pref_icon_shape_path", "", EncryptionType.ENCRYPTED) + + @JvmField + val ENABLE_TWOLINE_ALLAPPS_TOGGLE = backedUpItem("pref_enable_two_line_toggle", false) + @JvmField + val THEMED_ICONS = backedUpItem(Themes.KEY_THEMED_ICONS, false, EncryptionType.ENCRYPTED) + @JvmField val PROMISE_ICON_IDS = backedUpItem(InstallSessionHelper.PROMISE_ICON_IDS, "") + @JvmField val WORK_EDU_STEP = backedUpItem("showed_work_profile_edu", 0) + @JvmField + val WORKSPACE_SIZE = + backedUpItem(DeviceGridState.KEY_WORKSPACE_SIZE, "", EncryptionType.ENCRYPTED) + @JvmField + val HOTSEAT_COUNT = + backedUpItem(DeviceGridState.KEY_HOTSEAT_COUNT, -1, EncryptionType.ENCRYPTED) + @JvmField + val TASKBAR_PINNING = + backedUpItem(TASKBAR_PINNING_KEY, false, EncryptionType.DEVICE_PROTECTED) + @JvmField + val TASKBAR_PINNING_IN_DESKTOP_MODE = + backedUpItem(TASKBAR_PINNING_DESKTOP_MODE_KEY, true, EncryptionType.DEVICE_PROTECTED) + + @JvmField + val DEVICE_TYPE = + backedUpItem( + DeviceGridState.KEY_DEVICE_TYPE, + InvariantDeviceProfile.TYPE_PHONE, + EncryptionType.ENCRYPTED, + ) + @JvmField + val DB_FILE = backedUpItem(DeviceGridState.KEY_DB_FILE, "", EncryptionType.ENCRYPTED) + @JvmField + val SHOULD_SHOW_SMARTSPACE = + backedUpItem( + SHOULD_SHOW_SMARTSPACE_KEY, + WIDGET_ON_FIRST_SCREEN, + EncryptionType.DEVICE_PROTECTED, + ) + @JvmField + val RESTORE_DEVICE = + backedUpItem( + RestoreDbTask.RESTORED_DEVICE_TYPE, + InvariantDeviceProfile.TYPE_PHONE, + EncryptionType.ENCRYPTED, + ) + @JvmField + val IS_FIRST_LOAD_AFTER_RESTORE = + nonRestorableItem(FIRST_LOAD_AFTER_RESTORE_KEY, false, EncryptionType.ENCRYPTED) + @JvmField val APP_WIDGET_IDS = backedUpItem(RestoreDbTask.APPWIDGET_IDS, "") + @JvmField val OLD_APP_WIDGET_IDS = backedUpItem(RestoreDbTask.APPWIDGET_OLD_IDS, "") + @JvmField + val GRID_NAME = + ConstantItem( + "idp_grid_name", + isBackedUp = true, + defaultValue = null, + encryptionType = EncryptionType.ENCRYPTED, + type = String::class.java, + ) + @JvmField + val ALLOW_ROTATION = + backedUpItem(RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY, Boolean::class.java) { + RotationHelper.getAllowRotationDefaultValue(DisplayController.INSTANCE.get(it).info) + } + + // Preferences for widget configurations + @JvmField + val RECONFIGURABLE_WIDGET_EDUCATION_TIP_SEEN = + backedUpItem("launcher.reconfigurable_widget_education_tip_seen", false) + + @JvmStatic + fun backedUpItem( + sharedPrefKey: String, + defaultValue: T, + encryptionType: EncryptionType = EncryptionType.ENCRYPTED, + ): ConstantItem = + ConstantItem(sharedPrefKey, isBackedUp = true, defaultValue, encryptionType) + + @JvmStatic + fun backedUpItem( + sharedPrefKey: String, + type: Class, + encryptionType: EncryptionType = EncryptionType.ENCRYPTED, + defaultValueFromContext: (c: Context) -> T, + ): ContextualItem = + ContextualItem( + sharedPrefKey, + isBackedUp = true, + defaultValueFromContext, + encryptionType, + type, + ) + + @JvmStatic + fun nonRestorableItem( + sharedPrefKey: String, + defaultValue: T, + encryptionType: EncryptionType = EncryptionType.ENCRYPTED, + ): ConstantItem = + ConstantItem(sharedPrefKey, isBackedUp = false, defaultValue, encryptionType) + + @Deprecated("Don't use shared preferences directly. Use other LauncherPref methods.") + @JvmStatic + fun getPrefs(context: Context): SharedPreferences { + // Use application context for shared preferences, so we use single cached instance + return context.applicationContext.getSharedPreferences( + SHARED_PREFERENCES_KEY, + MODE_PRIVATE, + ) + } + + @Deprecated("Don't use shared preferences directly. Use other LauncherPref methods.") + @JvmStatic + fun getDevicePrefs(context: Context): SharedPreferences { + // Use application context for shared preferences, so we use a single cached instance + return context.applicationContext.getSharedPreferences( + DEVICE_PREFERENCES_KEY, + MODE_PRIVATE, + ) + } + } +} + +private class LauncherPrefsImpl(private val encryptedContext: Context) : LauncherPrefs() { private val deviceProtectedStorageContext = encryptedContext.createDeviceProtectedStorageContext() @@ -54,11 +219,11 @@ class LauncherPrefs(private val encryptedContext: Context) : SafeCloseable { else item.encryptedPrefs /** Wrapper around `getInner` for a `ContextualItem` */ - fun get(item: ContextualItem): T = + override fun get(item: ContextualItem): T = getInner(item, item.defaultValueFromContext(encryptedContext)) /** Wrapper around `getInner` for an `Item` */ - fun get(item: ConstantItem): T = getInner(item, item.defaultValue) + override fun get(item: ConstantItem): T = getInner(item, item.defaultValue) /** * Retrieves the value for an [Item] from [SharedPreferences]. It handles method typing via the @@ -97,17 +262,17 @@ class LauncherPrefs(private val encryptedContext: Context) : SafeCloseable { * prepareToPutValue(itemsToValues) for every distinct `SharedPreferences` file present in the * provided item configurations. */ - fun put(vararg itemsToValues: Pair): Unit = + override fun put(vararg itemsToValues: Pair): Unit = prepareToPutValues(itemsToValues).forEach { it.apply() } /** See referenced `put` method above. */ - fun put(item: Item, value: T): Unit = put(item.to(value)) + override fun put(item: Item, value: T): Unit = put(item.to(value)) /** * Synchronously stores all the values provided according to their associated Item * configuration. */ - fun putSync(vararg itemsToValues: Pair): Unit = + override fun putSync(vararg itemsToValues: Pair): Unit = prepareToPutValues(itemsToValues).forEach { it.commit() } /** @@ -152,7 +317,7 @@ class LauncherPrefs(private val encryptedContext: Context) : SafeCloseable { @Suppress("UNCHECKED_CAST") private fun SharedPreferences.Editor.putValue( item: Item, - value: Any? + value: Any?, ): SharedPreferences.Editor = when (item.type) { String::class.java -> putString(item.sharedPrefKey, value as? String) @@ -176,7 +341,7 @@ class LauncherPrefs(private val encryptedContext: Context) : SafeCloseable { * `SharedPreferences` files associated with the provided list of items. The listener will need * to filter update notifications so they don't activate for non-relevant updates. */ - fun addListener(listener: OnSharedPreferenceChangeListener, vararg items: Item) { + override fun addListener(listener: LauncherPrefChangeListener, vararg items: Item) { items .map { chooseSharedPreferences(it) } .distinct() @@ -187,7 +352,7 @@ class LauncherPrefs(private val encryptedContext: Context) : SafeCloseable { * Stops the listener from getting notified of any more updates to any of the * `SharedPreferences` files associated with any of the provided list of [Item]. */ - fun removeListener(listener: OnSharedPreferenceChangeListener, vararg items: Item) { + override fun removeListener(listener: LauncherPrefChangeListener, vararg items: Item) { // If a listener is not registered to a SharedPreference, unregistering it does nothing items .map { chooseSharedPreferences(it) } @@ -199,7 +364,7 @@ class LauncherPrefs(private val encryptedContext: Context) : SafeCloseable { * Checks if all the provided [Item] have values stored in their corresponding * `SharedPreferences` files. */ - fun has(vararg items: Item): Boolean { + override fun has(vararg items: Item): Boolean { items .groupBy { chooseSharedPreferences(it) } .forEach { (prefs, itemsSublist) -> @@ -211,10 +376,10 @@ class LauncherPrefs(private val encryptedContext: Context) : SafeCloseable { /** * Asynchronously removes the [Item]'s value from its corresponding `SharedPreferences` file. */ - fun remove(vararg items: Item) = prepareToRemove(items).forEach { it.apply() } + override fun remove(vararg items: Item) = prepareToRemove(items).forEach { it.apply() } /** Synchronously removes the [Item]'s value from its corresponding `SharedPreferences` file. */ - fun removeSync(vararg items: Item) = prepareToRemove(items).forEach { it.commit() } + override fun removeSync(vararg items: Item) = prepareToRemove(items).forEach { it.commit() } /** * Removes the key value pairs stored in `SharedPreferences` for each corresponding Item. If the @@ -244,138 +409,6 @@ class LauncherPrefs(private val encryptedContext: Context) : SafeCloseable { } override fun close() {} - - companion object { - @VisibleForTesting const val BOOT_AWARE_PREFS_KEY = "boot_aware_prefs" - - @JvmField var INSTANCE = MainThreadInitializedObject { LauncherPrefs(it) } - - @JvmStatic fun get(context: Context): LauncherPrefs = INSTANCE.get(context) - - const val TASKBAR_PINNING_KEY = "TASKBAR_PINNING_KEY" - const val TASKBAR_PINNING_DESKTOP_MODE_KEY = "TASKBAR_PINNING_DESKTOP_MODE_KEY" - const val SHOULD_SHOW_SMARTSPACE_KEY = "SHOULD_SHOW_SMARTSPACE_KEY" - @JvmField - val ICON_STATE = nonRestorableItem("pref_icon_shape_path", "", EncryptionType.ENCRYPTED) - - @JvmField - val ENABLE_TWOLINE_ALLAPPS_TOGGLE = backedUpItem("pref_enable_two_line_toggle", false) - @JvmField - val THEMED_ICONS = backedUpItem(Themes.KEY_THEMED_ICONS, false, EncryptionType.ENCRYPTED) - @JvmField val PROMISE_ICON_IDS = backedUpItem(InstallSessionHelper.PROMISE_ICON_IDS, "") - @JvmField val WORK_EDU_STEP = backedUpItem("showed_work_profile_edu", 0) - @JvmField - val WORKSPACE_SIZE = - backedUpItem(DeviceGridState.KEY_WORKSPACE_SIZE, "", EncryptionType.ENCRYPTED) - @JvmField - val HOTSEAT_COUNT = - backedUpItem(DeviceGridState.KEY_HOTSEAT_COUNT, -1, EncryptionType.ENCRYPTED) - @JvmField - val TASKBAR_PINNING = - backedUpItem(TASKBAR_PINNING_KEY, false, EncryptionType.DEVICE_PROTECTED) - @JvmField - val TASKBAR_PINNING_IN_DESKTOP_MODE = - backedUpItem(TASKBAR_PINNING_DESKTOP_MODE_KEY, true, EncryptionType.DEVICE_PROTECTED) - - @JvmField - val DEVICE_TYPE = - backedUpItem( - DeviceGridState.KEY_DEVICE_TYPE, - InvariantDeviceProfile.TYPE_PHONE, - EncryptionType.ENCRYPTED - ) - @JvmField - val DB_FILE = backedUpItem(DeviceGridState.KEY_DB_FILE, "", EncryptionType.ENCRYPTED) - @JvmField - val SHOULD_SHOW_SMARTSPACE = - backedUpItem( - SHOULD_SHOW_SMARTSPACE_KEY, - WIDGET_ON_FIRST_SCREEN, - EncryptionType.DEVICE_PROTECTED - ) - @JvmField - val RESTORE_DEVICE = - backedUpItem( - RestoreDbTask.RESTORED_DEVICE_TYPE, - InvariantDeviceProfile.TYPE_PHONE, - EncryptionType.ENCRYPTED - ) - @JvmField - val IS_FIRST_LOAD_AFTER_RESTORE = - nonRestorableItem(FIRST_LOAD_AFTER_RESTORE_KEY, false, EncryptionType.ENCRYPTED) - @JvmField val APP_WIDGET_IDS = backedUpItem(RestoreDbTask.APPWIDGET_IDS, "") - @JvmField val OLD_APP_WIDGET_IDS = backedUpItem(RestoreDbTask.APPWIDGET_OLD_IDS, "") - @JvmField - val GRID_NAME = - ConstantItem( - "idp_grid_name", - isBackedUp = true, - defaultValue = null, - encryptionType = EncryptionType.ENCRYPTED, - type = String::class.java - ) - @JvmField - val ALLOW_ROTATION = - backedUpItem(RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY, Boolean::class.java) { - RotationHelper.getAllowRotationDefaultValue(DisplayController.INSTANCE.get(it).info) - } - - // Preferences for widget configurations - @JvmField - val RECONFIGURABLE_WIDGET_EDUCATION_TIP_SEEN = - backedUpItem("launcher.reconfigurable_widget_education_tip_seen", false) - - @JvmStatic - fun backedUpItem( - sharedPrefKey: String, - defaultValue: T, - encryptionType: EncryptionType = EncryptionType.ENCRYPTED - ): ConstantItem = - ConstantItem(sharedPrefKey, isBackedUp = true, defaultValue, encryptionType) - - @JvmStatic - fun backedUpItem( - sharedPrefKey: String, - type: Class, - encryptionType: EncryptionType = EncryptionType.ENCRYPTED, - defaultValueFromContext: (c: Context) -> T - ): ContextualItem = - ContextualItem( - sharedPrefKey, - isBackedUp = true, - defaultValueFromContext, - encryptionType, - type - ) - - @JvmStatic - fun nonRestorableItem( - sharedPrefKey: String, - defaultValue: T, - encryptionType: EncryptionType = EncryptionType.ENCRYPTED - ): ConstantItem = - ConstantItem(sharedPrefKey, isBackedUp = false, defaultValue, encryptionType) - - @Deprecated("Don't use shared preferences directly. Use other LauncherPref methods.") - @JvmStatic - fun getPrefs(context: Context): SharedPreferences { - // Use application context for shared preferences, so we use single cached instance - return context.applicationContext.getSharedPreferences( - SHARED_PREFERENCES_KEY, - MODE_PRIVATE - ) - } - - @Deprecated("Don't use shared preferences directly. Use other LauncherPref methods.") - @JvmStatic - fun getDevicePrefs(context: Context): SharedPreferences { - // Use application context for shared preferences, so we use a single cached instance - return context.applicationContext.getSharedPreferences( - DEVICE_PREFERENCES_KEY, - MODE_PRIVATE - ) - } - } } abstract class Item { @@ -395,7 +428,7 @@ data class ConstantItem( val defaultValue: T, override val encryptionType: EncryptionType, // The default value can be null. If so, the type needs to be explicitly stated, or else NPE - override val type: Class = defaultValue!!::class.java + override val type: Class = defaultValue!!::class.java, ) : Item() { fun get(c: Context): T = LauncherPrefs.get(c).get(this) @@ -406,7 +439,7 @@ data class ContextualItem( override val isBackedUp: Boolean, private val defaultSupplier: (c: Context) -> T, override val encryptionType: EncryptionType, - override val type: Class + override val type: Class, ) : Item() { private var default: T? = null diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java index fdb37f0dcd..b3bcada148 100644 --- a/src/com/android/launcher3/states/RotationHelper.java +++ b/src/com/android/launcher3/states/RotationHelper.java @@ -26,8 +26,6 @@ import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.launcher3.util.window.WindowManagerProxy.MIN_TABLET_WIDTH; import android.content.Context; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.os.Handler; import android.os.Message; @@ -36,13 +34,14 @@ import androidx.annotation.WorkerThread; import com.android.launcher3.BaseActivity; import com.android.launcher3.DeviceProfile; +import com.android.launcher3.LauncherPrefChangeListener; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.util.DisplayController; /** * Utility class to manage launcher rotation */ -public class RotationHelper implements OnSharedPreferenceChangeListener, +public class RotationHelper implements LauncherPrefChangeListener, DeviceProfile.OnDeviceProfileChangeListener, DisplayController.DisplayInfoChangeListener { @@ -112,7 +111,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener, } @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { + public void onPrefChanged(String s) { if (mDestroyed || mIgnoreAutoRotateSettings) return; boolean wasRotationEnabled = mHomeRotationEnabled; mHomeRotationEnabled = LauncherPrefs.get(mActivity).get(ALLOW_ROTATION); diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java index c59cc81c47..0b45118e82 100644 --- a/src/com/android/launcher3/util/DisplayController.java +++ b/src/com/android/launcher3/util/DisplayController.java @@ -35,7 +35,6 @@ import android.annotation.SuppressLint; import android.content.ComponentCallbacks; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; @@ -51,6 +50,7 @@ import androidx.annotation.UiThread; import androidx.annotation.VisibleForTesting; import com.android.launcher3.InvariantDeviceProfile.DeviceType; +import com.android.launcher3.LauncherPrefChangeListener; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.Utilities; import com.android.launcher3.logging.FileLog; @@ -116,8 +116,7 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable { private Info mInfo; private boolean mDestroyed = false; - private SharedPreferences.OnSharedPreferenceChangeListener - mTaskbarPinningPreferenceChangeListener; + private LauncherPrefChangeListener mTaskbarPinningPreferenceChangeListener; @VisibleForTesting protected DisplayController(Context context) { @@ -142,19 +141,18 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable { } private void attachTaskbarPinningSharedPreferenceChangeListener(Context context) { - mTaskbarPinningPreferenceChangeListener = - (sharedPreferences, key) -> { - LauncherPrefs prefs = LauncherPrefs.get(mContext); - boolean isTaskbarPinningChanged = TASKBAR_PINNING_KEY.equals(key) - && mInfo.mIsTaskbarPinned != prefs.get(TASKBAR_PINNING); - boolean isTaskbarPinningDesktopModeChanged = - TASKBAR_PINNING_DESKTOP_MODE_KEY.equals(key) - && mInfo.mIsTaskbarPinnedInDesktopMode != prefs.get( - TASKBAR_PINNING_IN_DESKTOP_MODE); - if (isTaskbarPinningChanged || isTaskbarPinningDesktopModeChanged) { - notifyConfigChange(); - } - }; + mTaskbarPinningPreferenceChangeListener = key -> { + LauncherPrefs prefs = LauncherPrefs.get(mContext); + boolean isTaskbarPinningChanged = TASKBAR_PINNING_KEY.equals(key) + && mInfo.mIsTaskbarPinned != prefs.get(TASKBAR_PINNING); + boolean isTaskbarPinningDesktopModeChanged = + TASKBAR_PINNING_DESKTOP_MODE_KEY.equals(key) + && mInfo.mIsTaskbarPinnedInDesktopMode != prefs.get( + TASKBAR_PINNING_IN_DESKTOP_MODE); + if (isTaskbarPinningChanged || isTaskbarPinningDesktopModeChanged) { + notifyConfigChange(); + } + }; LauncherPrefs.get(context).addListener( mTaskbarPinningPreferenceChangeListener, TASKBAR_PINNING); diff --git a/tests/multivalentTests/src/com/android/launcher3/AppWidgetsRestoredReceiverTest.kt b/tests/multivalentTests/src/com/android/launcher3/AppWidgetsRestoredReceiverTest.kt index 21abab4d49..0e06051adf 100644 --- a/tests/multivalentTests/src/com/android/launcher3/AppWidgetsRestoredReceiverTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/AppWidgetsRestoredReceiverTest.kt @@ -29,7 +29,7 @@ class AppWidgetsRestoredReceiverTest { @Before fun setup() { - launcherPrefs = LauncherPrefs(DeviceHelpers.context) + launcherPrefs = LauncherPrefs.get(DeviceHelpers.context) receiverUnderTest = AppWidgetsRestoredReceiver() } diff --git a/tests/multivalentTests/src/com/android/launcher3/LauncherPrefsTest.kt b/tests/multivalentTests/src/com/android/launcher3/LauncherPrefsTest.kt index b81309506a..4aeef2e671 100644 --- a/tests/multivalentTests/src/com/android/launcher3/LauncherPrefsTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/LauncherPrefsTest.kt @@ -17,7 +17,6 @@ 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 @@ -63,7 +62,7 @@ class LauncherPrefsTest { @Test fun addListener_listeningForStringItemUpdates_isCorrectlyNotifiedOfUpdates() { val latch = CountDownLatch(1) - val listener = OnSharedPreferenceChangeListener { _, _ -> latch.countDown() } + val listener = LauncherPrefChangeListener { latch.countDown() } with(launcherPrefs) { putSync(TEST_STRING_ITEM.to(TEST_STRING_ITEM.defaultValue)) @@ -78,7 +77,7 @@ class LauncherPrefsTest { @Test fun removeListener_previouslyListeningForStringItemUpdates_isNoLongerNotifiedOfUpdates() { val latch = CountDownLatch(1) - val listener = OnSharedPreferenceChangeListener { _, _ -> latch.countDown() } + val listener = LauncherPrefChangeListener { latch.countDown() } with(launcherPrefs) { addListener(listener, TEST_STRING_ITEM) @@ -94,14 +93,14 @@ class LauncherPrefsTest { @Test fun addListenerAndRemoveListener_forMultipleItems_bothWorkProperly() { var latch = CountDownLatch(3) - val listener = OnSharedPreferenceChangeListener { _, _ -> latch.countDown() } + val listener = LauncherPrefChangeListener { 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) + TEST_BOOLEAN_ITEM.to(!TEST_BOOLEAN_ITEM.defaultValue), ) assertThat(latch.await(WAIT_TIME_IN_SECONDS, TimeUnit.SECONDS)).isTrue() @@ -110,7 +109,7 @@ class LauncherPrefsTest { 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) + TEST_BOOLEAN_ITEM.to(TEST_BOOLEAN_ITEM.defaultValue), ) remove(TEST_INT_ITEM, TEST_STRING_ITEM, TEST_BOOLEAN_ITEM) @@ -150,7 +149,7 @@ class LauncherPrefsTest { 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) + 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) @@ -191,7 +190,7 @@ class LauncherPrefsTest { LauncherPrefs.backedUpItem( TEST_PREF_KEY, TEST_DEFAULT_VALUE, - EncryptionType.DEVICE_PROTECTED + EncryptionType.DEVICE_PROTECTED, ) val bootAwarePrefs: SharedPreferences = @@ -212,7 +211,7 @@ class LauncherPrefsTest { LauncherPrefs.backedUpItem( TEST_PREF_KEY, TEST_DEFAULT_VALUE, - EncryptionType.DEVICE_PROTECTED + EncryptionType.DEVICE_PROTECTED, ) val bootAwarePrefs: SharedPreferences = diff --git a/tests/multivalentTests/src/com/android/launcher3/provider/RestoreDbTaskTest.java b/tests/multivalentTests/src/com/android/launcher3/provider/RestoreDbTaskTest.java index b3675a6e0c..d0c168a8d1 100644 --- a/tests/multivalentTests/src/com/android/launcher3/provider/RestoreDbTaskTest.java +++ b/tests/multivalentTests/src/com/android/launcher3/provider/RestoreDbTaskTest.java @@ -101,7 +101,7 @@ public class RestoreDbTaskTest { mMockController = Mockito.mock(ModelDbController.class); mMockDb = mock(SQLiteDatabase.class); mMockCursor = mock(Cursor.class); - mPrefs = new LauncherPrefs(mContext); + mPrefs = LauncherPrefs.get(mContext); mMockRestoreEventLogger = mock(LauncherRestoreEventLogger.class); }