Removing shadow and badging from the icon which is shown in the menu
These are added as soon as the icon is added to the workspace

Bug: 28980830
Change-Id: I725d2ee8994324f09d9ecf7bbbb0090a7ceb5769
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 921e90c..df87cc2 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -348,7 +348,7 @@
 
         public ShortcutInfo getShortcutInfo() {
             if (activityInfo != null) {
-                return ShortcutInfo.fromActivityInfo(activityInfo, mContext);
+                return new ShortcutInfo(activityInfo, mContext);
             } else {
                 return LauncherAppState.getInstance().getModel().infoFromShortcutIntent(mContext, data);
             }
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index ddd60c8..4561111 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -1957,8 +1957,7 @@
                                         }
                                     }
                                     incrementPinnedShortcutCount(key, shouldPin);
-                                    info = ShortcutInfo.fromDeepShortcutInfo(
-                                            pinnedShortcut, context);
+                                    info = new ShortcutInfo(pinnedShortcut, context);
                                 } else { // item type == ITEM_TYPE_SHORTCUT
                                     info = getShortcutInfo(c, context, titleIndex, cursorIconInfo);
 
@@ -3291,6 +3290,22 @@
         }
     }
 
+    /**
+     * Repopulates the shortcut info, possibly updating any icon already on the workspace.
+     */
+    public void updateShortcutInfo(final ShortcutInfoCompat fullDetail, final ShortcutInfo info) {
+        enqueueItemUpdatedTask(new Runnable() {
+            @Override
+            public void run() {
+                info.updateFromDeepShortcutInfo(
+                        fullDetail, LauncherAppState.getInstance().getContext());
+                ArrayList<ShortcutInfo> update = new ArrayList<ShortcutInfo>();
+                update.add(info);
+                bindUpdatedShortcuts(update, fullDetail.getUserHandle());
+            }
+        });
+    }
+
     private class ShortcutsChangedTask implements Runnable {
         private String mPackageName;
         private List<ShortcutInfoCompat> mShortcuts;
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index a9f73c2..0cc5a1b 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -162,19 +162,17 @@
         this.user = user;
     }
 
-    public ShortcutInfo(Context context, ShortcutInfo info) {
+    public ShortcutInfo(ShortcutInfo info) {
         super(info);
-        title = Utilities.trim(info.title);
+        title = info.title;
         intent = new Intent(info.intent);
-        if (info.iconResource != null) {
-            iconResource = new Intent.ShortcutIconResource();
-            iconResource.packageName = info.iconResource.packageName;
-            iconResource.resourceName = info.iconResource.resourceName;
-        }
+        iconResource = info.iconResource;
         mIcon = info.mIcon; // TODO: should make a copy here.  maybe we don't need this ctor at all
         flags = info.flags;
-        user = info.user;
         status = info.status;
+        mInstallProgress = info.mInstallProgress;
+        isDisabled = info.isDisabled;
+        usingFallbackIcon = info.usingFallbackIcon;
     }
 
     /** TODO: Remove this.  It's only called by ApplicationInfo.makeShortcut. */
@@ -186,6 +184,28 @@
         isDisabled = info.isDisabled;
     }
 
+    public ShortcutInfo(LauncherActivityInfoCompat info, Context context) {
+        user = info.getUser();
+        title = Utilities.trim(info.getLabel());
+        contentDescription = UserManagerCompat.getInstance(context)
+                .getBadgedLabelForUser(info.getLabel(), info.getUser());
+        intent = AppInfo.makeLaunchIntent(context, info, info.getUser());
+        itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
+        flags = AppInfo.initFlags(info);
+    }
+
+    /**
+     * Creates a {@link ShortcutInfo} from a {@link ShortcutInfoCompat}.
+     */
+    @TargetApi(Build.VERSION_CODES.N)
+    public ShortcutInfo(ShortcutInfoCompat shortcutInfo, Context context) {
+        user = shortcutInfo.getUserHandle();
+        itemType = LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
+        intent = shortcutInfo.makeIntent(context);
+        flags = 0;
+        updateFromDeepShortcutInfo(shortcutInfo, context);
+    }
+
     public void setIcon(Bitmap b) {
         mIcon = b;
     }
@@ -265,33 +285,6 @@
         return usingLowResIcon && container >= 0 && rank >= FolderIcon.NUM_ITEMS_IN_PREVIEW;
     }
 
