Merge "FastBitmapDrawable can draw an icon badge (notification count)" into ub-launcher3-master
diff --git a/build.gradle b/build.gradle
index 00667f1..3a812a9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -72,7 +72,7 @@
     androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
     androidTestCompile 'com.android.support.test:runner:0.5'
     androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
-    androidTestCompile 'com.android.support:support-annotations:23.2.0'
+    androidTestCompile "com.android.support:support-annotations:${SUPPORT_LIBS_VERSION}"
 }
 
 protobuf {
diff --git a/res/drawable/all_apps_search_hint.xml b/res/drawable/all_apps_search_hint.xml
index b2ff7a4..36a0f03 100644
--- a/res/drawable/all_apps_search_hint.xml
+++ b/res/drawable/all_apps_search_hint.xml
@@ -15,6 +15,6 @@
      limitations under the License.
 -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@android:color/transparent" android:state_focused="true" />
+    <item android:color="#00FFFFFF" android:state_focused="true" />
     <item android:color="?android:attr/colorAccent"/>
 </selector>
\ No newline at end of file
diff --git a/src/com/android/launcher3/AllAppsList.java b/src/com/android/launcher3/AllAppsList.java
index 34a44fc..9cce9b1 100644
--- a/src/com/android/launcher3/AllAppsList.java
+++ b/src/com/android/launcher3/AllAppsList.java
@@ -18,9 +18,9 @@
 
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.LauncherActivityInfo;
 import android.os.UserHandle;
 
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.util.FlagOp;
 import com.android.launcher3.util.ItemInfoMatcher;
@@ -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, LauncherActivityInfo 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);
     }
