From e62d2bb165498521f4033d40d972076ee17f4ff6 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 6 Nov 2018 10:28:37 -0800 Subject: [PATCH] Removing some Launcher3 dependencies from BaseIconCache Change-Id: Ic80ed4a5cd2fc414cd6c27096d798e7f0b8efc72 --- .../launcher3/icons/GraphicsUtils.java | 27 +++++++++ .../android/launcher3/AutoInstallsLayout.java | 4 +- .../launcher3/InstallShortcutReceiver.java | 3 +- src/com/android/launcher3/Utilities.java | 19 ------ .../launcher3/WidgetPreviewLoader.java | 3 +- .../launcher3/icons/BaseIconCache.java | 60 ++++++++++--------- .../android/launcher3/icons/IconCache.java | 19 +++++- .../icons/IconCacheUpdateHandler.java | 2 +- .../android/launcher3/util/ContentWriter.java | 4 +- 9 files changed, 86 insertions(+), 55 deletions(-) diff --git a/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java b/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java index b096cecb5c..11d5eef52c 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java +++ b/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java @@ -15,10 +15,18 @@ */ package com.android.launcher3.icons; +import android.graphics.Bitmap; +import android.util.Log; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + import androidx.annotation.ColorInt; public class GraphicsUtils { + private static final String TAG = "GraphicsUtils"; + /** * Set the alpha component of {@code color} to be {@code alpha}. Unlike the support lib version, * it bounds the alpha in valid range instead of throwing an exception to allow for safer @@ -33,4 +41,23 @@ public class GraphicsUtils { } return (color & 0x00ffffff) | (alpha << 24); } + + /** + * Compresses the bitmap to a byte array for serialization. + */ + public static byte[] flattenBitmap(Bitmap bitmap) { + // Try go guesstimate how much space the icon will take when serialized + // to avoid unnecessary allocations/copies during the write (4 bytes per pixel). + int size = bitmap.getWidth() * bitmap.getHeight() * 4; + ByteArrayOutputStream out = new ByteArrayOutputStream(size); + try { + bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); + out.flush(); + out.close(); + return out.toByteArray(); + } catch (IOException e) { + Log.w(TAG, "Could not write bitmap"); + return null; + } + } } diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java index c7c1d6ac0e..e5b1448b13 100644 --- a/src/com/android/launcher3/AutoInstallsLayout.java +++ b/src/com/android/launcher3/AutoInstallsLayout.java @@ -39,6 +39,7 @@ import android.util.Patterns; import com.android.launcher3.LauncherProvider.SqlArguments; import com.android.launcher3.LauncherSettings.Favorites; +import com.android.launcher3.icons.GraphicsUtils; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.Thunk; @@ -47,7 +48,6 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; -import java.util.ArrayList; import java.util.Locale; /** @@ -436,7 +436,7 @@ public class AutoInstallsLayout { // Auto installs should always support the current platform version. LauncherIcons li = LauncherIcons.obtain(mContext); - mValues.put(LauncherSettings.Favorites.ICON, Utilities.flattenBitmap( + mValues.put(LauncherSettings.Favorites.ICON, GraphicsUtils.flattenBitmap( li.createBadgedIconBitmap(icon, Process.myUserHandle(), VERSION.SDK_INT).icon)); li.recycle(); diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java index 73c999a923..ea59fff724 100644 --- a/src/com/android/launcher3/InstallShortcutReceiver.java +++ b/src/com/android/launcher3/InstallShortcutReceiver.java @@ -41,6 +41,7 @@ import android.util.Pair; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.icons.BitmapInfo; +import com.android.launcher3.icons.GraphicsUtils; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.shortcuts.ShortcutInfoCompat; @@ -457,7 +458,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver { .key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0)) .key(NAME_KEY).value(name); if (icon != null) { - byte[] iconByteArray = Utilities.flattenBitmap(icon); + byte[] iconByteArray = GraphicsUtils.flattenBitmap(icon); json = json.key(ICON_KEY).value( Base64.encodeToString( iconByteArray, 0, iconByteArray.length, Base64.DEFAULT)); diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index d11cfcb0cb..65f0703278 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -356,25 +356,6 @@ public final class Utilities { return null; } - /** - * Compresses the bitmap to a byte array for serialization. - */ - public static byte[] flattenBitmap(Bitmap bitmap) { - // Try go guesstimate how much space the icon will take when serialized - // to avoid unnecessary allocations/copies during the write. - int size = bitmap.getWidth() * bitmap.getHeight() * 4; - ByteArrayOutputStream out = new ByteArrayOutputStream(size); - try { - bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); - out.flush(); - out.close(); - return out.toByteArray(); - } catch (IOException e) { - Log.w(TAG, "Could not write bitmap"); - return null; - } - } - /** * Trims the string, removing all whitespace at the beginning and end of the string. * Non-breaking whitespaces are also removed. diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java index d47dcee92c..050849cc2b 100644 --- a/src/com/android/launcher3/WidgetPreviewLoader.java +++ b/src/com/android/launcher3/WidgetPreviewLoader.java @@ -31,6 +31,7 @@ import android.util.LongSparseArray; import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.compat.ShortcutConfigActivityInfo; import com.android.launcher3.compat.UserManagerCompat; +import com.android.launcher3.icons.GraphicsUtils; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.icons.ShadowGenerator; import com.android.launcher3.icons.IconCache; @@ -149,7 +150,7 @@ public class WidgetPreviewLoader { values.put(CacheDb.COLUMN_PACKAGE, key.componentName.getPackageName()); values.put(CacheDb.COLUMN_VERSION, versions[0]); values.put(CacheDb.COLUMN_LAST_UPDATED, versions[1]); - values.put(CacheDb.COLUMN_PREVIEW_BITMAP, Utilities.flattenBitmap(preview)); + values.put(CacheDb.COLUMN_PREVIEW_BITMAP, GraphicsUtils.flattenBitmap(preview)); mDb.insertOrReplace(values); } diff --git a/src/com/android/launcher3/icons/BaseIconCache.java b/src/com/android/launcher3/icons/BaseIconCache.java index 1f810b39f1..9a2e287dbe 100644 --- a/src/com/android/launcher3/icons/BaseIconCache.java +++ b/src/com/android/launcher3/icons/BaseIconCache.java @@ -42,13 +42,9 @@ import android.text.TextUtils; import android.util.Log; import com.android.launcher3.IconProvider; -import com.android.launcher3.LauncherFiles; import com.android.launcher3.LauncherModel; -import com.android.launcher3.Utilities; -import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.graphics.BitmapRenderer; import com.android.launcher3.util.ComponentKey; -import com.android.launcher3.util.InstantAppResolver; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.Provider; import com.android.launcher3.util.SQLiteCacheHelper; @@ -58,7 +54,7 @@ import java.util.HashSet; import androidx.annotation.NonNull; -public class BaseIconCache { +public abstract class BaseIconCache { private static final String TAG = "BaseIconCache"; private static final boolean DEBUG = false; @@ -76,26 +72,24 @@ public class BaseIconCache { private final HashMap mDefaultIcons = new HashMap<>(); - final Context mContext; - final PackageManager mPackageManager; - final IconProvider mIconProvider; - final UserManagerCompat mUserManager; + protected final Context mContext; + protected final PackageManager mPackageManager; + protected final IconProvider mIconProvider; private final HashMap mCache = new HashMap<>(INITIAL_ICON_CACHE_CAPACITY); - private final InstantAppResolver mInstantAppResolver; final Handler mWorkerHandler; - int mIconDpi; + protected int mIconDpi; IconDB mIconDb; + private final String mDbFileName; private final BitmapFactory.Options mDecodeOptions; - public BaseIconCache(Context context, int iconDpi, int iconPixelSize) { + public BaseIconCache(Context context, String dbFileName, int iconDpi, int iconPixelSize) { mContext = context; + mDbFileName = dbFileName; mPackageManager = context.getPackageManager(); - mUserManager = UserManagerCompat.getInstance(mContext); - mInstantAppResolver = InstantAppResolver.newInstance(mContext); mIconProvider = IconProvider.newInstance(context); mWorkerHandler = new Handler(LauncherModel.getWorkerLooper()); @@ -108,9 +102,21 @@ public class BaseIconCache { } mIconDpi = iconDpi; - mIconDb = new IconDB(context, iconPixelSize); + mIconDb = new IconDB(context, dbFileName, iconPixelSize); } + /** + * Returns the persistable serial number for {@param user}. Subclass should implement proper + * caching strategy to avoid making binder call every time. + */ + protected abstract long getSerialNumberForUser(UserHandle user); + + /** + * Return true if the given app is an instant app and should be badged appropriately. + */ + protected abstract boolean isInstantApp(ApplicationInfo info); + + public void updateIconParams(int iconDpi, int iconPixelSize) { mWorkerHandler.post(() -> updateIconParamsBg(iconDpi, iconPixelSize)); } @@ -120,13 +126,14 @@ public class BaseIconCache { mDefaultIcons.clear(); mIconDb.close(); - mIconDb = new IconDB(mContext, iconPixelSize); + mIconDb = new IconDB(mContext, mDbFileName, iconPixelSize); mCache.clear(); } private Drawable getFullResDefaultActivityIcon() { - return Resources.getSystem().getDrawableForDensity(Utilities.ATLEAST_OREO - ? android.R.drawable.sym_def_app_icon : android.R.mipmap.sym_def_app_icon, + return Resources.getSystem().getDrawableForDensity( + Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + ? android.R.drawable.sym_def_app_icon : android.R.mipmap.sym_def_app_icon, mIconDpi); } @@ -189,7 +196,7 @@ public class BaseIconCache { */ public synchronized void removeIconsForPkg(String packageName, UserHandle user) { removeFromMemCacheLocked(packageName, user); - long userSerial = mUserManager.getSerialNumberForUser(user); + long userSerial = getSerialNumberForUser(user); mIconDb.delete( IconDB.COLUMN_COMPONENT + " LIKE ? AND " + IconDB.COLUMN_USER + " = ?", new String[]{packageName + "/%", Long.toString(userSerial)}); @@ -395,7 +402,7 @@ public class BaseIconCache { // only keep the low resolution icon instead of the larger full-sized icon BitmapInfo iconInfo = li.createBadgedIconBitmap( appInfo.loadIcon(mPackageManager), user, appInfo.targetSdkVersion, - mInstantAppResolver.isInstantApp(appInfo)); + isInstantApp(appInfo)); li.recycle(); entry.title = appInfo.loadLabel(mPackageManager); @@ -407,8 +414,7 @@ public class BaseIconCache { // package updates. ContentValues values = newContentValues( iconInfo, entry.title.toString(), packageName); - addIconToDB(values, cacheKey.componentName, info, - mUserManager.getSerialNumberForUser(user)); + addIconToDB(values, cacheKey.componentName, info, getSerialNumberForUser(user)); } catch (NameNotFoundException e) { if (DEBUG) Log.d(TAG, "Application not installed " + packageName); @@ -432,7 +438,7 @@ public class BaseIconCache { IconDB.COLUMN_COMPONENT + " = ? AND " + IconDB.COLUMN_USER + " = ?", new String[]{ cacheKey.componentName.flattenToString(), - Long.toString(mUserManager.getSerialNumberForUser(cacheKey.user))}); + 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); @@ -485,10 +491,8 @@ public class BaseIconCache { public 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, - TABLE_NAME); + public IconDB(Context context, String dbFileName, int iconPixelSize) { + super(context, dbFileName, (RELEASE_VERSION << 16) + iconPixelSize, TABLE_NAME); } @Override @@ -510,7 +514,7 @@ public class BaseIconCache { private ContentValues newContentValues(BitmapInfo bitmapInfo, String label, String packageName) { ContentValues values = new ContentValues(); values.put(IconDB.COLUMN_ICON, - bitmapInfo.isLowRes() ? null : Utilities.flattenBitmap(bitmapInfo.icon)); + bitmapInfo.isLowRes() ? null : GraphicsUtils.flattenBitmap(bitmapInfo.icon)); values.put(IconDB.COLUMN_ICON_COLOR, bitmapInfo.color); values.put(IconDB.COLUMN_LABEL, label); diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java index e10ff5b1b8..9c0a36374a 100644 --- a/src/com/android/launcher3/icons/IconCache.java +++ b/src/com/android/launcher3/icons/IconCache.java @@ -18,6 +18,7 @@ package com.android.launcher3.icons; import android.content.Context; import android.content.Intent; +import android.content.pm.ApplicationInfo; import android.content.pm.LauncherActivityInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -31,13 +32,16 @@ import android.util.Log; import com.android.launcher3.AppInfo; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.ItemInfoWithIcon; +import com.android.launcher3.LauncherFiles; import com.android.launcher3.LauncherModel; import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.ShortcutInfo; import com.android.launcher3.Utilities; import com.android.launcher3.compat.LauncherAppsCompat; +import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic; import com.android.launcher3.model.PackageItemInfo; +import com.android.launcher3.util.InstantAppResolver; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.Provider; @@ -56,15 +60,28 @@ public class IconCache extends BaseIconCache { private final CachingLogic mLauncherActivityInfoCachingLogic; private final LauncherAppsCompat mLauncherApps; + private final UserManagerCompat mUserManager; + private final InstantAppResolver mInstantAppResolver; private int mPendingIconRequestCount = 0; public IconCache(Context context, InvariantDeviceProfile inv) { - super(context, inv.fillResIconDpi, inv.iconBitmapSize); + super(context, LauncherFiles.APP_ICONS_DB, inv.fillResIconDpi, inv.iconBitmapSize); mComponentWithLabelCachingLogic = new ComponentCachingLogic(context); mLauncherActivityInfoCachingLogic = new LauncherActivtiyCachingLogic(this); mLauncherApps = LauncherAppsCompat.getInstance(mContext); + mUserManager = UserManagerCompat.getInstance(mContext); + mInstantAppResolver = InstantAppResolver.newInstance(mContext); + } + @Override + protected long getSerialNumberForUser(UserHandle user) { + return mUserManager.getSerialNumberForUser(user); + } + + @Override + protected boolean isInstantApp(ApplicationInfo info) { + return mInstantAppResolver.isInstantApp(info); } /** diff --git a/src/com/android/launcher3/icons/IconCacheUpdateHandler.java b/src/com/android/launcher3/icons/IconCacheUpdateHandler.java index 07451b9504..c679da4a8c 100644 --- a/src/com/android/launcher3/icons/IconCacheUpdateHandler.java +++ b/src/com/android/launcher3/icons/IconCacheUpdateHandler.java @@ -131,7 +131,7 @@ public class IconCacheUpdateHandler { if (ignorePackages == null) { ignorePackages = Collections.emptySet(); } - long userSerial = mIconCache.mUserManager.getSerialNumberForUser(user); + long userSerial = mIconCache.getSerialNumberForUser(user); Stack appsToUpdate = new Stack<>(); diff --git a/src/com/android/launcher3/util/ContentWriter.java b/src/com/android/launcher3/util/ContentWriter.java index 4384328912..00adf1069a 100644 --- a/src/com/android/launcher3/util/ContentWriter.java +++ b/src/com/android/launcher3/util/ContentWriter.java @@ -25,8 +25,8 @@ import android.os.UserHandle; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; -import com.android.launcher3.Utilities; import com.android.launcher3.compat.UserManagerCompat; +import com.android.launcher3.icons.GraphicsUtils; /** * A wrapper around {@link ContentValues} with some utility methods. @@ -97,7 +97,7 @@ public class ContentWriter { Preconditions.assertNonUiThread(); if (mIcon != null && !LauncherAppState.getInstance(context).getIconCache() .isDefaultIcon(mIcon, mUser)) { - mValues.put(LauncherSettings.Favorites.ICON, Utilities.flattenBitmap(mIcon)); + mValues.put(LauncherSettings.Favorites.ICON, GraphicsUtils.flattenBitmap(mIcon)); mIcon = null; } return mValues;