Do not allow duplicate shortcuts when ALL_APPS is disabled.

When DISABLE_ALL_APPS is true, we want to have only one shortcut for each activityexposed via the Application's manifest.
We ignore INSTALL_SHORTCUT broadcasts which have launch intents with ACTION_MAIN and CATEGORY_LAUNCHER.
Applications can still create shortcuts pointing to an already exposed component if they provide data or extras in the intent.

Change-Id: I0b05283ea6c522d197e0262c2997f7298e08740b
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index a8ac074..c76425a 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -266,19 +266,8 @@
     private boolean isUninstallFromWorkspace(DragObject d) {
         if (AppsCustomizePagedView.DISABLE_ALL_APPS && isWorkspaceOrFolderApplication(d)) {
             ShortcutInfo shortcut = (ShortcutInfo) d.dragInfo;
-            if (shortcut.intent != null && shortcut.intent.getComponent() != null) {
-                Set<String> categories = shortcut.intent.getCategories();
-                boolean includesLauncherCategory = false;
-                if (categories != null) {
-                    for (String category : categories) {
-                        if (category.equals(Intent.CATEGORY_LAUNCHER)) {
-                            includesLauncherCategory = true;
-                            break;
-                        }
-                    }
-                }
-                return includesLauncherCategory;
-            }
+            // Only allow manifest shortcuts to initiate an un-install.
+            return !InstallShortcutReceiver.isValidShortcutLaunchIntent(shortcut.intent);
         }
         return false;
     }
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 140106a..1ff9472 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -24,6 +24,7 @@
 import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.text.TextUtils;
 import android.util.Base64;
 import android.util.Log;
 import android.widget.Toast;
@@ -223,6 +224,7 @@
         if (intent == null) {
             return;
         }
+
         // This name is only used for comparisons and notifications, so fall back to activity name
         // if not supplied
         String name = ensureValidName(context, intent,
@@ -269,6 +271,12 @@
                 //final Intent data = pendingInfo.data;
                 final Intent intent = pendingInfo.launchIntent;
                 final String name = pendingInfo.name;
+
+                if (AppsCustomizePagedView.DISABLE_ALL_APPS && !isValidShortcutLaunchIntent(intent)) {
+                    if (DBG) Log.d(TAG, "Ignoring shortcut with launchIntent:" + intent);
+                    continue;
+                }
+
                 final boolean exists = LauncherModel.shortcutExists(context, name, intent);
                 //final boolean allowDuplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
 
@@ -301,6 +309,30 @@
         }
     }
 
+    /**
+     * Returns true if the intent is a valid launch intent for a shortcut.
+     * This is used to identify shortcuts which are different from the ones exposed by the
+     * applications' manifest file.
+     *
+     * When DISABLE_ALL_APPS is true, shortcuts exposed via the app's manifest should never be
+     * duplicated or removed(unless the app is un-installed).
+     *
+     * @param launchIntent The intent that will be launched when the shortcut is clicked.
+     */
+    static boolean isValidShortcutLaunchIntent(Intent launchIntent) {
+        if (launchIntent != null
+                && Intent.ACTION_MAIN.equals(launchIntent.getAction())
+                && launchIntent.getComponent() != null
+                && launchIntent.getCategories() != null
+                && launchIntent.getCategories().size() == 1
+                && launchIntent.hasCategory(Intent.CATEGORY_LAUNCHER)
+                && launchIntent.getExtras() == null
+                && TextUtils.isEmpty(launchIntent.getDataString())) {
+            return false;
+        }
+        return true;
+    }
+
     private static ShortcutInfo getShortcutInfo(Context context, Intent data,
                                                 Intent launchIntent) {
         if (launchIntent.getAction() == null) {