@@ -97,11 +99,11 @@
      */
     public void addPackage(Context context, String packageName, UserHandle user) {
         final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
-        final List<LauncherActivityInfoCompat> matches = launcherApps.getActivityList(packageName,
+        final List<LauncherActivityInfo> matches = launcherApps.getActivityList(packageName,
                 user);
 
-        for (LauncherActivityInfoCompat info : matches) {
-            add(new AppInfo(context, info, user, mIconCache));
+        for (LauncherActivityInfo info : matches) {
+            add(new AppInfo(context, info, user), info);
         }
     }
 
@@ -148,7 +150,7 @@
      */
     public void updatePackage(Context context, String packageName, UserHandle user) {
         final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
-        final List<LauncherActivityInfoCompat> matches = launcherApps.getActivityList(packageName,
+        final List<LauncherActivityInfo> matches = launcherApps.getActivityList(packageName,
                 user);
         if (matches.size() > 0) {
             // Find disabled/removed activities and remove them from data and add them
@@ -166,12 +168,12 @@
 
             // Find enabled activities and add them to the adapter
             // Also updates existing activities with new labels/icons
-            for (final LauncherActivityInfoCompat info : matches) {
+            for (final LauncherActivityInfo info : matches) {
                 AppInfo applicationInfo = findApplicationInfoLocked(
                         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);
@@ -195,9 +197,9 @@
     /**
      * Returns whether <em>apps</em> contains <em>component</em>.
      */
-    private static boolean findActivity(List<LauncherActivityInfoCompat> apps,
+    private static boolean findActivity(List<LauncherActivityInfo> apps,
             ComponentName component) {
-        for (LauncherActivityInfoCompat info : apps) {
+        for (LauncherActivityInfo info : apps) {
             if (info.getComponentName().equals(component)) {
                 return true;
             }
diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java
index 9c9dcc5..6bec997 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -19,10 +19,10 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.LauncherActivityInfo;
 import android.os.UserHandle;
 import android.util.Log;
 
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.PackageManagerHelper;
@@ -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, LauncherActivityInfo 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) {
+    public AppInfo(Context context, LauncherActivityInfo info, UserHandle user,
+            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) {
@@ -118,7 +110,7 @@
         return new ComponentKey(componentName, user);
     }
 
-    public static Intent makeLaunchIntent(Context context, LauncherActivityInfoCompat info,
+    public static Intent makeLaunchIntent(Context context, LauncherActivityInfo info,
             UserHandle user) {
         long serialNumber = UserManagerCompat.getInstance(context).getSerialNumberForUser(user);
         return new Intent(Intent.ACTION_MAIN)
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index 92da9b7..1a405f9 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -320,7 +320,7 @@
 
     public static Rect getWidgetSizeRanges(Context context, int spanX, int spanY, Rect rect) {
         if (sCellSize == null) {
-            InvariantDeviceProfile inv = LauncherAppState.getInstance().getInvariantDeviceProfile();
+            InvariantDeviceProfile inv = LauncherAppState.getIDP(context);
 
             // Initiate cell sizes.
             sCellSize = new Point[2];
diff --git a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
index c6f1c48..7bc3692 100644
--- a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
+++ b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
@@ -8,6 +8,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.database.Cursor;
+import android.os.Handler;
 import android.util.Log;
 
 import com.android.launcher3.LauncherSettings.Favorites;
@@ -18,12 +19,19 @@
     private static final String TAG = "AWRestoredReceiver";
 
     @Override
-    public void onReceive(Context context, Intent intent) {
+    public void onReceive(final Context context, Intent intent) {
         if (AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED.equals(intent.getAction())) {
-            int[] oldIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS);
-            int[] newIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
+            final int[] oldIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS);
+            final int[] newIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
             if (oldIds.length == newIds.length) {
-                restoreAppWidgetIds(context, oldIds, newIds);
+                final PendingResult asyncResult = goAsync();
+                new Handler(LauncherModel.getWorkerLooper())
+                        .postAtFrontOfQueue(new Runnable() {
+                            @Override
+                            public void run() {
+                                restoreAppWidgetIds(context, asyncResult, oldIds, newIds);
+                            }
+                        });
             } else {
                 Log.e(TAG, "Invalid host restored received");
             }
@@ -33,7 +41,8 @@
     /**
      * Updates the app widgets whose id has changed during the restore process.
      */
-    static void restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
+    static void restoreAppWidgetIds(Context context, PendingResult asyncResult,
+            int[] oldWidgetIds, int[] newWidgetIds) {
         final ContentResolver cr = context.getContentResolver();
         final AppWidgetManager widgets = AppWidgetManager.getInstance(context);
         AppWidgetHost appWidgetHost = new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID);
@@ -76,5 +85,6 @@
         if (app != null) {
             app.reloadWorkspace();
         }
+        asyncResult.finish();
     }
 }
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index 2a4212a..2e017df 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -79,7 +79,7 @@
 
     static AutoInstallsLayout get(Context context, String pkg, Resources targetRes,
             AppWidgetHost appWidgetHost, LayoutParserCallback callback) {
-        InvariantDeviceProfile grid = LauncherAppState.getInstance().getInvariantDeviceProfile();
+        InvariantDeviceProfile grid = LauncherAppState.getIDP(context);
 
         // Try with grid size and hotseat count
         String layoutName = String.format(Locale.ENGLISH, FORMATTED_LAYOUT_RES_WITH_HOSTEAT,
@@ -182,7 +182,7 @@
         mSourceRes = res;
         mLayoutId = layoutId;
 
-        mIdp = LauncherAppState.getInstance().getInvariantDeviceProfile();
+        mIdp = LauncherAppState.getIDP(context);
         mRowCount = mIdp.numRows;
         mColumnCount = mIdp.numColumns;
     }
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 77572c7..d9e9c7b 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -596,7 +596,7 @@
         if (getTag() instanceof ItemInfoWithIcon) {
             ItemInfoWithIcon info = (ItemInfoWithIcon) getTag();
             if (info.usingLowResIcon) {
-                mIconLoadRequest = LauncherAppState.getInstance().getIconCache()
+                mIconLoadRequest = LauncherAppState.getInstance(getContext()).getIconCache()
                         .updateIconInBackground(BubbleTextView.this, info);
             }
         }
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 70c8739..da12e67 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -2096,6 +2096,7 @@
                 a.cancel();
             }
 
+            setInitialAnimationValues(true);
             a = new LauncherViewPropertyAnimator(child)
                 .scaleX(initScale)
                 .scaleY(initScale)
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 7c50a5c..6535d65 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -22,6 +22,7 @@
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.LauncherActivityInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -45,13 +46,13 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
 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);
     }
@@ -225,7 +226,7 @@
             PackageInfo info = mPackageManager.getPackageInfo(packageName,
                     PackageManager.GET_UNINSTALLED_PACKAGES);
             long userSerial = mUserManager.getSerialNumberForUser(user);
-            for (LauncherActivityInfoCompat app : mLauncherApps.getActivityList(packageName, user)) {
+            for (LauncherActivityInfo app : mLauncherApps.getActivityList(packageName, user)) {
                 addIconToDBAndMemCache(app, info, userSerial, false /*replace existing*/);
             }
         } catch (NameNotFoundException e) {
@@ -252,7 +253,7 @@
         mIconProvider.updateSystemStateString();
         for (UserHandle user : mUserManager.getUserProfiles()) {
             // Query for the set of apps
-            final List<LauncherActivityInfoCompat> apps = mLauncherApps.getActivityList(null, user);
+            final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
             // Fail if we don't have any apps
             // TODO: Fix this. Only fail for the current user.
             if (apps == null || apps.isEmpty()) {
@@ -271,7 +272,7 @@
      * the DB and are updated.
      * @return The set of packages for which icons have updated.
      */
-    private void updateDBIcons(UserHandle user, List<LauncherActivityInfoCompat> apps,
+    private void updateDBIcons(UserHandle user, List<LauncherActivityInfo> apps,
             Set<String> ignorePackages) {
         long userSerial = mUserManager.getSerialNumberForUser(user);
         PackageManager pm = mContext.getPackageManager();
@@ -280,13 +281,13 @@
             pkgInfoMap.put(info.packageName, info);
         }
 
-        HashMap<ComponentName, LauncherActivityInfoCompat> componentMap = new HashMap<>();
-        for (LauncherActivityInfoCompat app : apps) {
+        HashMap<ComponentName, LauncherActivityInfo> componentMap = new HashMap<>();
+        for (LauncherActivityInfo app : apps) {
             componentMap.put(app.getComponentName(), app);
         }
 
         HashSet<Integer> itemsToRemove = new HashSet<Integer>();
-        Stack<LauncherActivityInfoCompat> appsToUpdate = new Stack<>();
+        Stack<LauncherActivityInfo> appsToUpdate = new Stack<>();
 
         Cursor c = null;
         try {
@@ -321,7 +322,7 @@
 
                 long updateTime = c.getLong(indexLastUpdate);
                 int version = c.getInt(indexVersion);
-                LauncherActivityInfoCompat app = componentMap.remove(component);
+                LauncherActivityInfo app = componentMap.remove(component);
                 if (version == info.versionCode && updateTime == info.lastUpdateTime &&
                         TextUtils.equals(c.getString(systemStateIndex),
                                 mIconProvider.getIconSystemState(info.packageName))) {
@@ -349,7 +350,7 @@
 
         // Insert remaining apps.
         if (!componentMap.isEmpty() || !appsToUpdate.isEmpty()) {
-            Stack<LauncherActivityInfoCompat> appsToAdd = new Stack<>();
+            Stack<LauncherActivityInfo> appsToAdd = new Stack<>();
             appsToAdd.addAll(componentMap.values());
             new SerializedIconUpdateTask(userSerial, pkgInfoMap,
                     appsToAdd, appsToUpdate).scheduleNext();
@@ -362,7 +363,7 @@
      *                        the memory. This is useful then the previous bitmap was created using
      *                        old data.
      */
-    @Thunk synchronized void addIconToDBAndMemCache(LauncherActivityInfoCompat app,
+    @Thunk synchronized void addIconToDBAndMemCache(LauncherActivityInfo app,
             PackageInfo info, long userSerial, boolean replaceExisting) {
         final ComponentKey key = new ComponentKey(app.getComponentName(), app.getUser());
         CacheEntry entry = null;
@@ -435,7 +436,7 @@
      */
     public synchronized void updateTitleAndIcon(AppInfo application) {
         CacheEntry entry = cacheLocked(application.componentName,
-                Provider.<LauncherActivityInfoCompat>of(null),
+                Provider.<LauncherActivityInfo>of(null),
                 application.user, false, application.usingLowResIcon);
         if (entry.icon != null && !isDefaultIcon(entry.icon, application.user)) {
             applyCacheEntry(entry, application);
@@ -446,7 +447,7 @@
      * Fill in {@param info} with the icon and label for {@param activityInfo}
      */
     public synchronized void getTitleAndIcon(ItemInfoWithIcon info,
-            LauncherActivityInfoCompat activityInfo, boolean useLowResIcon) {
+            LauncherActivityInfo activityInfo, boolean useLowResIcon) {
         // If we already have activity info, no need to use package icon
         getTitleAndIcon(info, Provider.of(activityInfo), false, useLowResIcon);
     }
@@ -474,7 +475,7 @@
      */
     private synchronized void getTitleAndIcon(
             @NonNull ItemInfoWithIcon infoInOut,
-            @NonNull Provider<LauncherActivityInfoCompat> activityInfoProvider,
+            @NonNull Provider<LauncherActivityInfo> activityInfoProvider,
             boolean usePkgIcon, boolean useLowResIcon) {
         CacheEntry entry = cacheLocked(infoInOut.getTargetComponent(), activityInfoProvider,
                 infoInOut.user, usePkgIcon, useLowResIcon);
@@ -515,8 +516,9 @@
      */
     protected CacheEntry cacheLocked(
             @NonNull ComponentName componentName,
-            @NonNull Provider<LauncherActivityInfoCompat> infoProvider,
+            @NonNull Provider<LauncherActivityInfo> 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)) {
@@ -524,7 +526,7 @@
             mCache.put(cacheKey, entry);
 
             // Check the DB first.
-            LauncherActivityInfoCompat info = null;
+            LauncherActivityInfo info = null;
             boolean providerFetchedOnce = false;
 
             if (!getEntryFromDB(cacheKey, entry, useLowResIcon) || DEBUG_IGNORE_CACHE) {
@@ -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);
 
@@ -701,19 +704,19 @@
 
     /**
      * A runnable that updates invalid icons and adds missing icons in the DB for the provided
-     * LauncherActivityInfoCompat list. Items are updated/added one at a time, so that the
+     * LauncherActivityInfo list. Items are updated/added one at a time, so that the
      * worker thread doesn't get blocked.
      */
     @Thunk class SerializedIconUpdateTask implements Runnable {
         private final long mUserSerial;
         private final HashMap<String, PackageInfo> mPkgInfoMap;
-        private final Stack<LauncherActivityInfoCompat> mAppsToAdd;
-        private final Stack<LauncherActivityInfoCompat> mAppsToUpdate;
+        private final Stack<LauncherActivityInfo> mAppsToAdd;
+        private final Stack<LauncherActivityInfo> mAppsToUpdate;
         private final HashSet<String> mUpdatedPackages = new HashSet<String>();
 
         @Thunk SerializedIconUpdateTask(long userSerial, HashMap<String, PackageInfo> pkgInfoMap,
-                Stack<LauncherActivityInfoCompat> appsToAdd,
-                Stack<LauncherActivityInfoCompat> appsToUpdate) {
+                Stack<LauncherActivityInfo> appsToAdd,
+                Stack<LauncherActivityInfo> appsToUpdate) {
             mUserSerial = userSerial;
             mPkgInfoMap = pkgInfoMap;
             mAppsToAdd = appsToAdd;
@@ -723,7 +726,7 @@
         @Override
         public void run() {
             if (!mAppsToUpdate.isEmpty()) {
-                LauncherActivityInfoCompat app = mAppsToUpdate.pop();
+                LauncherActivityInfo app = mAppsToUpdate.pop();
                 String pkg = app.getComponentName().getPackageName();
                 PackageInfo info = mPkgInfoMap.get(pkg);
                 addIconToDBAndMemCache(app, info, mUserSerial, true /*replace existing*/);
@@ -731,14 +734,14 @@
 
                 if (mAppsToUpdate.isEmpty() && !mUpdatedPackages.isEmpty()) {
                     // No more app to update. Notify model.
-                    LauncherAppState.getInstance().getModel().onPackageIconsUpdated(
+                    LauncherAppState.getInstance(mContext).getModel().onPackageIconsUpdated(
                             mUpdatedPackages, mUserManager.getUserForSerialNumber(mUserSerial));
                 }
 
                 // Let it run one more time.
                 scheduleNext();
             } else if (!mAppsToAdd.isEmpty()) {
-                LauncherActivityInfoCompat app = mAppsToAdd.pop();
+                LauncherActivityInfo app = mAppsToAdd.pop();
                 PackageInfo info = mPkgInfoMap.get(app.getComponentName().getPackageName());
                 // We do not check the mPkgInfoMap when generating the mAppsToAdd. Although every
                 // app should have package info, this is not guaranteed by the api
@@ -840,7 +843,7 @@
         }
     }
 
-    private class ActivityInfoProvider extends Provider<LauncherActivityInfoCompat> {
+    private class ActivityInfoProvider extends Provider<LauncherActivityInfo> {
 
         private final Intent mIntent;
         private final UserHandle mUser;
@@ -851,7 +854,7 @@
         }
 
         @Override
-        public LauncherActivityInfoCompat get() {
+        public LauncherActivityInfo get() {
             return mLauncherApps.resolveActivity(mIntent, mUser);
         }
     }
diff --git a/src/com/android/launcher3/IconProvider.java b/src/com/android/launcher3/IconProvider.java
index 005bbaa..a5d3990 100644
--- a/src/com/android/launcher3/IconProvider.java
+++ b/src/com/android/launcher3/IconProvider.java
@@ -1,9 +1,8 @@
 package com.android.launcher3;
 
+import android.content.pm.LauncherActivityInfo;
 import android.graphics.drawable.Drawable;
 
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
-
 import java.util.Locale;
 
 public class IconProvider {
@@ -26,7 +25,7 @@
     }
 
 
-    public Drawable getIcon(LauncherActivityInfoCompat info, int iconDpi) {
+    public Drawable getIcon(LauncherActivityInfo info, int iconDpi) {
         return info.getIcon(iconDpi);
     }
 }
diff --git a/src/com/android/launcher3/InfoDropTarget.java b/src/com/android/launcher3/InfoDropTarget.java
index db14e2e..d831a3a 100644
--- a/src/com/android/launcher3/InfoDropTarget.java
+++ b/src/com/android/launcher3/InfoDropTarget.java
@@ -96,9 +96,14 @@
         // Only show the App Info drop target if developer settings are enabled.
         boolean developmentSettingsEnabled = Settings.Global.getInt(context.getContentResolver(),
                 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) == 1;
-        return developmentSettingsEnabled
-                && (info instanceof AppInfo || info instanceof ShortcutInfo
-                || info instanceof PendingAddItemInfo || info instanceof LauncherAppWidgetInfo)
-                && info.itemType != LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+        if (!developmentSettingsEnabled) {
+            return false;
+        }
+        return info.itemType != LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT &&
+                (info instanceof AppInfo ||
+                (info instanceof ShortcutInfo && !((ShortcutInfo) info).isPromise()) ||
+                (info instanceof LauncherAppWidgetInfo &&
+                        ((LauncherAppWidgetInfo) info).restoreStatus == 0) ||
+                info instanceof PendingAddItemInfo);
     }
 }
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index ecbfe38..ad10523 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -23,9 +23,11 @@
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.ActivityInfo;
+import android.content.pm.LauncherActivityInfo;
 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;
@@ -33,7 +35,6 @@
 import android.util.Base64;
 import android.util.Log;
 
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.graphics.LauncherIcons;
@@ -240,7 +241,7 @@
 
     private static void queuePendingShortcutInfo(PendingInstallShortcutInfo info, Context context) {
         // Queue the item up for adding if launcher has not loaded properly yet
-        LauncherAppState app = LauncherAppState.getInstance();
+        LauncherAppState app = LauncherAppState.getInstance(context);
         boolean launcherNotLoaded = app.getModel().getCallback() == null;
 
         addToInstallQueue(Utilities.getPrefs(context), info);
@@ -260,7 +261,7 @@
     static void flushInstallQueue(Context context) {
         ArrayList<PendingInstallShortcutInfo> items = getAndClearInstallQueue(context);
         if (!items.isEmpty()) {
-            LauncherAppState.getInstance().getModel().addAndBindAddedWorkspaceItems(
+            LauncherAppState.getInstance(context).getModel().addAndBindAddedWorkspaceItems(
                     new LazyShortcutsProvider(context.getApplicationContext(), items));
         }
     }
@@ -284,7 +285,7 @@
 
     private static class PendingInstallShortcutInfo {
 
-        final LauncherActivityInfoCompat activityInfo;
+        final LauncherActivityInfo activityInfo;
         final ShortcutInfoCompat shortcutInfo;
         final AppWidgetProviderInfo providerInfo;
 
@@ -314,7 +315,7 @@
         /**
          * Initializes a PendingInstallShortcutInfo to represent a launcher target.
          */
-        public PendingInstallShortcutInfo(LauncherActivityInfoCompat info, Context context) {
+        public PendingInstallShortcutInfo(LauncherActivityInfo info, Context context) {
             activityInfo = info;
             shortcutInfo = null;
             providerInfo = null;
@@ -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(mContext);
+                // 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) {
@@ -448,15 +464,14 @@
                 LauncherAppWidgetInfo widgetInfo = new LauncherAppWidgetInfo(
                         launchIntent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0),
                         info.provider);
-                InvariantDeviceProfile idp = LauncherAppState.getInstance()
-                        .getInvariantDeviceProfile();
+                InvariantDeviceProfile idp = LauncherAppState.getIDP(mContext);
                 widgetInfo.minSpanX = info.minSpanX;
                 widgetInfo.minSpanY = info.minSpanY;
                 widgetInfo.spanX = Math.min(info.spanX, idp.numColumns);
                 widgetInfo.spanY = Math.min(info.spanY, idp.numRows);
                 return widgetInfo;
             } else {
-                return createShortcutInfo(data, LauncherAppState.getInstance());
+                return createShortcutInfo(data, LauncherAppState.getInstance(mContext));
             }
         }
 
@@ -474,7 +489,7 @@
         try {
             Decoder decoder = new Decoder(encoded, context);
             if (decoder.optBoolean(APP_SHORTCUT_TYPE_KEY)) {
-                LauncherActivityInfoCompat info = LauncherAppsCompat.getInstance(context)
+                LauncherActivityInfo info = LauncherAppsCompat.getInstance(context)
                         .resolveActivity(decoder.launcherIntent, decoder.user);
                 return info == null ? null : new PendingInstallShortcutInfo(info, context);
             } else if (decoder.optBoolean(DEEPSHORTCUT_TYPE_KEY)) {
@@ -556,7 +571,7 @@
             return original;
         }
 
-        LauncherActivityInfoCompat info = LauncherAppsCompat.getInstance(original.mContext)
+        LauncherActivityInfo info = LauncherAppsCompat.getInstance(original.mContext)
                 .resolveActivity(original.launchIntent, original.user);
         if (info == null) {
             return original;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index d6c8cfb..fc112f3 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -356,7 +356,7 @@
 
         super.onCreate(savedInstanceState);
 
-        LauncherAppState app = LauncherAppState.getInstance();
+        LauncherAppState app = LauncherAppState.getInstance(this);
 
         // Load configuration-specific DeviceProfile
         mDeviceProfile =
@@ -1815,7 +1815,7 @@
         // been created. In this case, don't interfere with the new Launcher.
         if (mModel.isCurrentCallbacks(this)) {
             mModel.stopLoader();
-            LauncherAppState.getInstance().setLauncher(null);
+            LauncherAppState.getInstance(this).setLauncher(null);
         }
 
         if (mRotationPrefChangeHandler != null) {
@@ -2331,20 +2331,9 @@
                     startRestoredWidgetReconfigActivity(appWidgetInfo, info);
                 }
             }
-        } else if (info.installProgress < 0) {
-            // The install has not been queued
-            final String packageName = info.providerName.getPackageName();
-            showBrokenAppInstallDialog(packageName,
-                new DialogInterface.OnClickListener() {
-                    public void onClick(DialogInterface dialog, int id) {
-                        startActivitySafely(
-                                v, PackageManagerHelper.getMarketIntent(packageName), info);
-                    }
-                });
         } else {
-            // Download has started.
             final String packageName = info.providerName.getPackageName();
-            startActivitySafely(v, PackageManagerHelper.getMarketIntent(packageName), info);
+            onClickPendingAppItem(v, packageName, info.installProgress >= 0);
         }
     }
 
@@ -2381,12 +2370,22 @@
         }
     }
 
-    private void showBrokenAppInstallDialog(final String packageName,
-            DialogInterface.OnClickListener onSearchClickListener) {
+    private void onClickPendingAppItem(final View v, final String packageName,
+            boolean downloadStarted) {
+        if (downloadStarted) {
+            // If the download has started, simply direct to the market app.
+            startMarketIntentForPackage(v, packageName);
+            return;
+        }
         new AlertDialog.Builder(this)
             .setTitle(R.string.abandoned_promises_title)
             .setMessage(R.string.abandoned_promise_explanation)
-            .setPositiveButton(R.string.abandoned_search, onSearchClickListener)
+            .setPositiveButton(R.string.abandoned_search, new DialogInterface.OnClickListener() {
+                @Override
+                public void onClick(DialogInterface dialogInterface, int i) {
+                    startMarketIntentForPackage(v, packageName);
+                }
+            })
             .setNeutralButton(R.string.abandoned_clean_this,
                 new DialogInterface.OnClickListener() {
                     public void onClick(DialogInterface dialog, int id) {
@@ -2395,7 +2394,16 @@
                     }
                 })
             .create().show();
-        return;
+    }
+
+    private void startMarketIntentForPackage(View v, String packageName) {
+        ItemInfo item = (ItemInfo) v.getTag();
+        Intent intent = PackageManagerHelper.getMarketIntent(packageName);
+        boolean success = startActivitySafely(v, intent, item);
+        if (success && v instanceof BubbleTextView) {
+            mWaitingForResume = (BubbleTextView) v;
+            mWaitingForResume.setStayPressed(true);
+        }
     }
 
     /**
@@ -2439,17 +2447,14 @@
         }
 
         // Check for abandoned promise
-        if ((v instanceof BubbleTextView)
-                && shortcut.isPromise()
-                && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {
-            showBrokenAppInstallDialog(
-                    shortcut.getTargetComponent().getPackageName(),
-                    new DialogInterface.OnClickListener() {
-                        public void onClick(DialogInterface dialog, int id) {
-                            startAppShortcutOrInfoActivity(v);
-                        }
-                    });
-            return;
+        if ((v instanceof BubbleTextView) && shortcut.isPromise()) {
+            String packageName = shortcut.intent.getComponent() != null ?
+                    shortcut.intent.getComponent().getPackageName() : shortcut.intent.getPackage();
+            if (!TextUtils.isEmpty(packageName)) {
+                onClickPendingAppItem(v, packageName,
+                        shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE));
+                return;
+            }
         }
 
         // Start activities
@@ -2715,7 +2720,7 @@
             if (Utilities.ATLEAST_MARSHMALLOW && item != null
                     && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
                     || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
-                    && ((ShortcutInfo) item).promisedIntent == null) {
+                    && !((ShortcutInfo) item).isPromise()) {
                 // Shortcuts need some special checks due to legacy reasons.
                 startShortcutIntentSafely(intent, optsBundle, item);
             } else if (user == null || user.equals(Process.myUserHandle())) {
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 00e4bf4..4dc5a97 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -48,7 +48,7 @@
 
     private InvariantDeviceProfile mInvariantDeviceProfile;
 
-    public static LauncherAppState getInstance() {
+    public static LauncherAppState getInstance(Context context) {
         if (INSTANCE == null) {
             INSTANCE = new LauncherAppState();
         }
@@ -159,4 +159,11 @@
     public InvariantDeviceProfile getInvariantDeviceProfile() {
         return mInvariantDeviceProfile;
     }
+
+    /**
+     * Shorthand for {@link #getInvariantDeviceProfile()}
+     */
+    public static InvariantDeviceProfile getIDP(Context context) {
+        return LauncherAppState.getInstance(context).getInvariantDeviceProfile();
+    }
 }
diff --git a/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
index ab8f395..6cb703b 100644
--- a/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
@@ -65,7 +65,7 @@
     }
 
     public void initSpans(Context context) {
-        InvariantDeviceProfile idp = LauncherAppState.getInstance().getInvariantDeviceProfile();
+        InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
 
         Point paddingLand = idp.landscapeProfile.getTotalWorkspacePadding();
         Point paddingPort = idp.portraitProfile.getTotalWorkspacePadding();
@@ -107,8 +107,7 @@
         if (isCustomWidget) {
             return cache.getFullResIcon(provider.getPackageName(), icon);
         }
-        return super.loadIcon(context,
-                LauncherAppState.getInstance().getInvariantDeviceProfile().fillResIconDpi);
+        return super.loadIcon(context, LauncherAppState.getIDP(context).fillResIconDpi);
     }
 
     public String toString(PackageManager pm) {
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 616b2c7..2fc1502 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -25,6 +25,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.LauncherActivityInfo;
 import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Handler;
@@ -40,7 +41,6 @@
 import android.util.MutableInt;
 
 import com.android.launcher3.compat.AppWidgetManagerCompat;
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.PackageInstallerCompat;
 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
@@ -336,9 +336,10 @@
         final ContentResolver cr = context.getContentResolver();
 
         final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
+        final Context appContext = context.getApplicationContext();
         Runnable r = new Runnable() {
             public void run() {
-                cr.update(uri, writer.getValues(), null, null);
+                cr.update(uri, writer.getValues(appContext), null, null);
                 updateItemArrays(item, itemId, stackTrace);
             }
         };
@@ -553,13 +554,14 @@
         writer.put(LauncherSettings.Favorites._ID, item.id);
 
         final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
+        final Context appContext = context.getApplicationContext();
         Runnable r = new Runnable() {
             public void run() {
-                cr.insert(LauncherSettings.Favorites.CONTENT_URI, writer.getValues());
+                cr.insert(LauncherSettings.Favorites.CONTENT_URI, writer.getValues(appContext));
 
                 synchronized (sBgDataModel) {
                     checkItemInfoLocked(item.id, item, stackTrace);
-                    sBgDataModel.addItem(item, true);
+                    sBgDataModel.addItem(appContext, item, true);
                 }
             }
         };
@@ -588,13 +590,14 @@
     public static void deleteItemsFromDatabase(Context context,
             final Iterable<? extends ItemInfo> items) {
         final ContentResolver cr = context.getContentResolver();
+        final Context appContext = context.getApplicationContext();
         Runnable r = new Runnable() {
             public void run() {
                 for (ItemInfo item : items) {
                     final Uri uri = LauncherSettings.Favorites.getContentUri(item.id);
                     cr.delete(uri, null, null);
 
-                    sBgDataModel.removeItem(item);
+                    sBgDataModel.removeItem(appContext, item);
                 }
             }
         };
@@ -654,16 +657,17 @@
      */
     public static void deleteFolderAndContentsFromDatabase(Context context, final FolderInfo info) {
         final ContentResolver cr = context.getContentResolver();
+        final Context appContext = context.getApplicationContext();
 
         Runnable r = new Runnable() {
             public void run() {
                 cr.delete(LauncherSettings.Favorites.CONTENT_URI,
                         LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
-                sBgDataModel.removeItem(info.contents);
+                sBgDataModel.removeItem(appContext, info.contents);
                 info.contents.clear();
 
                 cr.delete(LauncherSettings.Favorites.getContentUri(info.id), null, null);
-                sBgDataModel.removeItem(info);
+                sBgDataModel.removeItem(appContext, info);
             }
         };
         runOnWorkerThread(r);
@@ -1101,11 +1105,6 @@
             final boolean isSdCardReady = Utilities.isBootCompleted();
             final MultiHashMap<UserHandle, String> pendingPackages = new MultiHashMap<>();
 
-            LauncherAppState app = LauncherAppState.getInstance();
-            InvariantDeviceProfile profile = app.getInvariantDeviceProfile();
-            int countX = profile.numColumns;
-            int countY = profile.numRows;
-
             boolean clearDb = false;
             try {
                 ImportDataTask.performImportIfPossible(context);
@@ -1156,8 +1155,6 @@
                             LauncherSettings.Favorites.SPANY);
                     final int rankIndex = c.getColumnIndexOrThrow(
                             LauncherSettings.Favorites.RANK);
-                    final int restoredIndex = c.getColumnIndexOrThrow(
-                            LauncherSettings.Favorites.RESTORED);
                     final int optionsIndex = c.getColumnIndexOrThrow(
                             LauncherSettings.Favorites.OPTIONS);
 
@@ -1204,7 +1201,6 @@
                                 continue;
                             }
 
-                            boolean restored = 0 != c.getInt(restoredIndex);
                             boolean allowMissingTarget = false;
                             switch (c.itemType) {
                             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: {
@@ -1217,7 +1213,6 @@
                             case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
                             case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
                                 intentDescription = c.getString(intentIndex);
-                                int promiseType = c.getInt(restoredIndex);
                                 int disabledState = 0;
                                 targetPackage = null;
 
@@ -1234,17 +1229,14 @@
                                         }
 
                                         if (validComponent) {
-                                            if (restored) {
-                                                // no special handling necessary for this item
-                                                c.markRestored();
-                                                restored = false;
-                                            }
+                                            // no special handling necessary for this item
+                                            c.markRestored();
                                             if (quietMode.get(c.serialNumber)) {
                                                 disabledState = ShortcutInfo.FLAG_DISABLED_QUIET_USER;
                                             }
                                         } else if (validPkg) {
                                             intent = null;
-                                            if ((promiseType & ShortcutInfo.FLAG_AUTOINTALL_ICON) != 0) {
+                                            if (c.hasRestoreFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
                                                 // We allow auto install apps to have their intent
                                                 // updated after an install.
                                                 intent = manager.getLaunchIntentForPackage(
@@ -1264,21 +1256,20 @@
                                             } else {
                                                 // no special handling necessary for this item
                                                 c.markRestored();
-                                                restored = false;
                                             }
-                                        } else if (restored) {
+                                        } else if (c.restoreFlag != 0) {
                                             // Package is not yet available but might be
                                             // installed later.
                                             FileLog.d(TAG, "package not yet restored: " + cn);
 
-                                            if ((promiseType & ShortcutInfo.FLAG_RESTORE_STARTED) != 0) {
+                                            if (c.hasRestoreFlag(ShortcutInfo.FLAG_RESTORE_STARTED)) {
                                                 // Restore has started once.
                                             } else if (installingPkgs.containsKey(cn.getPackageName())) {
                                                 // App restore has started. Update the flag
-                                                promiseType |= ShortcutInfo.FLAG_RESTORE_STARTED;
+                                                c.restoreFlag |= ShortcutInfo.FLAG_RESTORE_STARTED;
                                                 c.updater().put(
                                                         LauncherSettings.Favorites.RESTORED,
-                                                        promiseType).commit();
+                                                        c.restoreFlag).commit();
                                             } else {
                                                 c.markDeleted("Unrestored package removed: " + cn);
                                                 continue;
@@ -1305,7 +1296,6 @@
                                     } else if (cn == null) {
                                         // For shortcuts with no component, keep them as they are
                                         c.markRestored();
-                                        restored = false;
                                     }
                                 } catch (URISyntaxException e) {
                                     c.markDeleted("Invalid uri: " + intentDescription);
@@ -1315,11 +1305,9 @@
                                 boolean useLowResIcon = !c.isOnWorkspaceOrHotseat() &&
                                         c.getInt(rankIndex) >= FolderIcon.NUM_ITEMS_IN_PREVIEW;
 
-                                if (restored) {
+                                if (c.restoreFlag != 0) {
                                     if (c.user.equals(Process.myUserHandle())) {
-                                        info = c.getRestoredItemInfo(intent, promiseType);
-                                        intent = PackageManagerHelper.getMarketIntent(
-                                                intent.getComponent().getPackageName());
+                                        info = c.getRestoredItemInfo(intent);
                                     } else {
                                         // Don't restore items for other profiles.
                                         c.markDeleted("Restore from managed profile not supported");
@@ -1379,15 +1367,12 @@
                                     // TODO: Remove this extra. Instead we should be using
                                     // itemInfo#user.
                                     info.intent.putExtra(ItemInfo.EXTRA_PROFILE, c.serialNumber);
-                                    if (info.promisedIntent != null) {
-                                        info.promisedIntent.putExtra(ItemInfo.EXTRA_PROFILE, c.serialNumber);
-                                    }
                                     info.isDisabled |= disabledState;
                                     if (isSafeMode && !Utilities.isSystemApp(context, intent)) {
                                         info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE;
                                     }
 
-                                    if (restored) {
+                                    if (c.restoreFlag != 0) {
                                         ComponentName cn = info.getTargetComponent();
                                         if (cn != null) {
                                             Integer progress = installingPkgs.get(cn.getPackageName());
@@ -1415,10 +1400,8 @@
                                 folderInfo.spanY = 1;
                                 folderInfo.options = c.getInt(optionsIndex);
 
-                                if (restored) {
-                                    // no special handling required for restored folders
-                                    c.markRestored();
-                                }
+                                // no special handling required for restored folders
+                                c.markRestored();
 
                                 c.checkAndAddItem(folderInfo, sBgDataModel);
                                 break;
@@ -1435,11 +1418,10 @@
                                 final ComponentName component =
                                         ComponentName.unflattenFromString(savedProvider);
 
-                                final int restoreStatus = c.getInt(restoredIndex);
-                                final boolean isIdValid = (restoreStatus &
-                                        LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) == 0;
-                                final boolean wasProviderReady = (restoreStatus &
-                                        LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0;
+                                final boolean isIdValid = !c.hasRestoreFlag(
+                                        LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
+                                final boolean wasProviderReady = !c.hasRestoreFlag(
+                                        LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY);
 
                                 if (widgetProvidersMap == null) {
                                     widgetProvidersMap = AppWidgetManagerCompat
@@ -1464,7 +1446,7 @@
                                         // The provider is available. So the widget is either
                                         // available or not available. We do not need to track
                                         // any future restore updates.
-                                        int status = restoreStatus &
+                                        int status = c.restoreFlag &
                                                 ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
                                         if (!wasProviderReady) {
                                             // If provider was not previously ready, update the
@@ -1482,13 +1464,13 @@
                                     } else {
                                         Log.v(TAG, "Widget restore pending id=" + c.id
                                                 + " appWidgetId=" + appWidgetId
-                                                + " status =" + restoreStatus);
+                                                + " status =" + c.restoreFlag);
                                         appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId,
                                                 component);
-                                        appWidgetInfo.restoreStatus = restoreStatus;
+                                        appWidgetInfo.restoreStatus = c.restoreFlag;
                                         Integer installProgress = installingPkgs.get(component.getPackageName());
 
-                                        if ((restoreStatus & LauncherAppWidgetInfo.FLAG_RESTORE_STARTED) != 0) {
+                                        if (c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_RESTORE_STARTED)) {
                                             // Restore has started once.
                                         } else if (installProgress != null) {
                                             // App restore has started. Update the flag
@@ -1526,7 +1508,7 @@
                                         String providerName =
                                                 appWidgetInfo.providerName.flattenToString();
                                         if (!providerName.equals(savedProvider) ||
-                                                (appWidgetInfo.restoreStatus != restoreStatus)) {
+                                                (appWidgetInfo.restoreStatus != c.restoreFlag)) {
                                             c.updater()
                                                     .put(LauncherSettings.Favorites.APPWIDGET_PROVIDER,
                                                             providerName)
@@ -1693,8 +1675,7 @@
         /** Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to
          * right) */
         private void sortWorkspaceItemsSpatially(ArrayList<ItemInfo> workspaceItems) {
-            final LauncherAppState app = LauncherAppState.getInstance();
-            final InvariantDeviceProfile profile = app.getInvariantDeviceProfile();
+            final InvariantDeviceProfile profile = mApp.getInvariantDeviceProfile();
             final int screenCols = profile.numColumns;
             final int screenCellCount = profile.numColumns * profile.numRows;
             Collections.sort(workspaceItems, new Comparator<ItemInfo>() {
@@ -2013,7 +1994,7 @@
             for (UserHandle user : profiles) {
                 // Query for the set of apps
                 final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
-                final List<LauncherActivityInfoCompat> apps = mLauncherApps.getActivityList(null, user);
+                final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
                 if (DEBUG_LOADERS) {
                     Log.d(TAG, "getActivityList took "
                             + (SystemClock.uptimeMillis()-qiaTime) + "ms for user " + user);
@@ -2027,9 +2008,9 @@
                 boolean quietMode = mUserManager.isQuietModeEnabled(user);
                 // Create the ApplicationInfos
                 for (int i = 0; i < apps.size(); i++) {
-                    LauncherActivityInfoCompat app = apps.get(i);
+                    LauncherActivityInfo 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 +2202,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);
             }
         });
     }
@@ -2262,7 +2242,7 @@
                 bindWidgetsModel(callbacks);
 
                 // update the Widget entries inside DB on the worker thread.
-                LauncherAppState.getInstance().getWidgetCache().removeObsoletePreviews(allWidgets);
+                mApp.getWidgetCache().removeObsoletePreviews(allWidgets);
             }
         });
     }
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 8f56eb6..6266fae 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -556,8 +556,7 @@
     }
 
     private DefaultLayoutParser getDefaultLayoutParser(AppWidgetHost widgetHost) {
-        int defaultLayout = LauncherAppState.getInstance()
-                .getInvariantDeviceProfile().defaultLayoutId;
+        int defaultLayout = LauncherAppState.getIDP(getContext()).defaultLayoutId;
         return new DefaultLayoutParser(getContext(), widgetHost,
                 mOpenHelper, getContext().getResources(), defaultLayout);
     }
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 77c6837..976d733 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -17,6 +17,7 @@
 package com.android.launcher3;
 
 import android.annotation.TargetApi;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
@@ -29,6 +30,7 @@
 import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.graphics.LauncherIcons;
+import com.android.launcher3.model.PackageItemInfo;
 import com.android.launcher3.shortcuts.DeepShortcutManager;
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
 import com.android.launcher3.util.ContentWriter;
@@ -131,13 +133,6 @@
      */
     private int mInstallProgress;
 
-    /**
-     * If this shortcut is a placeholder, then intent will be a market intent for the package, and
-     * this will hold the original intent from the database.  Otherwise, null.
-     * Refer {@link #FLAG_RESTORED_ICON}, {@link #FLAG_AUTOINTALL_ICON}
-     */
-    public Intent promisedIntent;
-
     public ShortcutInfo() {
         itemType = LauncherSettings.BaseLauncherColumns.ITEM_TYPE_SHORTCUT;
     }
@@ -190,12 +185,9 @@
         }
     }
 
-    /**
-     *  Returns {@link #promisedIntent}, or {@link #intent} if promisedIntent is null.
-     */
     @Override
     public Intent getIntent() {
-        return promisedIntent != null ? promisedIntent : intent;
+        return intent;
     }
 
     public boolean hasStatusFlag(int flag) {
@@ -235,7 +227,7 @@
         disabledMessage = shortcutInfo.getDisabledMessage();
 
         // TODO: Use cache for this
-        LauncherAppState launcherAppState = LauncherAppState.getInstance();
+        LauncherAppState launcherAppState = LauncherAppState.getInstance(context);
         Drawable unbadgedDrawable = DeepShortcutManager.getInstance(context)
                 .getShortcutIconDrawable(shortcutInfo,
                         launcherAppState.getInvariantDeviceProfile().fillResIconDpi);
@@ -249,16 +241,26 @@
 
     protected Bitmap getBadgedIcon(Bitmap unbadgedBitmap, ShortcutInfoCompat shortcutInfo,
             IconCache cache, Context context) {
-        unbadgedBitmap = LauncherIcons.addShadowToIcon(unbadgedBitmap);
-        // Get the app info for the source activity.
-        AppInfo appInfo = new AppInfo();
-        appInfo.user = user;
-        appInfo.componentName = shortcutInfo.getActivity();
-        appInfo.intent = new Intent(Intent.ACTION_MAIN)
-                .addCategory(Intent.CATEGORY_LAUNCHER)
-                .setComponent(shortcutInfo.getActivity());
-        cache.getTitleAndIcon(appInfo, false);
-        return LauncherIcons.badgeWithBitmap(unbadgedBitmap, appInfo.iconBitmap, context);
+        unbadgedBitmap = LauncherIcons.addShadowToIcon(unbadgedBitmap, context);
+
+        final Bitmap badgeBitmap;
+        ComponentName cn = shortcutInfo.getActivity();
+        if (cn != null) {
+            // Get the app info for the source activity.
+            AppInfo appInfo = new AppInfo();
+            appInfo.user = user;
+            appInfo.componentName = cn;
+            appInfo.intent = new Intent(Intent.ACTION_MAIN)
+                    .addCategory(Intent.CATEGORY_LAUNCHER)
+                    .setComponent(cn);
+            cache.getTitleAndIcon(appInfo, false);
+            badgeBitmap = appInfo.iconBitmap;
+        } else {
+            PackageItemInfo pkgInfo = new PackageItemInfo(shortcutInfo.getPackage());
+            cache.getTitleAndIconForApp(pkgInfo, false);
+            badgeBitmap = pkgInfo.iconBitmap;
+        }
+        return LauncherIcons.badgeWithBitmap(unbadgedBitmap, badgeBitmap, context);
     }
 
     /** Returns the ShortcutInfo id associated with the deep shortcut. */
diff --git a/src/com/android/launcher3/UninstallDropTarget.java b/src/com/android/launcher3/UninstallDropTarget.java
index 73a9f64..e68a5b0 100644
--- a/src/com/android/launcher3/UninstallDropTarget.java
+++ b/src/com/android/launcher3/UninstallDropTarget.java
@@ -4,6 +4,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.LauncherActivityInfo;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.UserHandle;
@@ -11,7 +12,6 @@
 import android.util.AttributeSet;
 import android.widget.Toast;
 
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 
 public class UninstallDropTarget extends ButtonDropTarget {
@@ -69,7 +69,7 @@
             }
         }
         if (intent != null) {
-            LauncherActivityInfoCompat info = LauncherAppsCompat.getInstance(context)
+            LauncherActivityInfo info = LauncherAppsCompat.getInstance(context)
                     .resolveActivity(intent, user);
             if (info != null
                     && (info.getApplicationInfo().flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 1ba6520..6eb87f2 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1613,8 +1613,7 @@
         Utilities.THREAD_POOL_EXECUTOR.execute(new Runnable() {
             @Override
             public void run() {
-                final Point size = LauncherAppState.getInstance()
-                        .getInvariantDeviceProfile().defaultWallpaperSize;
+                final Point size = LauncherAppState.getIDP(getContext()).defaultWallpaperSize;
                 if (size.x != mWallpaperManager.getDesiredMinimumWidth()
                         || size.y != mWallpaperManager.getDesiredMinimumHeight()) {
                     mWallpaperManager.suggestDesiredDimensions(size.x, size.y);
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java
deleted file mode 100644
index 830b60a..0000000
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.compat;
-
-import android.content.ComponentName;
-import android.content.pm.ApplicationInfo;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-
-public abstract class LauncherActivityInfoCompat {
-
-    LauncherActivityInfoCompat() {
-    }
-
-    public abstract ComponentName getComponentName();
-    public abstract UserHandle getUser();
-    public abstract CharSequence getLabel();
-    public abstract Drawable getIcon(int density);
-    public abstract ApplicationInfo getApplicationInfo();
-    public abstract long getFirstInstallTime();
-}
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
deleted file mode 100644
index c3b9592..0000000
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.compat;
-
-import android.content.ComponentName;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.LauncherActivityInfo;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-
-public class LauncherActivityInfoCompatVL extends LauncherActivityInfoCompat {
-    private LauncherActivityInfo mLauncherActivityInfo;
-
-    LauncherActivityInfoCompatVL(LauncherActivityInfo launcherActivityInfo) {
-        super();
-        mLauncherActivityInfo = launcherActivityInfo;
-    }
-
-    public ComponentName getComponentName() {
-        return mLauncherActivityInfo.getComponentName();
-    }
-
-    public UserHandle getUser() {
-        return mLauncherActivityInfo.getUser();
-    }
-
-    public CharSequence getLabel() {
-        return mLauncherActivityInfo.getLabel();
-    }
-
-    public Drawable getIcon(int density) {
-        return mLauncherActivityInfo.getIcon(density);
-    }
-
-    public ApplicationInfo getApplicationInfo() {
-        return mLauncherActivityInfo.getApplicationInfo();
-    }
-
-    public long getFirstInstallTime() {
-        return mLauncherActivityInfo.getFirstInstallTime();
-    }
-}
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index 73ab36c..5c6eef8 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -19,6 +19,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.LauncherActivityInfo;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.UserHandle;
@@ -56,9 +57,9 @@
         }
     }
 
-    public abstract List<LauncherActivityInfoCompat> getActivityList(String packageName,
+    public abstract List<LauncherActivityInfo> getActivityList(String packageName,
             UserHandle user);
-    public abstract LauncherActivityInfoCompat resolveActivity(Intent intent,
+    public abstract LauncherActivityInfo resolveActivity(Intent intent,
             UserHandle user);
     public abstract void startActivityForProfile(ComponentName component, UserHandle user,
             Rect sourceBounds, Bundle opts);
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
index 60f9fab..e2739c1 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
@@ -29,7 +29,6 @@
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -45,26 +44,13 @@
     }
 
     @Override
-    public List<LauncherActivityInfoCompat> getActivityList(String packageName, UserHandle user) {
-        List<LauncherActivityInfo> list = mLauncherApps.getActivityList(packageName, user);
-        if (list.size() == 0) {
-            return Collections.emptyList();
-        }
-        ArrayList<LauncherActivityInfoCompat> compatList = new ArrayList<>(list.size());
-        for (LauncherActivityInfo info : list) {
-            compatList.add(new LauncherActivityInfoCompatVL(info));
-        }
-        return compatList;
+    public List<LauncherActivityInfo> getActivityList(String packageName, UserHandle user) {
+        return mLauncherApps.getActivityList(packageName, user);
     }
 
     @Override
-    public LauncherActivityInfoCompat resolveActivity(Intent intent, UserHandle user) {
-        LauncherActivityInfo activity = mLauncherApps.resolveActivity(intent, user);
-        if (activity != null) {
-            return new LauncherActivityInfoCompatVL(activity);
-        } else {
-            return null;
-        }
+    public LauncherActivityInfo resolveActivity(Intent intent, UserHandle user) {
+        return mLauncherApps.resolveActivity(intent, user);
     }
 
     @Override
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
index 953d93d..b87582f 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
@@ -42,7 +42,7 @@
 
     PackageInstallerCompatVL(Context context) {
         mInstaller = context.getPackageManager().getPackageInstaller();
-        mCache = LauncherAppState.getInstance().getIconCache();
+        mCache = LauncherAppState.getInstance(context).getIconCache();
         mWorker = new Handler(LauncherModel.getWorkerLooper());
 
         mInstaller.registerSessionCallback(mCallback, mWorker);
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index 4c12032..4a2a735 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -96,9 +96,7 @@
 
     public FolderPagedView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        LauncherAppState app = LauncherAppState.getInstance();
-
-        InvariantDeviceProfile profile = app.getInvariantDeviceProfile();
+        InvariantDeviceProfile profile = LauncherAppState.getIDP(context);
         mMaxCountX = profile.numFolderColumns;
         mMaxCountY = profile.numFolderRows;
 
diff --git a/src/com/android/launcher3/graphics/IconNormalizer.java b/src/com/android/launcher3/graphics/IconNormalizer.java
index 1410917..70b3dd6 100644
--- a/src/com/android/launcher3/graphics/IconNormalizer.java
+++ b/src/com/android/launcher3/graphics/IconNormalizer.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.graphics;
 
+import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -53,9 +54,9 @@
     private final float[] mLeftBorder;
     private final float[] mRightBorder;
 
-    private IconNormalizer() {
+    private IconNormalizer(Context context) {
         // Use twice the icon size as maximum size to avoid scaling down twice.
-        mMaxSize = LauncherAppState.getInstance().getInvariantDeviceProfile().iconBitmapSize * 2;
+        mMaxSize = LauncherAppState.getIDP(context).iconBitmapSize * 2;
         mBitmap = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ALPHA_8);
         mCanvas = new Canvas(mBitmap);
         mPixels = new byte[mMaxSize * mMaxSize];
@@ -239,10 +240,10 @@
         }
     }
 
-    public static IconNormalizer getInstance() {
+    public static IconNormalizer getInstance(Context context) {
         synchronized (LOCK) {
             if (sIconNormalizer == null) {
-                sIconNormalizer = new IconNormalizer();
+                sIconNormalizer = new IconNormalizer(context);
             }
         }
         return sIconNormalizer;
diff --git a/src/com/android/launcher3/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java
index 0619187..8d8f3d9 100644
--- a/src/com/android/launcher3/graphics/LauncherIcons.java
+++ b/src/com/android/launcher3/graphics/LauncherIcons.java
@@ -34,7 +34,11 @@
 
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.config.ProviderConfig;
+
+import java.lang.reflect.Method;
 
 /**
  * Helper methods for generating various launcher icons
@@ -60,9 +64,8 @@
             Resources resources = packageManager.getResourcesForApplication(iconRes.packageName);
             if (resources != null) {
                 final int id = resources.getIdentifier(iconRes.resourceName, null, null);
-                return createIconBitmap(
-                        resources.getDrawableForDensity(id, LauncherAppState.getInstance()
-                                .getInvariantDeviceProfile().fillResIconDpi), context);
+                return createIconBitmap(resources.getDrawableForDensity(
+                        id, LauncherAppState.getIDP(context).fillResIconDpi), context);
             }
         } catch (Exception e) {
             // Icon not found.
@@ -70,15 +73,11 @@
         return null;
     }
 
-    private static int getIconBitmapSize() {
-        return LauncherAppState.getInstance().getInvariantDeviceProfile().iconBitmapSize;
-    }
-
     /**
      * Returns a bitmap which is of the appropriate size to be displayed as an icon
      */
     public static Bitmap createIconBitmap(Bitmap icon, Context context) {
-        final int iconBitmapSize = getIconBitmapSize();
+        final int iconBitmapSize = LauncherAppState.getIDP(context).iconBitmapSize;
         if (iconBitmapSize == icon.getWidth() && iconBitmapSize == icon.getHeight()) {
             return icon;
         }
@@ -92,7 +91,7 @@
     public static Bitmap createBadgedIconBitmap(
             Drawable icon, UserHandle user, Context context) {
         float scale = FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION ?
-                1 : IconNormalizer.getInstance().getScale(icon, null);
+                1 : IconNormalizer.getInstance(context).getScale(icon, null);
         Bitmap bitmap = createIconBitmap(icon, context, scale);
         return badgeIconForUser(bitmap, user, context);
     }
@@ -122,7 +121,7 @@
     public static Bitmap createScaledBitmapWithoutShadow(Drawable icon, Context context) {
         RectF iconBounds = new RectF();
         float scale = FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION ?
-                1 : IconNormalizer.getInstance().getScale(icon, iconBounds);
+                1 : IconNormalizer.getInstance(context).getScale(icon, iconBounds);
         scale = Math.min(scale, ShadowGenerator.getScaleForBounds(iconBounds));
         return createIconBitmap(icon, context, scale);
     }
@@ -131,8 +130,8 @@
      * Adds a shadow to the provided icon. It assumes that the icon has already been scaled using
      * {@link #createScaledBitmapWithoutShadow(Drawable, Context)}
      */
-    public static Bitmap addShadowToIcon(Bitmap icon) {
-        return ShadowGenerator.getInstance().recreateIcon(icon);
+    public static Bitmap addShadowToIcon(Bitmap icon, Context context) {
+        return ShadowGenerator.getInstance(context).recreateIcon(icon);
     }
 
     /**
@@ -162,8 +161,9 @@
      * @param scale the scale to apply before drawing {@param icon} on the canvas
      */
     public static Bitmap createIconBitmap(Drawable icon, Context context, float scale) {
+        icon = castToMaskableIconDrawable(icon);
         synchronized (sCanvas) {
-            final int iconBitmapSize = getIconBitmapSize();
+            final int iconBitmapSize = LauncherAppState.getIDP(context).iconBitmapSize;
 
             int width = iconBitmapSize;
             int height = iconBitmapSize;
@@ -217,6 +217,19 @@
         }
     }
 
+    static Drawable castToMaskableIconDrawable(Drawable drawable) {
+        if (!(ProviderConfig.IS_DOGFOOD_BUILD && Utilities.isAtLeastO())) {
+            return drawable;
+        }
+        try {
+            Class clazz = Class.forName("android.graphics.drawable.MaskableIconDrawable");
+            Method method = clazz.getDeclaredMethod("wrap", Drawable.class);
+            return (Drawable) method.invoke(null, drawable);
+        } catch (Exception e) {
+            return drawable;
+        }
+    }
+
     /**
      * 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
diff --git a/src/com/android/launcher3/graphics/ShadowGenerator.java b/src/com/android/launcher3/graphics/ShadowGenerator.java
index 2b24ec9..8aea5a0 100644
--- a/src/com/android/launcher3/graphics/ShadowGenerator.java
+++ b/src/com/android/launcher3/graphics/ShadowGenerator.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.graphics;
 
+import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
 import android.graphics.BlurMaskFilter;
@@ -52,8 +53,8 @@
     private final Paint mBlurPaint;
     private final Paint mDrawPaint;
 
-    private ShadowGenerator() {
-        mIconSize = LauncherAppState.getInstance().getInvariantDeviceProfile().iconBitmapSize;
+    private ShadowGenerator(Context context) {
+        mIconSize = LauncherAppState.getIDP(context).iconBitmapSize;
         mCanvas = new Canvas();
         mBlurPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
         mBlurPaint.setMaskFilter(new BlurMaskFilter(mIconSize * BLUR_FACTOR, Blur.NORMAL));
@@ -82,11 +83,11 @@
         return result;
     }
 
-    public static ShadowGenerator getInstance() {
+    public static ShadowGenerator getInstance(Context context) {
         Preconditions.assertNonUiThread();
         synchronized (LOCK) {
             if (sShadowGenerator == null) {
-                sShadowGenerator = new ShadowGenerator();
+                sShadowGenerator = new ShadowGenerator(context);
             }
         }
         return sShadowGenerator;
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index a9ceb02..a03dd8f 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -163,10 +163,8 @@
             for (ItemInfo item : dataModel.itemsIdMap) {
                 if (item instanceof ShortcutInfo) {
                     ShortcutInfo info = (ShortcutInfo) item;
-                    Intent targetIntent = info.promisedIntent == null
-                            ? info.intent : info.promisedIntent;
-                    if (targetIntent != null && info.user.equals(user)) {
-                        Intent copyIntent = new Intent(targetIntent);
+                    if (item.getIntent() != null && info.user.equals(user)) {
+                        Intent copyIntent = new Intent(item.getIntent());
                         copyIntent.setSourceBounds(intent.getSourceBounds());
                         String s = copyIntent.toUri(0);
                         if (intentWithPkg.equals(s) || intentWithoutPkg.equals(s)) {
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 6dc5a36..2ac33ea 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -99,11 +99,11 @@
         deepShortcutMap.clear();
     }
 
-    public synchronized void removeItem(ItemInfo... items) {
-        removeItem(Arrays.asList(items));
+    public synchronized void removeItem(Context context, ItemInfo... items) {
+        removeItem(context, Arrays.asList(items));
     }
 
-    public synchronized void removeItem(Iterable<? extends ItemInfo> items) {
+    public synchronized void removeItem(Context context, Iterable<? extends ItemInfo> items) {
         for (ItemInfo item : items) {
             switch (item.itemType) {
                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
@@ -125,7 +125,6 @@
                     // Decrement pinned shortcut count
                     ShortcutKey pinnedShortcut = ShortcutKey.fromItemInfo(item);
                     MutableInt count = pinnedShortcutCounts.get(pinnedShortcut);
-                    Context context = LauncherAppState.getInstance().getContext();
                     if ((count == null || --count.value == 0)
                             && !InstallShortcutReceiver.getPendingShortcuts(context)
                                 .contains(pinnedShortcut)) {
@@ -146,7 +145,7 @@
         }
     }
 
-    public synchronized void addItem(ItemInfo item, boolean newItem) {
+    public synchronized void addItem(Context context, ItemInfo item, boolean newItem) {
         itemsIdMap.put(item.id, item);
         switch (item.itemType) {
             case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
@@ -166,8 +165,7 @@
 
                 // Since this is a new item, pin the shortcut in the system server.
                 if (newItem && count.value == 1) {
-                    DeepShortcutManager.getInstance(LauncherAppState.getInstance().getContext())
-                            .pinShortcut(pinnedShortcut);
+                    DeepShortcutManager.getInstance(context).pinShortcut(pinnedShortcut);
                 }
                 // Fall through
             }
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTask.java b/src/com/android/launcher3/model/GridSizeMigrationTask.java
index 599dcd0..bbc7ae4 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTask.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTask.java
@@ -895,7 +895,7 @@
      */
     public static boolean migrateGridIfNeeded(Context context) {
         SharedPreferences prefs = Utilities.getPrefs(context);
-        InvariantDeviceProfile idp = LauncherAppState.getInstance().getInvariantDeviceProfile();
+        InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
 
         String gridSizeString = getPointString(idp.numColumns, idp.numRows);
 
@@ -915,8 +915,7 @@
             if (srcHotseatCount != idp.numHotseatIcons) {
                 // Migrate hotseat.
 
-                dbChanged = new GridSizeMigrationTask(context,
-                        LauncherAppState.getInstance().getInvariantDeviceProfile(),
+                dbChanged = new GridSizeMigrationTask(context, LauncherAppState.getIDP(context),
                         validPackages, srcHotseatCount, idp.numHotseatIcons).migrateHotseat();
             }
 
@@ -978,9 +977,9 @@
      * @return a map with occupied hotseat position set to non-null value.
      */
     public static LongArrayMap<Object> removeBrokenHotseatItems(Context context) throws Exception {
-        GridSizeMigrationTask task = new GridSizeMigrationTask(context,
-                LauncherAppState.getInstance().getInvariantDeviceProfile(),
-                getValidPackages(context), Integer.MAX_VALUE, Integer.MAX_VALUE);
+        GridSizeMigrationTask task = new GridSizeMigrationTask(
+                context, LauncherAppState.getIDP(context), getValidPackages(context),
+                Integer.MAX_VALUE, Integer.MAX_VALUE);
 
         // Load all the valid entries
         ArrayList<DbEntry> items = task.loadHotseatEntries();
@@ -1038,8 +1037,7 @@
         }
 
         protected boolean runStepTask(Point sourceSize, Point nextSize) throws Exception {
-            return new GridSizeMigrationTask(mContext,
-                    LauncherAppState.getInstance().getInvariantDeviceProfile(),
+            return new GridSizeMigrationTask(mContext, LauncherAppState.getIDP(mContext),
                     mValidPackages, sourceSize, nextSize).migrateWorkspace();
         }
     }
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index 99a6cdf..711be37 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.Intent.ShortcutIconResource;
+import android.content.pm.LauncherActivityInfo;
 import android.database.Cursor;
 import android.database.CursorWrapper;
 import android.graphics.Bitmap;
@@ -39,7 +40,6 @@
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
@@ -83,6 +83,7 @@
     private final int cellXIndex;
     private final int cellYIndex;
     private final int profileIdIndex;
+    private final int restoredIndex;
 
     // Properties loaded per iteration
     public long serialNumber;
@@ -90,6 +91,7 @@
     public long id;
     public long container;
     public int itemType;
+    public int restoreFlag;
 
     public LoaderCursor(Cursor c, LauncherAppState app) {
         super(c);
@@ -111,6 +113,7 @@
         cellXIndex = getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
         cellYIndex = getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
         profileIdIndex = getColumnIndexOrThrow(LauncherSettings.Favorites.PROFILE_ID);
+        restoredIndex = getColumnIndexOrThrow(LauncherSettings.Favorites.RESTORED);
     }
 
     @Override
@@ -123,6 +126,7 @@
             id = getLong(idIndex);
             serialNumber = getInt(profileIdIndex);
             user = allUsers.get(serialNumber);
+            restoreFlag = getInt(restoredIndex);
         }
         return result;
     }
@@ -185,10 +189,10 @@
      * Make an ShortcutInfo object for a restored application or shortcut item that points
      * to a package that is not yet installed on the system.
      */
-    public ShortcutInfo getRestoredItemInfo(Intent intent, int promiseType) {
+    public ShortcutInfo getRestoredItemInfo(Intent intent) {
         final ShortcutInfo info = new ShortcutInfo();
         info.user = user;
-        info.promisedIntent = intent;
+        info.intent = intent;
 
         info.iconBitmap = loadIcon(info);
         // the fallback icon
@@ -196,22 +200,22 @@
             mIconCache.getTitleAndIcon(info, false /* useLowResIcon */);
         }
 
-        if ((promiseType & ShortcutInfo.FLAG_RESTORED_ICON) != 0) {
+        if (hasRestoreFlag(ShortcutInfo.FLAG_RESTORED_ICON)) {
             String title = getTitle();
             if (!TextUtils.isEmpty(title)) {
                 info.title = Utilities.trim(title);
             }
-        } else if  ((promiseType & ShortcutInfo.FLAG_AUTOINTALL_ICON) != 0) {
+        } else if  (hasRestoreFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
             if (TextUtils.isEmpty(info.title)) {
                 info.title = getTitle();
             }
         } else {
-            throw new InvalidParameterException("Invalid restoreType " + promiseType);
+            throw new InvalidParameterException("Invalid restoreType " + restoreFlag);
         }
 
         info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user);
         info.itemType = itemType;
-        info.status = promiseType;
+        info.status = restoreFlag;
         return info;
     }
 
@@ -234,7 +238,7 @@
         Intent newIntent = new Intent(Intent.ACTION_MAIN, null);
         newIntent.addCategory(Intent.CATEGORY_LAUNCHER);
         newIntent.setComponent(componentName);
-        LauncherActivityInfoCompat lai = LauncherAppsCompat.getInstance(mContext)
+        LauncherActivityInfo lai = LauncherAppsCompat.getInstance(mContext)
                 .resolveActivity(newIntent, user);
         if ((lai == null) && !allowMissingTarget) {
             Log.d(TAG, "Missing activity found in getShortcutInfo: " + componentName);
@@ -305,7 +309,14 @@
      * Marks the current item as restored
      */
     public void markRestored() {
-        restoredRows.add(id);
+        if (restoreFlag != 0) {
+            restoredRows.add(id);
+            restoreFlag = 0;
+        }
+    }
+
+    public boolean hasRestoreFlag(int flagMask) {
+        return (restoreFlag & flagMask) != 0;
     }
 
     public void commitRestoredItems() {
@@ -349,7 +360,7 @@
      */
     public void checkAndAddItem(ItemInfo info, BgDataModel dataModel) {
         if (checkItemPlacement(info, dataModel.workspaceScreens)) {
-            dataModel.addItem(info, false);
+            dataModel.addItem(mContext, info, false);
         } else {
             markDeleted("Item position overlap");
         }
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index f5de650..211b979 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -242,12 +242,10 @@
                                             removedShortcuts.add(si);
                                             continue;
                                         }
-                                        si.promisedIntent = intent;
+                                        si.intent = intent;
                                     }
                                 }
 
-                                si.intent = si.promisedIntent;
-                                si.promisedIntent = null;
                                 si.status = ShortcutInfo.DEFAULT;
                                 infoUpdated = true;
                                 if (si.itemType == Favorites.ITEM_TYPE_APPLICATION) {
diff --git a/src/com/android/launcher3/model/WidgetItem.java b/src/com/android/launcher3/model/WidgetItem.java
index 452dbe2..c256176 100644
--- a/src/com/android/launcher3/model/WidgetItem.java
+++ b/src/com/android/launcher3/model/WidgetItem.java
@@ -31,16 +31,16 @@
     public final String label;
     public final int spanX, spanY;
 
-    public WidgetItem(LauncherAppWidgetProviderInfo info, PackageManager pm) {
+    public WidgetItem(LauncherAppWidgetProviderInfo info, PackageManager pm,
+            InvariantDeviceProfile idp) {
         super(info.provider, info.getProfile());
 
         label = Utilities.trim(info.getLabel(pm));
         widgetInfo = info;
         activityInfo = null;
 
-        InvariantDeviceProfile idv = LauncherAppState.getInstance().getInvariantDeviceProfile();
-        spanX = Math.min(info.spanX, idv.numColumns);
-        spanY = Math.min(info.spanY, idv.numRows);
+        spanX = Math.min(info.spanX, idp.numColumns);
+        spanY = Math.min(info.spanY, idp.numRows);
     }
 
     public WidgetItem(ResolveInfo info, PackageManager pm) {
diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src/com/android/launcher3/model/WidgetsModel.java
index 2565985..2c62f89 100644
--- a/src/com/android/launcher3/model/WidgetsModel.java
+++ b/src/com/android/launcher3/model/WidgetsModel.java
@@ -60,12 +60,13 @@
         final ArrayList<WidgetItem> widgetsAndShortcuts = new ArrayList<>();
         try {
             PackageManager pm = context.getPackageManager();
+            InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
 
             // Widgets
             for (AppWidgetProviderInfo widgetInfo :
                     AppWidgetManagerCompat.getInstance(context).getAllProviders()) {
-                widgetsAndShortcuts.add(new WidgetItem(
-                        LauncherAppWidgetProviderInfo.fromProviderInfo(context, widgetInfo), pm));
+                widgetsAndShortcuts.add(new WidgetItem(LauncherAppWidgetProviderInfo
+                        .fromProviderInfo(context, widgetInfo), pm, idp));
             }
 
             // Shortcuts
@@ -73,7 +74,7 @@
                     pm.queryIntentActivities(new Intent(Intent.ACTION_CREATE_SHORTCUT), 0)) {
                 widgetsAndShortcuts.add(new WidgetItem(info, pm));
             }
-            setWidgetsAndShortcuts(widgetsAndShortcuts);
+            setWidgetsAndShortcuts(widgetsAndShortcuts, context);
         } catch (Exception e) {
             if (!ProviderConfig.IS_DOGFOOD_BUILD && Utilities.isBinderSizeError(e)) {
                 // the returned value may be incomplete and will not be refreshed until the next
@@ -87,7 +88,8 @@
         return widgetsAndShortcuts;
     }
 
-    private void setWidgetsAndShortcuts(ArrayList<WidgetItem> rawWidgetsShortcuts) {
+    private void setWidgetsAndShortcuts(ArrayList<WidgetItem> rawWidgetsShortcuts,
+            Context context) {
         if (DEBUG) {
             Log.d(TAG, "addWidgetsAndShortcuts, widgetsShortcuts#=" + rawWidgetsShortcuts.size());
         }
@@ -99,7 +101,7 @@
         // clear the lists.
         mWidgetsList.clear();
 
-        InvariantDeviceProfile idp = LauncherAppState.getInstance().getInvariantDeviceProfile();
+        InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
         UserHandle myUser = Process.myUserHandle();
 
         // add and update.
diff --git a/src/com/android/launcher3/provider/ImportDataTask.java b/src/com/android/launcher3/provider/ImportDataTask.java
index 808e6e3..b0482f8 100644
--- a/src/com/android/launcher3/provider/ImportDataTask.java
+++ b/src/com/android/launcher3/provider/ImportDataTask.java
@@ -306,7 +306,7 @@
         }
 
         LongArrayMap<Object> hotseatItems = GridSizeMigrationTask.removeBrokenHotseatItems(mContext);
-        int myHotseatCount = LauncherAppState.getInstance().getInvariantDeviceProfile().numHotseatIcons;
+        int myHotseatCount = LauncherAppState.getIDP(mContext).numHotseatIcons;
         if (!FeatureFlags.NO_ALL_APPS_ICON) {
             myHotseatCount--;
         }
@@ -381,8 +381,8 @@
         return c.getSharedPreferences(LauncherFiles.DEVICE_PREFERENCES_KEY, Context.MODE_PRIVATE);
     }
 
-    private static final int getMyHotseatLayoutId() {
-        return LauncherAppState.getInstance().getInvariantDeviceProfile().numHotseatIcons <= 5
+    private static final int getMyHotseatLayoutId(Context context) {
+        return LauncherAppState.getIDP(context).numHotseatIcons <= 5
                 ? R.xml.dw_phone_hotseat
                 : R.xml.dw_tablet_hotseat;
     }
@@ -392,7 +392,7 @@
      */
     private static class HotseatLayoutParser extends DefaultLayoutParser {
         public HotseatLayoutParser(Context context, LayoutParserCallback callback) {
-            super(context, null, callback, context.getResources(), getMyHotseatLayoutId());
+            super(context, null, callback, context.getResources(), getMyHotseatLayoutId(context));
         }
 
         @Override
diff --git a/src/com/android/launcher3/provider/LauncherDbUtils.java b/src/com/android/launcher3/provider/LauncherDbUtils.java
index 89fd99b..1758350 100644
--- a/src/com/android/launcher3/provider/LauncherDbUtils.java
+++ b/src/com/android/launcher3/provider/LauncherDbUtils.java
@@ -76,8 +76,7 @@
                 }
             }
 
-            new LossyScreenMigrationTask(
-                    context, LauncherAppState.getInstance().getInvariantDeviceProfile(), db)
+            new LossyScreenMigrationTask(context, LauncherAppState.getIDP(context), db)
                     .migrateScreen0();
             db.setTransactionSuccessful();
             return true;
diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java
index c83143b..38a3e1f 100644
--- a/src/com/android/launcher3/qsb/QsbContainerView.java
+++ b/src/com/android/launcher3/qsb/QsbContainerView.java
@@ -102,7 +102,7 @@
             }
 
             AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(activity);
-            InvariantDeviceProfile idp = LauncherAppState.getInstance().getInvariantDeviceProfile();
+            InvariantDeviceProfile idp = LauncherAppState.getIDP(activity);
 
             Bundle opts = new Bundle();
             Rect size = AppWidgetResizeFrame.getWidgetSizeRanges(activity, idp.numColumns, 1, null);
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/testing/ToggleWeightWatcher.java b/src/com/android/launcher3/testing/ToggleWeightWatcher.java
index e08ec3a..f0c3920 100644
--- a/src/com/android/launcher3/testing/ToggleWeightWatcher.java
+++ b/src/com/android/launcher3/testing/ToggleWeightWatcher.java
@@ -22,7 +22,7 @@
         show = !show;
         sp.edit().putBoolean(TestingUtils.SHOW_WEIGHT_WATCHER, show).apply();
 
-        Launcher launcher = (Launcher) LauncherAppState.getInstance().getModel().getCallback();
+        Launcher launcher = (Launcher) LauncherAppState.getInstance(this).getModel().getCallback();
         if (launcher != null && launcher.mWeightWatcher != null) {
             launcher.mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);
         }
diff --git a/src/com/android/launcher3/util/CachedPackageTracker.java b/src/com/android/launcher3/util/CachedPackageTracker.java
index ab5f44f..314b4c0 100644
--- a/src/com/android/launcher3/util/CachedPackageTracker.java
+++ b/src/com/android/launcher3/util/CachedPackageTracker.java
@@ -18,10 +18,10 @@
 
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.content.pm.LauncherActivityInfo;
 import android.os.UserHandle;
 
 import com.android.launcher3.Utilities;
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.LauncherAppsCompat.OnAppsChangedCallbackCompat;
 import com.android.launcher3.compat.UserManagerCompat;
@@ -55,7 +55,7 @@
      * Checks the list of user apps, and generates package event accordingly.
      * {@see #onLauncherAppsAdded}, {@see #onLauncherPackageRemoved}
      */
-    public void processUserApps(List<LauncherActivityInfoCompat> apps, UserHandle user) {
+    public void processUserApps(List<LauncherActivityInfo> apps, UserHandle user) {
         String prefKey = INSTALLED_PACKAGES_PREFIX + mUserManager.getSerialNumberForUser(user);
         HashSet<String> oldPackageSet = new HashSet<>();
         final boolean userAppsExisted = getUserApps(oldPackageSet, prefKey);
@@ -64,7 +64,7 @@
         HashSet<String> newPackageSet = new HashSet<>();
         ArrayList<LauncherActivityInstallInfo> packagesAdded = new ArrayList<>();
 
-        for (LauncherActivityInfoCompat info : apps) {
+        for (LauncherActivityInfo info : apps) {
             String packageName = info.getComponentName().getPackageName();
             newPackageSet.add(packageName);
             packagesRemoved.remove(packageName);
@@ -123,10 +123,10 @@
         HashSet<String> packageSet = new HashSet<>();
         final boolean userAppsExisted = getUserApps(packageSet, prefKey);
         if (!packageSet.contains(packageName)) {
-            List<LauncherActivityInfoCompat> activities =
+            List<LauncherActivityInfo> activities =
                     mLauncherApps.getActivityList(packageName, user);
             if (!activities.isEmpty()) {
-                LauncherActivityInfoCompat activityInfo = activities.get(0);
+                LauncherActivityInfo activityInfo = activities.get(0);
 
                 packageSet.add(packageName);
                 mPrefs.edit().putStringSet(prefKey, packageSet).apply();
@@ -172,10 +172,10 @@
 
     public static class LauncherActivityInstallInfo
             implements Comparable<LauncherActivityInstallInfo> {
-        public final LauncherActivityInfoCompat info;
+        public final LauncherActivityInfo info;
         public final long installTime;
 
-        public LauncherActivityInstallInfo(LauncherActivityInfoCompat info, long installTime) {
+        public LauncherActivityInstallInfo(LauncherActivityInfo info, long installTime) {
             this.info = info;
             this.installTime = installTime;
         }
diff --git a/src/com/android/launcher3/util/ContentWriter.java b/src/com/android/launcher3/util/ContentWriter.java
index 76ba9d6..4384328 100644
--- a/src/com/android/launcher3/util/ContentWriter.java
+++ b/src/com/android/launcher3/util/ContentWriter.java
@@ -93,9 +93,9 @@
      * Commits any pending validation and returns the final values.
      * Must not be called on UI thread.
      */
-    public ContentValues getValues() {
+    public ContentValues getValues(Context context) {
         Preconditions.assertNonUiThread();
-        if (mIcon != null && !LauncherAppState.getInstance().getIconCache()
+        if (mIcon != null && !LauncherAppState.getInstance(context).getIconCache()
                 .isDefaultIcon(mIcon, mUser)) {
             mValues.put(LauncherSettings.Favorites.ICON, Utilities.flattenBitmap(mIcon));
             mIcon = null;
@@ -105,7 +105,7 @@
 
     public int commit() {
         if (mCommitParams != null) {
-            return mContext.getContentResolver().update(mCommitParams.mUri, getValues(),
+            return mContext.getContentResolver().update(mCommitParams.mUri, getValues(mContext),
                     mCommitParams.mWhere, mCommitParams.mSelectionArgs);
         }
         return 0;
diff --git a/src/com/android/launcher3/util/ManagedProfileHeuristic.java b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
index ce42bcd..af61554 100644
--- a/src/com/android/launcher3/util/ManagedProfileHeuristic.java
+++ b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.content.pm.LauncherActivityInfo;
 import android.os.Process;
 import android.os.UserHandle;
 
@@ -31,7 +32,6 @@
 import com.android.launcher3.MainThreadExecutor;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutInfo;
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
 
@@ -72,8 +72,8 @@
     private ManagedProfileHeuristic(Context context, UserHandle user) {
         mContext = context;
         mUser = user;
-        mModel = LauncherAppState.getInstance().getModel();
-        mIconCache = LauncherAppState.getInstance().getIconCache();
+        mModel = LauncherAppState.getInstance(context).getModel();
+        mIconCache = LauncherAppState.getInstance(context).getIconCache();
     }
 
     public void processPackageRemoved(String[] packages) {
@@ -92,7 +92,7 @@
         }
     }
 
-    public void processUserApps(List<LauncherActivityInfoCompat> apps) {
+    public void processUserApps(List<LauncherActivityInfo> apps) {
         Preconditions.assertWorkerThread();
         new ManagedProfilePackageHandler().processUserApps(apps, mUser);
     }
@@ -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);
             }
 
diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java
index 310c1df..be4f635 100644
--- a/src/com/android/launcher3/widget/WidgetsContainerView.java
+++ b/src/com/android/launcher3/widget/WidgetsContainerView.java
@@ -87,7 +87,7 @@
         mLauncher = Launcher.getLauncher(context);
         mDragController = mLauncher.getDragController();
         mAdapter = new WidgetsListAdapter(this, this, context);
-        mIconCache = (LauncherAppState.getInstance()).getIconCache();
+        mIconCache = LauncherAppState.getInstance(context).getIconCache();
         if (LOGD) {
             Log.d(TAG, "WidgetsContainerView constructor");
         }
@@ -303,7 +303,7 @@
 
     private WidgetPreviewLoader getWidgetPreviewLoader() {
         if (mWidgetPreviewLoader == null) {
-            mWidgetPreviewLoader = LauncherAppState.getInstance().getWidgetCache();
+            mWidgetPreviewLoader = LauncherAppState.getInstance(getContext()).getWidgetCache();
         }
         return mWidgetPreviewLoader;
     }
diff --git a/src/com/android/launcher3/widget/WidgetsListAdapter.java b/src/com/android/launcher3/widget/WidgetsListAdapter.java
index f18313f..2d746d7 100644
--- a/src/com/android/launcher3/widget/WidgetsListAdapter.java
+++ b/src/com/android/launcher3/widget/WidgetsListAdapter.java
@@ -68,7 +68,7 @@
             View.OnLongClickListener iconLongClickListener,
             Context context) {
         mLayoutInflater = LayoutInflater.from(context);
-        mWidgetPreviewLoader = LauncherAppState.getInstance().getWidgetCache();
+        mWidgetPreviewLoader = LauncherAppState.getInstance(context).getWidgetCache();
 
         mIndexer = new AlphabeticIndexCompat(context);
 
diff --git a/tests/res/raw/cache_data_updated_task_data.txt b/tests/res/raw/cache_data_updated_task_data.txt
index 9095476..8199687 100644
--- a/tests/res/raw/cache_data_updated_task_data.txt
+++ b/tests/res/raw/cache_data_updated_task_data.txt
@@ -22,7 +22,7 @@
 bgItem s itemType=1 status=1 title=app3-shrt intent=component=app3/class3 id=9
 bgItem s itemType=1 status=1 title=app5-shrt intent=component=app5/class1 id=10
 
-allApps componentName=app1/class1
-allApps componentName=app1/class2
-allApps componentName=app2/class1
-allApps componentName=app2/class2
\ No newline at end of file
+allApps componentName=app1/class1 intent=component=app1/class1
+allApps componentName=app1/class2 intent=component=app1/class2
+allApps componentName=app2/class1 intent=component=app2/class1
+allApps componentName=app2/class2 intent=component=app2/class2
\ No newline at end of file
diff --git a/tests/src/com/android/launcher3/BindWidgetTest.java b/tests/src/com/android/launcher3/BindWidgetTest.java
index 72533e7..575b42b 100644
--- a/tests/src/com/android/launcher3/BindWidgetTest.java
+++ b/tests/src/com/android/launcher3/BindWidgetTest.java
@@ -16,7 +16,6 @@
 import com.android.launcher3.compat.PackageInstallerCompat;
 import com.android.launcher3.ui.LauncherInstrumentationTestCase;
 import com.android.launcher3.util.ContentWriter;
-import com.android.launcher3.util.ManagedProfileHeuristic;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
 import com.android.launcher3.widget.WidgetHostViewLoader;
 
@@ -223,20 +222,9 @@
         item.screenId = screenId;
         item.onAddToDatabase(writer);
         writer.put(LauncherSettings.Favorites._ID, item.id);
-        mResolver.insert(LauncherSettings.Favorites.CONTENT_URI, writer.getValues());
+        mResolver.insert(LauncherSettings.Favorites.CONTENT_URI, writer.getValues(mTargetContext));
+        resetLoaderState();
 
-        // Reset loader
-        try {
-            runTestOnUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    ManagedProfileHeuristic.markExistingUsersForNoFolderCreation(mTargetContext);
-                    LauncherAppState.getInstance().getModel().resetLoadedState(true, true);
-                }
-            });
-        } catch (Throwable t) {
-            throw new IllegalArgumentException(t);
-        }
         // Launch the home activity
         startLauncher();
         // Verify UI
diff --git a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
index b2f0cbb..2071389 100644
--- a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
+++ b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
@@ -164,7 +164,7 @@
                 info.cellX = x;
                 info.cellY = y;
                 info.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
-                bgDataModel.addItem(info, false);
+                bgDataModel.addItem(targetContext, info, false);
             }
         }
         return startId;
diff --git a/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java b/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
index 1d092ab..9b7fc6e 100644
--- a/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
+++ b/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
@@ -3,6 +3,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.LauncherActivityInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
@@ -13,6 +14,7 @@
 import android.test.ProviderTestCase2;
 
 import com.android.launcher3.AllAppsList;
+import com.android.launcher3.AppFilter;
 import com.android.launcher3.AppInfo;
 import com.android.launcher3.DeferredHandler;
 import com.android.launcher3.IconCache;
@@ -22,7 +24,6 @@
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherModel.BaseModelUpdateTask;
 import com.android.launcher3.LauncherModel.Callbacks;
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.config.ProviderConfig;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.Provider;
@@ -76,7 +77,7 @@
         idp = new InvariantDeviceProfile();
         iconCache = new MyIconCache(targetContext, idp);
 
-        allAppsList = new AllAppsList(iconCache, null);
+        allAppsList = new AllAppsList(iconCache, new AppFilter());
 
         when(appState.getIconCache()).thenReturn(iconCache);
         when(appState.getInvariantDeviceProfile()).thenReturn(idp);
@@ -127,11 +128,11 @@
                         classMap.put(commands[1], Class.forName(commands[2]));
                         break;
                     case "bgItem":
-                        bgDataModel.addItem(
+                        bgDataModel.addItem(targetContext,
                                 (ItemInfo) initItem(classMap.get(commands[1]), commands, 2), false);
                         break;
                     case "allApps":
-                        allAppsList.add((AppInfo) initItem(AppInfo.class, commands, 1));
+                        allAppsList.add((AppInfo) initItem(AppInfo.class, commands, 1), null);
                         break;
                 }
             }
@@ -188,7 +189,7 @@
         @Override
         protected CacheEntry cacheLocked(
                 @NonNull ComponentName componentName,
-                @NonNull Provider<LauncherActivityInfoCompat> infoProvider,
+                @NonNull Provider<LauncherActivityInfo> infoProvider,
                 UserHandle user, boolean usePackageIcon, boolean useLowResIcon) {
             CacheEntry entry = mCache.get(new ComponentKey(componentName, user));
             if (entry == null) {
@@ -208,5 +209,10 @@
         public Bitmap newIcon() {
             return Bitmap.createBitmap(1, 1, Config.ARGB_8888);
         }
+
+        @Override
+        protected Bitmap makeDefaultIcon(UserHandle user) {
+            return newIcon();
+        }
     }
 }
diff --git a/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java b/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
index 646ef27..d595e6c 100644
--- a/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
+++ b/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
@@ -30,6 +30,11 @@
     }
 
     public void testCacheUpdate_update_apps() throws Exception {
+        // Clear all icons from apps list so that its easy to check what was updated
+        for (AppInfo info : allAppsList.data) {
+            info.iconBitmap = null;
+        }
+
         executeTaskForTest(newTask(CacheDataUpdatedTask.OP_CACHE_UPDATE, "app1"));
 
         // Verify that only the app icons of app1 (id 1 & 2) are updated. Custom shortcut (id 7)
diff --git a/tests/src/com/android/launcher3/model/LoaderCursorTest.java b/tests/src/com/android/launcher3/model/LoaderCursorTest.java
index d40e6c2..b1c34d1 100644
--- a/tests/src/com/android/launcher3/model/LoaderCursorTest.java
+++ b/tests/src/com/android/launcher3/model/LoaderCursorTest.java
@@ -37,6 +37,7 @@
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
 import static com.android.launcher3.LauncherSettings.Favorites.PROFILE_ID;
+import static com.android.launcher3.LauncherSettings.Favorites.RESTORED;
 import static com.android.launcher3.LauncherSettings.Favorites.SCREEN;
 import static com.android.launcher3.LauncherSettings.Favorites.TITLE;
 import static com.android.launcher3.LauncherSettings.Favorites._ID;
@@ -72,7 +73,7 @@
         mCursor = new MatrixCursor(new String[] {
                 ICON, ICON_PACKAGE, ICON_RESOURCE, TITLE,
                 _ID, CONTAINER, ITEM_TYPE, PROFILE_ID,
-                SCREEN, CELLX, CELLY,
+                SCREEN, CELLX, CELLY, RESTORED
         });
         mContext = InstrumentationRegistry.getTargetContext();
 
diff --git a/tests/src/com/android/launcher3/ui/AllAppsAppLaunchTest.java b/tests/src/com/android/launcher3/ui/AllAppsAppLaunchTest.java
index 4a80735..0ced7cf 100644
--- a/tests/src/com/android/launcher3/ui/AllAppsAppLaunchTest.java
+++ b/tests/src/com/android/launcher3/ui/AllAppsAppLaunchTest.java
@@ -1,12 +1,12 @@
 package com.android.launcher3.ui;
 
+import android.content.pm.LauncherActivityInfo;
 import android.os.Process;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiObject2;
 import android.support.test.uiautomator.Until;
 import android.test.suitebuilder.annotation.LargeTest;
 
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.util.Condition;
 import com.android.launcher3.util.Wait;
@@ -17,7 +17,7 @@
 @LargeTest
 public class AllAppsAppLaunchTest extends LauncherInstrumentationTestCase {
 
-    private LauncherActivityInfoCompat mSettingsApp;
+    private LauncherActivityInfo mSettingsApp;
 
     @Override
     protected void setUp() throws Exception {
diff --git a/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java b/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java
index 8837b00..3f77bfd 100644
--- a/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java
+++ b/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java
@@ -1,12 +1,12 @@
 package com.android.launcher3.ui;
 
+import android.content.pm.LauncherActivityInfo;
 import android.os.Process;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiObject2;
 import android.support.test.uiautomator.Until;
 import android.test.suitebuilder.annotation.LargeTest;
 
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.util.Condition;
 import com.android.launcher3.util.Wait;
@@ -17,7 +17,7 @@
 @LargeTest
 public class AllAppsIconToHomeTest extends LauncherInstrumentationTestCase {
 
-    private LauncherActivityInfoCompat mSettingsApp;
+    private LauncherActivityInfo mSettingsApp;
 
     @Override
     protected void setUp() throws Exception {
diff --git a/tests/src/com/android/launcher3/ui/LauncherInstrumentationTestCase.java b/tests/src/com/android/launcher3/ui/LauncherInstrumentationTestCase.java
index fcf7122..42c6cd7 100644
--- a/tests/src/com/android/launcher3/ui/LauncherInstrumentationTestCase.java
+++ b/tests/src/com/android/launcher3/ui/LauncherInstrumentationTestCase.java
@@ -211,15 +211,22 @@
                 LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
         LauncherSettings.Settings.call(mTargetContext.getContentResolver(),
                 LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG);
-        ManagedProfileHeuristic.markExistingUsersForNoFolderCreation(mTargetContext);
+        resetLoaderState();
+    }
 
-        runTestOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                // Reset the loader state
-                LauncherAppState.getInstance().getModel().resetLoadedState(true, true);
-            }
-        });
+    protected void resetLoaderState() {
+        try {
+            runTestOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    ManagedProfileHeuristic.markExistingUsersForNoFolderCreation(mTargetContext);
+                    LauncherAppState.getInstance(mTargetContext).getModel()
+                            .resetLoadedState(true, true);
+                }
+            });
+        } catch (Throwable t) {
+            throw new IllegalArgumentException(t);
+        }
     }
 
     /**
@@ -248,8 +255,7 @@
         LauncherAppWidgetProviderInfo info = getOnUiThread(new Callable<LauncherAppWidgetProviderInfo>() {
             @Override
             public LauncherAppWidgetProviderInfo call() throws Exception {
-                InvariantDeviceProfile idv =
-                        LauncherAppState.getInstance().getInvariantDeviceProfile();
+                InvariantDeviceProfile idv = LauncherAppState.getIDP(mTargetContext);
 
                 ComponentName searchComponent = ((SearchManager) mTargetContext
                         .getSystemService(Context.SEARCH_SERVICE)).getGlobalSearchActivity();
diff --git a/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java b/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java
index 02d938c..c6828f0 100644
--- a/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java
+++ b/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java
@@ -1,5 +1,6 @@
 package com.android.launcher3.ui;
 
+import android.content.pm.LauncherActivityInfo;
 import android.graphics.Point;
 import android.os.Process;
 import android.support.test.uiautomator.By;
@@ -9,7 +10,6 @@
 import android.view.MotionEvent;
 
 import com.android.launcher3.R;
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.util.Condition;
 import com.android.launcher3.util.Wait;
@@ -20,7 +20,7 @@
 @LargeTest
 public class ShortcutsLaunchTest extends LauncherInstrumentationTestCase {
 
-    private LauncherActivityInfoCompat mSettingsApp;
+    private LauncherActivityInfo mSettingsApp;
 
     @Override
     protected void setUp() throws Exception {
diff --git a/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java b/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java
index afe4832..d573eea 100644
--- a/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java
+++ b/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java
@@ -1,5 +1,6 @@
 package com.android.launcher3.ui;
 
+import android.content.pm.LauncherActivityInfo;
 import android.graphics.Point;
 import android.os.Process;
 import android.support.test.uiautomator.By;
@@ -9,7 +10,6 @@
 import android.view.MotionEvent;
 
 import com.android.launcher3.R;
-import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.util.Condition;
 import com.android.launcher3.util.Wait;
@@ -20,7 +20,7 @@
 @LargeTest
 public class ShortcutsToHomeTest extends LauncherInstrumentationTestCase {
 
-    private LauncherActivityInfoCompat mSettingsApp;
+    private LauncherActivityInfo mSettingsApp;
 
     @Override
     protected void setUp() throws Exception {