diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java index d84633d563..36d1c3eccc 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java +++ b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java @@ -36,12 +36,16 @@ import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Handler; +import android.os.LocaleList; import android.os.Looper; import android.os.Process; import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.BitmapRenderer; @@ -57,8 +61,6 @@ import java.util.Map; import java.util.Set; import java.util.function.Supplier; -import androidx.annotation.NonNull; - public abstract class BaseIconCache { private static final String TAG = "BaseIconCache"; @@ -84,6 +86,7 @@ public abstract class BaseIconCache { protected int mIconDpi; protected IconDB mIconDb; + protected LocaleList mLocaleList = LocaleList.getEmptyLocaleList(); protected String mSystemState = ""; private final String mDbFileName; @@ -227,12 +230,12 @@ public abstract class BaseIconCache { /** * Refreshes the system state definition used to check the validity of the cache. It - * incorporates all the properties that can affect the cache like locale and system-version. + * incorporates all the properties that can affect the cache like the list of enabled locale + * and system-version. */ private void updateSystemState() { - final String locale = - mContext.getResources().getConfiguration().getLocales().toLanguageTags(); - mSystemState = locale + "," + Build.VERSION.SDK_INT; + mLocaleList = mContext.getResources().getConfiguration().getLocales(); + mSystemState = mLocaleList.toLanguageTags() + "," + Build.VERSION.SDK_INT; } protected String getIconSystemState(String packageName) { @@ -269,7 +272,7 @@ public abstract class BaseIconCache { mCache.put(key, entry); ContentValues values = newContentValues(entry, entry.title.toString(), - componentName.getPackageName()); + componentName.getPackageName(), cachingLogic.getKeywords(object, mLocaleList)); addIconToDB(values, componentName, info, userSerial); } @@ -445,7 +448,7 @@ public abstract class BaseIconCache { // Add the icon in the DB here, since these do not get written during // package updates. ContentValues values = newContentValues( - iconInfo, entry.title.toString(), packageName); + iconInfo, entry.title.toString(), packageName, null); addIconToDB(values, cacheKey.componentName, info, getSerialNumberForUser(user)); } catch (NameNotFoundException e) { @@ -504,23 +507,35 @@ public abstract class BaseIconCache { return false; } - static final class IconDB extends SQLiteCacheHelper { - private final static int RELEASE_VERSION = 26; + /** + * Returns a cursor for an arbitrary query to the cache db + */ + public synchronized Cursor queryCacheDb(String[] columns, String selection, + String[] selectionArgs) { + return mIconDb.query(columns, selection, selectionArgs); + } - public final static String TABLE_NAME = "icons"; - public final static String COLUMN_ROWID = "rowid"; - public final static String COLUMN_COMPONENT = "componentName"; - public final static String COLUMN_USER = "profileId"; - public final static String COLUMN_LAST_UPDATED = "lastUpdated"; - public final static String COLUMN_VERSION = "version"; - public final static String COLUMN_ICON = "icon"; - public final static String COLUMN_ICON_COLOR = "icon_color"; - public final static String COLUMN_LABEL = "label"; - public final static String COLUMN_SYSTEM_STATE = "system_state"; + /** + * Cache class to store the actual entries on disk + */ + public static final class IconDB extends SQLiteCacheHelper { + private static final int RELEASE_VERSION = 27; - public final static String[] COLUMNS_HIGH_RES = new String[] { + public static final String TABLE_NAME = "icons"; + public static final String COLUMN_ROWID = "rowid"; + public static final String COLUMN_COMPONENT = "componentName"; + public static final String COLUMN_USER = "profileId"; + public static final String COLUMN_LAST_UPDATED = "lastUpdated"; + public static final String COLUMN_VERSION = "version"; + public static final String COLUMN_ICON = "icon"; + public static final String COLUMN_ICON_COLOR = "icon_color"; + public static final String COLUMN_LABEL = "label"; + public static final String COLUMN_SYSTEM_STATE = "system_state"; + public static final String COLUMN_KEYWORDS = "keywords"; + + public static final String[] COLUMNS_HIGH_RES = new String[] { IconDB.COLUMN_ICON_COLOR, IconDB.COLUMN_LABEL, IconDB.COLUMN_ICON }; - public final static String[] COLUMNS_LOW_RES = new String[] { + public static final String[] COLUMNS_LOW_RES = new String[] { IconDB.COLUMN_ICON_COLOR, IconDB.COLUMN_LABEL }; public IconDB(Context context, String dbFileName, int iconPixelSize) { @@ -529,21 +544,23 @@ public abstract class BaseIconCache { @Override protected void onCreateTable(SQLiteDatabase db) { - db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" + - COLUMN_COMPONENT + " TEXT NOT NULL, " + - COLUMN_USER + " INTEGER NOT NULL, " + - COLUMN_LAST_UPDATED + " INTEGER NOT NULL DEFAULT 0, " + - COLUMN_VERSION + " INTEGER NOT NULL DEFAULT 0, " + - COLUMN_ICON + " BLOB, " + - COLUMN_ICON_COLOR + " INTEGER NOT NULL DEFAULT 0, " + - COLUMN_LABEL + " TEXT, " + - COLUMN_SYSTEM_STATE + " TEXT, " + - "PRIMARY KEY (" + COLUMN_COMPONENT + ", " + COLUMN_USER + ") " + - ");"); + db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" + + COLUMN_COMPONENT + " TEXT NOT NULL, " + + COLUMN_USER + " INTEGER NOT NULL, " + + COLUMN_LAST_UPDATED + " INTEGER NOT NULL DEFAULT 0, " + + COLUMN_VERSION + " INTEGER NOT NULL DEFAULT 0, " + + COLUMN_ICON + " BLOB, " + + COLUMN_ICON_COLOR + " INTEGER NOT NULL DEFAULT 0, " + + COLUMN_LABEL + " TEXT, " + + COLUMN_SYSTEM_STATE + " TEXT, " + + COLUMN_KEYWORDS + " TEXT, " + + "PRIMARY KEY (" + COLUMN_COMPONENT + ", " + COLUMN_USER + ") " + + ");"); } } - private ContentValues newContentValues(BitmapInfo bitmapInfo, String label, String packageName) { + private ContentValues newContentValues(BitmapInfo bitmapInfo, String label, + String packageName, @Nullable String keywords) { ContentValues values = new ContentValues(); values.put(IconDB.COLUMN_ICON, bitmapInfo.isLowRes() ? null : GraphicsUtils.flattenBitmap(bitmapInfo.icon)); @@ -551,7 +568,7 @@ public abstract class BaseIconCache { values.put(IconDB.COLUMN_LABEL, label); values.put(IconDB.COLUMN_SYSTEM_STATE, getIconSystemState(packageName)); - + values.put(IconDB.COLUMN_KEYWORDS, keywords); return values; } diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java b/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java index addb51fa78..09f59b84c2 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java +++ b/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java @@ -17,8 +17,11 @@ package com.android.launcher3.icons.cache; import android.content.ComponentName; import android.content.Context; +import android.os.LocaleList; import android.os.UserHandle; +import androidx.annotation.Nullable; + import com.android.launcher3.icons.BitmapInfo; public interface CachingLogic { @@ -30,4 +33,12 @@ public interface CachingLogic { CharSequence getLabel(T object); void loadIcon(Context context, T object, BitmapInfo target); + + /** + * Provides a option list of keywords to associate with this object + */ + @Nullable + default String getKeywords(T object, LocaleList localeList) { + return null; + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java index b90f6c2b17..17457aace6 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java @@ -16,6 +16,8 @@ package com.android.quickstep; +import static com.android.launcher3.util.MainThreadInitializedObject.forOverride; + import android.graphics.Matrix; import android.view.View; @@ -47,8 +49,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride { }; public static final MainThreadInitializedObject INSTANCE = - new MainThreadInitializedObject<>(c -> Overrides.getObject(TaskOverlayFactory.class, - c, R.string.task_overlay_factory_class)); + forOverride(TaskOverlayFactory.class, R.string.task_overlay_factory_class); public List getEnabledShortcuts(TaskView taskView) { final ArrayList shortcuts = new ArrayList<>(); diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java index 9f12484589..dfab43459d 100644 --- a/quickstep/src/com/android/quickstep/RecentsModel.java +++ b/quickstep/src/com/android/quickstep/RecentsModel.java @@ -16,15 +16,12 @@ package com.android.quickstep; import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId; -import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SUPPORTS_WINDOW_CORNERS; -import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_WINDOW_CORNER_RADIUS; import android.annotation.TargetApi; import android.app.ActivityManager; import android.content.ComponentCallbacks2; import android.content.Context; import android.os.Build; -import android.os.Bundle; import android.os.HandlerThread; import android.os.Process; import android.os.RemoteException; @@ -35,7 +32,6 @@ import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.TaskStackChangeListener; import java.util.ArrayList; @@ -52,7 +48,7 @@ public class RecentsModel extends TaskStackChangeListener { // We do not need any synchronization for this variable as its only written on UI thread. public static final MainThreadInitializedObject INSTANCE = - new MainThreadInitializedObject<>(c -> new RecentsModel(c)); + new MainThreadInitializedObject<>(RecentsModel::new); private final List mThumbnailChangeListeners = new ArrayList<>(); private final Context mContext; diff --git a/res/values/config.xml b/res/values/config.xml index 638a411be6..038718473b 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -72,6 +72,7 @@ + diff --git a/src/com/android/launcher3/IconProvider.java b/src/com/android/launcher3/IconProvider.java index e1ef9548cd..0f006f7c19 100644 --- a/src/com/android/launcher3/IconProvider.java +++ b/src/com/android/launcher3/IconProvider.java @@ -1,16 +1,17 @@ package com.android.launcher3; -import android.content.Context; +import static com.android.launcher3.util.MainThreadInitializedObject.forOverride; + import android.content.pm.LauncherActivityInfo; import android.graphics.drawable.Drawable; +import com.android.launcher3.util.MainThreadInitializedObject; import com.android.launcher3.util.ResourceBasedOverride; public class IconProvider implements ResourceBasedOverride { - public static IconProvider newInstance(Context context) { - return Overrides.getObject(IconProvider.class, context, R.string.icon_provider_class); - } + public static MainThreadInitializedObject INSTANCE = + forOverride(IconProvider.class, R.string.icon_provider_class); public IconProvider() { } diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java index d07638a5c1..2a801d6ef8 100644 --- a/src/com/android/launcher3/LauncherAppState.java +++ b/src/com/android/launcher3/LauncherAppState.java @@ -19,14 +19,12 @@ package com.android.launcher3; import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS; import static com.android.launcher3.util.SecureSettingsObserver.newNotificationSettingsObserver; -import android.app.KeyguardManager; import android.content.ComponentName; import android.content.ContentProviderClient; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Handler; -import android.os.Process; import android.util.Log; import com.android.launcher3.compat.LauncherAppsCompat; @@ -46,7 +44,7 @@ public class LauncherAppState { // We do not need any synchronization for this variable as its only written on UI thread. private static final MainThreadInitializedObject INSTANCE = - new MainThreadInitializedObject<>((c) -> new LauncherAppState(c)); + new MainThreadInitializedObject<>(LauncherAppState::new); private final Context mContext; private final LauncherModel mModel; diff --git a/src/com/android/launcher3/graphics/DrawableFactory.java b/src/com/android/launcher3/graphics/DrawableFactory.java index c9566cb145..288749fa7e 100644 --- a/src/com/android/launcher3/graphics/DrawableFactory.java +++ b/src/com/android/launcher3/graphics/DrawableFactory.java @@ -17,6 +17,7 @@ package com.android.launcher3.graphics; import static com.android.launcher3.graphics.IconShape.getShapePath; +import static com.android.launcher3.util.MainThreadInitializedObject.forOverride; import android.content.Context; import android.content.pm.ActivityInfo; @@ -31,6 +32,8 @@ import android.os.Process; import android.os.UserHandle; import android.util.ArrayMap; +import androidx.annotation.UiThread; + import com.android.launcher3.FastBitmapDrawable; import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.R; @@ -38,16 +41,13 @@ import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.util.MainThreadInitializedObject; import com.android.launcher3.util.ResourceBasedOverride; -import androidx.annotation.UiThread; - /** * Factory for creating new drawables. */ public class DrawableFactory implements ResourceBasedOverride { public static final MainThreadInitializedObject INSTANCE = - new MainThreadInitializedObject<>(c -> Overrides.getObject(DrawableFactory.class, - c.getApplicationContext(), R.string.drawable_factory_class)); + forOverride(DrawableFactory.class, R.string.drawable_factory_class); protected final UserHandle mMyUser = Process.myUserHandle(); protected final ArrayMap mUserBadges = new ArrayMap<>(); diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java index 648445e40c..55d58b9c09 100644 --- a/src/com/android/launcher3/icons/IconCache.java +++ b/src/com/android/launcher3/icons/IconCache.java @@ -29,6 +29,8 @@ import android.os.Process; import android.os.UserHandle; import android.util.Log; +import androidx.annotation.NonNull; + import com.android.launcher3.AppInfo; import com.android.launcher3.IconProvider; import com.android.launcher3.InvariantDeviceProfile; @@ -36,8 +38,8 @@ import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.LauncherFiles; import com.android.launcher3.LauncherModel; import com.android.launcher3.MainThreadExecutor; -import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.Utilities; +import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic; @@ -50,8 +52,6 @@ import com.android.launcher3.util.Preconditions; import java.util.function.Supplier; -import androidx.annotation.NonNull; - /** * Cache of application icons. Icons can be made from any thread. */ @@ -75,11 +75,11 @@ public class IconCache extends BaseIconCache { super(context, LauncherFiles.APP_ICONS_DB, LauncherModel.getWorkerLooper(), inv.fillResIconDpi, inv.iconBitmapSize, true /* inMemoryCache */); mComponentWithLabelCachingLogic = new ComponentCachingLogic(context); - mLauncherActivityInfoCachingLogic = new LauncherActivtiyCachingLogic(this); + mLauncherActivityInfoCachingLogic = LauncherActivityCachingLogic.newInstance(context); mLauncherApps = LauncherAppsCompat.getInstance(mContext); mUserManager = UserManagerCompat.getInstance(mContext); mInstantAppResolver = InstantAppResolver.newInstance(mContext); - mIconProvider = IconProvider.newInstance(context); + mIconProvider = IconProvider.INSTANCE.get(context); } @Override diff --git a/src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java similarity index 67% rename from src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java rename to src/com/android/launcher3/icons/LauncherActivityCachingLogic.java index 7c996339bd..f9a94daf53 100644 --- a/src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java +++ b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java @@ -20,14 +20,23 @@ import android.content.Context; import android.content.pm.LauncherActivityInfo; import android.os.UserHandle; +import com.android.launcher3.IconProvider; +import com.android.launcher3.R; import com.android.launcher3.icons.cache.CachingLogic; +import com.android.launcher3.util.ResourceBasedOverride; -public class LauncherActivtiyCachingLogic implements CachingLogic { +/** + * Caching logic for LauncherActivityInfo. + */ +public class LauncherActivityCachingLogic + implements CachingLogic, ResourceBasedOverride { - private final IconCache mCache; - - public LauncherActivtiyCachingLogic(IconCache cache) { - mCache = cache; + /** + * Creates and returns a new instance + */ + public static LauncherActivityCachingLogic newInstance(Context context) { + return Overrides.getObject(LauncherActivityCachingLogic.class, context, + R.string.launcher_activity_logic_class); } @Override @@ -49,8 +58,10 @@ public class LauncherActivtiyCachingLogic implements CachingLogic INSTANCE = - new MainThreadInitializedObject<>(c -> - getObject(AppLaunchTracker.class, c, R.string.app_launch_tracker_class)); + forOverride(AppLaunchTracker.class, R.string.app_launch_tracker_class); public void onStartShortcut(String packageName, String shortcutId, UserHandle user, @Nullable String container) { } diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java index 0138572d0c..4b01b5ed17 100644 --- a/src/com/android/launcher3/model/LoaderTask.java +++ b/src/com/android/launcher3/model/LoaderTask.java @@ -49,8 +49,8 @@ import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; -import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.Utilities; +import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.PackageInstallerCompat; @@ -61,7 +61,7 @@ import com.android.launcher3.folder.FolderIconPreviewVerifier; import com.android.launcher3.icons.ComponentWithLabel; import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic; import com.android.launcher3.icons.IconCache; -import com.android.launcher3.icons.LauncherActivtiyCachingLogic; +import com.android.launcher3.icons.LauncherActivityCachingLogic; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.icons.cache.IconCacheUpdateHandler; import com.android.launcher3.logging.FileLog; @@ -196,7 +196,7 @@ public class LoaderTask implements Runnable { IconCacheUpdateHandler updateHandler = mIconCache.getUpdateHandler(); setIgnorePackages(updateHandler); updateHandler.updateIcons(allActivityList, - new LauncherActivtiyCachingLogic(mApp.getIconCache()), + LauncherActivityCachingLogic.newInstance(mApp.getContext()), mApp.getModel()::onPackageIconsUpdated); // Take a break diff --git a/src/com/android/launcher3/popup/SystemShortcutFactory.java b/src/com/android/launcher3/popup/SystemShortcutFactory.java index 516fafad54..37a209289e 100644 --- a/src/com/android/launcher3/popup/SystemShortcutFactory.java +++ b/src/com/android/launcher3/popup/SystemShortcutFactory.java @@ -15,6 +15,10 @@ */ package com.android.launcher3.popup; +import static com.android.launcher3.util.MainThreadInitializedObject.forOverride; + +import androidx.annotation.NonNull; + import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; import com.android.launcher3.R; @@ -24,13 +28,10 @@ import com.android.launcher3.util.ResourceBasedOverride; import java.util.ArrayList; import java.util.List; -import androidx.annotation.NonNull; - public class SystemShortcutFactory implements ResourceBasedOverride { public static final MainThreadInitializedObject INSTANCE = - new MainThreadInitializedObject<>(c -> Overrides.getObject( - SystemShortcutFactory.class, c, R.string.system_shortcut_factory_class)); + forOverride(SystemShortcutFactory.class, R.string.system_shortcut_factory_class); /** Note that these are in order of priority. */ private final SystemShortcut[] mAllShortcuts; diff --git a/src/com/android/launcher3/util/MainThreadInitializedObject.java b/src/com/android/launcher3/util/MainThreadInitializedObject.java index 2ee0328597..e185a31990 100644 --- a/src/com/android/launcher3/util/MainThreadInitializedObject.java +++ b/src/com/android/launcher3/util/MainThreadInitializedObject.java @@ -18,12 +18,13 @@ package com.android.launcher3.util; import android.content.Context; import android.os.Looper; +import androidx.annotation.VisibleForTesting; + import com.android.launcher3.MainThreadExecutor; +import com.android.launcher3.util.ResourceBasedOverride.Overrides; import java.util.concurrent.ExecutionException; -import androidx.annotation.VisibleForTesting; - /** * Utility class for defining singletons which are initiated on main thread. */ @@ -60,6 +61,14 @@ public class MainThreadInitializedObject { mValue = value; } + /** + * Initializes a provider based on resource overrides + */ + public static MainThreadInitializedObject forOverride( + Class clazz, int resourceId) { + return new MainThreadInitializedObject<>(c -> Overrides.getObject(clazz, c, resourceId)); + } + public interface ObjectProvider { T get(Context context);