Enforcing background thread when accessing iconCacheDb.

> Moving any icon cache access to background thread
> Updating Apps list to avoid loading icons for ignored apps

Bug: 21325319
Change-Id: Id72755100f1176ccfcc99249c5e02873cc249a13
diff --git a/src/com/android/launcher3/AllAppsList.java b/src/com/android/launcher3/AllAppsList.java
index 34a44fc..2bf014a 100644
--- a/src/com/android/launcher3/AllAppsList.java
+++ b/src/com/android/launcher3/AllAppsList.java
@@ -65,13 +65,15 @@
      *
      * If the app is already in the list, doesn't add it.
      */
-    public void add(AppInfo info) {
+    public void add(AppInfo info, LauncherActivityInfoCompat activityInfo) {
         if (!mAppFilter.shouldShowApp(info.componentName)) {
             return;
         }
         if (findActivity(data, info.componentName, info.user)) {
             return;
         }
+        mIconCache.getTitleAndIcon(info, activityInfo, true /* useLowResIcon */);
+
         data.add(info);
         added.add(info);
     }
@@ -101,7 +103,7 @@
                 user);
 
         for (LauncherActivityInfoCompat info : matches) {
-            add(new AppInfo(context, info, user, mIconCache));
+            add(new AppInfo(context, info, user), info);
         }
     }
 
