Moving BaseIconCache to icon lib

Change-Id: I4fb56dcd6231a848d152e690edaf8885efbc995a
This commit is contained in:
Sunny Goyal 2018-11-08 10:51:05 -08:00
parent 024659c1b0
commit 1a9cbd3c88
14 changed files with 115 additions and 78 deletions

View File

@ -26,10 +26,11 @@ import static com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR;
* This class will be moved to androidx library. There shouldn't be any dependency outside
* this package.
*/
public class BaseIconFactory {
public class BaseIconFactory implements AutoCloseable {
private static final int DEFAULT_WRAPPER_BACKGROUND = Color.WHITE;
public static final boolean ATLEAST_OREO = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
static final boolean ATLEAST_OREO = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
static final boolean ATLEAST_P = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
private final Rect mOldBounds = new Rect();
private final Context mContext;
@ -115,6 +116,29 @@ public class BaseIconFactory {
return createBadgedIconBitmap(icon, user, shrinkNonAdaptiveIcons, isInstantApp, null);
}
public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
int iconAppTargetSdk) {
return createBadgedIconBitmap(icon, user, iconAppTargetSdk, false);
}
public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
int iconAppTargetSdk, boolean isInstantApp) {
return createBadgedIconBitmap(icon, user, iconAppTargetSdk, isInstantApp, null);
}
public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
int iconAppTargetSdk, boolean isInstantApp, float[] scale) {
boolean shrinkNonAdaptiveIcons = ATLEAST_P ||
(ATLEAST_OREO && iconAppTargetSdk >= Build.VERSION_CODES.O);
return createBadgedIconBitmap(icon, user, shrinkNonAdaptiveIcons, isInstantApp, scale);
}
public Bitmap createScaledBitmapWithoutShadow(Drawable icon, int iconAppTargetSdk) {
boolean shrinkNonAdaptiveIcons = ATLEAST_P ||
(ATLEAST_OREO && iconAppTargetSdk >= Build.VERSION_CODES.O);
return createScaledBitmapWithoutShadow(icon, shrinkNonAdaptiveIcons);
}
/**
* Creates bitmap using the source drawable and various parameters.
* The bitmap is visually normalized with other icons and has enough spacing to add shadow.
@ -277,6 +301,9 @@ public class BaseIconFactory {
return bitmap;
}
@Override
public void close() { }
/**
* An extension of {@link BitmapDrawable} which returns the bitmap pixel size as intrinsic size.
* This allows the badging to be done based on the action bitmap size rather than

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.icons;
package com.android.launcher3.icons.cache;
import static com.android.launcher3.icons.BitmapInfo.LOW_RES_ICON;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
@ -42,14 +42,17 @@ import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import com.android.launcher3.IconProvider;
import com.android.launcher3.icons.BaseIconFactory;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.Provider;
import com.android.launcher3.util.SQLiteCacheHelper;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import androidx.annotation.NonNull;
@ -72,14 +75,14 @@ public abstract class BaseIconCache {
protected final Context mContext;
protected final PackageManager mPackageManager;
protected final IconProvider mIconProvider;
private final HashMap<ComponentKey, CacheEntry> mCache =
new HashMap<>(INITIAL_ICON_CACHE_CAPACITY);
protected final Handler mWorkerHandler;
protected int mIconDpi;
IconDB mIconDb;
protected IconDB mIconDb;
protected String mSystemState = "";
private final String mDbFileName;
private final BitmapFactory.Options mDecodeOptions;
@ -91,8 +94,6 @@ public abstract class BaseIconCache {
mDbFileName = dbFileName;
mPackageManager = context.getPackageManager();
mBgLooper = bgLooper;
mIconProvider = IconProvider.newInstance(context);
mWorkerHandler = new Handler(mBgLooper);
if (BitmapRenderer.USE_HARDWARE_BITMAP && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@ -102,6 +103,7 @@ public abstract class BaseIconCache {
mDecodeOptions = null;
}
updateSystemState();
mIconDpi = iconDpi;
mIconDb = new IconDB(context, dbFileName, iconPixelSize);
}
@ -117,6 +119,10 @@ public abstract class BaseIconCache {
*/
protected abstract boolean isInstantApp(ApplicationInfo info);
/**
* Opens and returns an icon factory. The factory is recycled by the caller.
*/
protected abstract BaseIconFactory getIconFactory();
public void updateIconParams(int iconDpi, int iconPixelSize) {
mWorkerHandler.post(() -> updateIconParamsBg(iconDpi, iconPixelSize));
@ -163,7 +169,7 @@ public abstract class BaseIconCache {
}
protected BitmapInfo makeDefaultIcon(UserHandle user) {
try (LauncherIcons li = LauncherIcons.obtain(mContext)) {
try (BaseIconFactory li = getIconFactory()) {
return li.createBadgedIconBitmap(
getFullResDefaultActivityIcon(), user, VERSION.SDK_INT);
}
@ -204,10 +210,29 @@ public abstract class BaseIconCache {
}
public IconCacheUpdateHandler getUpdateHandler() {
mIconProvider.updateSystemStateString(mContext);
updateSystemState();
return new IconCacheUpdateHandler(this);
}
/**
* Refreshes the system state definition used to check the validity of the cache. It
* incorporates all the properties that can affect the cache like locale and system-version.
*/
private void updateSystemState() {
final String locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
locale = mContext.getResources().getConfiguration().getLocales().toLanguageTags();
} else {
locale = Locale.getDefault().toString();
}
mSystemState = locale + "," + Build.VERSION.SDK_INT;
}
protected String getIconSystemState(String packageName) {
return mSystemState;
}
/**
* Adds an entry into the DB and the in-memory cache.
* @param replaceExisting if true, it will recreate the bitmap even if it already exists in
@ -215,7 +240,7 @@ public abstract class BaseIconCache {
* old data.
* package private
*/
synchronized <T> void addIconToDBAndMemCache(T object, CachingLogic<T> cachingLogic,
protected synchronized <T> void addIconToDBAndMemCache(T object, CachingLogic<T> cachingLogic,
PackageInfo info, long userSerial, boolean replaceExisting) {
UserHandle user = cachingLogic.getUser(object);
ComponentName componentName = cachingLogic.getComponent(object);
@ -282,7 +307,7 @@ public abstract class BaseIconCache {
@NonNull ComponentName componentName, @NonNull UserHandle user,
@NonNull Provider<T> infoProvider, @NonNull CachingLogic<T> cachingLogic,
boolean usePackageIcon, boolean useLowResIcon, boolean addToMemCache) {
Preconditions.assertWorkerThread();
assertWorkerThread();
ComponentKey cacheKey = new ComponentKey(componentName, user);
CacheEntry entry = mCache.get(cacheKey);
if (entry == null || (entry.isLowRes() && !useLowResIcon)) {
@ -336,7 +361,7 @@ public abstract class BaseIconCache {
}
public synchronized void clear() {
Preconditions.assertWorkerThread();
assertWorkerThread();
mIconDb.clear();
}
@ -359,9 +384,9 @@ public abstract class BaseIconCache {
entry.title = title;
}
if (icon != null) {
LauncherIcons li = LauncherIcons.obtain(mContext);
BaseIconFactory li = getIconFactory();
li.createIconBitmap(icon).applyTo(entry);
li.recycle();
li.close();
}
if (!TextUtils.isEmpty(title) && entry.icon != null) {
mCache.put(cacheKey, entry);
@ -379,7 +404,7 @@ public abstract class BaseIconCache {
*/
protected CacheEntry getEntryForPackageLocked(String packageName, UserHandle user,
boolean useLowResIcon) {
Preconditions.assertWorkerThread();
assertWorkerThread();
ComponentKey cacheKey = getPackageKey(packageName, user);
CacheEntry entry = mCache.get(cacheKey);
@ -398,13 +423,13 @@ public abstract class BaseIconCache {
throw new NameNotFoundException("ApplicationInfo is null");
}
LauncherIcons li = LauncherIcons.obtain(mContext);
BaseIconFactory li = getIconFactory();
// Load the full res icon for the application, but if useLowResIcon is set, then
// only keep the low resolution icon instead of the larger full-sized icon
BitmapInfo iconInfo = li.createBadgedIconBitmap(
appInfo.loadIcon(mPackageManager), user, appInfo.targetSdkVersion,
isInstantApp(appInfo));
li.recycle();
li.close();
entry.title = appInfo.loadLabel(mPackageManager);
entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user);
@ -519,8 +544,14 @@ public abstract class BaseIconCache {
values.put(IconDB.COLUMN_ICON_COLOR, bitmapInfo.color);
values.put(IconDB.COLUMN_LABEL, label);
values.put(IconDB.COLUMN_SYSTEM_STATE, mIconProvider.getIconSystemState(packageName));
values.put(IconDB.COLUMN_SYSTEM_STATE, getIconSystemState(packageName));
return values;
}
private void assertWorkerThread() {
if (Looper.myLooper() != mBgLooper) {
throw new IllegalStateException("Cache accessed on wrong thread " + Looper.myLooper());
}
}
}

View File

@ -13,12 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.icons;
package com.android.launcher3.icons.cache;
import android.content.ComponentName;
import android.content.Context;
import android.os.UserHandle;
import com.android.launcher3.icons.BitmapInfo;
public interface CachingLogic<T> {
ComponentName getComponent(T object);

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.icons;
package com.android.launcher3.icons.cache;
import android.os.Handler;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.icons;
package com.android.launcher3.icons.cache;
import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
@ -27,7 +27,7 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.SparseBooleanArray;
import com.android.launcher3.icons.BaseIconCache.IconDB;
import com.android.launcher3.icons.cache.BaseIconCache.IconDB;
import java.util.Collections;
import java.util.HashMap;
@ -83,7 +83,8 @@ public class IconCacheUpdateHandler {
private void createPackageInfoMap() {
PackageManager pm = mIconCache.mPackageManager;
for (PackageInfo info : pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES)) {
for (PackageInfo info :
pm.getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES)) {
mPkgInfoMap.put(info.packageName, info);
}
}
@ -122,6 +123,7 @@ public class IconCacheUpdateHandler {
* the DB and are updated.
* @return The set of packages for which icons have updated.
*/
@SuppressWarnings("unchecked")
private <T> void updateIconsPerUser(UserHandle user, HashMap<ComponentName, T> componentMap,
CachingLogic<T> cachingLogic, OnUpdateCallback onUpdateCallback) {
Set<String> ignorePackages = mPackagesToIgnore.get(user);
@ -171,7 +173,7 @@ public class IconCacheUpdateHandler {
T app = componentMap.remove(component);
if (version == info.versionCode && updateTime == info.lastUpdateTime &&
TextUtils.equals(c.getString(systemStateIndex),
mIconCache.mIconProvider.getIconSystemState(info.packageName))) {
mIconCache.getIconSystemState(info.packageName))) {
if (mFilterMode == MODE_CLEAR_VALID_ITEMS) {
mItemsToDelete.put(rowId, false);

View File

@ -27,7 +27,7 @@ import android.view.accessibility.AccessibilityManager;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.icons.HandlerRunnable;
import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.util.Preconditions;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.TaskKeyLruCache;

View File

@ -23,7 +23,7 @@ import android.os.Looper;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.icons.HandlerRunnable;
import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.util.Preconditions;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.TaskKeyLruCache;

View File

@ -3,38 +3,19 @@ package com.android.launcher3;
import android.content.Context;
import android.content.pm.LauncherActivityInfo;
import android.graphics.drawable.Drawable;
import android.os.Build;
import com.android.launcher3.util.ResourceBasedOverride;
import java.util.Locale;
public class IconProvider implements ResourceBasedOverride {
protected String mSystemState;
public static IconProvider newInstance(Context context) {
IconProvider provider = Overrides.getObject(
IconProvider.class, context, R.string.icon_provider_class);
provider.updateSystemStateString(context);
return provider;
return Overrides.getObject(IconProvider.class, context, R.string.icon_provider_class);
}
public IconProvider() { }
public void updateSystemStateString(Context context) {
final String locale;
if (Utilities.ATLEAST_NOUGAT) {
locale = context.getResources().getConfiguration().getLocales().toLanguageTags();
} else {
locale = Locale.getDefault().toString();
}
mSystemState = locale + "," + Build.VERSION.SDK_INT;
}
public String getIconSystemState(String packageName) {
return mSystemState;
public String getSystemStateForPackage(String systemState, String packageName) {
return systemState;
}
/**

View File

@ -20,6 +20,8 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import com.android.launcher3.icons.cache.CachingLogic;
public interface ComponentWithLabel {
ComponentName getComponent();

View File

@ -30,6 +30,7 @@ import android.os.UserHandle;
import android.util.Log;
import com.android.launcher3.AppInfo;
import com.android.launcher3.IconProvider;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfoWithIcon;
import com.android.launcher3.LauncherFiles;
@ -40,6 +41,9 @@ 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.icons.cache.BaseIconCache;
import com.android.launcher3.icons.cache.CachingLogic;
import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.Preconditions;
@ -62,6 +66,7 @@ public class IconCache extends BaseIconCache {
private final LauncherAppsCompat mLauncherApps;
private final UserManagerCompat mUserManager;
private final InstantAppResolver mInstantAppResolver;
private final IconProvider mIconProvider;
private int mPendingIconRequestCount = 0;
@ -73,6 +78,7 @@ public class IconCache extends BaseIconCache {
mLauncherApps = LauncherAppsCompat.getInstance(mContext);
mUserManager = UserManagerCompat.getInstance(mContext);
mInstantAppResolver = InstantAppResolver.newInstance(mContext);
mIconProvider = IconProvider.newInstance(context);
}
@Override
@ -85,6 +91,11 @@ public class IconCache extends BaseIconCache {
return mInstantAppResolver.isInstantApp(info);
}
@Override
protected BaseIconFactory getIconFactory() {
return LauncherIcons.obtain(mContext);
}
/**
* Updates the entries related to the given package in memory and persistent DB.
*/
@ -223,6 +234,11 @@ public class IconCache extends BaseIconCache {
return mIconProvider.getIcon(info, mIconDpi, flattenDrawable);
}
@Override
protected String getIconSystemState(String packageName) {
return mIconProvider.getSystemStateForPackage(mSystemState, packageName);
}
public static abstract class IconLoadRequest extends HandlerRunnable {
IconLoadRequest(Handler handler, Runnable endRunnable) {
super(handler, endRunnable);

View File

@ -20,6 +20,8 @@ import android.content.Context;
import android.content.pm.LauncherActivityInfo;
import android.os.UserHandle;
import com.android.launcher3.icons.cache.CachingLogic;
public class LauncherActivtiyCachingLogic implements CachingLogic<LauncherActivityInfo> {
private final IconCache mCache;

View File

@ -21,16 +21,13 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
import com.android.launcher3.AppInfo;
import com.android.launcher3.FastBitmapDrawable;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfoWithIcon;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.Utilities;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
@ -112,29 +109,6 @@ public class LauncherIcons extends BaseIconFactory implements AutoCloseable {
recycle();
}
public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
int iconAppTargetSdk) {
return createBadgedIconBitmap(icon, user, iconAppTargetSdk, false);
}
public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
int iconAppTargetSdk, boolean isInstantApp) {
return createBadgedIconBitmap(icon, user, iconAppTargetSdk, isInstantApp, null);
}
public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
int iconAppTargetSdk, boolean isInstantApp, float[] scale) {
boolean shrinkNonAdaptiveIcons = Utilities.ATLEAST_P ||
(Utilities.ATLEAST_OREO && iconAppTargetSdk >= Build.VERSION_CODES.O);
return createBadgedIconBitmap(icon, user, shrinkNonAdaptiveIcons, isInstantApp, scale);
}
public Bitmap createScaledBitmapWithoutShadow(Drawable icon, int iconAppTargetSdk) {
boolean shrinkNonAdaptiveIcons = Utilities.ATLEAST_P ||
(Utilities.ATLEAST_OREO && iconAppTargetSdk >= Build.VERSION_CODES.O);
return createScaledBitmapWithoutShadow(icon, shrinkNonAdaptiveIcons);
}
// below methods should also migrate to BaseIconFactory
public BitmapInfo createShortcutIcon(ShortcutInfoCompat shortcutInfo) {

View File

@ -45,7 +45,7 @@ import com.android.launcher3.AppInfo;
import com.android.launcher3.FolderInfo;
import com.android.launcher3.icons.ComponentWithLabel;
import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
import com.android.launcher3.icons.IconCacheUpdateHandler;
import com.android.launcher3.icons.cache.IconCacheUpdateHandler;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.InstallShortcutReceiver;
import com.android.launcher3.ItemInfo;

View File

@ -23,7 +23,7 @@ import androidx.test.rule.provider.ProviderTestRule;
import com.android.launcher3.AllAppsList;
import com.android.launcher3.AppFilter;
import com.android.launcher3.AppInfo;
import com.android.launcher3.icons.CachingLogic;
import com.android.launcher3.icons.cache.CachingLogic;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfo;