diff --git a/iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java b/iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java index 245561ea53..d2b9c5e60b 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java +++ b/iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java @@ -18,32 +18,45 @@ package com.android.launcher3.icons; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + public class BitmapInfo { public static final Bitmap LOW_RES_ICON = Bitmap.createBitmap(1, 1, Config.ALPHA_8); + public static final BitmapInfo LOW_RES_INFO = fromBitmap(LOW_RES_ICON, null); - public Bitmap icon; - public int color; + public final Bitmap icon; + public final int color; - public void applyTo(BitmapInfo info) { - info.icon = icon; - info.color = color; + public BitmapInfo(Bitmap icon, int color) { + this.icon = icon; + this.color = color; + } + + /** + * Ideally icon should not be null, except in cases when generating hardware bitmap failed + */ + public final boolean isNullOrLowRes() { + return icon == null || icon == LOW_RES_ICON; } public final boolean isLowRes() { return LOW_RES_ICON == icon; } - public static BitmapInfo fromBitmap(Bitmap bitmap) { - return fromBitmap(bitmap, null); + public static BitmapInfo fromBitmap(@NonNull Bitmap bitmap) { + return of(bitmap, 0); } - public static BitmapInfo fromBitmap(Bitmap bitmap, ColorExtractor dominantColorExtractor) { - BitmapInfo info = new BitmapInfo(); - info.icon = bitmap; - info.color = dominantColorExtractor != null + public static BitmapInfo fromBitmap(@NonNull Bitmap bitmap, + @Nullable ColorExtractor dominantColorExtractor) { + return of(bitmap, dominantColorExtractor != null ? dominantColorExtractor.findDominantColorByHue(bitmap) - : 0; - return info; + : 0); + } + + public static BitmapInfo of(@NonNull Bitmap bitmap, int color) { + return new BitmapInfo(bitmap, color); } } diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java index 93f0538bd5..8bae94cf3d 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java +++ b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java @@ -71,7 +71,10 @@ public abstract class BaseIconCache { // Empty class name is used for storing package default entry. public static final String EMPTY_CLASS_NAME = "."; - public static class CacheEntry extends BitmapInfo { + public static class CacheEntry { + + @NonNull + public BitmapInfo bitmap = BitmapInfo.LOW_RES_INFO; public CharSequence title = ""; public CharSequence contentDescription = ""; } @@ -259,23 +262,23 @@ public abstract class BaseIconCache { if (!replaceExisting) { entry = mCache.get(key); // We can't reuse the entry if the high-res icon is not present. - if (entry == null || entry.icon == null || entry.isLowRes()) { + if (entry == null || entry.bitmap.isNullOrLowRes()) { entry = null; } } if (entry == null) { entry = new CacheEntry(); - cachingLogic.loadIcon(mContext, object, entry); + entry.bitmap = cachingLogic.loadIcon(mContext, object); } // Icon can't be loaded from cachingLogic, which implies alternative icon was loaded // (e.g. fallback icon, default icon). So we drop here since there's no point in caching // an empty entry. - if (entry.icon == null) return; + if (entry.bitmap.isNullOrLowRes()) return; entry.title = cachingLogic.getLabel(object); entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user); if (cachingLogic.addToMemCache()) mCache.put(key, entry); - ContentValues values = newContentValues(entry, entry.title.toString(), + ContentValues values = newContentValues(entry.bitmap, entry.title.toString(), componentName.getPackageName(), cachingLogic.getKeywords(object, mLocaleList)); addIconToDB(values, componentName, info, userSerial); } @@ -300,8 +303,8 @@ public abstract class BaseIconCache { return mDefaultIcons.get(user); } - public boolean isDefaultIcon(Bitmap icon, UserHandle user) { - return getDefaultIcon(user).icon == icon; + public boolean isDefaultIcon(BitmapInfo icon, UserHandle user) { + return getDefaultIcon(user).icon == icon.icon; } /** @@ -315,7 +318,7 @@ public abstract class BaseIconCache { assertWorkerThread(); ComponentKey cacheKey = new ComponentKey(componentName, user); CacheEntry entry = mCache.get(cacheKey); - if (entry == null || (entry.isLowRes() && !useLowResIcon)) { + if (entry == null || (entry.bitmap.isLowRes() && !useLowResIcon)) { entry = new CacheEntry(); if (cachingLogic.addToMemCache()) { mCache.put(cacheKey, entry); @@ -330,7 +333,7 @@ public abstract class BaseIconCache { providerFetchedOnce = true; if (object != null) { - cachingLogic.loadIcon(mContext, object, entry); + entry.bitmap = cachingLogic.loadIcon(mContext, object); } else { if (usePackageIcon) { CacheEntry packageEntry = getEntryForPackageLocked( @@ -338,15 +341,15 @@ public abstract class BaseIconCache { if (packageEntry != null) { if (DEBUG) Log.d(TAG, "using package default icon for " + componentName.toShortString()); - packageEntry.applyTo(entry); + entry.bitmap = packageEntry.bitmap; entry.title = packageEntry.title; entry.contentDescription = packageEntry.contentDescription; } } - if (entry.icon == null) { + if (entry.bitmap == null) { if (DEBUG) Log.d(TAG, "using default icon for " + componentName.toShortString()); - getDefaultIcon(user).applyTo(entry); + entry.bitmap = getDefaultIcon(user); } } } @@ -390,10 +393,10 @@ public abstract class BaseIconCache { } if (icon != null) { BaseIconFactory li = getIconFactory(); - li.createIconBitmap(icon).applyTo(entry); + entry.bitmap = li.createIconBitmap(icon); li.close(); } - if (!TextUtils.isEmpty(title) && entry.icon != null) { + if (!TextUtils.isEmpty(title) && entry.bitmap.icon != null) { mCache.put(cacheKey, entry); } } @@ -413,7 +416,7 @@ public abstract class BaseIconCache { ComponentKey cacheKey = getPackageKey(packageName, user); CacheEntry entry = mCache.get(cacheKey); - if (entry == null || (entry.isLowRes() && !useLowResIcon)) { + if (entry == null || (entry.bitmap.isLowRes() && !useLowResIcon)) { entry = new CacheEntry(); boolean entryUpdated = true; @@ -438,8 +441,8 @@ public abstract class BaseIconCache { entry.title = appInfo.loadLabel(mPackageManager); entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user); - entry.icon = useLowResIcon ? LOW_RES_ICON : iconInfo.icon; - entry.color = iconInfo.color; + entry.bitmap = BitmapInfo.of( + useLowResIcon ? LOW_RES_ICON : iconInfo.icon, iconInfo.color); // Add the icon in the DB here, since these do not get written during // package updates. @@ -472,7 +475,7 @@ public abstract class BaseIconCache { Long.toString(getSerialNumberForUser(cacheKey.user))}); if (c.moveToNext()) { // Set the alpha to be 255, so that we never have a wrong color - entry.color = setColorAlphaBound(c.getInt(0), 255); + entry.bitmap = BitmapInfo.of(LOW_RES_ICON, setColorAlphaBound(c.getInt(0), 255)); entry.title = c.getString(1); if (entry.title == null) { entry.title = ""; @@ -482,13 +485,12 @@ public abstract class BaseIconCache { entry.title, cacheKey.user); } - if (lowRes) { - entry.icon = LOW_RES_ICON; - } else { + if (!lowRes) { byte[] data = c.getBlob(2); try { - entry.icon = BitmapFactory.decodeByteArray(data, 0, data.length, - mDecodeOptions); + entry.bitmap = BitmapInfo.of( + BitmapFactory.decodeByteArray(data, 0, data.length, mDecodeOptions), + entry.bitmap.color); } catch (Exception e) { } } return true; diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java b/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java index e40a9c2c96..ea1ca536fc 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java +++ b/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java @@ -20,6 +20,7 @@ import android.content.Context; import android.os.LocaleList; import android.os.UserHandle; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.icons.BitmapInfo; @@ -32,7 +33,8 @@ public interface CachingLogic { CharSequence getLabel(T object); - void loadIcon(Context context, T object, BitmapInfo target); + @NonNull + BitmapInfo loadIcon(Context context, T object); /** * Provides a option list of keywords to associate with this object diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java index 65e69b6046..06580b95a3 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java @@ -170,7 +170,7 @@ public class DynamicItemCache { if (!details.isEmpty()) { WorkspaceItemInfo si = new WorkspaceItemInfo(details.get(0), mContext); try (LauncherIcons li = LauncherIcons.obtain(mContext)) { - si.applyFrom(li.createShortcutIcon(details.get(0), true /* badged */, null)); + si.bitmap = li.createShortcutIcon(details.get(0), true /* badged */, null); } catch (Exception e) { if (DEBUG) { Log.e(TAG, "Error loading shortcut icon for " + shortcutKey.toString()); @@ -209,7 +209,7 @@ public class DynamicItemCache { InstantAppItemInfo info = new InstantAppItemInfo(intent, pkgName); IconCache iconCache = LauncherAppState.getInstance(mContext).getIconCache(); iconCache.getTitleAndIcon(info, false); - if (info.iconBitmap == null || iconCache.isDefaultIcon(info.iconBitmap, info.user)) { + if (info.bitmap.icon == null || iconCache.isDefaultIcon(info.bitmap, info.user)) { return null; } return info; diff --git a/robolectric_tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java b/robolectric_tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java index 32eb2ec5fe..5b6d94d732 100644 --- a/robolectric_tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java +++ b/robolectric_tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java @@ -202,15 +202,14 @@ public class BaseModelUpdateTaskTestCase { CacheEntry entry = mCache.get(new ComponentKey(componentName, user)); if (entry == null) { entry = new CacheEntry(); - getDefaultIcon(user).applyTo(entry); + entry.bitmap = getDefaultIcon(user); } return entry; } public void addCache(ComponentName key, String title) { CacheEntry entry = new CacheEntry(); - entry.icon = newIcon(); - entry.color = Color.RED; + entry.bitmap = BitmapInfo.of(newIcon(), Color.RED); entry.title = title; mCache.put(new ComponentKey(key, Process.myUserHandle()), entry); } diff --git a/robolectric_tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java b/robolectric_tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java index 81b90431a0..69c5b00c27 100644 --- a/robolectric_tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java +++ b/robolectric_tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java @@ -2,13 +2,13 @@ package com.android.launcher3.model; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import com.android.launcher3.AppInfo; import com.android.launcher3.ItemInfo; import com.android.launcher3.WorkspaceItemInfo; +import com.android.launcher3.icons.BitmapInfo; import org.junit.Before; import org.junit.Test; @@ -43,7 +43,7 @@ public class CacheDataUpdatedTaskTest extends BaseModelUpdateTaskTestCase { public void testCacheUpdate_update_apps() throws Exception { // Clear all icons from apps list so that its easy to check what was updated for (AppInfo info : allAppsList.data) { - info.iconBitmap = null; + info.bitmap = BitmapInfo.LOW_RES_INFO; } executeTaskForTest(newTask(CacheDataUpdatedTask.OP_CACHE_UPDATE, "app1")); @@ -56,9 +56,9 @@ public class CacheDataUpdatedTaskTest extends BaseModelUpdateTaskTestCase { assertFalse(allAppsList.data.isEmpty()); for (AppInfo info : allAppsList.data) { if (info.componentName.getPackageName().equals("app1")) { - assertNotNull(info.iconBitmap); + assertFalse(info.bitmap.isNullOrLowRes()); } else { - assertNull(info.iconBitmap); + assertTrue(info.bitmap.isNullOrLowRes()); } } } @@ -85,10 +85,10 @@ public class CacheDataUpdatedTaskTest extends BaseModelUpdateTaskTestCase { for (ItemInfo info : bgDataModel.itemsIdMap) { if (updates.contains(info.id)) { assertEquals(NEW_LABEL_PREFIX + info.id, info.title); - assertNotNull(((WorkspaceItemInfo) info).iconBitmap); + assertFalse(((WorkspaceItemInfo) info).bitmap.isNullOrLowRes()); } else { assertNotSame(NEW_LABEL_PREFIX + info.id, info.title); - assertNull(((WorkspaceItemInfo) info).iconBitmap); + assertTrue(((WorkspaceItemInfo) info).bitmap.isNullOrLowRes()); } } } diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 7adb6a4420..e8aa83f70f 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -289,7 +289,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, private void applyIconAndLabel(ItemInfoWithIcon info) { FastBitmapDrawable iconDrawable = DrawableFactory.INSTANCE.get(getContext()) .newIcon(getContext(), info); - mDotParams.color = IconPalette.getMutedColor(info.iconColor, 0.54f); + mDotParams.color = IconPalette.getMutedColor(info.bitmap.color, 0.54f); setIcon(iconDrawable); setText(info.title); @@ -665,7 +665,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, mDisableRelayout = true; // Optimization: Starting in N, pre-uploads the bitmap to RenderThread. - info.iconBitmap.prepareToDraw(); + info.bitmap.icon.prepareToDraw(); if (info instanceof AppInfo) { applyFromApplicationInfo((AppInfo) info); diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java index a90025e97f..2e57f71412 100644 --- a/src/com/android/launcher3/FastBitmapDrawable.java +++ b/src/com/android/launcher3/FastBitmapDrawable.java @@ -98,10 +98,6 @@ public class FastBitmapDrawable extends Drawable { this(info.icon, info.color); } - public FastBitmapDrawable(ItemInfoWithIcon info) { - this(info.iconBitmap, info.iconColor); - } - protected FastBitmapDrawable(Bitmap b, int iconColor) { this(b, iconColor, false); } diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java index 93def50398..2bf1a850a0 100644 --- a/src/com/android/launcher3/InstallShortcutReceiver.java +++ b/src/com/android/launcher3/InstallShortcutReceiver.java @@ -485,7 +485,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver { } else if (shortcutInfo != null) { WorkspaceItemInfo itemInfo = new WorkspaceItemInfo(shortcutInfo, mContext); LauncherIcons li = LauncherIcons.obtain(mContext); - itemInfo.applyFrom(li.createShortcutIcon(shortcutInfo)); + itemInfo.bitmap = li.createShortcutIcon(shortcutInfo); li.recycle(); return Pair.create(itemInfo, shortcutInfo); } else if (providerInfo != null) { @@ -656,7 +656,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver { if (iconInfo == null) { iconInfo = app.getIconCache().getDefaultIcon(info.user); } - info.applyFrom(iconInfo); + info.bitmap = iconInfo; info.title = Utilities.trim(name); info.contentDescription = app.getContext().getPackageManager() diff --git a/src/com/android/launcher3/ItemInfoWithIcon.java b/src/com/android/launcher3/ItemInfoWithIcon.java index 1550bb080d..19414550f8 100644 --- a/src/com/android/launcher3/ItemInfoWithIcon.java +++ b/src/com/android/launcher3/ItemInfoWithIcon.java @@ -16,10 +16,6 @@ package com.android.launcher3; -import static com.android.launcher3.icons.BitmapInfo.LOW_RES_ICON; - -import android.graphics.Bitmap; - import com.android.launcher3.icons.BitmapInfo; /** @@ -30,14 +26,9 @@ public abstract class ItemInfoWithIcon extends ItemInfo { public static final String TAG = "ItemInfoDebug"; /** - * A bitmap version of the application icon. + * The bitmap for the application icon */ - public Bitmap iconBitmap; - - /** - * Dominant color in the {@link #iconBitmap}. - */ - public int iconColor; + public BitmapInfo bitmap = BitmapInfo.LOW_RES_INFO; /** * Indicates that the icon is disabled due to safe mode restrictions. @@ -106,8 +97,7 @@ public abstract class ItemInfoWithIcon extends ItemInfo { protected ItemInfoWithIcon(ItemInfoWithIcon info) { super(info); - iconBitmap = info.iconBitmap; - iconColor = info.iconColor; + bitmap = info.bitmap; runtimeStatusFlags = info.runtimeStatusFlags; } @@ -120,12 +110,7 @@ public abstract class ItemInfoWithIcon extends ItemInfo { * Indicates whether we're using a low res icon */ public boolean usingLowResIcon() { - return iconBitmap == LOW_RES_ICON; - } - - public void applyFrom(BitmapInfo info) { - iconBitmap = info.icon; - iconColor = info.color; + return bitmap.isLowRes(); } /** diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index b0b213c087..93304a177a 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -510,7 +510,7 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi updateAndBindWorkspaceItem(() -> { si.updateFromDeepShortcutInfo(info, mApp.getContext()); LauncherIcons li = LauncherIcons.obtain(mApp.getContext()); - si.applyFrom(li.createShortcutIcon(info)); + si.bitmap = li.createShortcutIcon(info); li.recycle(); return si; }); @@ -546,7 +546,8 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi if (args.length > 0 && TextUtils.equals(args[0], "--all")) { writer.println(prefix + "All apps list: size=" + mBgAllAppsList.data.size()); for (AppInfo info : mBgAllAppsList.data) { - writer.println(prefix + " title=\"" + info.title + "\" iconBitmap=" + info.iconBitmap + writer.println(prefix + " title=\"" + info.title + + "\" bitmapIcon=" + info.bitmap.icon + " componentName=" + info.componentName.getPackageName()); } } diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 92f8069064..aa6e61cc77 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -582,7 +582,7 @@ public final class Utilities { } ShortcutInfo si = (ShortcutInfo) obj; LauncherIcons li = LauncherIcons.obtain(appState.getContext()); - Bitmap badge = li.getShortcutInfoBadge(si, appState.getIconCache()).iconBitmap; + Bitmap badge = li.getShortcutInfoBadge(si, appState.getIconCache()).bitmap.icon; li.recycle(); float badgeSize = iconSize * LauncherIcons.getBadgeSizeForIconSize(iconSize); float insetFraction = (iconSize - badgeSize) / iconSize; diff --git a/src/com/android/launcher3/WorkspaceItemInfo.java b/src/com/android/launcher3/WorkspaceItemInfo.java index 71bd92f9dd..be907e5aa8 100644 --- a/src/com/android/launcher3/WorkspaceItemInfo.java +++ b/src/com/android/launcher3/WorkspaceItemInfo.java @@ -140,7 +140,7 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon { .put(Favorites.RESTORED, status); if (!usingLowResIcon()) { - writer.putIcon(iconBitmap, user); + writer.putIcon(bitmap, user); } if (iconResource != null) { writer.put(Favorites.ICON_PACKAGE, iconResource.packageName) diff --git a/src/com/android/launcher3/graphics/DrawableFactory.java b/src/com/android/launcher3/graphics/DrawableFactory.java index 837301fb89..13dbab589c 100644 --- a/src/com/android/launcher3/graphics/DrawableFactory.java +++ b/src/com/android/launcher3/graphics/DrawableFactory.java @@ -57,8 +57,8 @@ public class DrawableFactory implements ResourceBasedOverride { */ public FastBitmapDrawable newIcon(Context context, ItemInfoWithIcon info) { FastBitmapDrawable drawable = info.usingLowResIcon() - ? new PlaceHolderIconDrawable(info, getShapePath(), context) - : new FastBitmapDrawable(info); + ? new PlaceHolderIconDrawable(info.bitmap, getShapePath(), context) + : new FastBitmapDrawable(info.bitmap); drawable.setIsDisabled(info.isDisabled()); return drawable; } diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index d7b845b58c..2badb6e2f3 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -50,8 +50,8 @@ import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.R; -import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.Utilities; +import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.WorkspaceLayoutManager; import com.android.launcher3.allapps.SearchUiManager; import com.android.launcher3.config.FeatureFlags; @@ -105,7 +105,7 @@ public class LauncherPreviewRenderer implements Callable { Build.VERSION.SDK_INT); mWorkspaceItemInfo = new WorkspaceItemInfo(); - mWorkspaceItemInfo.applyFrom(iconInfo); + mWorkspaceItemInfo.bitmap = iconInfo; mWorkspaceItemInfo.intent = new Intent(); mWorkspaceItemInfo.contentDescription = mWorkspaceItemInfo.title = context.getString(R.string.label_application); diff --git a/src/com/android/launcher3/graphics/PlaceHolderIconDrawable.java b/src/com/android/launcher3/graphics/PlaceHolderIconDrawable.java index 23745cbd96..c6f807f63a 100644 --- a/src/com/android/launcher3/graphics/PlaceHolderIconDrawable.java +++ b/src/com/android/launcher3/graphics/PlaceHolderIconDrawable.java @@ -24,7 +24,6 @@ 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.icons.BitmapInfo; import com.android.launcher3.util.Themes; @@ -41,10 +40,6 @@ public class PlaceHolderIconDrawable extends FastBitmapDrawable { 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); diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java index cc4c2efafb..acdf9420fc 100644 --- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java +++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java @@ -105,7 +105,7 @@ public class PreloadIconDrawable extends FastBitmapDrawable { * @param progressPath fixed path in the bounds [0, 0, 100, 100] representing a progress bar. */ public PreloadIconDrawable(ItemInfoWithIcon info, Path progressPath, Context context) { - super(info); + super(info.bitmap); mItem = info; mProgressPath = progressPath; mScaledTrackPath = new Path(); diff --git a/src/com/android/launcher3/icons/ComponentWithLabel.java b/src/com/android/launcher3/icons/ComponentWithLabel.java index 832956d7ed..f7ee5f9329 100644 --- a/src/com/android/launcher3/icons/ComponentWithLabel.java +++ b/src/com/android/launcher3/icons/ComponentWithLabel.java @@ -57,10 +57,8 @@ public interface ComponentWithLabel { } @Override - public void loadIcon(Context context, - ComponentWithLabel object, BitmapInfo target) { - // Do not load icon. - target.icon = BitmapInfo.LOW_RES_ICON; + public BitmapInfo loadIcon(Context context, ComponentWithLabel object) { + return BitmapInfo.LOW_RES_INFO; } @Override diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java index 9886f53863..13dc08f458 100644 --- a/src/com/android/launcher3/icons/IconCache.java +++ b/src/com/android/launcher3/icons/IconCache.java @@ -161,7 +161,7 @@ public class IconCache extends BaseIconCache { CacheEntry entry = cacheLocked(application.componentName, application.user, () -> null, mLauncherActivityInfoCachingLogic, false, application.usingLowResIcon()); - if (entry.icon != null && !isDefaultIcon(entry.icon, application.user)) { + if (entry.bitmap != null && !isDefaultIcon(entry.bitmap, application.user)) { applyCacheEntry(entry, application); } } @@ -183,7 +183,7 @@ public class IconCache extends BaseIconCache { // null info means not installed, but if we have a component from the intent then // we should still look in the cache for restored app icons. if (info.getTargetComponent() == null) { - info.applyFrom(getDefaultIcon(info.user)); + info.bitmap = getDefaultIcon(info.user); info.title = ""; info.contentDescription = ""; } else { @@ -226,7 +226,7 @@ public class IconCache extends BaseIconCache { protected void applyCacheEntry(CacheEntry entry, ItemInfoWithIcon info) { info.title = Utilities.trim(entry.title); info.contentDescription = entry.contentDescription; - info.applyFrom((entry.icon == null) ? getDefaultIcon(info.user) : entry); + info.bitmap = (entry.bitmap == null) ? getDefaultIcon(info.user) : entry.bitmap; } public Drawable getFullResIcon(LauncherActivityInfo info) { diff --git a/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java index f9a94daf53..a29d4feb9d 100644 --- a/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java +++ b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java @@ -55,13 +55,12 @@ public class LauncherActivityCachingLogic } @Override - public void loadIcon(Context context, LauncherActivityInfo object, - BitmapInfo target) { - LauncherIcons li = LauncherIcons.obtain(context); - li.createBadgedIconBitmap( - IconProvider.INSTANCE.get(context) - .getIcon(object, li.mFillResIconDpi, true /* flattenDrawable */), - object.getUser(), object.getApplicationInfo().targetSdkVersion).applyTo(target); - li.recycle(); + public BitmapInfo loadIcon(Context context, LauncherActivityInfo object) { + try (LauncherIcons li = LauncherIcons.obtain(context)) { + return li.createBadgedIconBitmap( + IconProvider.INSTANCE.get(context) + .getIcon(object, li.mFillResIconDpi, true /* flattenDrawable */), + object.getUser(), object.getApplicationInfo().targetSdkVersion); + } } } diff --git a/src/com/android/launcher3/icons/LauncherIcons.java b/src/com/android/launcher3/icons/LauncherIcons.java index adc92c46c4..1c34dc455b 100644 --- a/src/com/android/launcher3/icons/LauncherIcons.java +++ b/src/com/android/launcher3/icons/LauncherIcons.java @@ -137,32 +137,25 @@ public class LauncherIcons extends BaseIconFactory implements AutoCloseable { if (fallbackIconProvider != null) { // Fallback icons are already badged and with appropriate shadow ItemInfoWithIcon fullIcon = fallbackIconProvider.get(); - if (fullIcon != null && fullIcon.iconBitmap != null) { - BitmapInfo result = new BitmapInfo(); - result.icon = fullIcon.iconBitmap; - result.color = fullIcon.iconColor; - return result; + if (fullIcon != null && fullIcon.bitmap != null) { + return fullIcon.bitmap; } } unbadgedBitmap = cache.getDefaultIcon(Process.myUserHandle()).icon; } - BitmapInfo result = new BitmapInfo(); if (!badged) { - result.color = Themes.getColorAccent(mContext); - result.icon = unbadgedBitmap; - return result; + return BitmapInfo.of(unbadgedBitmap, Themes.getColorAccent(mContext)); } final Bitmap unbadgedfinal = unbadgedBitmap; final ItemInfoWithIcon badge = getShortcutInfoBadge(shortcutInfo, cache); - result.color = badge.iconColor; - result.icon = BitmapRenderer.createHardwareBitmap(mIconBitmapSize, mIconBitmapSize, (c) -> { + Bitmap icon = BitmapRenderer.createHardwareBitmap(mIconBitmapSize, mIconBitmapSize, (c) -> { getShadowGenerator().recreateIcon(unbadgedfinal, c); - badgeWithDrawable(c, new FastBitmapDrawable(badge)); + badgeWithDrawable(c, new FastBitmapDrawable(badge.bitmap)); }); - return result; + return BitmapInfo.of(icon, badge.bitmap.color); } public ItemInfoWithIcon getShortcutInfoBadge(ShortcutInfo shortcutInfo, IconCache cache) { diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java index 2d62c9ee77..21c73e9b13 100644 --- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java +++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java @@ -137,7 +137,7 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask { .makeWorkspaceItem(); WorkspaceItemInfo wii = (WorkspaceItemInfo) itemInfo; wii.title = ""; - wii.applyFrom(app.getIconCache().getDefaultIcon(item.user)); + wii.bitmap = app.getIconCache().getDefaultIcon(item.user); app.getIconCache().getTitleAndIcon(wii, ((WorkspaceItemInfo) itemInfo).usingLowResIcon()); } diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java index 6154e7ef84..95268d088e 100644 --- a/src/com/android/launcher3/model/LoaderCursor.java +++ b/src/com/android/launcher3/model/LoaderCursor.java @@ -153,7 +153,7 @@ public class LoaderCursor extends CursorWrapper { info.title = getTitle(); // the fallback icon if (!loadIcon(info)) { - info.applyFrom(mIconCache.getDefaultIcon(info.user)); + info.bitmap = mIconCache.getDefaultIcon(info.user); } // TODO: If there's an explicit component and we can't install that, delete it. @@ -183,7 +183,7 @@ public class LoaderCursor extends CursorWrapper { info.iconResource.resourceName = resourceName; BitmapInfo iconInfo = li.createIconBitmap(info.iconResource); if (iconInfo != null) { - info.applyFrom(iconInfo); + info.bitmap = iconInfo; return true; } } @@ -192,7 +192,7 @@ public class LoaderCursor extends CursorWrapper { // Failed to load from resource, try loading from DB. byte[] data = getBlob(iconIndex); try { - info.applyFrom(li.createIconBitmap(BitmapFactory.decodeByteArray(data, 0, data.length))); + info.bitmap = li.createIconBitmap(BitmapFactory.decodeByteArray(data, 0, data.length)); return true; } catch (Exception e) { Log.e(TAG, "Failed to decode byte array for info " + info, e); @@ -273,7 +273,7 @@ public class LoaderCursor extends CursorWrapper { info.intent = newIntent; mIconCache.getTitleAndIcon(info, lai, useLowResIcon); - if (mIconCache.isDefaultIcon(info.iconBitmap, user)) { + if (mIconCache.isDefaultIcon(info.bitmap, user)) { loadIcon(info); } diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java index 353a0d231f..6383a5f480 100644 --- a/src/com/android/launcher3/model/LoaderTask.java +++ b/src/com/android/launcher3/model/LoaderTask.java @@ -503,8 +503,9 @@ public class LoaderTask implements Runnable { // use the last saved icon instead of the default. Supplier fallbackIconProvider = () -> c.loadIcon(finalInfo, li) ? finalInfo : null; - info.applyFrom(li.createShortcutIcon(pinnedShortcut, - true /* badged */, fallbackIconProvider)); + info.bitmap = li.createShortcutIcon( + pinnedShortcut, true /* badged */, + fallbackIconProvider); li.recycle(); if (pmHelper.isAppSuspended( pinnedShortcut.getPackage(), info.user)) { diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java index db63b7c251..1e614bda95 100644 --- a/src/com/android/launcher3/model/PackageUpdatedTask.java +++ b/src/com/android/launcher3/model/PackageUpdatedTask.java @@ -189,7 +189,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask { BitmapInfo iconInfo = li.createIconBitmap(si.iconResource); li.recycle(); if (iconInfo != null) { - si.applyFrom(iconInfo); + si.bitmap = iconInfo; infoUpdated = true; } } diff --git a/src/com/android/launcher3/model/ShortcutsChangedTask.java b/src/com/android/launcher3/model/ShortcutsChangedTask.java index 6c358b1709..05225d4fa0 100644 --- a/src/com/android/launcher3/model/ShortcutsChangedTask.java +++ b/src/com/android/launcher3/model/ShortcutsChangedTask.java @@ -93,8 +93,8 @@ public class ShortcutsChangedTask extends BaseModelUpdateTask { // If the shortcut is pinned but no longer has an icon in the system, // keep the current icon instead of reverting to the default icon. LauncherIcons li = LauncherIcons.obtain(context); - workspaceItemInfo.applyFrom(li.createShortcutIcon(fullDetails, true, - () -> workspaceItemInfo)); + workspaceItemInfo.bitmap = li.createShortcutIcon( + fullDetails, true, () -> workspaceItemInfo); li.recycle(); updatedWorkspaceItemInfos.add(workspaceItemInfo); } diff --git a/src/com/android/launcher3/model/UserLockStateChangedTask.java b/src/com/android/launcher3/model/UserLockStateChangedTask.java index 4b773d7204..db1c307480 100644 --- a/src/com/android/launcher3/model/UserLockStateChangedTask.java +++ b/src/com/android/launcher3/model/UserLockStateChangedTask.java @@ -92,7 +92,7 @@ public class UserLockStateChangedTask extends BaseModelUpdateTask { // If the shortcut is pinned but no longer has an icon in the system, // keep the current icon instead of reverting to the default icon. LauncherIcons li = LauncherIcons.obtain(context); - si.applyFrom(li.createShortcutIcon(shortcut, true, () -> si)); + si.bitmap = li.createShortcutIcon(shortcut, true, () -> si); li.recycle(); } else { si.runtimeStatusFlags |= FLAG_DISABLED_LOCKED_USER; diff --git a/src/com/android/launcher3/pm/PinRequestHelper.java b/src/com/android/launcher3/pm/PinRequestHelper.java index 68ea6c43ad..e13645c42b 100644 --- a/src/com/android/launcher3/pm/PinRequestHelper.java +++ b/src/com/android/launcher3/pm/PinRequestHelper.java @@ -82,7 +82,7 @@ public class PinRequestHelper { WorkspaceItemInfo info = new WorkspaceItemInfo(si, context); // Apply the unbadged icon and fetch the actual icon asynchronously. LauncherIcons li = LauncherIcons.obtain(context); - info.applyFrom(li.createShortcutIcon(si, false /* badged */)); + info.bitmap = li.createShortcutIcon(si, false /* badged */); li.recycle(); LauncherAppState.getInstance(context).getModel() .updateAndBindWorkspaceItem(info, si); diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index 203492677d..b7eefe794e 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -507,7 +507,7 @@ public class PopupContainerWithArrow extends ArrowPopup implements DragSource, DotInfo dotInfo = mLauncher.getDotInfoForItem(itemInfo); if (mNotificationItemView != null && dotInfo != null) { mNotificationItemView.updateHeader( - dotInfo.getNotificationCount(), itemInfo.iconColor); + dotInfo.getNotificationCount(), itemInfo.bitmap.color); } } diff --git a/src/com/android/launcher3/popup/PopupPopulator.java b/src/com/android/launcher3/popup/PopupPopulator.java index 96189270ec..80c6683d31 100644 --- a/src/com/android/launcher3/popup/PopupPopulator.java +++ b/src/com/android/launcher3/popup/PopupPopulator.java @@ -154,7 +154,7 @@ public class PopupPopulator { final WorkspaceItemInfo si = new WorkspaceItemInfo(shortcut, launcher); // Use unbadged icon for the menu. LauncherIcons li = LauncherIcons.obtain(launcher); - si.applyFrom(li.createShortcutIcon(shortcut, false /* badged */)); + si.bitmap = li.createShortcutIcon(shortcut, false /* badged */); li.recycle(); si.rank = i; diff --git a/src/com/android/launcher3/util/ContentWriter.java b/src/com/android/launcher3/util/ContentWriter.java index 00adf1069a..2d643531e8 100644 --- a/src/com/android/launcher3/util/ContentWriter.java +++ b/src/com/android/launcher3/util/ContentWriter.java @@ -26,6 +26,7 @@ import android.os.UserHandle; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; import com.android.launcher3.compat.UserManagerCompat; +import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.GraphicsUtils; /** @@ -37,7 +38,7 @@ public class ContentWriter { private final Context mContext; private CommitParams mCommitParams; - private Bitmap mIcon; + private BitmapInfo mIcon; private UserHandle mUser; public ContentWriter(Context context, CommitParams commitParams) { @@ -79,7 +80,7 @@ public class ContentWriter { return this; } - public ContentWriter putIcon(Bitmap value, UserHandle user) { + public ContentWriter putIcon(BitmapInfo value, UserHandle user) { mIcon = value; mUser = user; return this; @@ -97,7 +98,7 @@ public class ContentWriter { Preconditions.assertNonUiThread(); if (mIcon != null && !LauncherAppState.getInstance(context).getIconCache() .isDefaultIcon(mIcon, mUser)) { - mValues.put(LauncherSettings.Favorites.ICON, GraphicsUtils.flattenBitmap(mIcon)); + mValues.put(LauncherSettings.Favorites.ICON, GraphicsUtils.flattenBitmap(mIcon.icon)); mIcon = null; } return mValues; diff --git a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java index 50db40fde8..3ece5f4c09 100644 --- a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java +++ b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java @@ -33,12 +33,12 @@ import android.view.View.OnClickListener; import com.android.launcher3.DeviceProfile; import com.android.launcher3.FastBitmapDrawable; -import com.android.launcher3.icons.IconCache; -import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver; import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.R; import com.android.launcher3.graphics.DrawableFactory; +import com.android.launcher3.icons.IconCache; +import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver; import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.touch.ItemClickHandler; import com.android.launcher3.util.Themes; @@ -128,7 +128,7 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView mCenterDrawable.setCallback(null); mCenterDrawable = null; } - if (info.iconBitmap != null) { + if (info.bitmap.icon != null) { // The view displays three modes, // 1) App icon in the center // 2) Preload icon in the center @@ -142,7 +142,7 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView } else if (isReadyForClickSetup()) { mCenterDrawable = drawableFactory.newIcon(getContext(), info); mSettingIconDrawable = getResources().getDrawable(R.drawable.ic_setting).mutate(); - updateSettingColor(info.iconColor); + updateSettingColor(info.bitmap.color); } else { mCenterDrawable = DrawableFactory.INSTANCE.get(getContext()) .newPendingIcon(getContext(), info); diff --git a/src/com/android/launcher3/widget/WidgetsDiffReporter.java b/src/com/android/launcher3/widget/WidgetsDiffReporter.java index 435125bd83..f3b325db58 100644 --- a/src/com/android/launcher3/widget/WidgetsDiffReporter.java +++ b/src/com/android/launcher3/widget/WidgetsDiffReporter.java @@ -18,6 +18,8 @@ package com.android.launcher3.widget; import android.util.Log; +import androidx.recyclerview.widget.RecyclerView; + import com.android.launcher3.icons.IconCache; import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.widget.WidgetsListAdapter.WidgetListRowEntryComparator; @@ -25,8 +27,6 @@ import com.android.launcher3.widget.WidgetsListAdapter.WidgetListRowEntryCompara import java.util.ArrayList; import java.util.Iterator; -import androidx.recyclerview.widget.RecyclerView; - /** * Do diff on widget's tray list items and call the {@link RecyclerView.Adapter} * methods accordingly. @@ -137,7 +137,7 @@ public class WidgetsDiffReporter { } private boolean isSamePackageItemInfo(PackageItemInfo curInfo, PackageItemInfo newInfo) { - return curInfo.iconBitmap.equals(newInfo.iconBitmap) && - !mIconCache.isDefaultIcon(curInfo.iconBitmap, curInfo.user); + return curInfo.bitmap.icon.equals(newInfo.bitmap.icon) + && !mIconCache.isDefaultIcon(curInfo.bitmap, curInfo.user); } } diff --git a/tests/src/com/android/launcher3/model/LoaderCursorTest.java b/tests/src/com/android/launcher3/model/LoaderCursorTest.java index 7029ad586c..0dcfaa814d 100644 --- a/tests/src/com/android/launcher3/model/LoaderCursorTest.java +++ b/tests/src/com/android/launcher3/model/LoaderCursorTest.java @@ -142,7 +142,7 @@ public class LoaderCursorTest { when(mMockIconCache.getDefaultIcon(eq(mLoaderCursor.user))) .thenReturn(BitmapInfo.fromBitmap(icon)); WorkspaceItemInfo info = mLoaderCursor.loadSimpleWorkspaceItem(); - assertEquals(icon, info.iconBitmap); + assertEquals(icon, info.bitmap.icon); assertEquals("my-shortcut", info.title); assertEquals(ITEM_TYPE_SHORTCUT, info.itemType); } diff --git a/tests/src/com/android/launcher3/widget/WidgetsListAdapterTest.java b/tests/src/com/android/launcher3/widget/WidgetsListAdapterTest.java index a31d8a6561..c7f7cd6ad6 100644 --- a/tests/src/com/android/launcher3/widget/WidgetsListAdapterTest.java +++ b/tests/src/com/android/launcher3/widget/WidgetsListAdapterTest.java @@ -23,16 +23,19 @@ import static org.mockito.Mockito.verify; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.graphics.Bitmap; +import android.view.LayoutInflater; + +import androidx.recyclerview.widget.RecyclerView; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import android.view.LayoutInflater; -import com.android.launcher3.icons.IconCache; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.WidgetPreviewLoader; import com.android.launcher3.compat.AppWidgetManagerCompat; +import com.android.launcher3.icons.BitmapInfo; +import com.android.launcher3.icons.IconCache; import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.model.WidgetItem; import com.android.launcher3.util.MultiHashMap; @@ -46,8 +49,6 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.Map; -import androidx.recyclerview.widget.RecyclerView; - @SmallTest @RunWith(AndroidJUnit4.class) public class WidgetsListAdapterTest { @@ -136,7 +137,7 @@ public class WidgetsListAdapterTest { PackageItemInfo pInfo = new PackageItemInfo(wi.componentName.getPackageName()); pInfo.title = pInfo.packageName; pInfo.user = wi.user; - pInfo.iconBitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8); + pInfo.bitmap = BitmapInfo.of(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8), 0); newMap.addToList(pInfo, wi); if (newMap.size() == num) { break;