Implement ranking for shortcuts.

- Manifest shortcuts are closest to the original icon, in rank order,
  followed by dynamic shortcuts in rank order.
- Also prevent pinned shortcuts from showing in container if they
  aren't also dynamic (only manifest and dynamic show in container).

Bug: 29822383
Bug: 29946657
Change-Id: I5cdb2ef3700daedca01987f64c245beb3f4aa5ee
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutManager.java b/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
index 66e98cd..450c36d 100644
--- a/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
+++ b/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
@@ -81,11 +81,13 @@
     }
 
     /**
-     * Gets all the shortcuts associated with the given package and user.
+     * Gets all the manifest and dynamic shortcuts associated with the given package and user,
+     * to be displayed in the shortcuts container on long press.
      */
-    public List<ShortcutInfoCompat> queryForAllAppShortcuts(ComponentName activity,
+    public List<ShortcutInfoCompat> queryForShortcutsContainer(ComponentName activity,
             List<String> ids, UserHandleCompat user) {
-        return query(FLAG_GET_ALL, activity.getPackageName(), activity, ids, user);
+        return query(FLAG_MATCH_MANIFEST | FLAG_MATCH_DYNAMIC,
+                activity.getPackageName(), activity, ids, user);
     }
 
     /**
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java b/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java
index d9e34a6..70082f3 100644
--- a/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java
+++ b/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java
@@ -38,6 +38,8 @@
 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
 import com.android.launcher3.util.UiThreadCircularReveal;
 
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 
 /**
@@ -65,6 +67,26 @@
     private boolean mIsLeftAligned;
     private boolean mIsAboveIcon;
 
+    /**
+     * Sorts shortcuts in rank order, with manifest shortcuts coming before dynamic shortcuts.
+     */
+    private static final Comparator<ShortcutInfoCompat> sShortcutsComparator
+            = new Comparator<ShortcutInfoCompat>() {
+        @Override
+        public int compare(ShortcutInfoCompat a, ShortcutInfoCompat b) {
+            if (a.isDeclaredInManifest() && !b.isDeclaredInManifest()) {
+                return -1;
+            }
+            if (!a.isDeclaredInManifest() && b.isDeclaredInManifest()) {
+                return 1;
+            }
+            return Integer.compare(a.getRank(), b.getRank());
+        }
+    };
+
+    private static final Comparator<ShortcutInfoCompat> sShortcutsComparatorReversed
+            = Collections.reverseOrder(sShortcutsComparator);
+
     public DeepShortcutsContainer(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         mLauncher = (Launcher) context;
@@ -109,7 +131,11 @@
             @Override
             public void run() {
                 final List<ShortcutInfoCompat> shortcuts = mDeepShortcutsManager
-                        .queryForAllAppShortcuts(activity, ids, user);
+                        .queryForShortcutsContainer(activity, ids, user);
+                // We want the lowest rank to be closest to the user's finger.
+                final Comparator<ShortcutInfoCompat> shortcutsComparator = mIsAboveIcon ?
+                        sShortcutsComparatorReversed : sShortcutsComparator;
+                Collections.sort(shortcuts, shortcutsComparator);
                 for (int i = 0; i < shortcuts.size(); i++) {
                     final ShortcutInfoCompat shortcut = shortcuts.get(i);
                     final ShortcutInfo launcherShortcutInfo = ShortcutInfo
diff --git a/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java b/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
index 8dbeaa7..00553df 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
@@ -97,6 +97,14 @@
         return mShortcutInfo.isPinned();
     }
 
+    public boolean isDeclaredInManifest() {
+        return mShortcutInfo.isDeclaredInManifest();
+    }
+
+    public int getRank() {
+        return mShortcutInfo.getRank();
+    }
+
     @Override
     public String toString() {
         return mShortcutInfo.toString();