Adding support for customizing shortcut pinning logic

> Allowing support for overring shortcut badge
> Updating pendingShortcutInfo so that the
  handler can be easily overridden

Bug: 268253894
Test: Verified on device
Change-Id: I3184cb6494bc98c7eed33798b35b4e6e6a1e7ddc
diff --git a/quickstep/res/drawable/close_icon.xml b/quickstep/res/drawable/close_icon.xml
deleted file mode 100644
index 07f4336..0000000
--- a/quickstep/res/drawable/close_icon.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24"
-    android:tint="?attr/colorControlNormal">
-  <path
-      android:fillColor="#909090"
-      android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
-</vector>
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 8097fd7..8e53101 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1947,7 +1947,7 @@
         Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setComponent(info.componentName);
         setWaitingForResult(PendingRequestArgs.forIntent(REQUEST_CREATE_SHORTCUT, intent, info));
         TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "start: processShortcutFromDrop");
-        if (!info.activityInfo.startConfigActivity(this, REQUEST_CREATE_SHORTCUT)) {
+        if (!info.getActivityInfo(this).startConfigActivity(this, REQUEST_CREATE_SHORTCUT)) {
             handleActivityResult(REQUEST_CREATE_SHORTCUT, RESULT_CANCELED, null);
         }
     }
diff --git a/src/com/android/launcher3/PendingAddItemInfo.java b/src/com/android/launcher3/PendingAddItemInfo.java
index b7a22fc..000ddd8 100644
--- a/src/com/android/launcher3/PendingAddItemInfo.java
+++ b/src/com/android/launcher3/PendingAddItemInfo.java
@@ -21,7 +21,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.ItemInfoWithIcon;
 
 import java.util.Optional;
 
@@ -29,13 +29,20 @@
  * Meta data that is used for deferred binding. e.g., this object is used to pass information on
  * draggable targets when they are dropped onto the workspace from another container.
  */
