Lazy loading high res icons

> Loading low-res icons for icons which are not visible on
the homescreen.

Change-Id: I8ac7bf09f6030ed554cb60a4cd402f3f36ffe12b
diff --git a/src/com/android/launcher3/AllAppsList.java b/src/com/android/launcher3/AllAppsList.java
index 5ed7a62..dd646bb 100644
--- a/src/com/android/launcher3/AllAppsList.java
+++ b/src/com/android/launcher3/AllAppsList.java
@@ -148,7 +148,7 @@
                 if (applicationInfo == null) {
                     add(new AppInfo(context, info, user, mIconCache));
                 } else {
-                    mIconCache.getTitleAndIcon(applicationInfo, info);
+                    mIconCache.getTitleAndIcon(applicationInfo, info, true /* useLowResIcon */);
                     modified.add(applicationInfo);
                 }
             }
diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java
index 455c6d1..a1391b2 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -46,6 +46,11 @@
     Bitmap iconBitmap;
 
     /**
+     * Indicates whether we're using a low res icon
+     */
+    boolean usingLowResIcon;
+
+    /**
      * The time at which the app was first installed.
      */
     long firstInstallTime;
@@ -79,7 +84,7 @@
 
         flags = initFlags(info);
         firstInstallTime = info.getFirstInstallTime();
-        iconCache.getTitleAndIcon(this, info);
+        iconCache.getTitleAndIcon(this, info, true /* useLowResIcon */);
         intent = makeLaunchIntent(context, info, user);
         this.user = user;
     }
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 8ef234b..50549ca 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -34,6 +34,8 @@
 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 @@
     private boolean mStayPressed;
     private boolean mIgnorePressedStateChange;
 
+    private IconLoadRequest mIconLoadRequest;
+
     public BubbleTextView(Context context) {
         this(context, null, 0);
     }
@@ -163,6 +167,9 @@
         }
         // 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 @@
         }
         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);
+            }
+        }
+    }
 }
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index deb94ca..c7c6571 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -536,6 +536,11 @@
         if (mDragController.isDragging()) {
             mDragController.forceTouchMove();
         }
+
+        if (ALLOW_FOLDER_SCROLL) {
+            FolderPagedView pages = (FolderPagedView) mContent;
+            pages.verifyVisibleHighResIcons(pages.getNextPage());
+        }
     }
 
     public void beginExternalDrag(ShortcutInfo item) {
diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java
index a3e8295..dbfedaa 100644
--- a/src/com/android/launcher3/FolderIcon.java
+++ b/src/com/android/launcher3/FolderIcon.java
@@ -58,7 +58,7 @@
     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;
diff --git a/src/com/android/launcher3/FolderPagedView.java b/src/com/android/launcher3/FolderPagedView.java
index 5290644..21158b4 100644
--- a/src/com/android/launcher3/FolderPagedView.java
+++ b/src/com/android/launcher3/FolderPagedView.java
@@ -642,6 +642,28 @@
     }
 
     @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();
         int delay = 0;
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 43f838e..57d23a7 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -31,8 +31,10 @@
 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 @@
 
     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 @@
     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 @@
         mLauncherApps = LauncherAppsCompat.getInstance(mContext);
         mIconDpi = activityManager.getLauncherLargeIconDensity();
         mIconDb = new IconDB(context);
+
+        mWorkerHandler = new Handler(LauncherModel.sWorkerThread.getLooper());
     }
 
     private Drawable getFullResDefaultActivityIcon() {
@@ -306,10 +315,7 @@
         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());
     }
 
 
@@ -335,16 +341,52 @@
     }
 
     /**
+     * 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 @@
         }
 
         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 @@
      * 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 @@
             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 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 @@
      * 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 @@
             // 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 @@
         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 @@
         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 @@
                     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 @@
             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;
+        }
     }
 }
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index d80debb..1e16baf 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -117,7 +117,7 @@
 
     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 @@
                                     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 @@
                                         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 @@
                                 } 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 @@
                                 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 @@
      * 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 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 @@
         }
 
         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);
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 08ffaa2..9f7da6c 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -84,6 +84,11 @@
     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 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 @@
         mInstallProgress = progress;
         status |= FLAG_INSTALL_SESSION_ACTIVE;
     }
+
+    public boolean shouldUseLowResIcon() {
+        return usingLowResIcon && container >= 0 && rank >= FolderIcon.NUM_ITEMS_IN_PREVIEW;
+    }
 }
 
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index a59e25e..7ebdf3a 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -4817,7 +4817,8 @@
                         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);