diff options
author | Hyunyoung Song <hyunyoungs@google.com> | 2015-05-19 13:39:44 -0700 |
---|---|---|
committer | Hyunyoung Song <hyunyoungs@google.com> | 2015-05-19 13:39:44 -0700 |
commit | 0b493c86c5d0803f11095b71396ffac0097d26ef (patch) | |
tree | 208433d6fb00d8178610964bfe3a4dc91f2d9881 | |
parent | 6cfad01b1cace11a3fe523cebe5dde987f148585 (diff) | |
download | android_packages_apps_Trebuchet-0b493c86c5d0803f11095b71396ffac0097d26ef.tar.gz android_packages_apps_Trebuchet-0b493c86c5d0803f11095b71396ffac0097d26ef.tar.bz2 android_packages_apps_Trebuchet-0b493c86c5d0803f11095b71396ffac0097d26ef.zip |
Unify sorting between all apps and widget tray
- selected locale names are shown before latin
- case independent sorting
- main app > enterprise app
Future possible refactoring:
- Move all the *ItemInfo data structures to model package
- Rename the comparator based on NOT what data structure it supports
but what functionality it supports (locale? case independent?
main app > enterprise app?)
b/21271658
b/20339403
Change-Id: I8a776467392e21d5014e85cd3f51931a3ef89724
5 files changed, 175 insertions, 136 deletions
diff --git a/src/com/android/launcher3/AlphabeticalAppsList.java b/src/com/android/launcher3/AlphabeticalAppsList.java index eff7b0625..82aaeb99a 100644 --- a/src/com/android/launcher3/AlphabeticalAppsList.java +++ b/src/com/android/launcher3/AlphabeticalAppsList.java @@ -7,6 +7,7 @@ import android.util.Log; import com.android.launcher3.compat.AlphabeticIndexCompat; import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.compat.UserManagerCompat; +import com.android.launcher3.model.AppNameComparator; import java.text.Collator; import java.util.ArrayList; @@ -18,96 +19,6 @@ import java.util.Locale; import java.util.Map; import java.util.TreeMap; - -/** - * A private class to manage access to an app name comparator. - */ -class AppNameComparator { - private final UserManagerCompat mUserManager; - private final Collator mCollator; - private final Comparator<AppInfo> mAppInfoComparator; - private final Comparator<String> mSectionNameComparator; - private HashMap<UserHandleCompat, Long> mUserSerialCache = new HashMap<>(); - - public AppNameComparator(Context context) { - mCollator = Collator.getInstance(); - mUserManager = UserManagerCompat.getInstance(context); - mAppInfoComparator = new Comparator<AppInfo>() { - public final int compare(AppInfo a, AppInfo b) { - // Order by the title in the current locale - int result = compareTitles(a.title.toString(), b.title.toString()); - if (result == 0) { - // If two apps have the same title, then order by the component name - result = a.componentName.compareTo(b.componentName); - if (result == 0) { - // If the two apps are the same component, then prioritize by the order that - // the app user was created (prioritizing the main user's apps) - if (UserHandleCompat.myUserHandle().equals(a.user)) { - return -1; - } else { - Long aUserSerial = getAndCacheUserSerial(a.user); - Long bUserSerial = getAndCacheUserSerial(b.user); - return aUserSerial.compareTo(bUserSerial); - } - } - } - return result; - } - }; - mSectionNameComparator = new Comparator<String>() { - @Override - public int compare(String o1, String o2) { - return compareTitles(o1, o2); - } - }; - } - - /** - * Returns a locale-aware comparator that will alphabetically order a list of applications. - */ - public Comparator<AppInfo> getAppInfoComparator() { - // Clear the user serial cache so that we get serials as needed in the comparator - mUserSerialCache.clear(); - return mAppInfoComparator; - } - - /** - * Returns a locale-aware comparator that will alphabetically order a list of section names. - */ - public Comparator<String> getSectionNameComparator() { - return mSectionNameComparator; - } - - /** - * Compares two titles with the same return value semantics as Comparator. - */ - private int compareTitles(String titleA, String titleB) { - // Ensure that we de-prioritize any titles that don't start with a linguistic letter or digit - boolean aStartsWithLetter = Character.isLetterOrDigit(titleA.codePointAt(0)); - boolean bStartsWithLetter = Character.isLetterOrDigit(titleB.codePointAt(0)); - if (aStartsWithLetter && !bStartsWithLetter) { - return -1; - } else if (!aStartsWithLetter && bStartsWithLetter) { - return 1; - } - - // Order by the title in the current locale - return mCollator.compare(titleA, titleB); - } - - /** - * Returns the user serial for this user, using a cached serial if possible. - */ - private Long getAndCacheUserSerial(UserHandleCompat user) { - Long userSerial = mUserSerialCache.get(user); - if (userSerial == null) { - userSerial = mUserManager.getSerialNumberForUser(user); - mUserSerialCache.put(user, userSerial); - } - return userSerial; - } -} - /** * The alphabetically sorted list of applications. */ diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 0b3049c2e..58e899aec 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -66,7 +66,6 @@ import com.android.launcher3.util.Thunk; import java.lang.ref.WeakReference; import java.net.URISyntaxException; import java.security.InvalidParameterException; -import java.text.Collator; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -3665,39 +3664,6 @@ public class LauncherModel extends BroadcastReceiver return folderInfo; } - public static class WidgetAndShortcutNameComparator implements Comparator<Object> { - private final AppWidgetManagerCompat mManager; - private final PackageManager mPackageManager; - private final HashMap<Object, String> mLabelCache; - private final Collator mCollator; - - public WidgetAndShortcutNameComparator(Context context) { - mManager = AppWidgetManagerCompat.getInstance(context); - mPackageManager = context.getPackageManager(); - mLabelCache = new HashMap<Object, String>(); - mCollator = Collator.getInstance(); - } - public final int compare(Object a, Object b) { - String labelA, labelB; - if (mLabelCache.containsKey(a)) { - labelA = mLabelCache.get(a); - } else { - labelA = (a instanceof LauncherAppWidgetProviderInfo) - ? Utilities.trim(mManager.loadLabel((LauncherAppWidgetProviderInfo) a)) - : Utilities.trim(((ResolveInfo) a).loadLabel(mPackageManager)); - mLabelCache.put(a, labelA); - } - if (mLabelCache.containsKey(b)) { - labelB = mLabelCache.get(b); - } else { - labelB = (b instanceof LauncherAppWidgetProviderInfo) - ? Utilities.trim(mManager.loadLabel((LauncherAppWidgetProviderInfo) b)) - : Utilities.trim(((ResolveInfo) b).loadLabel(mPackageManager)); - mLabelCache.put(b, labelB); - } - return mCollator.compare(labelA, labelB); - } - }; static boolean isValidProvider(AppWidgetProviderInfo provider) { return (provider != null) && (provider.provider != null) diff --git a/src/com/android/launcher3/model/AppNameComparator.java b/src/com/android/launcher3/model/AppNameComparator.java new file mode 100644 index 000000000..706f7515d --- /dev/null +++ b/src/com/android/launcher3/model/AppNameComparator.java @@ -0,0 +1,105 @@ +package com.android.launcher3.model; + +import android.content.Context; + +import com.android.launcher3.AppInfo; +import com.android.launcher3.ItemInfo; +import com.android.launcher3.compat.UserHandleCompat; +import com.android.launcher3.compat.UserManagerCompat; +import java.text.Collator; +import java.util.Comparator; +import java.util.HashMap; + +/** + * Class to manage access to an app name comparator. + * <p> + * Used to sort application name in all apps view and widget tray view. + */ +public class AppNameComparator { + private final UserManagerCompat mUserManager; + private final Collator mCollator; + private final Comparator<ItemInfo> mAppInfoComparator; + private final Comparator<String> mSectionNameComparator; + private HashMap<UserHandleCompat, Long> mUserSerialCache = new HashMap<>(); + + public AppNameComparator(Context context) { + mCollator = Collator.getInstance(); + mUserManager = UserManagerCompat.getInstance(context); + mAppInfoComparator = new Comparator<ItemInfo>() { + + public final int compare(ItemInfo a, ItemInfo b) { + // Order by the title in the current locale + int result = compareTitles(a.title.toString(), b.title.toString()); + if (result == 0 && a instanceof AppInfo && b instanceof AppInfo) { + AppInfo aAppInfo = (AppInfo) a; + AppInfo bAppInfo = (AppInfo) b; + // If two apps have the same title, then order by the component name + result = aAppInfo.componentName.compareTo(bAppInfo.componentName); + if (result == 0) { + // If the two apps are the same component, then prioritize by the order that + // the app user was created (prioritizing the main user's apps) + if (UserHandleCompat.myUserHandle().equals(a.user)) { + return -1; + } else { + Long aUserSerial = getAndCacheUserSerial(a.user); + Long bUserSerial = getAndCacheUserSerial(b.user); + return aUserSerial.compareTo(bUserSerial); + } + } + } + return result; + } + }; + mSectionNameComparator = new Comparator<String>() { + @Override + public int compare(String o1, String o2) { + return compareTitles(o1, o2); + } + }; + } + + /** + * Returns a locale-aware comparator that will alphabetically order a list of applications. + */ + public Comparator<ItemInfo> getAppInfoComparator() { + // Clear the user serial cache so that we get serials as needed in the comparator + mUserSerialCache.clear(); + return mAppInfoComparator; + } + + /** + * Returns a locale-aware comparator that will alphabetically order a list of section names. + */ + public Comparator<String> getSectionNameComparator() { + return mSectionNameComparator; + } + + /** + * Compares two titles with the same return value semantics as Comparator. + */ + private int compareTitles(String titleA, String titleB) { + // Ensure that we de-prioritize any titles that don't start with a linguistic letter or digit + boolean aStartsWithLetter = Character.isLetterOrDigit(titleA.codePointAt(0)); + boolean bStartsWithLetter = Character.isLetterOrDigit(titleB.codePointAt(0)); + if (aStartsWithLetter && !bStartsWithLetter) { + return -1; + } else if (!aStartsWithLetter && bStartsWithLetter) { + return 1; + } + + // Order by the title in the current locale + return mCollator.compare(titleA, titleB); + } + + /** + * Returns the user serial for this user, using a cached serial if possible. + */ + private Long getAndCacheUserSerial(UserHandleCompat user) { + Long userSerial = mUserSerialCache.get(user); + if (userSerial == null) { + userSerial = mUserManager.getSerialNumberForUser(user); + mUserSerialCache.put(user, userSerial); + } + return userSerial; + } +} diff --git a/src/com/android/launcher3/model/WidgetsAndShortcutNameComparator.java b/src/com/android/launcher3/model/WidgetsAndShortcutNameComparator.java new file mode 100644 index 000000000..7c4e80651 --- /dev/null +++ b/src/com/android/launcher3/model/WidgetsAndShortcutNameComparator.java @@ -0,0 +1,63 @@ +package com.android.launcher3.model; + +import android.appwidget.AppWidgetProviderInfo; +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; + +import com.android.launcher3.LauncherAppWidgetProviderInfo; +import com.android.launcher3.Utilities; +import com.android.launcher3.compat.AppWidgetManagerCompat; + +import java.text.Collator; +import java.util.Comparator; +import java.util.HashMap; + +public class WidgetsAndShortcutNameComparator implements Comparator<Object> { + private final AppWidgetManagerCompat mManager; + private final PackageManager mPackageManager; + private final HashMap<Object, String> mLabelCache; + private final Collator mCollator; + + public WidgetsAndShortcutNameComparator(Context context) { + mManager = AppWidgetManagerCompat.getInstance(context); + mPackageManager = context.getPackageManager(); + mLabelCache = new HashMap<Object, String>(); + mCollator = Collator.getInstance(); + } + + @Override + public final int compare(Object a, Object b) { + String labelA, labelB; + if (mLabelCache.containsKey(a)) { + labelA = mLabelCache.get(a); + } else { + labelA = (a instanceof LauncherAppWidgetProviderInfo) + ? Utilities.trim(mManager.loadLabel((LauncherAppWidgetProviderInfo) a)) + : Utilities.trim(((ResolveInfo) a).loadLabel(mPackageManager)); + mLabelCache.put(a, labelA); + } + if (mLabelCache.containsKey(b)) { + labelB = mLabelCache.get(b); + } else { + labelB = (b instanceof LauncherAppWidgetProviderInfo) + ? Utilities.trim(mManager.loadLabel((LauncherAppWidgetProviderInfo) b)) + : Utilities.trim(((ResolveInfo) b).loadLabel(mPackageManager)); + mLabelCache.put(b, labelB); + } + int result = mCollator.compare(labelA, labelB); + if (result == 0 && a instanceof AppWidgetProviderInfo && + b instanceof AppWidgetProviderInfo) { + AppWidgetProviderInfo aInfo = (AppWidgetProviderInfo) a; + AppWidgetProviderInfo bInfo = (AppWidgetProviderInfo) b; + + // prioritize main user's widgets against work profile widgets. + if (aInfo.getProfile().equals(android.os.Process.myUserHandle())) { + return -1; + } else if (bInfo.getProfile().equals(android.os.Process.myUserHandle())) { + return 1; + } + } + return result; + } +}; diff --git a/src/com/android/launcher3/widget/WidgetsModel.java b/src/com/android/launcher3/widget/WidgetsModel.java index 71a7b9446..5a920e8d4 100644 --- a/src/com/android/launcher3/widget/WidgetsModel.java +++ b/src/com/android/launcher3/widget/WidgetsModel.java @@ -10,8 +10,9 @@ import android.util.Log; import com.android.launcher3.IconCache; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetProviderInfo; -import com.android.launcher3.LauncherModel.WidgetAndShortcutNameComparator; import com.android.launcher3.compat.UserHandleCompat; +import com.android.launcher3.model.AppNameComparator; +import com.android.launcher3.model.WidgetsAndShortcutNameComparator; import java.util.ArrayList; import java.util.Collections; @@ -40,12 +41,14 @@ public class WidgetsModel { private RecyclerView.Adapter mAdapter; private Comparator mWidgetAndShortcutNameComparator; + private Comparator mAppNameComparator; private IconCache mIconCache; public WidgetsModel(Context context, RecyclerView.Adapter adapter) { mAdapter = adapter; - mWidgetAndShortcutNameComparator = new WidgetAndShortcutNameComparator(context); + mWidgetAndShortcutNameComparator = new WidgetsAndShortcutNameComparator(context); + mAppNameComparator = (new AppNameComparator(context)).getAppInfoComparator(); mIconCache = LauncherAppState.getInstance().getIconCache(); } @@ -108,7 +111,7 @@ public class WidgetsModel { } // sort. - sortPackageItemInfos(); + Collections.sort(mPackageItemInfos, mAppNameComparator); for (PackageItemInfo p: mPackageItemInfos) { Collections.sort(mWidgetsList.get(p), mWidgetAndShortcutNameComparator); } @@ -116,13 +119,4 @@ public class WidgetsModel { // notify. mAdapter.notifyDataSetChanged(); } - - private void sortPackageItemInfos() { - Collections.sort(mPackageItemInfos, new Comparator<PackageItemInfo>() { - @Override - public int compare(PackageItemInfo lhs, PackageItemInfo rhs) { - return lhs.title.toString().compareTo(rhs.title.toString()); - } - }); - } }
\ No newline at end of file |