-public class PendingAddItemInfo extends ItemInfo {
+public class PendingAddItemInfo extends ItemInfoWithIcon {
 
     /**
      * The component that will be created.
      */
     public ComponentName componentName;
 
+    public PendingAddItemInfo() { }
+
+    public PendingAddItemInfo(PendingAddItemInfo info) {
+        super(info);
+        componentName = info.componentName;
+    }
+
     @Override
     protected String dumpProperties() {
         return super.dumpProperties() + " componentName=" + componentName;
@@ -46,13 +53,18 @@
      */
     @NonNull
     @Override
-    public ItemInfo makeShallowCopy() {
+    public PendingAddItemInfo makeShallowCopy() {
         PendingAddItemInfo itemInfo = new PendingAddItemInfo();
         itemInfo.copyFrom(this);
         itemInfo.componentName = this.componentName;
         return itemInfo;
     }
 
+    @Override
+    public PendingAddItemInfo clone() {
+        return makeShallowCopy();
+    }
+
     @Nullable
     @Override
     public ComponentName getTargetComponent() {
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index bd9493b..b32ff3c 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -557,6 +557,12 @@
             int width, int height, Object[] outObj) {
         ActivityContext activity = ActivityContext.lookupContext(context);
         LauncherAppState appState = LauncherAppState.getInstance(context);
+        if (info instanceof PendingAddShortcutInfo) {
+            ShortcutConfigActivityInfo activityInfo =
+                    ((PendingAddShortcutInfo) info).getActivityInfo(context);
+            outObj[0] = activityInfo;
+            return activityInfo.getFullResIcon(appState.getIconCache());
+        }
         if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
             LauncherActivityInfo activityInfo = context.getSystemService(LauncherApps.class)
                     .resolveActivity(info.getIntent(), info.user);
@@ -565,12 +571,6 @@
                     .getIconProvider().getIcon(
                             activityInfo, activity.getDeviceProfile().inv.fillResIconDpi);
         } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
-            if (info instanceof PendingAddShortcutInfo) {
-                ShortcutConfigActivityInfo activityInfo =
-                        ((PendingAddShortcutInfo) info).activityInfo;
-                outObj[0] = activityInfo;
-                return activityInfo.getFullResIcon(appState.getIconCache());
-            }
             List<ShortcutInfo> si = ShortcutKey.fromItemInfo(info)
                     .buildRequest(context)
                     .query(ShortcutRequest.ALL);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index cfb8ca4..ba492d5 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2690,7 +2690,7 @@
     private void onDropExternal(final int[] touchXY, final CellLayout cellLayout, DragObject d) {
         if (d.dragInfo instanceof PendingAddShortcutInfo) {
             WorkspaceItemInfo si = ((PendingAddShortcutInfo) d.dragInfo)
-                    .activityInfo.createWorkspaceItemInfo();
+                    .getActivityInfo(mLauncher).createWorkspaceItemInfo();
             if (si != null) {
                 d.dragInfo = si;
             }
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index f54d05d..e10fdf5 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -56,7 +56,6 @@
 import androidx.dynamicanimation.animation.SpringAnimation;
 import androidx.dynamicanimation.animation.SpringForce;
 
-import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.Interpolators;
@@ -218,12 +217,6 @@
      */
     @TargetApi(Build.VERSION_CODES.O)
     public void setItemInfo(final ItemInfo info) {
-        if (info.itemType != LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
-                && info.itemType != LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION
-                && info.itemType != LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
-                && info.itemType != LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
-            return;
-        }
         // Load the adaptive icon on a background thread and add the view in ui thread.
         MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(() -> {
             Object[] outObj = new Object[1];
diff --git a/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java b/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
index f9916d0..6b21522 100644
--- a/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
+++ b/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
@@ -44,7 +44,7 @@
  * request.
  */
 @TargetApi(Build.VERSION_CODES.O)
-class PinShortcutRequestActivityInfo extends ShortcutConfigActivityInfo {
+public class PinShortcutRequestActivityInfo extends ShortcutConfigActivityInfo {
 
     // Class name used in the target component, such that it will never represent an
     // actual existing class.
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 9a5d77e..c9fe745 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -1263,7 +1263,7 @@
         PendingAddShortcutInfo pasi = d.dragInfo instanceof PendingAddShortcutInfo
                 ? (PendingAddShortcutInfo) d.dragInfo : null;
         WorkspaceItemInfo pasiSi =
-                pasi != null ? pasi.activityInfo.createWorkspaceItemInfo() : null;
+                pasi != null ? pasi.getActivityInfo(launcher).createWorkspaceItemInfo() : null;
         if (pasi != null && pasiSi == null) {
             // There is no WorkspaceItemInfo, so we have to go through a configuration activity.
             pasi.container = mInfo.id;
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index 0b4a4a5..c8ccdca 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -60,6 +60,7 @@
 import com.android.launcher3.model.data.ItemInfoWithIcon;
 import com.android.launcher3.model.data.PackageItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.pm.InstallSessionHelper;
 import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.shortcuts.ShortcutKey;
 import com.android.launcher3.util.InstantAppResolver;
@@ -81,6 +82,11 @@
  */
 public class IconCache extends BaseIconCache {
 
+    // Shortcut extra which can point to a packageName and can be used to indicate an alternate
+    // badge info. Launcher only reads this if the shortcut comes from a system app.
+    public static final String EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE =
+            "extra_shortcut_badge_override_package";
+
     private static final String TAG = "Launcher.IconCache";
 
     private final Predicate<ItemInfoWithIcon> mIsUsingFallbackOrNonDefaultIconCheck = w ->
@@ -260,8 +266,15 @@
             getTitleAndIcon(appInfo, false);
             return appInfo.bitmap;
         } else {
-            PackageItemInfo pkgInfo = new PackageItemInfo(shortcutInfo.getPackage(),
-                    shortcutInfo.getUserHandle());
+            String pkg = shortcutInfo.getPackage();
+            String override = shortcutInfo.getExtras() == null ? null
+                    : shortcutInfo.getExtras().getString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE);
+            if (!TextUtils.isEmpty(override)
+                    && InstallSessionHelper.INSTANCE.get(mContext)
+                            .isTrustedPackage(pkg, shortcutInfo.getUserHandle())) {
+                pkg = override;
+            }
+            PackageItemInfo pkgInfo = new PackageItemInfo(pkg, shortcutInfo.getUserHandle());
             getTitleAndIconForApp(pkgInfo, false);
             return pkgInfo.bitmap;
         }
diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java
index db23566..7ca3b11 100644
--- a/src/com/android/launcher3/pm/InstallSessionHelper.java
+++ b/src/com/android/launcher3/pm/InstallSessionHelper.java
@@ -171,15 +171,22 @@
             }
             return null;
         }
-        String pkg = sessionInfo.getInstallerPackageName();
+        return isTrustedPackage(sessionInfo.getInstallerPackageName(), getUserHandle(sessionInfo))
+                ? sessionInfo : null;
+    }
+
+    /**
+     * Returns true if the provided packageName can be trusted for user configurations
+     */
+    public boolean isTrustedPackage(String pkg, UserHandle user) {
         synchronized (mSessionVerifiedMap) {
             if (!mSessionVerifiedMap.containsKey(pkg)) {
                 boolean hasSystemFlag = new PackageManagerHelper(mAppContext).getApplicationInfo(
-                        pkg, getUserHandle(sessionInfo), ApplicationInfo.FLAG_SYSTEM) != null;
+                        pkg, user, ApplicationInfo.FLAG_SYSTEM) != null;
                 mSessionVerifiedMap.put(pkg, DEBUG || hasSystemFlag);
             }
         }
-        return mSessionVerifiedMap.get(pkg) ? sessionInfo : null;
+        return mSessionVerifiedMap.get(pkg);
     }
 
     @NonNull
diff --git a/src/com/android/launcher3/pm/ShortcutConfigActivityInfo.java b/src/com/android/launcher3/pm/ShortcutConfigActivityInfo.java
index 7af14c6..14e67b2 100644
--- a/src/com/android/launcher3/pm/ShortcutConfigActivityInfo.java
+++ b/src/com/android/launcher3/pm/ShortcutConfigActivityInfo.java
@@ -23,7 +23,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentSender;
-import android.content.pm.ActivityInfo;
 import android.content.pm.LauncherActivityInfo;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
@@ -112,26 +111,6 @@
         return true;
     }
 
-    static class ShortcutConfigActivityInfoVL extends ShortcutConfigActivityInfo {
-
-        private final ActivityInfo mInfo;
-
-        ShortcutConfigActivityInfoVL(ActivityInfo info) {
-            super(new ComponentName(info.packageName, info.name), Process.myUserHandle());
-            mInfo = info;
-        }
-
-        @Override
-        public CharSequence getLabel(PackageManager pm) {
-            return mInfo.loadLabel(pm);
-        }
-
-        @Override
-        public Drawable getFullResIcon(IconCache cache) {
-            return cache.getFullResIcon(mInfo);
-        }
-    }
-
     @TargetApi(26)
     public static class ShortcutConfigActivityInfoVO extends ShortcutConfigActivityInfo {
 
diff --git a/src/com/android/launcher3/widget/PendingAddShortcutInfo.java b/src/com/android/launcher3/widget/PendingAddShortcutInfo.java
index 9601652..3935be5 100644
--- a/src/com/android/launcher3/widget/PendingAddShortcutInfo.java
+++ b/src/com/android/launcher3/widget/PendingAddShortcutInfo.java
@@ -17,6 +17,8 @@
 
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_TRAY;
 
+import android.content.Context;
+
 import com.android.launcher3.PendingAddItemInfo;
 import com.android.launcher3.pm.ShortcutConfigActivityInfo;
 
@@ -27,13 +29,28 @@
  */
 public class PendingAddShortcutInfo extends PendingAddItemInfo {
 
-    public ShortcutConfigActivityInfo activityInfo;
+    // TODO: Make it @NonNull
+    protected ShortcutConfigActivityInfo mActivityInfo;
 
     public PendingAddShortcutInfo(ShortcutConfigActivityInfo activityInfo) {
-        this.activityInfo = activityInfo;
+        this.mActivityInfo = activityInfo;
         componentName = activityInfo.getComponent();
         user = activityInfo.getUser();
         itemType = activityInfo.getItemType();
         this.container = CONTAINER_WIDGETS_TRAY;
     }
+
+    public PendingAddShortcutInfo(PendingAddShortcutInfo info) {
+        super(info);
+        mActivityInfo = info.mActivityInfo;
+    }
+
+    public PendingAddShortcutInfo() { }
+
+    /**
+     * Returns the info used for creating the shortcut
+     */
+    public ShortcutConfigActivityInfo getActivityInfo(Context context) {
+        return mActivityInfo;
+    }
 }
diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java
index bbbc329..2dedd12 100644
--- a/src/com/android/launcher3/widget/PendingItemDragHelper.java
+++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java
@@ -180,7 +180,8 @@
             draggableView = DraggableView.ofType(DraggableView.DRAGGABLE_WIDGET);
         } else {
             PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) mAddInfo;
-            Drawable icon = createShortcutInfo.activityInfo.getFullResIcon(app.getIconCache());
+            Drawable icon = createShortcutInfo.getActivityInfo(launcher)
+                    .getFullResIcon(app.getIconCache());
             LauncherIcons li = LauncherIcons.obtain(launcher);
             preview = new FastBitmapDrawable(
                     li.createScaledBitmap(icon, BaseIconFactory.MODE_DEFAULT));