Merge "Update sorting for rule types and instances."
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
index cd26172..3a30369 100644
--- a/src/com/android/settings/notification/ZenModeAutomationSettings.java
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -61,11 +61,11 @@
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         addPreferencesFromResource(R.xml.zen_mode_automation_settings);
+        mPm = mContext.getPackageManager();
         mServiceListing = new ServiceListing(mContext, CONFIG);
         mServiceListing.addCallback(mServiceListingCallback);
         mServiceListing.reload();
         mServiceListing.setListening(true);
-        mPm = mContext.getPackageManager();
     }
 
     @Override
@@ -223,7 +223,7 @@
         @Override
         public void onServicesReloaded(List<ServiceInfo> services) {
             for (ServiceInfo service : services) {
-                final ZenRuleInfo ri = getRuleInfo(service);
+                final ZenRuleInfo ri = getRuleInfo(mPm, service);
                 if (ri != null && ri.serviceComponent != null
                         && Objects.equals(ri.settingsAction,
                         Settings.ACTION_ZEN_MODE_EXTERNAL_RULE_SETTINGS)) {
@@ -236,7 +236,7 @@
         }
     };
 
-    public static ZenRuleInfo getRuleInfo(ServiceInfo si) {
+    public static ZenRuleInfo getRuleInfo(PackageManager pm, ServiceInfo si) {
         if (si == null || si.metaData == null) return null;
         final String ruleType = si.metaData.getString(ConditionProviderService.META_DATA_RULE_TYPE);
         final ComponentName configurationActivity = getSettingsActivity(si);
@@ -246,6 +246,7 @@
             ri.title = ruleType;
             ri.packageName = si.packageName;
             ri.configurationActivity = getSettingsActivity(si);
+            ri.packageLabel = si.applicationInfo.loadLabel(pm);
 
             return ri;
         }
@@ -262,12 +263,16 @@
         return null;
     }
 
-    // TODO: Sort by creation date, once that data is available.
     private static final Comparator<AutomaticZenRule> RULE_COMPARATOR =
             new Comparator<AutomaticZenRule>() {
         @Override
         public int compare(AutomaticZenRule lhs, AutomaticZenRule rhs) {
-            return key(lhs).compareTo(key(rhs));
+            int byDate = Long.compare(lhs.getCreationTime(), rhs.getCreationTime());
+            if (byDate != 0) {
+                return byDate;
+            } else {
+                return key(lhs).compareTo(key(rhs));
+            }
         }
 
         private String key(AutomaticZenRule rule) {
diff --git a/src/com/android/settings/notification/ZenRuleInfo.java b/src/com/android/settings/notification/ZenRuleInfo.java
index 46ed497..30fa06d 100644
--- a/src/com/android/settings/notification/ZenRuleInfo.java
+++ b/src/com/android/settings/notification/ZenRuleInfo.java
@@ -11,4 +11,5 @@
     public Uri defaultConditionId;
     public ComponentName serviceComponent;
     public boolean isSystem;
+    public CharSequence packageLabel;
 }
diff --git a/src/com/android/settings/notification/ZenRuleSelectionDialog.java b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
index 26fa40c..ee1f73f 100644
--- a/src/com/android/settings/notification/ZenRuleSelectionDialog.java
+++ b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
@@ -17,6 +17,7 @@
 package com.android.settings.notification;
 
 import android.app.AlertDialog;
+import android.app.AutomaticZenRule;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnDismissListener;
@@ -36,7 +37,10 @@
 import com.android.settings.R;
 
 import java.lang.ref.WeakReference;
+import java.text.Collator;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
 import java.util.List;
 
 public abstract class ZenRuleSelectionDialog {
@@ -48,7 +52,6 @@
     private final AlertDialog mDialog;
     private final LinearLayout mRuleContainer;
     private final ServiceListing mServiceListing;
-    private final List<ZenRuleInfo> mExternalRuleTypes = new ArrayList<ZenRuleInfo>();
 
     public ZenRuleSelectionDialog(Context context, ServiceListing serviceListing) {
         mContext = context;
@@ -59,9 +62,8 @@
 
         mRuleContainer = (LinearLayout) v.findViewById(R.id.rule_container);
         if (mServiceListing != null) {
-            bindType(defaultNewSchedule());
             bindType(defaultNewEvent());
-            bindExternalRules();
+            bindType(defaultNewSchedule());
             mServiceListing.addCallback(mServiceListingCallback);
             mServiceListing.reload();
         }
@@ -147,8 +149,9 @@
         return rt;
     }
 
-    private void bindExternalRules() {
-        for (ZenRuleInfo ri : mExternalRuleTypes) {
+    private void bindExternalRules(ZenRuleInfo[] externalRuleTypes) {
+        Arrays.sort(externalRuleTypes, RULE_TYPE_COMPARATOR);
+        for (ZenRuleInfo ri : externalRuleTypes) {
             bindType(ri);
         }
     }
@@ -157,16 +160,32 @@
         @Override
         public void onServicesReloaded(List<ServiceInfo> services) {
             if (DEBUG) Log.d(TAG, "Services reloaded: count=" + services.size());
-            for (ServiceInfo si : services) {
-                final ZenRuleInfo ri = ZenModeAutomationSettings.getRuleInfo(si);
+            ZenRuleInfo[] externalRuleTypes = new ZenRuleInfo[services.size()];
+            for (int i = 0; i < services.size(); i++) {
+                final ZenRuleInfo ri = ZenModeAutomationSettings.getRuleInfo(mPm, services.get(i));
                 if (ri != null && ri.configurationActivity != null) {
-                    mExternalRuleTypes.add(ri);
+                    externalRuleTypes[i] = ri;
                 }
             }
-            bindExternalRules();
+            bindExternalRules(externalRuleTypes);
         }
     };
 
+    private static final Comparator<ZenRuleInfo> RULE_TYPE_COMPARATOR =
+            new Comparator<ZenRuleInfo>() {
+                private final Collator mCollator = Collator.getInstance();
+
+                @Override
+                public int compare(ZenRuleInfo lhs, ZenRuleInfo rhs) {
+                    int byAppName = mCollator.compare(lhs.packageLabel, rhs.packageLabel);
+                    if (byAppName != 0) {
+                        return byAppName;
+                    } else {
+                        return mCollator.compare(lhs.title, rhs.title);
+                    }
+                }
+            };
+
     private class LoadIconTask extends AsyncTask<ApplicationInfo, Void, Drawable> {
         private final WeakReference<ImageView> viewReference;