• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.launcher3.shortcuts;
18 
19 import android.support.annotation.VisibleForTesting;
20 
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Comparator;
24 import java.util.List;
25 
26 /**
27  * Sorts and filters shortcuts.
28  */
29 public class ShortcutFilter {
30 
31     public static final int MAX_SHORTCUTS = 4;
32     @VisibleForTesting static final int NUM_DYNAMIC = 2;
33 
34     /**
35      * Sorts shortcuts in rank order, with manifest shortcuts coming before dynamic shortcuts.
36      */
37     private static final Comparator<ShortcutInfoCompat> RANK_COMPARATOR
38             = new Comparator<ShortcutInfoCompat>() {
39         @Override
40         public int compare(ShortcutInfoCompat a, ShortcutInfoCompat b) {
41             if (a.isDeclaredInManifest() && !b.isDeclaredInManifest()) {
42                 return -1;
43             }
44             if (!a.isDeclaredInManifest() && b.isDeclaredInManifest()) {
45                 return 1;
46             }
47             return Integer.compare(a.getRank(), b.getRank());
48         }
49     };
50 
51     /**
52      * Filters the shortcuts so that only MAX_SHORTCUTS or fewer shortcuts are retained.
53      * We want the filter to include both static and dynamic shortcuts, so we always
54      * include NUM_DYNAMIC dynamic shortcuts, if at least that many are present.
55      *
56      * @return a subset of shortcuts, in sorted order, with size <= MAX_SHORTCUTS.
57      */
sortAndFilterShortcuts( List<ShortcutInfoCompat> shortcuts)58     public static List<ShortcutInfoCompat> sortAndFilterShortcuts(
59             List<ShortcutInfoCompat> shortcuts) {
60         Collections.sort(shortcuts, RANK_COMPARATOR);
61         if (shortcuts.size() <= MAX_SHORTCUTS) {
62             return shortcuts;
63         }
64 
65         // The list of shortcuts is now sorted with static shortcuts followed by dynamic
66         // shortcuts. We want to preserve this order, but only keep MAX_SHORTCUTS.
67         List<ShortcutInfoCompat> filteredShortcuts = new ArrayList<>(MAX_SHORTCUTS);
68         int numDynamic = 0;
69         int size = shortcuts.size();
70         for (int i = 0; i < size; i++) {
71             ShortcutInfoCompat shortcut = shortcuts.get(i);
72             int filteredSize = filteredShortcuts.size();
73             if (filteredSize < MAX_SHORTCUTS) {
74                 // Always add the first MAX_SHORTCUTS to the filtered list.
75                 filteredShortcuts.add(shortcut);
76                 if (shortcut.isDynamic()) {
77                     numDynamic++;
78                 }
79                 continue;
80             }
81             // At this point, we have MAX_SHORTCUTS already, but they may all be static.
82             // If there are dynamic shortcuts, remove static shortcuts to add them.
83             if (shortcut.isDynamic() && numDynamic < NUM_DYNAMIC) {
84                 numDynamic++;
85                 int lastStaticIndex = filteredSize - numDynamic;
86                 filteredShortcuts.remove(lastStaticIndex);
87                 filteredShortcuts.add(shortcut);
88             }
89         }
90         return filteredShortcuts;
91     }
92 }
93