Lazy loading high res icons
> Loading low-res icons for icons which are not visible on the homescreen. Change-Id: I8ac7bf09f6030ed554cb60a4cd402f3f36ffe12b
This commit is contained in:
@@ -148,7 +148,7 @@ class AllAppsList {
|
||||
if (applicationInfo == null) {
|
||||
add(new AppInfo(context, info, user, mIconCache));
|
||||
} else {
|
||||
mIconCache.getTitleAndIcon(applicationInfo, info);
|
||||
mIconCache.getTitleAndIcon(applicationInfo, info, true /* useLowResIcon */);
|
||||
modified.add(applicationInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,11 @@ public class AppInfo extends ItemInfo {
|
||||
*/
|
||||
Bitmap iconBitmap;
|
||||
|
||||
/**
|
||||
* Indicates whether we're using a low res icon
|
||||
*/
|
||||
boolean usingLowResIcon;
|
||||
|
||||
/**
|
||||
* The time at which the app was first installed.
|
||||
*/
|
||||
@@ -79,7 +84,7 @@ public class AppInfo extends ItemInfo {
|
||||
|
||||
flags = initFlags(info);
|
||||
firstInstallTime = info.getFirstInstallTime();
|
||||
iconCache.getTitleAndIcon(this, info);
|
||||
iconCache.getTitleAndIcon(this, info, true /* useLowResIcon */);
|
||||
intent = makeLaunchIntent(context, info, user);
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ import android.view.MotionEvent;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.launcher3.IconCache.IconLoadRequest;
|
||||
|
||||
/**
|
||||
* TextView that draws a bubble behind the text. We cannot use a LineBackgroundSpan
|
||||
* because we want to make the bubble taller than the text and TextView's clip is
|
||||
@@ -74,6 +76,8 @@ public class BubbleTextView extends TextView {
|
||||
private boolean mStayPressed;
|
||||
private boolean mIgnorePressedStateChange;
|
||||
|
||||
private IconLoadRequest mIconLoadRequest;
|
||||
|
||||
public BubbleTextView(Context context) {
|
||||
this(context, null, 0);
|
||||
}
|
||||
@@ -163,6 +167,9 @@ public class BubbleTextView extends TextView {
|
||||
}
|
||||
// We don't need to check the info since it's not a ShortcutInfo
|
||||
super.setTag(info);
|
||||
|
||||
// Verify high res immediately
|
||||
verifyHighRes();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -450,4 +457,42 @@ public class BubbleTextView extends TextView {
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the item info if it is same as what the view is pointing to currently.
|
||||
*/
|
||||
public void reapplyItemInfo(final ItemInfo info) {
|
||||
if (getTag() == info) {
|
||||
mIconLoadRequest = null;
|
||||
if (info instanceof AppInfo) {
|
||||
applyFromApplicationInfo((AppInfo) info);
|
||||
} else if (info instanceof ShortcutInfo) {
|
||||
applyFromShortcutInfo((ShortcutInfo) info,
|
||||
LauncherAppState.getInstance().getIconCache(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the current icon is high-res otherwise posts a request to load the icon.
|
||||
*/
|
||||
public void verifyHighRes() {
|
||||
if (mIconLoadRequest != null) {
|
||||
mIconLoadRequest.cancel();
|
||||
mIconLoadRequest = null;
|
||||
}
|
||||
if (getTag() instanceof AppInfo) {
|
||||
AppInfo info = (AppInfo) getTag();
|
||||
if (info.usingLowResIcon) {
|
||||
mIconLoadRequest = LauncherAppState.getInstance().getIconCache()
|
||||
.updateIconInBackground(BubbleTextView.this, info);
|
||||
}
|
||||
} else if (getTag() instanceof ShortcutInfo) {
|
||||
ShortcutInfo info = (ShortcutInfo) getTag();
|
||||
if (info.usingLowResIcon) {
|
||||
mIconLoadRequest = LauncherAppState.getInstance().getIconCache()
|
||||
.updateIconInBackground(BubbleTextView.this, info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,6 +536,11 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
|
||||
if (mDragController.isDragging()) {
|
||||
mDragController.forceTouchMove();
|
||||
}
|
||||
|
||||
if (ALLOW_FOLDER_SCROLL) {
|
||||
FolderPagedView pages = (FolderPagedView) mContent;
|
||||
pages.verifyVisibleHighResIcons(pages.getNextPage());
|
||||
}
|
||||
}
|
||||
|
||||
public void beginExternalDrag(ShortcutInfo item) {
|
||||
|
||||
@@ -58,7 +58,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
|
||||
private CheckLongPressHelper mLongPressHelper;
|
||||
|
||||
// The number of icons to display in the
|
||||
private static final int NUM_ITEMS_IN_PREVIEW = 3;
|
||||
public static final int NUM_ITEMS_IN_PREVIEW = 3;
|
||||
private static final int CONSUMPTION_ANIMATION_DURATION = 100;
|
||||
private static final int DROP_IN_ANIMATION_DURATION = 400;
|
||||
private static final int INITIAL_ITEM_ANIMATION_DURATION = 350;
|
||||
|
||||
@@ -641,6 +641,28 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
|
||||
return p == getNextPage();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPageBeginMoving() {
|
||||
super.onPageBeginMoving();
|
||||
getVisiblePages(sTempPosArray);
|
||||
for (int i = sTempPosArray[0]; i <= sTempPosArray[1]; i++) {
|
||||
verifyVisibleHighResIcons(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that all the icons on the given page are of high-res
|
||||
*/
|
||||
public void verifyVisibleHighResIcons(int pageNo) {
|
||||
CellLayout page = getPageAt(pageNo);
|
||||
if (page != null) {
|
||||
ShortcutAndWidgetContainer parent = page.getShortcutsAndWidgets();
|
||||
for (int i = parent.getChildCount() - 1; i >= 0; i--) {
|
||||
((BubbleTextView) parent.getChildAt(i)).verifyHighRes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void realTimeReorder(int empty, int target) {
|
||||
completePendingPageChanges();
|
||||
|
||||
@@ -31,8 +31,10 @@ import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -62,10 +64,13 @@ public class IconCache {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static final int LOW_RES_SCALE_FACTOR = 8;
|
||||
|
||||
private static class CacheEntry {
|
||||
public Bitmap icon;
|
||||
public CharSequence title;
|
||||
public CharSequence contentDescription;
|
||||
public boolean isLowResIcon;
|
||||
}
|
||||
|
||||
private final HashMap<UserHandleCompat, Bitmap> mDefaultIcons =
|
||||
@@ -79,6 +84,8 @@ public class IconCache {
|
||||
private final int mIconDpi;
|
||||
private final IconDB mIconDb;
|
||||
|
||||
private final Handler mWorkerHandler;
|
||||
|
||||
public IconCache(Context context) {
|
||||
ActivityManager activityManager =
|
||||
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
@@ -89,6 +96,8 @@ public class IconCache {
|
||||
mLauncherApps = LauncherAppsCompat.getInstance(mContext);
|
||||
mIconDpi = activityManager.getLauncherLargeIconDensity();
|
||||
mIconDb = new IconDB(context);
|
||||
|
||||
mWorkerHandler = new Handler(LauncherModel.sWorkerThread.getLooper());
|
||||
}
|
||||
|
||||
private Drawable getFullResDefaultActivityIcon() {
|
||||
@@ -306,10 +315,7 @@ public class IconCache {
|
||||
entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, app.getUser());
|
||||
mCache.put(new ComponentKey(app.getComponentName(), app.getUser()), entry);
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(IconDB.COLUMN_ICON, ItemInfo.flattenBitmap(entry.icon));
|
||||
values.put(IconDB.COLUMN_LABEL, entry.title.toString());
|
||||
return values;
|
||||
return mIconDb.newContentValues(entry.icon, entry.title.toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -334,17 +340,53 @@ public class IconCache {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches high-res icon for the provided ItemInfo and updates the caller when done.
|
||||
* @return a request ID that can be used to cancel the request.
|
||||
*/
|
||||
public IconLoadRequest updateIconInBackground(final BubbleTextView caller, final ItemInfo info) {
|
||||
Runnable request = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (info instanceof AppInfo) {
|
||||
getTitleAndIcon((AppInfo) info, null, false);
|
||||
} else if (info instanceof ShortcutInfo) {
|
||||
ShortcutInfo st = (ShortcutInfo) info;
|
||||
getTitleAndIcon(st,
|
||||
st.promisedIntent != null ? st.promisedIntent : st.intent,
|
||||
st.user, false);
|
||||
}
|
||||
caller.post(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
caller.reapplyItemInfo(info);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
mWorkerHandler.post(request);
|
||||
return new IconLoadRequest(request, mWorkerHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in "application" with the icon and label for "info."
|
||||
*/
|
||||
public synchronized void getTitleAndIcon(AppInfo application, LauncherActivityInfoCompat info) {
|
||||
CacheEntry entry = cacheLocked(application.componentName, info, info.getUser(), false);
|
||||
|
||||
public synchronized void getTitleAndIcon(AppInfo application,
|
||||
LauncherActivityInfoCompat info, boolean useLowResIcon) {
|
||||
CacheEntry entry = cacheLocked(application.componentName, info,
|
||||
info == null ? application.user : info.getUser(),
|
||||
false, useLowResIcon);
|
||||
application.title = entry.title;
|
||||
application.iconBitmap = entry.icon;
|
||||
application.contentDescription = entry.contentDescription;
|
||||
application.usingLowResIcon = entry.isLowResIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a high res icon for the given intent and user
|
||||
*/
|
||||
public synchronized Bitmap getIcon(Intent intent, UserHandleCompat user) {
|
||||
ComponentName component = intent.getComponent();
|
||||
// null info means not installed, but if we have a component from the intent then
|
||||
@@ -354,7 +396,7 @@ public class IconCache {
|
||||
}
|
||||
|
||||
LauncherActivityInfoCompat launcherActInfo = mLauncherApps.resolveActivity(intent, user);
|
||||
CacheEntry entry = cacheLocked(component, launcherActInfo, user, true);
|
||||
CacheEntry entry = cacheLocked(component, launcherActInfo, user, true, true);
|
||||
return entry.icon;
|
||||
}
|
||||
|
||||
@@ -363,7 +405,7 @@ public class IconCache {
|
||||
* corresponding activity is not found, it reverts to the package icon.
|
||||
*/
|
||||
public synchronized void getTitleAndIcon(ShortcutInfo shortcutInfo, Intent intent,
|
||||
UserHandleCompat user) {
|
||||
UserHandleCompat user, boolean useLowResIcon) {
|
||||
ComponentName component = intent.getComponent();
|
||||
// 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.
|
||||
@@ -371,9 +413,10 @@ public class IconCache {
|
||||
shortcutInfo.setIcon(getDefaultIcon(user));
|
||||
shortcutInfo.title = "";
|
||||
shortcutInfo.usingFallbackIcon = true;
|
||||
shortcutInfo.usingLowResIcon = false;
|
||||
} else {
|
||||
LauncherActivityInfoCompat info = mLauncherApps.resolveActivity(intent, user);
|
||||
getTitleAndIcon(shortcutInfo, component, info, user, true);
|
||||
getTitleAndIcon(shortcutInfo, component, info, user, true, useLowResIcon);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,11 +425,12 @@ public class IconCache {
|
||||
*/
|
||||
public synchronized void getTitleAndIcon(
|
||||
ShortcutInfo shortcutInfo, ComponentName component, LauncherActivityInfoCompat info,
|
||||
UserHandleCompat user, boolean usePkgIcon) {
|
||||
CacheEntry entry = cacheLocked(component, info, user, usePkgIcon);
|
||||
UserHandleCompat user, boolean usePkgIcon, boolean useLowResIcon) {
|
||||
CacheEntry entry = cacheLocked(component, info, user, usePkgIcon, useLowResIcon);
|
||||
shortcutInfo.setIcon(entry.icon);
|
||||
shortcutInfo.title = entry.title;
|
||||
shortcutInfo.usingFallbackIcon = isDefaultIcon(entry.icon, user);
|
||||
shortcutInfo.usingLowResIcon = entry.isLowResIcon;
|
||||
}
|
||||
|
||||
public synchronized Bitmap getDefaultIcon(UserHandleCompat user) {
|
||||
@@ -405,15 +449,15 @@ public class IconCache {
|
||||
* This method is not thread safe, it must be called from a synchronized method.
|
||||
*/
|
||||
private CacheEntry cacheLocked(ComponentName componentName, LauncherActivityInfoCompat info,
|
||||
UserHandleCompat user, boolean usePackageIcon) {
|
||||
UserHandleCompat user, boolean usePackageIcon, boolean useLowResIcon) {
|
||||
ComponentKey cacheKey = new ComponentKey(componentName, user);
|
||||
CacheEntry entry = mCache.get(cacheKey);
|
||||
if (entry == null) {
|
||||
if (entry == null || (entry.isLowResIcon && !useLowResIcon)) {
|
||||
entry = new CacheEntry();
|
||||
mCache.put(cacheKey, entry);
|
||||
|
||||
// Check the DB first.
|
||||
if (!getEntryFromDB(componentName, user, entry)) {
|
||||
if (!getEntryFromDB(componentName, user, entry, useLowResIcon)) {
|
||||
if (info != null) {
|
||||
entry.icon = Utilities.createIconBitmap(info.getBadgedIcon(mIconDpi), mContext);
|
||||
} else {
|
||||
@@ -509,25 +553,26 @@ public class IconCache {
|
||||
// pass
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
ContentValues values = mIconDb.newContentValues(icon, label);
|
||||
values.put(IconDB.COLUMN_COMPONENT, componentName.flattenToString());
|
||||
values.put(IconDB.COLUMN_USER, userSerial);
|
||||
values.put(IconDB.COLUMN_ICON, ItemInfo.flattenBitmap(icon));
|
||||
values.put(IconDB.COLUMN_LABEL, label);
|
||||
mIconDb.getWritableDatabase().insertWithOnConflict(IconDB.TABLE_NAME, null, values,
|
||||
SQLiteDatabase.CONFLICT_REPLACE);
|
||||
}
|
||||
|
||||
private boolean getEntryFromDB(ComponentName component, UserHandleCompat user, CacheEntry entry) {
|
||||
private boolean getEntryFromDB(ComponentName component, UserHandleCompat user,
|
||||
CacheEntry entry, boolean lowRes) {
|
||||
Cursor c = mIconDb.getReadableDatabase().query(IconDB.TABLE_NAME,
|
||||
new String[] {IconDB.COLUMN_ICON, IconDB.COLUMN_LABEL},
|
||||
new String[] {lowRes ? IconDB.COLUMN_ICON_LOW_RES : IconDB.COLUMN_ICON,
|
||||
IconDB.COLUMN_LABEL},
|
||||
IconDB.COLUMN_COMPONENT + " = ? AND " + IconDB.COLUMN_USER + " = ?",
|
||||
new String[] {component.flattenToString(),
|
||||
Long.toString(mUserManager.getSerialNumberForUser(user))},
|
||||
null, null, null);
|
||||
try {
|
||||
if (c.moveToNext()) {
|
||||
entry.icon = Utilities.createIconBitmap(c, 0, mContext);
|
||||
entry.icon = loadIconNoResize(c, 0);
|
||||
entry.isLowResIcon = lowRes;
|
||||
entry.title = c.getString(1);
|
||||
if (entry.title == null) {
|
||||
entry.title = "";
|
||||
@@ -543,8 +588,22 @@ public class IconCache {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class IconLoadRequest {
|
||||
private final Runnable mRunnable;
|
||||
private final Handler mHandler;
|
||||
|
||||
IconLoadRequest(Runnable runnable, Handler handler) {
|
||||
mRunnable = runnable;
|
||||
mHandler = handler;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
mHandler.removeCallbacks(mRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class IconDB extends SQLiteOpenHelper {
|
||||
private final static int DB_VERSION = 1;
|
||||
private final static int DB_VERSION = 2;
|
||||
|
||||
private final static String TABLE_NAME = "icons";
|
||||
private final static String COLUMN_ROWID = "rowid";
|
||||
@@ -553,6 +612,7 @@ public class IconCache {
|
||||
private final static String COLUMN_LAST_UPDATED = "lastUpdated";
|
||||
private final static String COLUMN_VERSION = "version";
|
||||
private final static String COLUMN_ICON = "icon";
|
||||
private final static String COLUMN_ICON_LOW_RES = "icon_low_res";
|
||||
private final static String COLUMN_LABEL = "label";
|
||||
|
||||
public IconDB(Context context) {
|
||||
@@ -567,6 +627,7 @@ public class IconCache {
|
||||
COLUMN_LAST_UPDATED + " INTEGER NOT NULL DEFAULT 0, " +
|
||||
COLUMN_VERSION + " INTEGER NOT NULL DEFAULT 0, " +
|
||||
COLUMN_ICON + " BLOB, " +
|
||||
COLUMN_ICON_LOW_RES + " BLOB, " +
|
||||
COLUMN_LABEL + " TEXT, " +
|
||||
"PRIMARY KEY (" + COLUMN_COMPONENT + ", " + COLUMN_USER + ") " +
|
||||
");");
|
||||
@@ -590,5 +651,25 @@ public class IconCache {
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
|
||||
onCreate(db);
|
||||
}
|
||||
|
||||
public ContentValues newContentValues(Bitmap icon, String label) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(IconDB.COLUMN_ICON, ItemInfo.flattenBitmap(icon));
|
||||
values.put(IconDB.COLUMN_ICON_LOW_RES, ItemInfo.flattenBitmap(
|
||||
Bitmap.createScaledBitmap(icon,
|
||||
icon.getWidth() / LOW_RES_SCALE_FACTOR,
|
||||
icon.getHeight() / LOW_RES_SCALE_FACTOR, true)));
|
||||
values.put(IconDB.COLUMN_LABEL, label);
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
private static Bitmap loadIconNoResize(Cursor c, int iconIndex) {
|
||||
byte[] data = c.getBlob(iconIndex);
|
||||
try {
|
||||
return BitmapFactory.decodeByteArray(data, 0, data.length);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
|
||||
private static final String MIGRATE_AUTHORITY = "com.android.launcher2.settings";
|
||||
|
||||
private static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
|
||||
static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
|
||||
static {
|
||||
sWorkerThread.start();
|
||||
}
|
||||
@@ -2018,10 +2018,14 @@ public class LauncherModel extends BroadcastReceiver
|
||||
continue;
|
||||
}
|
||||
|
||||
container = c.getInt(containerIndex);
|
||||
boolean useLowResIcon = container >= 0 &&
|
||||
c.getInt(rankIndex) >= FolderIcon.NUM_ITEMS_IN_PREVIEW;
|
||||
|
||||
if (itemReplaced) {
|
||||
if (user.equals(UserHandleCompat.myUserHandle())) {
|
||||
info = getAppShortcutInfo(manager, intent, user, context, null,
|
||||
iconIndex, titleIndex, false);
|
||||
iconIndex, titleIndex, false, useLowResIcon);
|
||||
} else {
|
||||
// Don't replace items for other profiles.
|
||||
itemsToRemove.add(id);
|
||||
@@ -2032,7 +2036,8 @@ public class LauncherModel extends BroadcastReceiver
|
||||
Launcher.addDumpLog(TAG,
|
||||
"constructing info for partially restored package",
|
||||
true);
|
||||
info = getRestoredItemInfo(c, titleIndex, intent, promiseType);
|
||||
info = getRestoredItemInfo(c, titleIndex, intent,
|
||||
promiseType, useLowResIcon);
|
||||
intent = getRestoredItemIntent(c, context, intent);
|
||||
} else {
|
||||
// Don't restore items for other profiles.
|
||||
@@ -2042,7 +2047,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
} else if (itemType ==
|
||||
LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
|
||||
info = getAppShortcutInfo(manager, intent, user, context, c,
|
||||
iconIndex, titleIndex, allowMissingTarget);
|
||||
iconIndex, titleIndex, allowMissingTarget, useLowResIcon);
|
||||
} else {
|
||||
info = getShortcutInfo(c, context, iconTypeIndex,
|
||||
iconPackageIndex, iconResourceIndex, iconIndex,
|
||||
@@ -2064,7 +2069,6 @@ public class LauncherModel extends BroadcastReceiver
|
||||
if (info != null) {
|
||||
info.id = id;
|
||||
info.intent = intent;
|
||||
container = c.getInt(containerIndex);
|
||||
info.container = container;
|
||||
info.screenId = c.getInt(screenIndex);
|
||||
info.cellX = c.getInt(cellXIndex);
|
||||
@@ -3352,10 +3356,10 @@ public class LauncherModel extends BroadcastReceiver
|
||||
* to a package that is not yet installed on the system.
|
||||
*/
|
||||
public ShortcutInfo getRestoredItemInfo(Cursor cursor, int titleIndex, Intent intent,
|
||||
int promiseType) {
|
||||
int promiseType, boolean useLowResIcon) {
|
||||
final ShortcutInfo info = new ShortcutInfo();
|
||||
info.user = UserHandleCompat.myUserHandle();
|
||||
mIconCache.getTitleAndIcon(info, intent, info.user);
|
||||
mIconCache.getTitleAndIcon(info, intent, info.user, useLowResIcon);
|
||||
|
||||
if ((promiseType & ShortcutInfo.FLAG_RESTORED_ICON) != 0) {
|
||||
String title = (cursor != null) ? cursor.getString(titleIndex) : null;
|
||||
@@ -3404,7 +3408,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
*/
|
||||
public ShortcutInfo getAppShortcutInfo(PackageManager manager, Intent intent,
|
||||
UserHandleCompat user, Context context, Cursor c, int iconIndex, int titleIndex,
|
||||
boolean allowMissingTarget) {
|
||||
boolean allowMissingTarget, boolean useLowResIcon) {
|
||||
if (user == null) {
|
||||
Log.d(TAG, "Null user found in getShortcutInfo");
|
||||
return null;
|
||||
@@ -3426,7 +3430,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
}
|
||||
|
||||
final ShortcutInfo info = new ShortcutInfo();
|
||||
mIconCache.getTitleAndIcon(info, componentName, lai, user, false);
|
||||
mIconCache.getTitleAndIcon(info, componentName, lai, user, false, useLowResIcon);
|
||||
if (mIconCache.isDefaultIcon(info.getIcon(mIconCache), user) && c != null) {
|
||||
Bitmap icon = Utilities.createIconBitmap(c, iconIndex, context);
|
||||
info.setIcon(icon == null ? mIconCache.getDefaultIcon(user) : icon);
|
||||
|
||||
@@ -83,6 +83,11 @@ public class ShortcutInfo extends ItemInfo {
|
||||
*/
|
||||
boolean usingFallbackIcon;
|
||||
|
||||
/**
|
||||
* Indicates whether we're using a low res icon
|
||||
*/
|
||||
boolean usingLowResIcon;
|
||||
|
||||
/**
|
||||
* If isShortcut=true and customIcon=false, this contains a reference to the
|
||||
* shortcut icon as an application's resource.
|
||||
@@ -192,7 +197,8 @@ public class ShortcutInfo extends ItemInfo {
|
||||
|
||||
public void updateIcon(IconCache iconCache) {
|
||||
if (itemType == Favorites.ITEM_TYPE_APPLICATION) {
|
||||
iconCache.getTitleAndIcon(this, promisedIntent != null ? promisedIntent : intent, user);
|
||||
iconCache.getTitleAndIcon(this, promisedIntent != null ? promisedIntent : intent, user,
|
||||
shouldUseLowResIcon());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,5 +270,9 @@ public class ShortcutInfo extends ItemInfo {
|
||||
mInstallProgress = progress;
|
||||
status |= FLAG_INSTALL_SESSION_ACTIVE;
|
||||
}
|
||||
|
||||
public boolean shouldUseLowResIcon() {
|
||||
return usingLowResIcon && container >= 0 && rank >= FolderIcon.NUM_ITEMS_IN_PREVIEW;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4817,7 +4817,8 @@ public class Workspace extends SmoothPagedView
|
||||
if (shortcutInfo.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
|
||||
// For auto install apps update the icon as well as label.
|
||||
mIconCache.getTitleAndIcon(shortcutInfo,
|
||||
shortcutInfo.promisedIntent, user);
|
||||
shortcutInfo.promisedIntent, user,
|
||||
shortcutInfo.shouldUseLowResIcon());
|
||||
} else {
|
||||
// Only update the icon for restored apps.
|
||||
shortcutInfo.updateIcon(mIconCache);
|
||||
|
||||
Reference in New Issue
Block a user