Merge "Removing some Launcher3 dependencies from BaseIconCache" into ub-launcher3-master

This commit is contained in:
TreeHugger Robot 2018-11-07 20:16:21 +00:00 committed by Android (Google) Code Review
commit 8b8ff994d2
9 changed files with 86 additions and 55 deletions

View File

@ -15,10 +15,18 @@
*/ */
package com.android.launcher3.icons; 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; import androidx.annotation.ColorInt;
public class GraphicsUtils { 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, * 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 * 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); 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;
}
}
} }

View File

@ -39,6 +39,7 @@ import android.util.Patterns;
import com.android.launcher3.LauncherProvider.SqlArguments; import com.android.launcher3.LauncherProvider.SqlArguments;
import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.Thunk; import com.android.launcher3.util.Thunk;
@ -47,7 +48,6 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
/** /**
@ -436,7 +436,7 @@ public class AutoInstallsLayout {
// Auto installs should always support the current platform version. // Auto installs should always support the current platform version.
LauncherIcons li = LauncherIcons.obtain(mContext); 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.createBadgedIconBitmap(icon, Process.myUserHandle(), VERSION.SDK_INT).icon));
li.recycle(); li.recycle();

View File

@ -41,6 +41,7 @@ import android.util.Pair;
import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.ShortcutInfoCompat; import com.android.launcher3.shortcuts.ShortcutInfoCompat;
@ -457,7 +458,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
.key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0)) .key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0))
.key(NAME_KEY).value(name); .key(NAME_KEY).value(name);
if (icon != null) { if (icon != null) {
byte[] iconByteArray = Utilities.flattenBitmap(icon); byte[] iconByteArray = GraphicsUtils.flattenBitmap(icon);
json = json.key(ICON_KEY).value( json = json.key(ICON_KEY).value(
Base64.encodeToString( Base64.encodeToString(
iconByteArray, 0, iconByteArray.length, Base64.DEFAULT)); iconByteArray, 0, iconByteArray.length, Base64.DEFAULT));

View File

@ -356,25 +356,6 @@ public final class Utilities {
return null; 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. * Trims the string, removing all whitespace at the beginning and end of the string.
* Non-breaking whitespaces are also removed. * Non-breaking whitespaces are also removed.

View File

@ -31,6 +31,7 @@ import android.util.LongSparseArray;
import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.ShortcutConfigActivityInfo; import com.android.launcher3.compat.ShortcutConfigActivityInfo;
import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.ShadowGenerator; import com.android.launcher3.icons.ShadowGenerator;
import com.android.launcher3.icons.IconCache; 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_PACKAGE, key.componentName.getPackageName());
values.put(CacheDb.COLUMN_VERSION, versions[0]); values.put(CacheDb.COLUMN_VERSION, versions[0]);
values.put(CacheDb.COLUMN_LAST_UPDATED, versions[1]); 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); mDb.insertOrReplace(values);
} }

View File

@ -42,13 +42,9 @@ import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.android.launcher3.IconProvider; import com.android.launcher3.IconProvider;
import com.android.launcher3.LauncherFiles;
import com.android.launcher3.LauncherModel; 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.graphics.BitmapRenderer;
import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.Provider; import com.android.launcher3.util.Provider;
import com.android.launcher3.util.SQLiteCacheHelper; import com.android.launcher3.util.SQLiteCacheHelper;
@ -58,7 +54,7 @@ import java.util.HashSet;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
public class BaseIconCache { public abstract class BaseIconCache {
private static final String TAG = "BaseIconCache"; private static final String TAG = "BaseIconCache";
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
@ -76,26 +72,24 @@ public class BaseIconCache {
private final HashMap<UserHandle, BitmapInfo> mDefaultIcons = new HashMap<>(); private final HashMap<UserHandle, BitmapInfo> mDefaultIcons = new HashMap<>();
final Context mContext; protected final Context mContext;
final PackageManager mPackageManager; protected final PackageManager mPackageManager;
final IconProvider mIconProvider; protected final IconProvider mIconProvider;
final UserManagerCompat mUserManager;
private final HashMap<ComponentKey, CacheEntry> mCache = private final HashMap<ComponentKey, CacheEntry> mCache =
new HashMap<>(INITIAL_ICON_CACHE_CAPACITY); new HashMap<>(INITIAL_ICON_CACHE_CAPACITY);
private final InstantAppResolver mInstantAppResolver;
final Handler mWorkerHandler; final Handler mWorkerHandler;
int mIconDpi; protected int mIconDpi;
IconDB mIconDb; IconDB mIconDb;
private final String mDbFileName;
private final BitmapFactory.Options mDecodeOptions; 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; mContext = context;
mDbFileName = dbFileName;
mPackageManager = context.getPackageManager(); mPackageManager = context.getPackageManager();
mUserManager = UserManagerCompat.getInstance(mContext);
mInstantAppResolver = InstantAppResolver.newInstance(mContext);
mIconProvider = IconProvider.newInstance(context); mIconProvider = IconProvider.newInstance(context);
mWorkerHandler = new Handler(LauncherModel.getWorkerLooper()); mWorkerHandler = new Handler(LauncherModel.getWorkerLooper());
@ -108,9 +102,21 @@ public class BaseIconCache {
} }
mIconDpi = iconDpi; 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) { public void updateIconParams(int iconDpi, int iconPixelSize) {
mWorkerHandler.post(() -> updateIconParamsBg(iconDpi, iconPixelSize)); mWorkerHandler.post(() -> updateIconParamsBg(iconDpi, iconPixelSize));
} }
@ -120,12 +126,13 @@ public class BaseIconCache {
mDefaultIcons.clear(); mDefaultIcons.clear();
mIconDb.close(); mIconDb.close();
mIconDb = new IconDB(mContext, iconPixelSize); mIconDb = new IconDB(mContext, mDbFileName, iconPixelSize);
mCache.clear(); mCache.clear();
} }
private Drawable getFullResDefaultActivityIcon() { private Drawable getFullResDefaultActivityIcon() {
return Resources.getSystem().getDrawableForDensity(Utilities.ATLEAST_OREO 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, ? android.R.drawable.sym_def_app_icon : android.R.mipmap.sym_def_app_icon,
mIconDpi); mIconDpi);
} }
@ -189,7 +196,7 @@ public class BaseIconCache {
*/ */
public synchronized void removeIconsForPkg(String packageName, UserHandle user) { public synchronized void removeIconsForPkg(String packageName, UserHandle user) {
removeFromMemCacheLocked(packageName, user); removeFromMemCacheLocked(packageName, user);
long userSerial = mUserManager.getSerialNumberForUser(user); long userSerial = getSerialNumberForUser(user);
mIconDb.delete( mIconDb.delete(
IconDB.COLUMN_COMPONENT + " LIKE ? AND " + IconDB.COLUMN_USER + " = ?", IconDB.COLUMN_COMPONENT + " LIKE ? AND " + IconDB.COLUMN_USER + " = ?",
new String[]{packageName + "/%", Long.toString(userSerial)}); 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 // only keep the low resolution icon instead of the larger full-sized icon
BitmapInfo iconInfo = li.createBadgedIconBitmap( BitmapInfo iconInfo = li.createBadgedIconBitmap(
appInfo.loadIcon(mPackageManager), user, appInfo.targetSdkVersion, appInfo.loadIcon(mPackageManager), user, appInfo.targetSdkVersion,
mInstantAppResolver.isInstantApp(appInfo)); isInstantApp(appInfo));
li.recycle(); li.recycle();
entry.title = appInfo.loadLabel(mPackageManager); entry.title = appInfo.loadLabel(mPackageManager);
@ -407,8 +414,7 @@ public class BaseIconCache {
// package updates. // package updates.
ContentValues values = newContentValues( ContentValues values = newContentValues(
iconInfo, entry.title.toString(), packageName); iconInfo, entry.title.toString(), packageName);
addIconToDB(values, cacheKey.componentName, info, addIconToDB(values, cacheKey.componentName, info, getSerialNumberForUser(user));
mUserManager.getSerialNumberForUser(user));
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
if (DEBUG) Log.d(TAG, "Application not installed " + packageName); if (DEBUG) Log.d(TAG, "Application not installed " + packageName);
@ -432,7 +438,7 @@ public class BaseIconCache {
IconDB.COLUMN_COMPONENT + " = ? AND " + IconDB.COLUMN_USER + " = ?", IconDB.COLUMN_COMPONENT + " = ? AND " + IconDB.COLUMN_USER + " = ?",
new String[]{ new String[]{
cacheKey.componentName.flattenToString(), cacheKey.componentName.flattenToString(),
Long.toString(mUserManager.getSerialNumberForUser(cacheKey.user))}); Long.toString(getSerialNumberForUser(cacheKey.user))});
if (c.moveToNext()) { if (c.moveToNext()) {
// Set the alpha to be 255, so that we never have a wrong color // Set the alpha to be 255, so that we never have a wrong color
entry.color = setColorAlphaBound(c.getInt(0), 255); entry.color = setColorAlphaBound(c.getInt(0), 255);
@ -485,10 +491,8 @@ public class BaseIconCache {
public final static String[] COLUMNS_LOW_RES = new String[] { public final static String[] COLUMNS_LOW_RES = new String[] {
IconDB.COLUMN_ICON_COLOR, IconDB.COLUMN_LABEL }; IconDB.COLUMN_ICON_COLOR, IconDB.COLUMN_LABEL };
public IconDB(Context context, int iconPixelSize) { public IconDB(Context context, String dbFileName, int iconPixelSize) {
super(context, LauncherFiles.APP_ICONS_DB, super(context, dbFileName, (RELEASE_VERSION << 16) + iconPixelSize, TABLE_NAME);
(RELEASE_VERSION << 16) + iconPixelSize,
TABLE_NAME);
} }
@Override @Override
@ -510,7 +514,7 @@ public class BaseIconCache {
private ContentValues newContentValues(BitmapInfo bitmapInfo, String label, String packageName) { private ContentValues newContentValues(BitmapInfo bitmapInfo, String label, String packageName) {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(IconDB.COLUMN_ICON, 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_ICON_COLOR, bitmapInfo.color);
values.put(IconDB.COLUMN_LABEL, label); values.put(IconDB.COLUMN_LABEL, label);

View File

@ -18,6 +18,7 @@ package com.android.launcher3.icons;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo; import android.content.pm.LauncherActivityInfo;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@ -31,13 +32,16 @@ import android.util.Log;
import com.android.launcher3.AppInfo; import com.android.launcher3.AppInfo;
import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.ItemInfoWithIcon;
import com.android.launcher3.LauncherFiles;
import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherModel;
import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.ShortcutInfo; import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities; import com.android.launcher3.Utilities;
import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic; import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.Provider; import com.android.launcher3.util.Provider;
@ -56,15 +60,28 @@ public class IconCache extends BaseIconCache {
private final CachingLogic<LauncherActivityInfo> mLauncherActivityInfoCachingLogic; private final CachingLogic<LauncherActivityInfo> mLauncherActivityInfoCachingLogic;
private final LauncherAppsCompat mLauncherApps; private final LauncherAppsCompat mLauncherApps;
private final UserManagerCompat mUserManager;
private final InstantAppResolver mInstantAppResolver;
private int mPendingIconRequestCount = 0; private int mPendingIconRequestCount = 0;
public IconCache(Context context, InvariantDeviceProfile inv) { 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); mComponentWithLabelCachingLogic = new ComponentCachingLogic(context);
mLauncherActivityInfoCachingLogic = new LauncherActivtiyCachingLogic(this); mLauncherActivityInfoCachingLogic = new LauncherActivtiyCachingLogic(this);
mLauncherApps = LauncherAppsCompat.getInstance(mContext); 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);
} }
/** /**

View File

@ -128,7 +128,7 @@ public class IconCacheUpdateHandler {
if (ignorePackages == null) { if (ignorePackages == null) {
ignorePackages = Collections.emptySet(); ignorePackages = Collections.emptySet();
} }
long userSerial = mIconCache.mUserManager.getSerialNumberForUser(user); long userSerial = mIconCache.getSerialNumberForUser(user);
Stack<T> appsToUpdate = new Stack<>(); Stack<T> appsToUpdate = new Stack<>();

View File

@ -25,8 +25,8 @@ import android.os.UserHandle;
import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.icons.GraphicsUtils;
/** /**
* A wrapper around {@link ContentValues} with some utility methods. * A wrapper around {@link ContentValues} with some utility methods.
@ -97,7 +97,7 @@ public class ContentWriter {
Preconditions.assertNonUiThread(); Preconditions.assertNonUiThread();
if (mIcon != null && !LauncherAppState.getInstance(context).getIconCache() if (mIcon != null && !LauncherAppState.getInstance(context).getIconCache()
.isDefaultIcon(mIcon, mUser)) { .isDefaultIcon(mIcon, mUser)) {
mValues.put(LauncherSettings.Favorites.ICON, Utilities.flattenBitmap(mIcon)); mValues.put(LauncherSettings.Favorites.ICON, GraphicsUtils.flattenBitmap(mIcon));
mIcon = null; mIcon = null;
} }
return mValues; return mValues;