summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2018-08-20 15:01:03 -0700
committerSunny Goyal <sunnygoyal@google.com>2018-08-27 10:43:46 -0700
commit2b787e5bd6314b3b657b73e529e16cb52863bcbb (patch)
tree8d546393acb2c6bdf11206b8bb40f942909da80b
parent018e3c4447ad77344c378bf3cca4a6484fa45a9e (diff)
downloadandroid_packages_apps_Trebuchet-2b787e5bd6314b3b657b73e529e16cb52863bcbb.tar.gz
android_packages_apps_Trebuchet-2b787e5bd6314b3b657b73e529e16cb52863bcbb.tar.bz2
android_packages_apps_Trebuchet-2b787e5bd6314b3b657b73e529e16cb52863bcbb.zip
Using a placeholder icon shape instead of low-res/blurry icon
Bug: 111142970 Change-Id: I867224464ae9c026f4dcb5256ef14fc39c8e751d
-rw-r--r--quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java4
-rw-r--r--quickstep/src/com/android/quickstep/NormalizedIconLoader.java4
-rw-r--r--res/values/attrs.xml1
-rw-r--r--res/values/styles.xml2
-rw-r--r--src/com/android/launcher3/AllAppsList.java2
-rw-r--r--src/com/android/launcher3/BubbleTextView.java9
-rw-r--r--src/com/android/launcher3/IconCache.java100
-rw-r--r--src/com/android/launcher3/ItemInfoWithIcon.java15
-rw-r--r--src/com/android/launcher3/ShortcutInfo.java2
-rw-r--r--src/com/android/launcher3/allapps/AllAppsRecyclerView.java3
-rw-r--r--src/com/android/launcher3/graphics/BitmapInfo.java3
-rw-r--r--src/com/android/launcher3/graphics/DrawableFactory.java84
-rw-r--r--src/com/android/launcher3/graphics/PlaceHolderIconDrawable.java60
-rw-r--r--src/com/android/launcher3/model/CacheDataUpdatedTask.java2
-rw-r--r--src/com/android/launcher3/model/LoaderTask.java2
-rw-r--r--src/com/android/launcher3/model/PackageUpdatedTask.java2
-rw-r--r--src/com/android/launcher3/widget/PendingAppWidgetHostView.java14
-rw-r--r--src/com/android/launcher3/widget/WidgetCell.java4
18 files changed, 179 insertions, 134 deletions
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 37d0b12bd..5680a6709 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -427,8 +427,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
mFloatingView = new View(mLauncher);
if (isBubbleTextView && v.getTag() instanceof ItemInfoWithIcon ) {
// Create a copy of the app icon
- mFloatingView.setBackground(
- DrawableFactory.get(mLauncher).newIcon((ItemInfoWithIcon) v.getTag()));
+ mFloatingView.setBackground(DrawableFactory.INSTANCE.get(mLauncher)
+ .newIcon(v.getContext(), (ItemInfoWithIcon) v.getTag()));
}
// Position the floating view exactly on top of the original
diff --git a/quickstep/src/com/android/quickstep/NormalizedIconLoader.java b/quickstep/src/com/android/quickstep/NormalizedIconLoader.java
index a4a2e5690..8f7dbdd36 100644
--- a/quickstep/src/com/android/quickstep/NormalizedIconLoader.java
+++ b/quickstep/src/com/android/quickstep/NormalizedIconLoader.java
@@ -49,7 +49,7 @@ public class NormalizedIconLoader extends IconLoader {
LruCache<ComponentName, ActivityInfo> activityInfoCache,
boolean disableColorExtraction) {
super(context, iconCache, activityInfoCache);
- mDrawableFactory = DrawableFactory.get(context);
+ mDrawableFactory = DrawableFactory.INSTANCE.get(context);
mDisableColorExtraction = disableColorExtraction;
}
@@ -96,6 +96,6 @@ public class NormalizedIconLoader extends IconLoader {
userId,
desc.getPrimaryColor(),
activityInfo.applicationInfo.isInstantApp());
- return mDrawableFactory.newIcon(bitmapInfo, activityInfo);
+ return mDrawableFactory.newIcon(mContext, bitmapInfo, activityInfo);
}
}
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 045e4e98c..956270cba 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -34,6 +34,7 @@
<attr name="workspaceStatusBarScrim" format="reference" />
<attr name="widgetsTheme" format="reference" />
<attr name="folderBadgeColor" format="color" />
+ <attr name="loadingIconColor" format="color" />
<!-- BubbleTextView specific attributes. -->
<declare-styleable name="BubbleTextView">
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 7ea28ccf0..098aac562 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -43,6 +43,7 @@
<item name="workspaceStatusBarScrim">@drawable/workspace_bg</item>
<item name="widgetsTheme">@style/WidgetContainerTheme</item>
<item name="folderBadgeColor">?android:attr/colorPrimary</item>
+ <item name="loadingIconColor">#FFF</item>
</style>
<style name="LauncherTheme" parent="@style/BaseLauncherThemeWithCustomAttrs"></style>
@@ -73,6 +74,7 @@
<item name="widgetsTheme">@style/WidgetContainerTheme.Dark</item>
<item name="folderBadgeColor">#FF464646</item>
<item name="isMainColorDark">true</item>
+ <item name="loadingIconColor">#000</item>
</style>
<style name="LauncherTheme.Dark.DarkText" parent="@style/LauncherTheme.Dark">
diff --git a/src/com/android/launcher3/AllAppsList.java b/src/com/android/launcher3/AllAppsList.java
index 24826918f..45859ca07 100644
--- a/src/com/android/launcher3/AllAppsList.java
+++ b/src/com/android/launcher3/AllAppsList.java
@@ -92,7 +92,7 @@ public class AllAppsList {
// only if not yet installed
if (applicationInfo == null) {
PromiseAppInfo info = new PromiseAppInfo(installInfo);
- mIconCache.getTitleAndIcon(info, info.usingLowResIcon);
+ mIconCache.getTitleAndIcon(info, info.usingLowResIcon());
data.add(info);
added.add(info);
}
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 230ea4fea..5d401433b 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -256,7 +256,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
}
private void applyIconAndLabel(ItemInfoWithIcon info) {
- FastBitmapDrawable iconDrawable = DrawableFactory.get(getContext()).newIcon(info);
+ FastBitmapDrawable iconDrawable = DrawableFactory.INSTANCE.get(getContext())
+ .newIcon(getContext(), info);
mBadgeColor = IconPalette.getMutedColor(info.iconColor, 0.54f);
setIcon(iconDrawable);
@@ -527,8 +528,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
preloadDrawable = (PreloadIconDrawable) mIcon;
preloadDrawable.setLevel(progressLevel);
} else {
- preloadDrawable = DrawableFactory.get(getContext())
- .newPendingIcon(info, getContext());
+ preloadDrawable = DrawableFactory.INSTANCE.get(getContext())
+ .newPendingIcon(getContext(), info);
preloadDrawable.setLevel(progressLevel);
setIcon(preloadDrawable);
}
@@ -639,7 +640,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
}
if (getTag() instanceof ItemInfoWithIcon) {
ItemInfoWithIcon info = (ItemInfoWithIcon) getTag();
- if (info.usingLowResIcon) {
+ if (info.usingLowResIcon()) {
mIconLoadRequest = LauncherAppState.getInstance(getContext()).getIconCache()
.updateIconInBackground(BubbleTextView.this, info);
}
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index abd5538c6..61fb3e38b 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -16,6 +16,8 @@
package com.android.launcher3;
+import static com.android.launcher3.graphics.BitmapInfo.LOW_RES_ICON;
+
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
@@ -79,14 +81,15 @@ public class IconCache {
private static final boolean DEBUG = false;
private static final boolean DEBUG_IGNORE_CACHE = false;
- private static final int LOW_RES_SCALE_FACTOR = 5;
-
@Thunk static final Object ICON_UPDATE_TOKEN = new Object();
public static class CacheEntry extends BitmapInfo {
public CharSequence title = "";
public CharSequence contentDescription = "";
- public boolean isLowResIcon;
+
+ public boolean isLowRes() {
+ return LOW_RES_ICON == icon;
+ }
}
private final HashMap<UserHandle, BitmapInfo> mDefaultIcons = new HashMap<>();
@@ -105,8 +108,7 @@ public class IconCache {
@Thunk final Handler mWorkerHandler;
- private final BitmapFactory.Options mLowResOptions;
- private final BitmapFactory.Options mHighResOptions;
+ private final BitmapFactory.Options mDecodeOptions;
private int mPendingIconRequestCount = 0;
@@ -122,16 +124,11 @@ public class IconCache {
mIconProvider = IconProvider.newInstance(context);
mWorkerHandler = new Handler(LauncherModel.getWorkerLooper());
- mLowResOptions = new BitmapFactory.Options();
- // Always prefer RGB_565 config for low res. If the bitmap has transparency, it will
- // automatically be loaded as ALPHA_8888.
- mLowResOptions.inPreferredConfig = Bitmap.Config.RGB_565;
-
if (BitmapRenderer.USE_HARDWARE_BITMAP) {
- mHighResOptions = new BitmapFactory.Options();
- mHighResOptions.inPreferredConfig = Bitmap.Config.HARDWARE;
+ mDecodeOptions = new BitmapFactory.Options();
+ mDecodeOptions.inPreferredConfig = Bitmap.Config.HARDWARE;
} else {
- mHighResOptions = null;
+ mDecodeOptions = null;
}
}
@@ -374,7 +371,7 @@ public class IconCache {
if (!replaceExisting) {
entry = mCache.get(key);
// We can't reuse the entry if the high-res icon is not present.
- if (entry == null || entry.isLowResIcon || entry.icon == null) {
+ if (entry == null || entry.icon == null || entry.isLowRes()) {
entry = null;
}
}
@@ -389,8 +386,7 @@ public class IconCache {
entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, app.getUser());
mCache.put(key, entry);
- Bitmap lowResIcon = generateLowResIcon(entry.icon);
- ContentValues values = newContentValues(entry.icon, lowResIcon, entry.color,
+ ContentValues values = newContentValues(entry.icon, entry.color,
entry.title.toString(), app.getApplicationInfo().packageName);
addIconToDB(values, app.getComponentName(), info, userSerial);
}
@@ -451,7 +447,7 @@ public class IconCache {
public synchronized void updateTitleAndIcon(AppInfo application) {
CacheEntry entry = cacheLocked(application.componentName,
Provider.<LauncherActivityInfo>of(null),
- application.user, false, application.usingLowResIcon);
+ application.user, false, application.usingLowResIcon());
if (entry.icon != null && !isDefaultIcon(entry.icon, application.user)) {
applyCacheEntry(entry, application);
}
@@ -477,7 +473,6 @@ public class IconCache {
getDefaultIcon(info.user).applyTo(info);
info.title = "";
info.contentDescription = "";
- info.usingLowResIcon = false;
} else {
Intent intent = info.getIntent();
getTitleAndIcon(info, () -> mLauncherApps.resolveActivity(intent, info.user),
@@ -510,7 +505,6 @@ public class IconCache {
private void applyCacheEntry(CacheEntry entry, ItemInfoWithIcon info) {
info.title = Utilities.trim(entry.title);
info.contentDescription = entry.contentDescription;
- info.usingLowResIcon = entry.isLowResIcon;
((entry.icon == null) ? getDefaultIcon(info.user) : entry).applyTo(info);
}
@@ -536,7 +530,7 @@ public class IconCache {
Preconditions.assertWorkerThread();
ComponentKey cacheKey = new ComponentKey(componentName, user);
CacheEntry entry = mCache.get(cacheKey);
- if (entry == null || (entry.isLowResIcon && !useLowResIcon)) {
+ if (entry == null || (entry.isLowRes() && !useLowResIcon)) {
entry = new CacheEntry();
mCache.put(cacheKey, entry);
@@ -635,7 +629,7 @@ public class IconCache {
ComponentKey cacheKey = getPackageKey(packageName, user);
CacheEntry entry = mCache.get(cacheKey);
- if (entry == null || (entry.isLowResIcon && !useLowResIcon)) {
+ if (entry == null || (entry.isLowRes() && !useLowResIcon)) {
entry = new CacheEntry();
boolean entryUpdated = true;
@@ -658,16 +652,14 @@ public class IconCache {
mInstantAppResolver.isInstantApp(appInfo));
li.recycle();
- Bitmap lowResIcon = generateLowResIcon(iconInfo.icon);
entry.title = appInfo.loadLabel(mPackageManager);
entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);
- entry.icon = useLowResIcon ? lowResIcon : iconInfo.icon;
+ entry.icon = useLowResIcon ? LOW_RES_ICON : iconInfo.icon;
entry.color = iconInfo.color;
- entry.isLowResIcon = useLowResIcon;
// Add the icon in the DB here, since these do not get written during
// package updates.
- ContentValues values = newContentValues(iconInfo.icon, lowResIcon, entry.color,
+ ContentValues values = newContentValues(iconInfo.icon, entry.color,
entry.title.toString(), packageName);
addIconToDB(values, cacheKey.componentName, info,
mUserManager.getSerialNumberForUser(user));
@@ -690,17 +682,15 @@ public class IconCache {
Cursor c = null;
try {
c = mIconDb.query(
- new String[]{lowRes ? IconDB.COLUMN_ICON_LOW_RES : IconDB.COLUMN_ICON,
- IconDB.COLUMN_ICON_COLOR, IconDB.COLUMN_LABEL},
- IconDB.COLUMN_COMPONENT + " = ? AND " + IconDB.COLUMN_USER + " = ?",
- new String[]{cacheKey.componentName.flattenToString(),
- Long.toString(mUserManager.getSerialNumberForUser(cacheKey.user))});
+ lowRes ? IconDB.COLUMNS_LOW_RES : IconDB.COLUMNS_HIGH_RES,
+ IconDB.COLUMN_COMPONENT + " = ? AND " + IconDB.COLUMN_USER + " = ?",
+ new String[]{
+ cacheKey.componentName.flattenToString(),
+ Long.toString(mUserManager.getSerialNumberForUser(cacheKey.user))});
if (c.moveToNext()) {
- entry.icon = loadIconNoResize(c, 0, lowRes ? mLowResOptions : mHighResOptions);
// Set the alpha to be 255, so that we never have a wrong color
- entry.color = ColorUtils.setAlphaComponent(c.getInt(1), 255);
- entry.isLowResIcon = lowRes;
- entry.title = c.getString(2);
+ entry.color = ColorUtils.setAlphaComponent(c.getInt(0), 255);
+ entry.title = c.getString(1);
if (entry.title == null) {
entry.title = "";
entry.contentDescription = "";
@@ -708,6 +698,16 @@ public class IconCache {
entry.contentDescription = mUserManager.getBadgedLabelForUser(
entry.title, cacheKey.user);
}
+
+ if (lowRes) {
+ entry.icon = LOW_RES_ICON;
+ } else {
+ byte[] data = c.getBlob(2);
+ try {
+ entry.icon = BitmapFactory.decodeByteArray(data, 0, data.length,
+ mDecodeOptions);
+ } catch (Exception e) { }
+ }
return true;
}
} catch (SQLiteException e) {
@@ -803,7 +803,7 @@ public class IconCache {
}
private static final class IconDB extends SQLiteCacheHelper {
- private final static int RELEASE_VERSION = 24;
+ private final static int RELEASE_VERSION = 25;
private final static String TABLE_NAME = "icons";
private final static String COLUMN_ROWID = "rowid";
@@ -812,11 +812,15 @@ public class IconCache {
private final static String COLUMN_LAST_UPDATED = "lastUpdated";
private final static String COLUMN_VERSION = "version";
private final static String COLUMN_ICON = "icon";
- private final static String COLUMN_ICON_LOW_RES = "icon_low_res";
private final static String COLUMN_ICON_COLOR = "icon_color";
private final static String COLUMN_LABEL = "label";
private final static String COLUMN_SYSTEM_STATE = "system_state";
+ private final static String[] COLUMNS_HIGH_RES = new String[] {
+ IconDB.COLUMN_ICON_COLOR, IconDB.COLUMN_LABEL, IconDB.COLUMN_ICON };
+ private final static String[] COLUMNS_LOW_RES = new String[] {
+ IconDB.COLUMN_ICON_COLOR, IconDB.COLUMN_LABEL };
+
public IconDB(Context context, int iconPixelSize) {
super(context, LauncherFiles.APP_ICONS_DB,
(RELEASE_VERSION << 16) + iconPixelSize,
@@ -831,7 +835,6 @@ public class IconCache {
COLUMN_LAST_UPDATED + " INTEGER NOT NULL DEFAULT 0, " +
COLUMN_VERSION + " INTEGER NOT NULL DEFAULT 0, " +
COLUMN_ICON + " BLOB, " +
- COLUMN_ICON_LOW_RES + " BLOB, " +
COLUMN_ICON_COLOR + " INTEGER NOT NULL DEFAULT 0, " +
COLUMN_LABEL + " TEXT, " +
COLUMN_SYSTEM_STATE + " TEXT, " +
@@ -840,11 +843,10 @@ public class IconCache {
}
}
- private ContentValues newContentValues(Bitmap icon, Bitmap lowResIcon, int iconColor,
- String label, String packageName) {
+ private ContentValues newContentValues(Bitmap icon, int iconColor, String label,
+ String packageName) {
ContentValues values = new ContentValues();
values.put(IconDB.COLUMN_ICON, Utilities.flattenBitmap(icon));
- values.put(IconDB.COLUMN_ICON_LOW_RES, Utilities.flattenBitmap(lowResIcon));
values.put(IconDB.COLUMN_ICON_COLOR, iconColor);
values.put(IconDB.COLUMN_LABEL, label);
@@ -854,24 +856,6 @@ public class IconCache {
}
/**
- * Generates a new low-res icon given a high-res icon.
- */
- private Bitmap generateLowResIcon(Bitmap icon) {
- return Bitmap.createScaledBitmap(icon,
- icon.getWidth() / LOW_RES_SCALE_FACTOR,
- icon.getHeight() / LOW_RES_SCALE_FACTOR, true);
- }
-
- private static Bitmap loadIconNoResize(Cursor c, int iconIndex, BitmapFactory.Options options) {
- byte[] data = c.getBlob(iconIndex);
- try {
- return BitmapFactory.decodeByteArray(data, 0, data.length, options);
- } catch (Exception e) {
- return null;
- }
- }
-
- /**
* Interface for receiving itemInfo with high-res icon.
*/
public interface ItemInfoUpdateReceiver {
diff --git a/src/com/android/launcher3/ItemInfoWithIcon.java b/src/com/android/launcher3/ItemInfoWithIcon.java
index 4677d3181..2ceb0dd71 100644
--- a/src/com/android/launcher3/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/ItemInfoWithIcon.java
@@ -16,6 +16,8 @@
package com.android.launcher3;
+import static com.android.launcher3.graphics.BitmapInfo.LOW_RES_ICON;
+
import android.graphics.Bitmap;
/**
@@ -34,11 +36,6 @@ public abstract class ItemInfoWithIcon extends ItemInfo {
public int iconColor;
/**
- * Indicates whether we're using a low res icon
- */
- public boolean usingLowResIcon;
-
- /**
* Indicates that the icon is disabled due to safe mode restrictions.
*/
public static final int FLAG_DISABLED_SAFEMODE = 1 << 0;
@@ -107,7 +104,6 @@ public abstract class ItemInfoWithIcon extends ItemInfo {
super(info);
iconBitmap = info.iconBitmap;
iconColor = info.iconColor;
- usingLowResIcon = info.usingLowResIcon;
runtimeStatusFlags = info.runtimeStatusFlags;
}
@@ -115,4 +111,11 @@ public abstract class ItemInfoWithIcon extends ItemInfo {
public boolean isDisabled() {
return (runtimeStatusFlags & FLAG_DISABLED_MASK) != 0;
}
+
+ /**
+ * Indicates whether we're using a low res icon
+ */
+ public boolean usingLowResIcon() {
+ return iconBitmap == LOW_RES_ICON;
+ }
}
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 8588c7a92..a84bfd54e 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -125,7 +125,7 @@ public class ShortcutInfo extends ItemInfoWithIcon {
.put(LauncherSettings.BaseLauncherColumns.INTENT, getIntent())
.put(LauncherSettings.Favorites.RESTORED, status);
- if (!usingLowResIcon) {
+ if (!usingLowResIcon()) {
writer.putIcon(iconBitmap, user);
}
if (iconResource != null) {
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index adc4a72d1..fa07d4d75 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -152,8 +152,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine
if (mApps.hasNoFilteredResults()) {
if (mEmptySearchBackground == null) {
- mEmptySearchBackground = DrawableFactory.get(getContext())
- .getAllAppsBackground(getContext());
+ mEmptySearchBackground = new AllAppsBackgroundDrawable(getContext());
mEmptySearchBackground.setAlpha(0);
mEmptySearchBackground.setCallback(this);
updateEmptySearchBackgroundBounds();
diff --git a/src/com/android/launcher3/graphics/BitmapInfo.java b/src/com/android/launcher3/graphics/BitmapInfo.java
index c905a78e5..69c068412 100644
--- a/src/com/android/launcher3/graphics/BitmapInfo.java
+++ b/src/com/android/launcher3/graphics/BitmapInfo.java
@@ -16,11 +16,14 @@
package com.android.launcher3.graphics;
import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
import com.android.launcher3.ItemInfoWithIcon;
public class BitmapInfo {
+ public static final Bitmap LOW_RES_ICON = Bitmap.createBitmap(1, 1, Config.ALPHA_8);
+
public Bitmap icon;
public int color;
diff --git a/src/com/android/launcher3/graphics/DrawableFactory.java b/src/com/android/launcher3/graphics/DrawableFactory.java
index 5bc81e69a..8377adff8 100644
--- a/src/com/android/launcher3/graphics/DrawableFactory.java
+++ b/src/com/android/launcher3/graphics/DrawableFactory.java
@@ -16,6 +16,8 @@
package com.android.launcher3.graphics;
+import static com.android.launcher3.graphics.BitmapInfo.LOW_RES_ICON;
+
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
@@ -24,18 +26,18 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Path;
import android.graphics.Rect;
+import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Process;
import android.os.UserHandle;
import android.util.ArrayMap;
-import android.util.Log;
import com.android.launcher3.FastBitmapDrawable;
import com.android.launcher3.ItemInfoWithIcon;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.allapps.AllAppsBackgroundDrawable;
+import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.ResourceBasedOverride;
import androidx.annotation.UiThread;
@@ -45,71 +47,65 @@ import androidx.annotation.UiThread;
*/
public class DrawableFactory implements ResourceBasedOverride {
- private static final String TAG = "DrawableFactory";
+ public static final MainThreadInitializedObject<DrawableFactory> INSTANCE =
+ new MainThreadInitializedObject<>(c -> {
+ DrawableFactory factory = Overrides.getObject(DrawableFactory.class,
+ c.getApplicationContext(), R.string.drawable_factory_class);
+ factory.mContext = c;
+ return factory;
+ });
- private static DrawableFactory sInstance;
- private static final Object LOCK = new Object();
+ private Context mContext;
private Path mPreloadProgressPath;
- public static DrawableFactory get(Context context) {
- synchronized (LOCK) {
- if (sInstance == null) {
- sInstance = Overrides.getObject(DrawableFactory.class,
- context.getApplicationContext(), R.string.drawable_factory_class);
- }
- return sInstance;
- }
- }
-
protected final UserHandle mMyUser = Process.myUserHandle();
protected final ArrayMap<UserHandle, Bitmap> mUserBadges = new ArrayMap<>();
/**
* Returns a FastBitmapDrawable with the icon.
*/
- public FastBitmapDrawable newIcon(ItemInfoWithIcon info) {
- FastBitmapDrawable drawable = new FastBitmapDrawable(info);
+ public FastBitmapDrawable newIcon(Context context, ItemInfoWithIcon info) {
+ FastBitmapDrawable drawable = info.iconBitmap == LOW_RES_ICON
+ ? new PlaceHolderIconDrawable(info, getPreloadProgressPath(), context)
+ : new FastBitmapDrawable(info);
drawable.setIsDisabled(info.isDisabled());
return drawable;
}
- public FastBitmapDrawable newIcon(BitmapInfo info, ActivityInfo target) {
- return new FastBitmapDrawable(info);
+ public FastBitmapDrawable newIcon(Context context, BitmapInfo info, ActivityInfo target) {
+ return info.icon == LOW_RES_ICON
+ ? new PlaceHolderIconDrawable(info, getPreloadProgressPath(), context)
+ : new FastBitmapDrawable(info);
}
/**
* Returns a FastBitmapDrawable with the icon.
*/
- public PreloadIconDrawable newPendingIcon(ItemInfoWithIcon info, Context context) {
- if (mPreloadProgressPath == null) {
- mPreloadProgressPath = getPreloadProgressPath(context);
- }
- return new PreloadIconDrawable(info, mPreloadProgressPath, context);
+ public PreloadIconDrawable newPendingIcon(Context context, ItemInfoWithIcon info) {
+ return new PreloadIconDrawable(info, getPreloadProgressPath(), context);
}
- protected Path getPreloadProgressPath(Context context) {
- if (Utilities.ATLEAST_OREO) {
- try {
- // Try to load the path from Mask Icon
- Drawable icon = context.getDrawable(R.drawable.adaptive_icon_drawable_wrapper);
- icon.setBounds(0, 0,
- PreloadIconDrawable.PATH_SIZE, PreloadIconDrawable.PATH_SIZE);
- return (Path) icon.getClass().getMethod("getIconMask").invoke(icon);
- } catch (Exception e) {
- Log.e(TAG, "Error loading mask icon", e);
- }
+ protected Path getPreloadProgressPath() {
+ if (mPreloadProgressPath != null) {
+ return mPreloadProgressPath;
}
+ if (Utilities.ATLEAST_OREO) {
+ // Load the path from Mask Icon
+ AdaptiveIconDrawable icon = (AdaptiveIconDrawable)
+ mContext.getDrawable(R.drawable.adaptive_icon_drawable_wrapper);
+ icon.setBounds(0, 0,
+ PreloadIconDrawable.PATH_SIZE, PreloadIconDrawable.PATH_SIZE);
+ mPreloadProgressPath = icon.getIconMask();
+ } else {
- // Create a circle static from top center and going clockwise.
- Path p = new Path();
- p.moveTo(PreloadIconDrawable.PATH_SIZE / 2, 0);
- p.addArc(0, 0, PreloadIconDrawable.PATH_SIZE, PreloadIconDrawable.PATH_SIZE, -90, 360);
- return p;
- }
-
- public AllAppsBackgroundDrawable getAllAppsBackground(Context context) {
- return new AllAppsBackgroundDrawable(context);
+ // Create a circle static from top center and going clockwise.
+ Path p = new Path();
+ p.moveTo(PreloadIconDrawable.PATH_SIZE / 2, 0);
+ p.addArc(0, 0, PreloadIconDrawable.PATH_SIZE, PreloadIconDrawable.PATH_SIZE, -90, 360);
+ mPreloadProgressPath = p;
+ }
+ return mPreloadProgressPath;
}
/**
diff --git a/src/com/android/launcher3/graphics/PlaceHolderIconDrawable.java b/src/com/android/launcher3/graphics/PlaceHolderIconDrawable.java
new file mode 100644
index 000000000..18efd47b6
--- /dev/null
+++ b/src/com/android/launcher3/graphics/PlaceHolderIconDrawable.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 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.graphics;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Path;
+import android.graphics.Rect;
+
+import com.android.launcher3.FastBitmapDrawable;
+import com.android.launcher3.ItemInfoWithIcon;
+import com.android.launcher3.R;
+import com.android.launcher3.util.Themes;
+
+/**
+ * Subclass which draws a placeholder icon when the actual icon is not yet loaded
+ */
+public class PlaceHolderIconDrawable extends FastBitmapDrawable {
+
+ // Path in [0, 100] bounds.
+ private final Path mProgressPath;
+
+ public PlaceHolderIconDrawable(BitmapInfo info, Path progressPath, Context context) {
+ this(info.icon, info.color, progressPath, context);
+ }
+
+ public PlaceHolderIconDrawable(ItemInfoWithIcon info, Path progressPath, Context context) {
+ this(info.iconBitmap, info.iconColor, progressPath, context);
+ }
+
+ protected PlaceHolderIconDrawable(Bitmap b, int iconColor, Path progressPath, Context context) {
+ super(b, iconColor);
+
+ mProgressPath = progressPath;
+ mPaint.setColor(Themes.getAttrColor(context, R.attr.loadingIconColor));
+ }
+
+ @Override
+ protected void drawInternal(Canvas canvas, Rect bounds) {
+ int saveCount = canvas.save();
+ canvas.translate(bounds.left, bounds.top);
+ canvas.scale(bounds.width() / 100f, bounds.height() / 100f);
+ canvas.drawPath(mProgressPath, mPaint);
+ canvas.restoreToCount(saveCount);
+ }
+}
diff --git a/src/com/android/launcher3/model/CacheDataUpdatedTask.java b/src/com/android/launcher3/model/CacheDataUpdatedTask.java
index 0139bd902..54c054276 100644
--- a/src/com/android/launcher3/model/CacheDataUpdatedTask.java
+++ b/src/com/android/launcher3/model/CacheDataUpdatedTask.java
@@ -64,7 +64,7 @@ public class CacheDataUpdatedTask extends BaseModelUpdateTask {
if (si.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
&& isValidShortcut(si) && cn != null
&& mPackages.contains(cn.getPackageName())) {
- iconCache.getTitleAndIcon(si, si.usingLowResIcon);
+ iconCache.getTitleAndIcon(si, si.usingLowResIcon());
updatedShortcuts.add(si);
}
}
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index e82c8f100..85faf4fbc 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -742,7 +742,7 @@ public class LoaderTask implements Runnable {
int numItemsInPreview = 0;
for (ShortcutInfo info : folder.contents) {
- if (info.usingLowResIcon
+ if (info.usingLowResIcon()
&& info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
&& verifier.isItemInPreview(info.rank)) {
mIconCache.getTitleAndIcon(info, false);
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 977dcd7d5..ccb1f0959 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -261,7 +261,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
if (isNewApkAvailable &&
si.itemType == Favorites.ITEM_TYPE_APPLICATION) {
- iconCache.getTitleAndIcon(si, si.usingLowResIcon);
+ iconCache.getTitleAndIcon(si, si.usingLowResIcon());
infoUpdated = true;
}
diff --git a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
index 961799d57..29b4b0ba2 100644
--- a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
@@ -17,7 +17,6 @@
package com.android.launcher3.widget;
import android.content.Context;
-import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
@@ -37,15 +36,12 @@ import com.android.launcher3.FastBitmapDrawable;
import com.android.launcher3.IconCache;
import com.android.launcher3.IconCache.ItemInfoUpdateReceiver;
import com.android.launcher3.ItemInfoWithIcon;
-import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.graphics.DrawableFactory;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.util.Themes;
-import com.android.launcher3.widget.LauncherAppWidgetHostView;
public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
implements OnClickListener, ItemInfoUpdateReceiver {
@@ -137,19 +133,19 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
// 1) App icon in the center
// 2) Preload icon in the center
// 3) Setup icon in the center and app icon in the top right corner.
- DrawableFactory drawableFactory = DrawableFactory.get(getContext());
+ DrawableFactory drawableFactory = DrawableFactory.INSTANCE.get(getContext());
if (mDisabledForSafeMode) {
- FastBitmapDrawable disabledIcon = drawableFactory.newIcon(info);
+ FastBitmapDrawable disabledIcon = drawableFactory.newIcon(getContext(), info);
disabledIcon.setIsDisabled(true);
mCenterDrawable = disabledIcon;
mSettingIconDrawable = null;
} else if (isReadyForClickSetup()) {
- mCenterDrawable = drawableFactory.newIcon(info);
+ mCenterDrawable = drawableFactory.newIcon(getContext(), info);
mSettingIconDrawable = getResources().getDrawable(R.drawable.ic_setting).mutate();
updateSettingColor(info.iconColor);
} else {
- mCenterDrawable = DrawableFactory.get(getContext())
- .newPendingIcon(info, getContext());
+ mCenterDrawable = DrawableFactory.INSTANCE.get(getContext())
+ .newPendingIcon(getContext(), info);
mSettingIconDrawable = null;
applyState();
}
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 2ba55ab97..66af43aeb 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -179,8 +179,8 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
return;
}
if (bitmap != null) {
- mWidgetImage.setBitmap(bitmap,
- DrawableFactory.get(getContext()).getBadgeForUser(mItem.user, getContext()));
+ mWidgetImage.setBitmap(bitmap, DrawableFactory.INSTANCE.get(getContext())
+ .getBadgeForUser(mItem.user, getContext()));
if (mAnimatePreview) {
mWidgetImage.setAlpha(0f);
ViewPropertyAnimator anim = mWidgetImage.animate();