-    public static ShortcutInfo fromActivityInfo(LauncherActivityInfoCompat info, Context context) {
-        final ShortcutInfo shortcut = new ShortcutInfo();
-        shortcut.user = info.getUser();
-        shortcut.title = Utilities.trim(info.getLabel());
-        shortcut.contentDescription = UserManagerCompat.getInstance(context)
-                .getBadgedLabelForUser(info.getLabel(), info.getUser());
-        shortcut.intent = AppInfo.makeLaunchIntent(context, info, info.getUser());
-        shortcut.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
-        shortcut.flags = AppInfo.initFlags(info);
-        return shortcut;
-    }
-
-    /**
-     * Creates a {@link ShortcutInfo} from a {@link ShortcutInfoCompat}. Pardon the overloaded name.
-     */
-    @TargetApi(Build.VERSION_CODES.N)
-    public static ShortcutInfo fromDeepShortcutInfo(ShortcutInfoCompat shortcutInfo,
-            Context context) {
-        ShortcutInfo si = new ShortcutInfo();
-        si.user = shortcutInfo.getUserHandle();
-        si.itemType = LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
-        si.intent = shortcutInfo.makeIntent(context);
-        si.flags = 0;
-        si.updateFromDeepShortcutInfo(shortcutInfo, context);
-        return si;
-    }
-
     public void updateFromDeepShortcutInfo(ShortcutInfoCompat shortcutInfo, Context context) {
         title = shortcutInfo.getShortLabel();
 
@@ -306,11 +299,14 @@
         Drawable unbadgedIcon = launcherAppState.getShortcutManager()
                 .getShortcutIconDrawable(shortcutInfo,
                         launcherAppState.getInvariantDeviceProfile().fillResIconDpi);
-        Bitmap icon = unbadgedIcon == null ? null
-                : Utilities.createBadgedIconBitmapWithShadow(unbadgedIcon, user, context);
+        Bitmap icon = unbadgedIcon == null ? null : getBadgedIcon(unbadgedIcon, context);
         setIcon(icon != null ? icon : launcherAppState.getIconCache().getDefaultIcon(user));
     }
 
+    protected Bitmap getBadgedIcon(Drawable unbadgedIcon, Context context) {
+        return Utilities.createBadgedIconBitmapWithShadow(unbadgedIcon, user, context);
+    }
+
     /** Returns the ShortcutInfo id associated with the deep shortcut. */
     public String getDeepShortcutId() {
         return itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT ?
@@ -322,4 +318,3 @@
         return isDisabled != 0;
     }
 }
