1 package com.android.launcher3.model; 2 3 import android.content.ComponentName; 4 import android.content.Context; 5 import android.content.pm.PackageManager; 6 import android.content.pm.ResolveInfo; 7 import com.android.launcher3.LauncherAppWidgetProviderInfo; 8 import com.android.launcher3.Utilities; 9 import com.android.launcher3.compat.AppWidgetManagerCompat; 10 import com.android.launcher3.compat.UserHandleCompat; 11 import com.android.launcher3.util.ComponentKey; 12 13 import java.text.Collator; 14 import java.util.Comparator; 15 import java.util.HashMap; 16 17 public class WidgetsAndShortcutNameComparator implements Comparator<Object> { 18 private final AppWidgetManagerCompat mManager; 19 private final PackageManager mPackageManager; 20 private final HashMap<ComponentKey, String> mLabelCache; 21 private final Collator mCollator; 22 private final UserHandleCompat mMainHandle; 23 WidgetsAndShortcutNameComparator(Context context)24 public WidgetsAndShortcutNameComparator(Context context) { 25 mManager = AppWidgetManagerCompat.getInstance(context); 26 mPackageManager = context.getPackageManager(); 27 mLabelCache = new HashMap<>(); 28 mCollator = Collator.getInstance(); 29 mMainHandle = UserHandleCompat.myUserHandle(); 30 } 31 32 /** 33 * Resets any stored state. 34 */ reset()35 public void reset() { 36 mLabelCache.clear(); 37 } 38 39 @Override compare(Object objA, Object objB)40 public final int compare(Object objA, Object objB) { 41 ComponentKey keyA = getComponentKey(objA); 42 ComponentKey keyB = getComponentKey(objB); 43 44 // Independent of how the labels compare, if only one of the two widget info belongs to 45 // work profile, put that one in the back. 46 boolean aWorkProfile = !mMainHandle.equals(keyA.user); 47 boolean bWorkProfile = !mMainHandle.equals(keyB.user); 48 if (aWorkProfile && !bWorkProfile) { 49 return 1; 50 } 51 if (!aWorkProfile && bWorkProfile) { 52 return -1; 53 } 54 55 // Get the labels for comparison 56 String labelA = mLabelCache.get(keyA); 57 String labelB = mLabelCache.get(keyB); 58 if (labelA == null) { 59 labelA = getLabel(objA); 60 mLabelCache.put(keyA, labelA); 61 } 62 if (labelB == null) { 63 labelB = getLabel(objB); 64 mLabelCache.put(keyB, labelB); 65 } 66 return mCollator.compare(labelA, labelB); 67 } 68 69 /** 70 * @return a component key for the given widget or shortcut info. 71 */ getComponentKey(Object o)72 private ComponentKey getComponentKey(Object o) { 73 if (o instanceof LauncherAppWidgetProviderInfo) { 74 LauncherAppWidgetProviderInfo widgetInfo = (LauncherAppWidgetProviderInfo) o; 75 return new ComponentKey(widgetInfo.provider, mManager.getUser(widgetInfo)); 76 } else { 77 ResolveInfo shortcutInfo = (ResolveInfo) o; 78 ComponentName cn = new ComponentName(shortcutInfo.activityInfo.packageName, 79 shortcutInfo.activityInfo.name); 80 // Currently, there are no work profile shortcuts 81 return new ComponentKey(cn, UserHandleCompat.myUserHandle()); 82 } 83 } 84 85 /** 86 * @return the label for the given widget or shortcut info. This may be an expensive call. 87 */ getLabel(Object o)88 private String getLabel(Object o) { 89 if (o instanceof LauncherAppWidgetProviderInfo) { 90 LauncherAppWidgetProviderInfo widgetInfo = (LauncherAppWidgetProviderInfo) o; 91 return Utilities.trim(mManager.loadLabel(widgetInfo)); 92 } else { 93 ResolveInfo shortcutInfo = (ResolveInfo) o; 94 return Utilities.trim(shortcutInfo.loadLabel(mPackageManager)); 95 } 96 } 97 }; 98