diff --git a/src/com/android/launcher3/AlphabeticalAppsList.java b/src/com/android/launcher3/AlphabeticalAppsList.java index c1d2738da2..9ab9d12956 100644 --- a/src/com/android/launcher3/AlphabeticalAppsList.java +++ b/src/com/android/launcher3/AlphabeticalAppsList.java @@ -4,13 +4,75 @@ import android.content.ComponentName; import android.content.Context; import android.support.v7.widget.RecyclerView; import com.android.launcher3.compat.AlphabeticIndexCompat; +import com.android.launcher3.compat.UserHandleCompat; +import com.android.launcher3.compat.UserManagerCompat; +import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.List; +/** + * A private class to manage access to an app name comparator. + */ +class AppNameComparator { + private UserManagerCompat mUserManager; + private Comparator mAppNameComparator; + private HashMap mUserSerialCache = new HashMap<>(); + + public AppNameComparator(Context context) { + final Collator collator = Collator.getInstance(); + mUserManager = UserManagerCompat.getInstance(context); + mAppNameComparator = new Comparator() { + public final int compare(AppInfo a, AppInfo b) { + // Order by the title + int result = collator.compare(a.title.toString().trim(), + b.title.toString().trim()); + 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; + } + }; + } + + /** + * Returns a locale-aware comparator that will alphabetically order a list of applications. + */ + public Comparator getComparator() { + // Clear the user serial cache so that we get serials as needed in the comparator + mUserSerialCache.clear(); + return mAppNameComparator; + } + + /** + * 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. */ @@ -41,9 +103,11 @@ public class AlphabeticalAppsList { private RecyclerView.Adapter mAdapter; private Filter mFilter; private AlphabeticIndexCompat mIndexer; + private AppNameComparator mAppNameComparator; public AlphabeticalAppsList(Context context) { mIndexer = new AlphabeticIndexCompat(context); + mAppNameComparator = new AppNameComparator(context); } /** @@ -81,13 +145,6 @@ public class AlphabeticalAppsList { return mIndexer.computeSectionName(info.title.toString().trim()); } - /** - * Returns the indexer for this locale. - */ - public AlphabeticIndexCompat getIndexer() { - return mIndexer; - } - /** * Returns whether there are no filtered results. */ @@ -108,7 +165,7 @@ public class AlphabeticalAppsList { * Sets the current set of apps. */ public void setApps(List apps) { - Collections.sort(apps, LauncherModel.getAppNameComparator()); + Collections.sort(apps, mAppNameComparator.getComparator()); mApps.clear(); mApps.addAll(apps); onAppsUpdated(); @@ -183,8 +240,7 @@ public class AlphabeticalAppsList { * Implementation to actually add an app to the alphabetic list */ private void addApp(AppInfo info) { - Comparator appNameComparator = LauncherModel.getAppNameComparator(); - int index = Collections.binarySearch(mApps, info, appNameComparator); + int index = Collections.binarySearch(mApps, info, mAppNameComparator.getComparator()); if (index < 0) { mApps.add(-(index + 1), info); onAppsUpdated(); diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index c6ed0da82e..1f36331ec3 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -3622,41 +3622,6 @@ public class LauncherModel extends BroadcastReceiver return folderInfo; } - public static final Comparator getAppNameComparator() { - final Collator collator = Collator.getInstance(); - return new Comparator() { - public final int compare(AppInfo a, AppInfo b) { - if (a.user.equals(b.user)) { - int result = collator.compare(a.title.toString().trim(), - b.title.toString().trim()); - if (result == 0) { - result = a.componentName.compareTo(b.componentName); - } - return result; - } else { - // TODO Need to figure out rules for sorting - // profiles, this puts work second. - return a.user.toString().compareTo(b.user.toString()); - } - } - }; - } - public static final Comparator APP_INSTALL_TIME_COMPARATOR - = new Comparator() { - public final int compare(AppInfo a, AppInfo b) { - if (a.firstInstallTime < b.firstInstallTime) return 1; - if (a.firstInstallTime > b.firstInstallTime) return -1; - return 0; - } - }; - static ComponentName getComponentNameFromResolveInfo(ResolveInfo info) { - if (info.activityInfo != null) { - return new ComponentName(info.activityInfo.packageName, info.activityInfo.name); - } else { - return new ComponentName(info.serviceInfo.packageName, info.serviceInfo.name); - } - } - public static class WidgetAndShortcutNameComparator implements Comparator { private final AppWidgetManagerCompat mManager; private final PackageManager mPackageManager;