Merge "Fixing AppWidgetsRestoredReceiver updating model on UI thread" into ub-launcher3-master
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/Launcher.java b/src/com/android/launcher3/Launcher.java
index 8322f66..fc112f3 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -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/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 0907c8c..6938611 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -1321,8 +1321,6 @@
                                 if (restored) {
                                     if (c.user.equals(Process.myUserHandle())) {
                                         info = c.getRestoredItemInfo(intent, promiseType);
-                                        intent = PackageManagerHelper.getMarketIntent(
-                                                intent.getComponent().getPackageName());
                                     } else {
                                         // Don't restore items for other profiles.
                                         c.markDeleted("Restore from managed profile not supported");
@@ -1382,9 +1380,6 @@
                                     // 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;
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 8c83dff..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) {
@@ -250,15 +242,25 @@
     protected Bitmap getBadgedIcon(Bitmap unbadgedBitmap, ShortcutInfoCompat shortcutInfo,
             IconCache cache, Context context) {
         unbadgedBitmap = LauncherIcons.addShadowToIcon(unbadgedBitmap, context);
-        // 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);
+
+        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/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java
index 01bae0e..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
@@ -157,6 +161,7 @@
      * @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 = LauncherAppState.getIDP(context).iconBitmapSize;
 
@@ -212,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/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/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index 43e1bd6..b271e6f 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -188,7 +188,7 @@
     public ShortcutInfo getRestoredItemInfo(Intent intent, int promiseType) {
         final ShortcutInfo info = new ShortcutInfo();
         info.user = user;
-        info.promisedIntent = intent;
+        info.intent = intent;
 
         info.iconBitmap = loadIcon(info);
         // the fallback icon
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) {