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;
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;
}
}
}

View File

@ -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();

View File

@ -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));

View File

@ -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.

View File

@ -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);
}

View File

@ -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<UserHandle, BitmapInfo> 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<ComponentKey, CacheEntry> 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,12 +126,13 @@ 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
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);

View File

@ -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<LauncherActivityInfo> 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);
}
/**

View File

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

View File

@ -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;