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