@@ -171,7 +173,7 @@
                         info.getComponentName().getPackageName(), user,
                         info.getComponentName().getClassName());
                 if (applicationInfo == null) {
-                    add(new AppInfo(context, info, user, mIconCache));
+                    add(new AppInfo(context, info, user), info);
                 } else {
                     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 9c9dcc5..9b23df3 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -58,19 +58,12 @@
     /**
      * Must not hold the Context.
      */
-    public AppInfo(Context context, LauncherActivityInfoCompat info, UserHandle user,
-            IconCache iconCache) {
-        this(context, info, user, iconCache,
-                UserManagerCompat.getInstance(context).isQuietModeEnabled(user));
+    public AppInfo(Context context, LauncherActivityInfoCompat info, UserHandle user) {
+        this(context, info, user, UserManagerCompat.getInstance(context).isQuietModeEnabled(user));
     }
 
     public AppInfo(Context context, LauncherActivityInfoCompat info, UserHandle user,
-            IconCache iconCache, boolean quietModeEnabled) {
-        this(context, info, user, iconCache, quietModeEnabled, true /* useLowResIcon */);
-    }
-
-    public AppInfo(Context context, LauncherActivityInfoCompat info, UserHandle user,
-            IconCache iconCache, boolean quietModeEnabled, boolean useLowResIcon) {
+            boolean quietModeEnabled) {
         this.componentName = info.getComponentName();
         this.container = ItemInfo.NO_ID;
         this.user = user;
@@ -82,7 +75,6 @@
         }
 
         intent = makeLaunchIntent(context, info, user);
-        iconCache.getTitleAndIcon(this, info, useLowResIcon);
     }
 
     public AppInfo(AppInfo info) {
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 7c50a5c..603d25a 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -52,6 +52,7 @@
 import com.android.launcher3.graphics.LauncherIcons;
 import com.android.launcher3.model.PackageItemInfo;
 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 com.android.launcher3.util.Thunk;
@@ -188,7 +189,7 @@
         return getFullResDefaultActivityIcon();
     }
 
-    private Bitmap makeDefaultIcon(UserHandle user) {
+    protected Bitmap makeDefaultIcon(UserHandle user) {
         Drawable unbadged = getFullResDefaultActivityIcon();
         return LauncherIcons.createBadgedIconBitmap(unbadged, user, mContext);
     }
@@ -517,6 +518,7 @@
             @NonNull ComponentName componentName,
             @NonNull Provider<LauncherActivityInfoCompat> infoProvider,
             UserHandle user, boolean usePackageIcon, boolean useLowResIcon) {
+        Preconditions.assertWorkerThread();
         ComponentKey cacheKey = new ComponentKey(componentName, user);
         CacheEntry entry = mCache.get(cacheKey);
         if (entry == null || (entry.isLowResIcon && !useLowResIcon)) {
@@ -604,6 +606,7 @@
      */
     private CacheEntry getEntryForPackageLocked(String packageName, UserHandle user,
             boolean useLowResIcon) {
+        Preconditions.assertWorkerThread();
         ComponentKey cacheKey = getPackageKey(packageName, user);
         CacheEntry entry = mCache.get(cacheKey);
 
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index ecbfe38..cba7cfe 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -26,6 +26,7 @@
 import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.os.Looper;
 import android.os.Parcelable;
 import android.os.Process;
 import android.os.UserHandle;
@@ -436,10 +437,25 @@
 
         public ItemInfo getItemInfo() {
             if (activityInfo != null) {
-                return new AppInfo(mContext, activityInfo, user,
-                        LauncherAppState.getInstance().getIconCache(),
-                        UserManagerCompat.getInstance(mContext).isQuietModeEnabled(user),
-                        false /* useLowResIcon */).makeShortcut();
+                AppInfo appInfo = new AppInfo(mContext, activityInfo, user);
+                final LauncherAppState app = LauncherAppState.getInstance();
+                // Set default values until proper values is loaded.
+                appInfo.title = "";
+                appInfo.iconBitmap = app.getIconCache().getDefaultIcon(user);
+                final ShortcutInfo si = appInfo.makeShortcut();
+                if (Looper.myLooper() == LauncherModel.getWorkerLooper()) {
+                    app.getIconCache().getTitleAndIcon(si, activityInfo, false /* useLowResIcon */);
+                } else {
+                    app.getModel().updateAndBindShortcutInfo(new Provider<ShortcutInfo>() {
+                        @Override
+                        public ShortcutInfo get() {
+                            app.getIconCache().getTitleAndIcon(
+                                    si, activityInfo, false /* useLowResIcon */);
+                            return si;
+                        }
+                    });
+                }
+                return si;
             } else if (shortcutInfo != null) {
                 return new ShortcutInfo(shortcutInfo, mContext);
             } else if (providerInfo != null) {
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 616b2c7..56892ff 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -2029,7 +2029,7 @@
                 for (int i = 0; i < apps.size(); i++) {
                     LauncherActivityInfoCompat app = apps.get(i);
                     // This builds the icon bitmaps.
-                    mBgAllAppsList.add(new AppInfo(mContext, app, user, mIconCache, quietMode));
+                    mBgAllAppsList.add(new AppInfo(mContext, app, user, quietMode), app);
                 }
 
                 final ManagedProfileHeuristic heuristic = ManagedProfileHeuristic.get(mContext, user);
@@ -2221,17 +2221,16 @@
     }
 
     /**
-     * Repopulates the shortcut info, possibly updating any icon already on the workspace.
+     * Utility method to update a shortcut on the background thread.
      */
-    public void updateShortcutInfo(final ShortcutInfoCompat fullDetail, final ShortcutInfo info) {
+    public void updateAndBindShortcutInfo(final Provider<ShortcutInfo> shortcutProvider) {
         enqueueModelUpdateTask(new ExtendedModelTask() {
             @Override
             public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
-                info.updateFromDeepShortcutInfo(fullDetail, app.getContext());
-
+                ShortcutInfo info = shortcutProvider.get();
                 ArrayList<ShortcutInfo> update = new ArrayList<>();
                 update.add(info);
-                bindUpdatedShortcuts(update, fullDetail.getUserHandle());
+                bindUpdatedShortcuts(update, info.user);
             }
         });
     }
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutView.java b/src/com/android/launcher3/shortcuts/DeepShortcutView.java
index 6796137..04c71ec 100644
--- a/src/com/android/launcher3/shortcuts/DeepShortcutView.java
+++ b/src/com/android/launcher3/shortcuts/DeepShortcutView.java
@@ -34,6 +34,7 @@
 import com.android.launcher3.shortcuts.DeepShortcutsContainer.UnbadgedShortcutInfo;
 import com.android.launcher3.util.PillRevealOutlineProvider;
 import com.android.launcher3.util.PillWidthRevealOutlineProvider;
+import com.android.launcher3.util.Provider;
 
 /**
  * A {@link android.widget.FrameLayout} that contains a {@link DeepShortcutView}.
@@ -114,10 +115,17 @@
      * Returns the shortcut info that is suitable to be added on the homescreen
      */
     public ShortcutInfo getFinalInfo() {
-        ShortcutInfo badged = new ShortcutInfo(mInfo);
+        final ShortcutInfo badged = new ShortcutInfo(mInfo);
         // Queue an update task on the worker thread. This ensures that the badged
         // shortcut eventually gets its icon updated.
-        Launcher.getLauncher(getContext()).getModel().updateShortcutInfo(mInfo.mDetail, badged);
+        Launcher.getLauncher(getContext()).getModel().updateAndBindShortcutInfo(
+                new Provider<ShortcutInfo>() {
+                    @Override
+                    public ShortcutInfo get() {
+                        badged.updateFromDeepShortcutInfo(mInfo.mDetail, getContext());
+                        return badged;
+                    }
+        });
         return badged;
     }
 
diff --git a/src/com/android/launcher3/util/ManagedProfileHeuristic.java b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
index ce42bcd..c27a3b5 100644
--- a/src/com/android/launcher3/util/ManagedProfileHeuristic.java
+++ b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
@@ -116,8 +116,9 @@
                     .isQuietModeEnabled(user);
             for (int i = 0; i < count; i++) {
                 LauncherActivityInstallInfo info = apps.get(i);
-                ShortcutInfo si = new AppInfo(mContext, info.info, user, mIconCache,
-                        quietModeEnabled, false /* useLowResIcon */).makeShortcut();
+                AppInfo appInfo = new AppInfo(mContext, info.info, user, quietModeEnabled);
+                mIconCache.getTitleAndIcon(appInfo, info.info, false /* useLowResIcon */);
+                ShortcutInfo si = appInfo.makeShortcut();
                 ((info.installTime <= folderCreationTime) ? workFolderApps : homescreenApps).add(si);
             }