-
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index ef78195..f09b7cc 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -264,18 +264,25 @@
     }
 
     /**
+     * Creates a normalized bitmap suitable for the all apps view. The bitmap is also visually
+     * normalized with other icons and has enough spacing to add shadow.
+     */
+    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);
+        scale = Math.min(scale, ShadowGenerator.getScaleForBounds(iconBounds));
+        return createIconBitmap(icon, context, scale);
+    }
+
+    /**
      * Same as {@link #createBadgedIconBitmap} but adds a shadow before badging the icon
      */
     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     public static Bitmap createBadgedIconBitmapWithShadow(
             Drawable icon, UserHandleCompat user, Context context) {
-        RectF iconBounds = new RectF();
-        float scale = FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION ?
-                1 : IconNormalizer.getInstance().getScale(icon, iconBounds);
-        scale = Math.min(scale, ShadowGenerator.getScaleForBounds(iconBounds));
-
-        Bitmap bitmap = createIconBitmap(icon, context, scale);
-        bitmap = ShadowGenerator.getInstance().recreateIcon(bitmap);
+        Bitmap bitmap = ShadowGenerator.getInstance().recreateIcon(
+                createScaledBitmapWithoutShadow(icon, context));
         if (Utilities.ATLEAST_LOLLIPOP && user != null
                 && !UserHandleCompat.myUserHandle().equals(user)) {
             BitmapDrawable drawable = new FixedSizeBitmapDrawable(bitmap);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 946c306..4ed2467 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2301,11 +2301,19 @@
     }
 
     public void beginDragShared(View child, DragSource source, boolean accessible) {
-        beginDragShared(child, new Point(), source, accessible, new DragPreviewProvider(child));
+        Object dragObject = child.getTag();
+        if (!(dragObject instanceof ItemInfo)) {
+            String msg = "Drag started with a view that has no tag set. This "
+                    + "will cause a crash (issue 11627249) down the line. "
+                    + "View: " + child + "  tag: " + child.getTag();
+            throw new IllegalStateException(msg);
+        }
+        beginDragShared(child, new Point(), source, accessible,
+                (ItemInfo) dragObject, new DragPreviewProvider(child));
     }
 
     public void beginDragShared(View child, Point relativeTouchPos, DragSource source,
-                                boolean accessible, DragPreviewProvider previewProvider) {
+            boolean accessible, ItemInfo dragObject, DragPreviewProvider previewProvider) {
         child.clearFocus();
         child.setPressed(false);
 
@@ -2362,20 +2370,12 @@
             icon.clearPressedBackground();
         }
 
-        Object dragObject = child.getTag();
-        if (!(dragObject instanceof ItemInfo)) {
-            String msg = "Drag started with a view that has no tag set. This "
-                    + "will cause a crash (issue 11627249) down the line. "
-                    + "View: " + child + "  tag: " + child.getTag();
-            throw new IllegalStateException(msg);
-        }
-
         if (child.getParent() instanceof ShortcutAndWidgetContainer) {
             mDragSourceInternal = (ShortcutAndWidgetContainer) child.getParent();
         }
 
         DragView dv = mDragController.startDrag(b, dragLayerX, dragLayerY, source,
-                (ItemInfo) dragObject, DragController.DRAG_ACTION_MOVE, dragVisualizeOffset,
+                dragObject, DragController.DRAG_ACTION_MOVE, dragVisualizeOffset,
                 dragRect, scale, accessible);
         dv.setIntrinsicIconScaleFactor(source.getIntrinsicIconScaleFactor());
 
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java b/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java
index fdc0bd2..4f67e46 100644
--- a/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java
+++ b/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java
@@ -25,6 +25,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
@@ -166,8 +167,8 @@
                 Collections.sort(shortcuts, shortcutsComparator);
                 for (int i = 0; i < shortcuts.size(); i++) {
                     final ShortcutInfoCompat shortcut = shortcuts.get(i);
-                    final ShortcutInfo launcherShortcutInfo = ShortcutInfo
-                            .fromDeepShortcutInfo(shortcut, mLauncher);
+                    final ShortcutInfo launcherShortcutInfo =
+                            new UnbadgedShortcutInfo(shortcut, mLauncher);
                     CharSequence shortLabel = shortcut.getShortLabel();
                     CharSequence longLabel = shortcut.getLongLabel();
                     uiHandler.post(new UpdateShortcutChild(i, launcherShortcutInfo,
@@ -446,8 +447,14 @@
         // Return if global dragging is not enabled
         if (!mLauncher.isDraggingEnabled()) return false;
 
+        UnbadgedShortcutInfo unbadgedInfo = (UnbadgedShortcutInfo) v.getTag();
+        ShortcutInfo badged = new ShortcutInfo(unbadgedInfo);
+        // Queue an update task on the worker thread. This ensures that the badged
+        // shortcut eventually gets its icon updated.
+        mLauncher.getModel().updateShortcutInfo(unbadgedInfo.mDetail, badged);
+
         // Long clicked on a shortcut.
-        mLauncher.getWorkspace().beginDragShared(v, mIconLastTouchPos, this, false,
+        mLauncher.getWorkspace().beginDragShared(v, mIconLastTouchPos, this, false, badged,
                 new ScaledPreviewProvider(v));
         // TODO: support dragging from within folder without having to close it
         mLauncher.closeFolder();
@@ -530,4 +537,21 @@
         }
         return null;
     }
+
+    /**
+     * Extension of {@link ShortcutInfo} which does not badge the icons.
+     */
+    private static class UnbadgedShortcutInfo extends ShortcutInfo {
+        private final ShortcutInfoCompat mDetail;
+
+        public UnbadgedShortcutInfo(ShortcutInfoCompat shortcutInfo, Context context) {
+            super(shortcutInfo, context);
+            mDetail = shortcutInfo;
+        }
+
+        @Override
+        protected Bitmap getBadgedIcon(Drawable unbadgedIcon, Context context) {
+            return Utilities.createScaledBitmapWithoutShadow(unbadgedIcon, context);
+        }
+    }
 }
diff --git a/src/com/android/launcher3/util/ManagedProfileHeuristic.java b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
index 7dbc0e7a..6661429 100644
--- a/src/com/android/launcher3/util/ManagedProfileHeuristic.java
+++ b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
@@ -111,7 +111,7 @@
             for (int i = 0; i < count; i++) {
                 LauncherActivityInstallInfo info = apps.get(i);
 
-                ShortcutInfo si = ShortcutInfo.fromActivityInfo(info.info, mContext);
+                ShortcutInfo si = new ShortcutInfo(info.info, mContext);
                 ((info.installTime <= folderCreationTime) ? workFolderApps : homescreenApps).add(si);
             }