Merge "Expanded LauncherPrefs APIs to Replace Direct Shared Preference Usage." into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
1eb59d6c6a
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.quickstep.logging;
|
||||
|
||||
import static com.android.launcher3.LauncherPrefs.THEMED_ICONS;
|
||||
import static com.android.launcher3.LauncherPrefs.getDevicePrefs;
|
||||
import static com.android.launcher3.LauncherPrefs.getPrefs;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_SCREEN_SUGGESTIONS_DISABLED;
|
||||
@@ -39,6 +40,7 @@ import android.util.Log;
|
||||
import android.util.Xml;
|
||||
|
||||
import com.android.launcher3.AutoInstallsLayout;
|
||||
import com.android.launcher3.LauncherPrefs;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.logging.InstanceId;
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
@@ -178,7 +180,7 @@ public class SettingsChangeLogger implements
|
||||
logger::log);
|
||||
|
||||
SharedPreferences prefs = getPrefs(mContext);
|
||||
logger.log(prefs.getBoolean(KEY_THEMED_ICONS, false)
|
||||
logger.log(LauncherPrefs.get(mContext).get(THEMED_ICONS)
|
||||
? LAUNCHER_THEMED_ICON_ENABLED
|
||||
: LAUNCHER_THEMED_ICON_DISABLED);
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@ package com.android.launcher3;
|
||||
|
||||
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
|
||||
|
||||
import static com.android.launcher3.LauncherPrefs.getDevicePrefs;
|
||||
import static com.android.launcher3.LauncherPrefs.ICON_STATE;
|
||||
import static com.android.launcher3.LauncherPrefs.THEMED_ICONS;
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
|
||||
|
||||
@@ -55,7 +56,7 @@ import com.android.launcher3.widget.custom.CustomWidgetManager;
|
||||
public class LauncherAppState implements SafeCloseable {
|
||||
|
||||
public static final String ACTION_FORCE_ROLOAD = "force-reload-launcher";
|
||||
private static final String KEY_ICON_STATE = "pref_icon_shape_path";
|
||||
public static final String KEY_ICON_STATE = "pref_icon_shape_path";
|
||||
|
||||
// We do not need any synchronization for this variable as its only written on UI thread.
|
||||
public static final MainThreadInitializedObject<LauncherAppState> INSTANCE =
|
||||
@@ -117,10 +118,9 @@ public class LauncherAppState implements SafeCloseable {
|
||||
observer, MODEL_EXECUTOR.getHandler());
|
||||
mOnTerminateCallback.add(iconChangeTracker::close);
|
||||
MODEL_EXECUTOR.execute(observer::verifyIconChanged);
|
||||
SharedPreferences prefs = LauncherPrefs.getPrefs(mContext);
|
||||
prefs.registerOnSharedPreferenceChangeListener(observer);
|
||||
LauncherPrefs.get(context).addListener(observer, THEMED_ICONS);
|
||||
mOnTerminateCallback.add(
|
||||
() -> prefs.unregisterOnSharedPreferenceChangeListener(observer));
|
||||
() -> LauncherPrefs.get(mContext).removeListener(observer, THEMED_ICONS));
|
||||
|
||||
InstallSessionTracker installSessionTracker =
|
||||
InstallSessionHelper.INSTANCE.get(context).registerInstallTracker(mModel);
|
||||
@@ -207,12 +207,12 @@ public class LauncherAppState implements SafeCloseable {
|
||||
public void onSystemIconStateChanged(String iconState) {
|
||||
IconShape.init(mContext);
|
||||
refreshAndReloadLauncher();
|
||||
getDevicePrefs(mContext).edit().putString(KEY_ICON_STATE, iconState).apply();
|
||||
LauncherPrefs.get(mContext).put(ICON_STATE, iconState);
|
||||
}
|
||||
|
||||
void verifyIconChanged() {
|
||||
String iconState = mIconProvider.getSystemIconState();
|
||||
if (!iconState.equals(getDevicePrefs(mContext).getString(KEY_ICON_STATE, ""))) {
|
||||
if (!iconState.equals(LauncherPrefs.get(mContext).get(ICON_STATE))) {
|
||||
onSystemIconStateChanged(iconState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,24 +2,255 @@ package com.android.launcher3
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.android.launcher3.allapps.WorkProfileManager
|
||||
import com.android.launcher3.model.DeviceGridState
|
||||
import com.android.launcher3.pm.InstallSessionHelper
|
||||
import com.android.launcher3.provider.RestoreDbTask
|
||||
import com.android.launcher3.util.MainThreadInitializedObject
|
||||
import com.android.launcher3.util.Themes
|
||||
|
||||
object LauncherPrefs {
|
||||
/**
|
||||
* Use same context for shared preferences, so that we use a single cached instance
|
||||
* TODO(b/262721340): Replace all direct SharedPreference refs with LauncherPrefs / Item methods.
|
||||
*/
|
||||
class LauncherPrefs(private val context: Context) {
|
||||
|
||||
@JvmStatic
|
||||
fun getPrefs(context: Context): SharedPreferences {
|
||||
// Use application context for shared preferences, so that we use a single cached instance
|
||||
return context.applicationContext.getSharedPreferences(
|
||||
LauncherFiles.SHARED_PREFERENCES_KEY,
|
||||
Context.MODE_PRIVATE
|
||||
)
|
||||
/**
|
||||
* Retrieves the value for an [Item] from [SharedPreferences]. It handles method typing via the
|
||||
* default value type, and will throw an error if the type of the item provided is not a
|
||||
* `String`, `Boolean`, `Float`, `Int`, `Long`, or `Set<String>`.
|
||||
*/
|
||||
@Suppress("IMPLICIT_CAST_TO_ANY", "UNCHECKED_CAST")
|
||||
fun <T : Any> get(item: Item<T>): T {
|
||||
val sp = context.getSharedPreferences(item.sharedPrefFile, Context.MODE_PRIVATE)
|
||||
|
||||
return when (item.defaultValue::class.java) {
|
||||
String::class.java -> sp.getString(item.sharedPrefKey, item.defaultValue as String)
|
||||
Boolean::class.java,
|
||||
java.lang.Boolean::class.java ->
|
||||
sp.getBoolean(item.sharedPrefKey, item.defaultValue as Boolean)
|
||||
Int::class.java,
|
||||
java.lang.Integer::class.java -> sp.getInt(item.sharedPrefKey, item.defaultValue as Int)
|
||||
Float::class.java,
|
||||
java.lang.Float::class.java ->
|
||||
sp.getFloat(item.sharedPrefKey, item.defaultValue as Float)
|
||||
Long::class.java,
|
||||
java.lang.Long::class.java -> sp.getLong(item.sharedPrefKey, item.defaultValue as Long)
|
||||
Set::class.java -> sp.getStringSet(item.sharedPrefKey, item.defaultValue as Set<String>)
|
||||
else ->
|
||||
throw IllegalArgumentException(
|
||||
"item type: ${item.defaultValue::class.java}" +
|
||||
" is not compatible with sharedPref methods"
|
||||
)
|
||||
}
|
||||
as T
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getDevicePrefs(context: Context): SharedPreferences {
|
||||
// Use application context for shared preferences, so that we use a single cached instance
|
||||
return context.applicationContext.getSharedPreferences(
|
||||
LauncherFiles.DEVICE_PREFERENCES_KEY,
|
||||
Context.MODE_PRIVATE
|
||||
)
|
||||
/**
|
||||
* Stores each of the values provided in `SharedPreferences` according to the configuration
|
||||
* contained within the associated items provided. Internally, it uses apply, so the caller
|
||||
* cannot assume that the values that have been put are immediately available for use.
|
||||
*
|
||||
* The forEach loop is necessary here since there is 1 `SharedPreference.Editor` returned from
|
||||
* prepareToPutValue(itemsToValues) for every distinct `SharedPreferences` file present in the
|
||||
* provided item configurations.
|
||||
*/
|
||||
fun put(vararg itemsToValues: Pair<Item<*>, Any>): Unit =
|
||||
prepareToPutValues(itemsToValues).forEach { it.apply() }
|
||||
|
||||
/**
|
||||
* Stores the value provided in `SharedPreferences` according to the item configuration provided
|
||||
* It is asynchronous, so the caller can't assume that the value put is immediately available.
|
||||
*/
|
||||
fun <T : Any> put(item: Item<T>, value: T): Unit =
|
||||
context
|
||||
.getSharedPreferences(item.sharedPrefFile, Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
.putValue(item, value)
|
||||
.apply()
|
||||
|
||||
/**
|
||||
* Synchronously stores all the values provided according to their associated Item
|
||||
* configuration.
|
||||
*/
|
||||
fun putSync(vararg itemsToValues: Pair<Item<*>, Any>): Unit =
|
||||
prepareToPutValues(itemsToValues).forEach { it.commit() }
|
||||
|
||||
/**
|
||||
* Update each shared preference file with the item - value pairs provided. This method is
|
||||
* optimized to avoid retrieving the same shared preference file multiple times.
|
||||
*
|
||||
* @return `List<SharedPreferences.Editor>` 1 for each distinct shared preference file among the
|
||||
* items given as part of the itemsToValues parameter
|
||||
*/
|
||||
private fun prepareToPutValues(
|
||||
itemsToValues: Array<out Pair<Item<*>, Any>>
|
||||
): List<SharedPreferences.Editor> =
|
||||
itemsToValues
|
||||
.groupBy { it.first.sharedPrefFile }
|
||||
.map { fileToItemValueList ->
|
||||
context
|
||||
.getSharedPreferences(fileToItemValueList.key, Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
.apply {
|
||||
fileToItemValueList.value.forEach { itemToValue ->
|
||||
putValue(itemToValue.first, itemToValue.second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles adding values to `SharedPreferences` regardless of type. This method is especially
|
||||
* helpful for updating `SharedPreferences` values for `List<<Item>Any>` that have multiple
|
||||
* types of Item values.
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun SharedPreferences.Editor.putValue(
|
||||
item: Item<*>,
|
||||
value: Any
|
||||
): SharedPreferences.Editor =
|
||||
when (value::class.java) {
|
||||
String::class.java -> putString(item.sharedPrefKey, value as String)
|
||||
Boolean::class.java,
|
||||
java.lang.Boolean::class.java -> putBoolean(item.sharedPrefKey, value as Boolean)
|
||||
Int::class.java,
|
||||
java.lang.Integer::class.java -> putInt(item.sharedPrefKey, value as Int)
|
||||
Float::class.java,
|
||||
java.lang.Float::class.java -> putFloat(item.sharedPrefKey, value as Float)
|
||||
Long::class.java,
|
||||
java.lang.Long::class.java -> putLong(item.sharedPrefKey, value as Long)
|
||||
Set::class.java -> putStringSet(item.sharedPrefKey, value as Set<String>)
|
||||
else ->
|
||||
throw IllegalArgumentException(
|
||||
"item type: " +
|
||||
"${item.defaultValue!!::class} is not compatible with sharedPref methods"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* After calling this method, the listener will be notified of any future updates to the
|
||||
* `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<*>) {
|
||||
items
|
||||
.map { it.sharedPrefFile }
|
||||
.distinct()
|
||||
.forEach {
|
||||
context
|
||||
.getSharedPreferences(it, Context.MODE_PRIVATE)
|
||||
.registerOnSharedPreferenceChangeListener(listener)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<*>) {
|
||||
// If a listener is not registered to a SharedPreference, unregistering it does nothing
|
||||
items
|
||||
.map { it.sharedPrefFile }
|
||||
.distinct()
|
||||
.forEach {
|
||||
context
|
||||
.getSharedPreferences(it, Context.MODE_PRIVATE)
|
||||
.unregisterOnSharedPreferenceChangeListener(listener)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if all the provided [Item] have values stored in their corresponding
|
||||
* `SharedPreferences` files.
|
||||
*/
|
||||
fun has(vararg items: Item<*>): Boolean {
|
||||
items
|
||||
.groupBy { it.sharedPrefFile }
|
||||
.forEach { (file, itemsSublist) ->
|
||||
val prefs: SharedPreferences =
|
||||
context.getSharedPreferences(file, Context.MODE_PRIVATE)
|
||||
if (!itemsSublist.none { !prefs.contains(it.sharedPrefKey) }) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously removes the [Item]'s value from its corresponding `SharedPreferences` file.
|
||||
*/
|
||||
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() }
|
||||
|
||||
/**
|
||||
* Creates `SharedPreferences.Editor` transactions for removing all the provided [Item] values
|
||||
* from their respective `SharedPreferences` files. These returned `Editors` can then be
|
||||
* committed or applied for synchronous or async behavior.
|
||||
*/
|
||||
private fun prepareToRemove(items: Array<out Item<*>>): List<SharedPreferences.Editor> =
|
||||
items
|
||||
.groupBy { it.sharedPrefFile }
|
||||
.map { (file, items) ->
|
||||
context.getSharedPreferences(file, Context.MODE_PRIVATE).edit().also { editor ->
|
||||
items.forEach { item -> editor.remove(item.sharedPrefKey) }
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField var INSTANCE = MainThreadInitializedObject { LauncherPrefs(it) }
|
||||
|
||||
@JvmStatic fun get(context: Context): LauncherPrefs = INSTANCE.get(context)
|
||||
|
||||
@JvmField val ICON_STATE = nonRestorableItem(LauncherAppState.KEY_ICON_STATE, "")
|
||||
@JvmField val THEMED_ICONS = backedUpItem(Themes.KEY_THEMED_ICONS, false)
|
||||
@JvmField val PROMISE_ICON_IDS = backedUpItem(InstallSessionHelper.PROMISE_ICON_IDS, "")
|
||||
@JvmField val WORK_EDU_STEP = backedUpItem(WorkProfileManager.KEY_WORK_EDU_STEP, 0)
|
||||
@JvmField val WORKSPACE_SIZE = backedUpItem(DeviceGridState.KEY_WORKSPACE_SIZE, "")
|
||||
@JvmField val HOTSEAT_COUNT = backedUpItem(DeviceGridState.KEY_HOTSEAT_COUNT, -1)
|
||||
@JvmField
|
||||
val DEVICE_TYPE =
|
||||
backedUpItem(DeviceGridState.KEY_DEVICE_TYPE, InvariantDeviceProfile.TYPE_PHONE)
|
||||
@JvmField val DB_FILE = backedUpItem(DeviceGridState.KEY_DB_FILE, "")
|
||||
@JvmField
|
||||
val RESTORE_DEVICE =
|
||||
backedUpItem(RestoreDbTask.RESTORED_DEVICE_TYPE, InvariantDeviceProfile.TYPE_PHONE)
|
||||
@JvmField val APP_WIDGET_IDS = backedUpItem(RestoreDbTask.APPWIDGET_IDS, "")
|
||||
@JvmField val OLD_APP_WIDGET_IDS = backedUpItem(RestoreDbTask.APPWIDGET_OLD_IDS, "")
|
||||
|
||||
@VisibleForTesting
|
||||
@JvmStatic
|
||||
fun <T> backedUpItem(sharedPrefKey: String, defaultValue: T): Item<T> =
|
||||
Item(sharedPrefKey, LauncherFiles.SHARED_PREFERENCES_KEY, defaultValue)
|
||||
|
||||
@VisibleForTesting
|
||||
@JvmStatic
|
||||
fun <T> nonRestorableItem(sharedPrefKey: String, defaultValue: T): Item<T> =
|
||||
Item(sharedPrefKey, LauncherFiles.DEVICE_PREFERENCES_KEY, defaultValue)
|
||||
|
||||
@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(
|
||||
LauncherFiles.SHARED_PREFERENCES_KEY,
|
||||
Context.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(
|
||||
LauncherFiles.DEVICE_PREFERENCES_KEY,
|
||||
Context.MODE_PRIVATE
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class Item<T>(val sharedPrefKey: String, val sharedPrefFile: String, val defaultValue: T) {
|
||||
fun to(value: T): Pair<Item<T>, T> = Pair(this, value)
|
||||
}
|
||||
|
||||
@@ -57,7 +57,6 @@ import com.android.launcher3.DragSource;
|
||||
import com.android.launcher3.DropTarget.DragObject;
|
||||
import com.android.launcher3.Insettable;
|
||||
import com.android.launcher3.InsettableFrameLayout;
|
||||
import com.android.launcher3.LauncherPrefs;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.allapps.search.DefaultSearchAdapterProvider;
|
||||
@@ -161,10 +160,8 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
|
||||
R.dimen.dynamic_grid_cell_border_spacing);
|
||||
mHeaderProtectionColor = Themes.getAttrColor(context, R.attr.allappsHeaderProtectionColor);
|
||||
|
||||
mWorkManager = new WorkProfileManager(
|
||||
mActivityContext.getSystemService(UserManager.class),
|
||||
this, LauncherPrefs.getPrefs(mActivityContext),
|
||||
mActivityContext.getStatsLogManager());
|
||||
mWorkManager = new WorkProfileManager(mActivityContext.getSystemService(UserManager.class),
|
||||
this, mActivityContext.getStatsLogManager());
|
||||
mAH = Arrays.asList(null, null, null);
|
||||
mNavBarScrimPaint = new Paint();
|
||||
mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor));
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.launcher3.allapps;
|
||||
|
||||
import static com.android.launcher3.LauncherPrefs.WORK_EDU_STEP;
|
||||
import static com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.getTabWidth;
|
||||
|
||||
import android.content.Context;
|
||||
@@ -85,8 +86,7 @@ public class WorkEduCard extends FrameLayout implements
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
startAnimation(mDismissAnim);
|
||||
LauncherPrefs.getPrefs(getContext()).edit().putInt(WorkProfileManager.KEY_WORK_EDU_STEP,
|
||||
1).apply();
|
||||
LauncherPrefs.get(getContext()).put(WORK_EDU_STEP, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.launcher3.allapps;
|
||||
|
||||
import static com.android.launcher3.LauncherPrefs.WORK_EDU_STEP;
|
||||
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_DISABLED_CARD;
|
||||
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_EDU_CARD;
|
||||
import static com.android.launcher3.allapps.BaseAllAppsContainerView.AdapterHolder.MAIN;
|
||||
@@ -26,7 +27,6 @@ import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_
|
||||
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
@@ -40,6 +40,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.launcher3.LauncherPrefs;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
|
||||
@@ -86,14 +87,12 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP
|
||||
|
||||
@WorkProfileState
|
||||
private int mCurrentState;
|
||||
private SharedPreferences mPreferences;
|
||||
|
||||
public WorkProfileManager(
|
||||
UserManager userManager, BaseAllAppsContainerView<?> allApps, SharedPreferences prefs,
|
||||
UserManager userManager, BaseAllAppsContainerView<?> allApps,
|
||||
StatsLogManager statsLogManager) {
|
||||
mUserManager = userManager;
|
||||
mAllApps = allApps;
|
||||
mPreferences = prefs;
|
||||
mMatcher = mAllApps.mPersonalMatcher.negate();
|
||||
mStatsLogManager = statsLogManager;
|
||||
}
|
||||
@@ -225,7 +224,7 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP
|
||||
}
|
||||
|
||||
private boolean isEduSeen() {
|
||||
return mPreferences.getInt(KEY_WORK_EDU_STEP, 0) != 0;
|
||||
return LauncherPrefs.get(mAllApps.getContext()).get(WORK_EDU_STEP) != 0;
|
||||
}
|
||||
|
||||
private void onWorkFabClicked(View view) {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package com.android.launcher3.graphics;
|
||||
|
||||
import static com.android.launcher3.LauncherPrefs.getPrefs;
|
||||
import static com.android.launcher3.LauncherPrefs.THEMED_ICONS;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
import static com.android.launcher3.util.Themes.KEY_THEMED_ICONS;
|
||||
import static com.android.launcher3.util.Themes.isThemedIconEnabled;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
@@ -25,6 +24,7 @@ import android.util.Log;
|
||||
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.InvariantDeviceProfile.GridOption;
|
||||
import com.android.launcher3.LauncherPrefs;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.Executors;
|
||||
|
||||
@@ -142,9 +142,8 @@ public class GridCustomizationsProvider extends ContentProvider {
|
||||
}
|
||||
case ICON_THEMED:
|
||||
case SET_ICON_THEMED: {
|
||||
getPrefs(getContext()).edit()
|
||||
.putBoolean(KEY_THEMED_ICONS, values.getAsBoolean(BOOLEAN_VALUE))
|
||||
.apply();
|
||||
LauncherPrefs.get(getContext())
|
||||
.put(THEMED_ICONS, values.getAsBoolean(BOOLEAN_VALUE));
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -17,7 +17,10 @@
|
||||
package com.android.launcher3.model;
|
||||
|
||||
import static com.android.launcher3.InvariantDeviceProfile.DeviceType;
|
||||
import static com.android.launcher3.InvariantDeviceProfile.TYPE_PHONE;
|
||||
import static com.android.launcher3.LauncherPrefs.DB_FILE;
|
||||
import static com.android.launcher3.LauncherPrefs.DEVICE_TYPE;
|
||||
import static com.android.launcher3.LauncherPrefs.HOTSEAT_COUNT;
|
||||
import static com.android.launcher3.LauncherPrefs.WORKSPACE_SIZE;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_2;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_3;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_4;
|
||||
@@ -25,7 +28,6 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_6;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
@@ -58,11 +60,11 @@ public class DeviceGridState implements Comparable<DeviceGridState> {
|
||||
}
|
||||
|
||||
public DeviceGridState(Context context) {
|
||||
SharedPreferences prefs = LauncherPrefs.getPrefs(context);
|
||||
mGridSizeString = prefs.getString(KEY_WORKSPACE_SIZE, "");
|
||||
mNumHotseat = prefs.getInt(KEY_HOTSEAT_COUNT, -1);
|
||||
mDeviceType = prefs.getInt(KEY_DEVICE_TYPE, TYPE_PHONE);
|
||||
mDbFile = prefs.getString(KEY_DB_FILE, "");
|
||||
LauncherPrefs lp = LauncherPrefs.get(context);
|
||||
mGridSizeString = lp.get(WORKSPACE_SIZE);
|
||||
mNumHotseat = lp.get(HOTSEAT_COUNT);
|
||||
mDeviceType = lp.get(DEVICE_TYPE);
|
||||
mDbFile = lp.get(DB_FILE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,12 +92,11 @@ public class DeviceGridState implements Comparable<DeviceGridState> {
|
||||
* Stores the device state to shared preferences
|
||||
*/
|
||||
public void writeToPrefs(Context context) {
|
||||
LauncherPrefs.getPrefs(context).edit()
|
||||
.putString(KEY_WORKSPACE_SIZE, mGridSizeString)
|
||||
.putInt(KEY_HOTSEAT_COUNT, mNumHotseat)
|
||||
.putInt(KEY_DEVICE_TYPE, mDeviceType)
|
||||
.putString(KEY_DB_FILE, mDbFile)
|
||||
.apply();
|
||||
LauncherPrefs.get(context).put(
|
||||
WORKSPACE_SIZE.to(mGridSizeString),
|
||||
HOTSEAT_COUNT.to(mNumHotseat),
|
||||
DEVICE_TYPE.to(mDeviceType),
|
||||
DB_FILE.to(mDbFile));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package com.android.launcher3.pm;
|
||||
|
||||
import static com.android.launcher3.LauncherPrefs.getPrefs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.LauncherApps;
|
||||
@@ -34,6 +32,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.launcher3.LauncherPrefs;
|
||||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.SessionCommitReceiver;
|
||||
import com.android.launcher3.Utilities;
|
||||
@@ -65,7 +64,7 @@ public class InstallSessionHelper {
|
||||
// Set<String> of session ids of promise icons that have been added to the home screen
|
||||
// as FLAG_PROMISE_NEW_INSTALLS.
|
||||
@NonNull
|
||||
protected static final String PROMISE_ICON_IDS = "promise_icon_ids";
|
||||
public static final String PROMISE_ICON_IDS = "promise_icon_ids";
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
@@ -102,7 +101,7 @@ public class InstallSessionHelper {
|
||||
return mPromiseIconIds;
|
||||
}
|
||||
mPromiseIconIds = IntSet.wrap(IntArray.fromConcatString(
|
||||
getPrefs(mAppContext).getString(PROMISE_ICON_IDS, "")));
|
||||
LauncherPrefs.get(mAppContext).get(LauncherPrefs.PROMISE_ICON_IDS)));
|
||||
|
||||
IntArray existingIds = new IntArray();
|
||||
for (SessionInfo info : getActiveSessions().values()) {
|
||||
@@ -146,9 +145,8 @@ public class InstallSessionHelper {
|
||||
}
|
||||
|
||||
private void updatePromiseIconPrefs() {
|
||||
getPrefs(mAppContext).edit()
|
||||
.putString(PROMISE_ICON_IDS, getPromiseIconIds().getArray().toConcatString())
|
||||
.apply();
|
||||
LauncherPrefs.get(mAppContext).put(LauncherPrefs.PROMISE_ICON_IDS,
|
||||
getPromiseIconIds().getArray().toConcatString());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -17,13 +17,14 @@
|
||||
package com.android.launcher3.provider;
|
||||
|
||||
import static com.android.launcher3.InvariantDeviceProfile.TYPE_MULTI_DISPLAY;
|
||||
import static com.android.launcher3.InvariantDeviceProfile.TYPE_PHONE;
|
||||
import static com.android.launcher3.LauncherPrefs.APP_WIDGET_IDS;
|
||||
import static com.android.launcher3.LauncherPrefs.OLD_APP_WIDGET_IDS;
|
||||
import static com.android.launcher3.LauncherPrefs.RESTORE_DEVICE;
|
||||
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
|
||||
|
||||
import android.app.backup.BackupManager;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.UserHandle;
|
||||
@@ -62,13 +63,13 @@ import java.util.Arrays;
|
||||
public class RestoreDbTask {
|
||||
|
||||
private static final String TAG = "RestoreDbTask";
|
||||
private static final String RESTORED_DEVICE_TYPE = "restored_task_pending";
|
||||
public static final String RESTORED_DEVICE_TYPE = "restored_task_pending";
|
||||
|
||||
private static final String INFO_COLUMN_NAME = "name";
|
||||
private static final String INFO_COLUMN_DEFAULT_VALUE = "dflt_value";
|
||||
|
||||
private static final String APPWIDGET_OLD_IDS = "appwidget_old_ids";
|
||||
private static final String APPWIDGET_IDS = "appwidget_ids";
|
||||
public static final String APPWIDGET_OLD_IDS = "appwidget_old_ids";
|
||||
public static final String APPWIDGET_IDS = "appwidget_ids";
|
||||
|
||||
/**
|
||||
* Tries to restore the backup DB if needed
|
||||
@@ -87,7 +88,7 @@ public class RestoreDbTask {
|
||||
|
||||
// Set is pending to false irrespective of the result, so that it doesn't get
|
||||
// executed again.
|
||||
LauncherPrefs.getPrefs(context).edit().remove(RESTORED_DEVICE_TYPE).commit();
|
||||
LauncherPrefs.get(context).removeSync(RESTORE_DEVICE);
|
||||
|
||||
idp.reinitializeAfterRestore(context);
|
||||
}
|
||||
@@ -240,8 +241,7 @@ public class RestoreDbTask {
|
||||
}
|
||||
|
||||
// If restored from a single display backup, remove gaps between screenIds
|
||||
if (LauncherPrefs.getPrefs(context).getInt(RESTORED_DEVICE_TYPE, TYPE_PHONE)
|
||||
!= TYPE_MULTI_DISPLAY) {
|
||||
if (LauncherPrefs.get(context).get(RESTORE_DEVICE) != TYPE_MULTI_DISPLAY) {
|
||||
removeScreenIdGaps(db);
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ public class RestoreDbTask {
|
||||
}
|
||||
|
||||
public static boolean isPending(Context context) {
|
||||
return LauncherPrefs.getPrefs(context).contains(RESTORED_DEVICE_TYPE);
|
||||
return LauncherPrefs.get(context).has(RESTORE_DEVICE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -347,34 +347,31 @@ public class RestoreDbTask {
|
||||
*/
|
||||
public static void setPending(Context context) {
|
||||
FileLog.d(TAG, "Restore data received through full backup ");
|
||||
LauncherPrefs.getPrefs(context).edit()
|
||||
.putInt(RESTORED_DEVICE_TYPE, new DeviceGridState(context).getDeviceType())
|
||||
.commit();
|
||||
LauncherPrefs.get(context)
|
||||
.putSync(RESTORE_DEVICE.to(new DeviceGridState(context).getDeviceType()));
|
||||
}
|
||||
|
||||
private void restoreAppWidgetIdsIfExists(Context context) {
|
||||
SharedPreferences prefs = LauncherPrefs.getPrefs(context);
|
||||
if (prefs.contains(APPWIDGET_OLD_IDS) && prefs.contains(APPWIDGET_IDS)) {
|
||||
LauncherPrefs lp = LauncherPrefs.get(context);
|
||||
if (lp.has(APP_WIDGET_IDS, OLD_APP_WIDGET_IDS)) {
|
||||
LauncherWidgetHolder holder = LauncherWidgetHolder.newInstance(context);
|
||||
AppWidgetsRestoredReceiver.restoreAppWidgetIds(context,
|
||||
IntArray.fromConcatString(prefs.getString(APPWIDGET_OLD_IDS, "")).toArray(),
|
||||
IntArray.fromConcatString(prefs.getString(APPWIDGET_IDS, "")).toArray(),
|
||||
IntArray.fromConcatString(lp.get(OLD_APP_WIDGET_IDS)).toArray(),
|
||||
IntArray.fromConcatString(lp.get(APP_WIDGET_IDS)).toArray(),
|
||||
holder);
|
||||
holder.destroy();
|
||||
} else {
|
||||
FileLog.d(TAG, "No app widget ids to restore.");
|
||||
}
|
||||
|
||||
prefs.edit().remove(APPWIDGET_OLD_IDS)
|
||||
.remove(APPWIDGET_IDS).apply();
|
||||
lp.remove(APP_WIDGET_IDS, OLD_APP_WIDGET_IDS);
|
||||
}
|
||||
|
||||
public static void setRestoredAppWidgetIds(Context context, @NonNull int[] oldIds,
|
||||
@NonNull int[] newIds) {
|
||||
LauncherPrefs.getPrefs(context).edit()
|
||||
.putString(APPWIDGET_OLD_IDS, IntArray.wrap(oldIds).toConcatString())
|
||||
.putString(APPWIDGET_IDS, IntArray.wrap(newIds).toConcatString())
|
||||
.commit();
|
||||
LauncherPrefs.get(context).putSync(
|
||||
OLD_APP_WIDGET_IDS.to(IntArray.wrap(oldIds).toConcatString()),
|
||||
APP_WIDGET_IDS.to(IntArray.wrap(newIds).toConcatString()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.android.launcher3.util;
|
||||
import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_TEXT;
|
||||
import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_THEME;
|
||||
|
||||
import static com.android.launcher3.LauncherPrefs.THEMED_ICONS;
|
||||
|
||||
import android.app.WallpaperColors;
|
||||
import android.app.WallpaperManager;
|
||||
import android.content.Context;
|
||||
@@ -74,7 +76,7 @@ public class Themes {
|
||||
* Returns true if workspace icon theming is enabled
|
||||
*/
|
||||
public static boolean isThemedIconEnabled(Context context) {
|
||||
return LauncherPrefs.getPrefs(context).getBoolean(KEY_THEMED_ICONS, false);
|
||||
return LauncherPrefs.get(context).get(THEMED_ICONS);
|
||||
}
|
||||
|
||||
public static String getDefaultBodyFont(Context context) {
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
package com.android.launcher3
|
||||
|
||||
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.google.common.truth.Truth.assertThat
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.TimeUnit
|
||||
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)
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class LauncherPrefsTest {
|
||||
|
||||
private val launcherPrefs by lazy {
|
||||
LauncherPrefs.get(InstrumentationRegistry.getInstrumentation().targetContext).apply {
|
||||
remove(TEST_BOOLEAN_ITEM, TEST_STRING_ITEM, TEST_INT_ITEM)
|
||||
}
|
||||
}
|
||||
|
||||
@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(2, 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(2, 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(2, 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(2, 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,8 @@ import android.os.Process
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.launcher3.InvariantDeviceProfile
|
||||
import com.android.launcher3.LauncherFiles
|
||||
import com.android.launcher3.LauncherPrefs
|
||||
import com.android.launcher3.LauncherPrefs.Companion.WORKSPACE_SIZE
|
||||
import com.android.launcher3.LauncherSettings.Favorites.*
|
||||
import com.android.launcher3.config.FeatureFlags
|
||||
import com.android.launcher3.model.GridSizeMigrationUtil.DbReader
|
||||
@@ -754,11 +755,7 @@ class GridSizeMigrationUtilTest {
|
||||
.edit()
|
||||
.putBoolean(FeatureFlags.ENABLE_NEW_MIGRATION_LOGIC.key, true)
|
||||
.commit()
|
||||
context
|
||||
.getSharedPreferences(LauncherFiles.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
.putString(DeviceGridState.KEY_WORKSPACE_SIZE, srcGridSize)
|
||||
.commit()
|
||||
LauncherPrefs.get(context).putSync(WORKSPACE_SIZE.to(srcGridSize))
|
||||
FeatureFlags.initialize(context)
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherModel;
|
||||
import com.android.launcher3.LauncherModel.ModelUpdateTask;
|
||||
import com.android.launcher3.LauncherPrefs;
|
||||
import com.android.launcher3.LauncherProvider;
|
||||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.model.AllAppsList;
|
||||
@@ -506,7 +507,7 @@ public class LauncherModelHelper {
|
||||
|
||||
SanboxModelContext() {
|
||||
super(ApplicationProvider.getApplicationContext(),
|
||||
UserCache.INSTANCE, InstallSessionHelper.INSTANCE,
|
||||
UserCache.INSTANCE, InstallSessionHelper.INSTANCE, LauncherPrefs.INSTANCE,
|
||||
LauncherAppState.INSTANCE, InvariantDeviceProfile.INSTANCE,
|
||||
DisplayController.INSTANCE, CustomWidgetManager.INSTANCE,
|
||||
SettingsCache.INSTANCE, PluginManagerWrapper.INSTANCE,
|
||||
|
||||
Reference in New Issue
Block a user