Loading services/core/java/com/android/server/notification/GroupedNotificationComparator.java→services/core/java/com/android/server/notification/GlobalSortKeyComparator.java +34 −0 Original line number Original line Diff line number Diff line Loading @@ -15,43 +15,20 @@ */ */ package com.android.server.notification; package com.android.server.notification; import android.text.TextUtils; import java.util.Comparator; import android.util.Log; /** /** * Sorts notifications, accounting for groups and sort keys. * Sorts notifications by their global sort key. */ */ public class GroupedNotificationComparator extends NotificationComparator { public class GlobalSortKeyComparator implements Comparator<NotificationRecord> { private static final String TAG = "GroupedNotificationComparator"; @Override @Override public int compare(NotificationRecord left, NotificationRecord right) { public int compare(NotificationRecord left, NotificationRecord right) { // "recently intrusive" is an ad hoc group that temporarily claims noisy notifications if (left.getGlobalSortKey() == null) { if (left.isRecentlyIntrusive() != right.isRecentlyIntrusive()) { throw new IllegalStateException("Missing left global sort key: " + left); return left.isRecentlyIntrusive() ? -1 : 1; } final NotificationRecord leftProxy = left.getRankingProxy(); if (leftProxy == null) { throw new RuntimeException("left proxy cannot be null: " + left.getKey()); } final NotificationRecord rightProxy = right.getRankingProxy(); if (rightProxy == null) { throw new RuntimeException("right proxy cannot be null: " + right.getKey()); } } final String leftSortKey = left.getNotification().getSortKey(); if (right.getGlobalSortKey() == null) { final String rightSortKey = right.getNotification().getSortKey(); throw new IllegalStateException("Missing right global sort key: " + right); if (leftProxy != rightProxy) { // between groups, compare proxies return Integer.compare(leftProxy.getAuthoritativeRank(), rightProxy.getAuthoritativeRank()); } else if (TextUtils.isEmpty(leftSortKey) || TextUtils.isEmpty(rightSortKey)) { // missing sort keys, use prior rank return Integer.compare(left.getAuthoritativeRank(), right.getAuthoritativeRank()); } else { // use sort keys within group return leftSortKey.compareTo(rightSortKey); } } return left.getGlobalSortKey().compareTo(right.getGlobalSortKey()); } } } } services/core/java/com/android/server/notification/NotificationManagerService.java +44 −60 Original line number Original line Diff line number Diff line Loading @@ -1605,6 +1605,8 @@ public class NotificationManagerService extends SystemService { @Override @Override public void run() { public void run() { synchronized (mNotificationList) { // === Scoring === // === Scoring === // 0. Sanitize inputs // 0. Sanitize inputs Loading Loading @@ -1653,7 +1655,6 @@ public class NotificationManagerService extends SystemService { return; return; } } synchronized (mNotificationList) { // Clear out group children of the old notification if the update causes the // Clear out group children of the old notification if the update causes the // group summary to go away. This happens when the old notification was a // group summary to go away. This happens when the old notification was a // summary and the new one isn't, or when the old notification was a summary // summary and the new one isn't, or when the old notification was a summary Loading Loading @@ -1688,24 +1689,7 @@ public class NotificationManagerService extends SystemService { } } applyZenModeLocked(r); applyZenModeLocked(r); try { mRankingHelper.sort(mNotificationList); mRankingHelper.sort(mNotificationList); } catch (RuntimeException ex) { // Don't crash the system server if something bad happened. Log.e(TAG, "Extreme badness during notification sort", ex); Log.e(TAG, "Current notification list: "); for (int ii=0; ii < mNotificationList.size(); ii++) { NotificationRecord nr = mNotificationList.get(ii); Log.e(TAG, String.format( " [%d] %s (group %s, rank %d, sortkey %s, proxy %s)", ii, nr, nr.getGroupKey(), nr.getAuthoritativeRank(), nr.getNotification().getSortKey(), nr.getRankingProxy())); } // STOPSHIP: remove once b/16626175 is found throw ex; } if (notification.icon != 0) { if (notification.icon != 0) { StatusBarNotification oldSbn = (old != null) ? old.sbn : null; StatusBarNotification oldSbn = (old != null) ? old.sbn : null; Loading services/core/java/com/android/server/notification/NotificationRecord.java +7 −9 Original line number Original line Diff line number Diff line Loading @@ -63,9 +63,8 @@ public final class NotificationRecord { public boolean isUpdate; public boolean isUpdate; private int mPackagePriority; private int mPackagePriority; // The record that ranking should use for comparisons outside the group. private NotificationRecord mRankingProxy; private int mAuthoritativeRank; private int mAuthoritativeRank; private String mGlobalSortKey; @VisibleForTesting @VisibleForTesting public NotificationRecord(StatusBarNotification sbn, int score) public NotificationRecord(StatusBarNotification sbn, int score) Loading @@ -81,9 +80,8 @@ public final class NotificationRecord { mRecentlyIntrusive = previous.mRecentlyIntrusive; mRecentlyIntrusive = previous.mRecentlyIntrusive; mPackagePriority = previous.mPackagePriority; mPackagePriority = previous.mPackagePriority; mIntercept = previous.mIntercept; mIntercept = previous.mIntercept; mRankingProxy = previous.mRankingProxy; mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs()); mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs()); // Don't copy mGroupKey, recompute it, in case it has changed // Don't copy mGlobalSortKey, recompute it. } } public Notification getNotification() { return sbn.getNotification(); } public Notification getNotification() { return sbn.getNotification(); } Loading Loading @@ -158,7 +156,7 @@ public final class NotificationRecord { pw.println(prefix + " mRecentlyIntrusive=" + mRecentlyIntrusive); pw.println(prefix + " mRecentlyIntrusive=" + mRecentlyIntrusive); pw.println(prefix + " mPackagePriority=" + mPackagePriority); pw.println(prefix + " mPackagePriority=" + mPackagePriority); pw.println(prefix + " mIntercept=" + mIntercept); pw.println(prefix + " mIntercept=" + mIntercept); pw.println(prefix + " mRankingProxy=" + getRankingProxy().getKey()); pw.println(prefix + " mGlobalSortKey=" + mGlobalSortKey); pw.println(prefix + " mRankingTimeMs=" + mRankingTimeMs); pw.println(prefix + " mRankingTimeMs=" + mRankingTimeMs); } } Loading Loading @@ -265,12 +263,12 @@ public final class NotificationRecord { return sbn.getPostTime(); return sbn.getPostTime(); } } public NotificationRecord getRankingProxy() { public void setGlobalSortKey(String globalSortKey) { return mRankingProxy; mGlobalSortKey = globalSortKey; } } public void setRankingProxy(NotificationRecord proxy) { public String getGlobalSortKey() { mRankingProxy = proxy; return mGlobalSortKey; } } public void setAuthoritativeRank(int authoritativeRank) { public void setAuthoritativeRank(int authoritativeRank) { Loading services/core/java/com/android/server/notification/RankingHelper.java +64 −22 Original line number Original line Diff line number Diff line Loading @@ -17,12 +17,12 @@ package com.android.server.notification; import android.app.Notification; import android.app.Notification; import android.content.Context; import android.content.Context; import android.net.Uri; import android.os.Handler; import android.os.Handler; import android.os.Message; import android.os.Message; import android.os.UserHandle; import android.os.UserHandle; import android.text.TextUtils; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; import android.util.Slog; import android.util.SparseIntArray; import android.util.SparseIntArray; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser; Loading @@ -33,6 +33,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.ArrayList; import java.util.Collections; import java.util.Collections; import java.util.Comparator; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit; public class RankingHelper implements RankingConfig { public class RankingHelper implements RankingConfig { Loading @@ -51,7 +52,7 @@ public class RankingHelper implements RankingConfig { private final NotificationSignalExtractor[] mSignalExtractors; private final NotificationSignalExtractor[] mSignalExtractors; private final NotificationComparator mPreliminaryComparator = new NotificationComparator(); private final NotificationComparator mPreliminaryComparator = new NotificationComparator(); private final NotificationComparator mFinalComparator = new GroupedNotificationComparator(); private final GlobalSortKeyComparator mFinalComparator = new GlobalSortKeyComparator(); // Package name to uid, to priority. Would be better as Table<String, Int, Int> // Package name to uid, to priority. Would be better as Table<String, Int, Int> private final ArrayMap<String, SparseIntArray> mPackagePriorities; private final ArrayMap<String, SparseIntArray> mPackagePriorities; Loading Loading @@ -168,36 +169,77 @@ public class RankingHelper implements RankingConfig { public void sort(ArrayList<NotificationRecord> notificationList) { public void sort(ArrayList<NotificationRecord> notificationList) { final int N = notificationList.size(); final int N = notificationList.size(); // clear group proxies // clear global sort keys for (int i = N - 1; i >= 0; i--) { for (int i = N - 1; i >= 0; i--) { notificationList.get(i).setRankingProxy(null); notificationList.get(i).setGlobalSortKey(null); } } try { // rank each record individually // rank each record individually Collections.sort(notificationList, mPreliminaryComparator); Collections.sort(notificationList, mPreliminaryComparator); } catch (RuntimeException ex) { // Don't crash the system server if something bad happened. Log.e(TAG, "Extreme badness during notification sort", ex); Log.e(TAG, "Current notification list: "); for (int i = 0; i < N; i++) { NotificationRecord nr = notificationList.get(i); Log.e(TAG, String.format( " [%d] %s (group %s, rank %d, sortkey %s)", i, nr, nr.getGroupKey(), nr.getAuthoritativeRank(), nr.getNotification().getSortKey())); } // STOPSHIP: remove once b/16626175 is found throw ex; } // record inidivdual ranking result and nominate proxies for each group synchronized (mProxyByGroupTmp) { // record individual ranking result and nominate proxies for each group for (int i = N - 1; i >= 0; i--) { for (int i = N - 1; i >= 0; i--) { final NotificationRecord record = notificationList.get(i); final NotificationRecord record = notificationList.get(i); record.setAuthoritativeRank(i); record.setAuthoritativeRank(i); final String groupKey = record.getGroupKey(); final String groupKey = record.getGroupKey(); boolean isGroupSummary = record.getNotification().getGroup() != null boolean isGroupSummary = record.getNotification().isGroupSummary(); && (record.getNotification().flags & Notification.FLAG_GROUP_SUMMARY) != 0; if (isGroupSummary || !mProxyByGroupTmp.containsKey(groupKey)) { if (isGroupSummary || mProxyByGroupTmp.get(groupKey) == null) { mProxyByGroupTmp.put(groupKey, record); mProxyByGroupTmp.put(groupKey, record); } } } } // assign nominated proxies to each notification // assign global sort key: // is_recently_intrusive:group_rank:is_group_summary:group_sort_key:rank for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) { final NotificationRecord record = notificationList.get(i); final NotificationRecord record = notificationList.get(i); record.setRankingProxy(mProxyByGroupTmp.get(record.getGroupKey())); NotificationRecord groupProxy = mProxyByGroupTmp.get(record.getGroupKey()); String groupSortKey = record.getNotification().getSortKey(); // We need to make sure the developer provided group sort key (gsk) is handled // correctly: // gsk="" < gsk=non-null-string < gsk=null // // We enforce this by using different prefixes for these three cases. String groupSortKeyPortion; if (groupSortKey == null) { groupSortKeyPortion = "nsk"; } else if (groupSortKey.equals("")) { groupSortKeyPortion = "esk"; } else { groupSortKeyPortion = "gsk=" + groupSortKey; } } // Do a second ranking pass, using group proxies Collections.sort(notificationList, mFinalComparator); boolean isGroupSummary = record.getNotification().isGroupSummary(); record.setGlobalSortKey( String.format("intrsv=%c:grnk=0x%04x:gsmry=%c:%s:rnk=0x%04x", record.isRecentlyIntrusive() ? '0' : '1', groupProxy.getAuthoritativeRank(), isGroupSummary ? '0' : '1', groupSortKeyPortion, record.getAuthoritativeRank())); } mProxyByGroupTmp.clear(); mProxyByGroupTmp.clear(); } } // Do a second ranking pass, using group proxies Collections.sort(notificationList, mFinalComparator); } public int indexOf(ArrayList<NotificationRecord> notificationList, NotificationRecord target) { public int indexOf(ArrayList<NotificationRecord> notificationList, NotificationRecord target) { return Collections.binarySearch(notificationList, target, mFinalComparator); return Collections.binarySearch(notificationList, target, mFinalComparator); } } Loading Loading
services/core/java/com/android/server/notification/GroupedNotificationComparator.java→services/core/java/com/android/server/notification/GlobalSortKeyComparator.java +34 −0 Original line number Original line Diff line number Diff line Loading @@ -15,43 +15,20 @@ */ */ package com.android.server.notification; package com.android.server.notification; import android.text.TextUtils; import java.util.Comparator; import android.util.Log; /** /** * Sorts notifications, accounting for groups and sort keys. * Sorts notifications by their global sort key. */ */ public class GroupedNotificationComparator extends NotificationComparator { public class GlobalSortKeyComparator implements Comparator<NotificationRecord> { private static final String TAG = "GroupedNotificationComparator"; @Override @Override public int compare(NotificationRecord left, NotificationRecord right) { public int compare(NotificationRecord left, NotificationRecord right) { // "recently intrusive" is an ad hoc group that temporarily claims noisy notifications if (left.getGlobalSortKey() == null) { if (left.isRecentlyIntrusive() != right.isRecentlyIntrusive()) { throw new IllegalStateException("Missing left global sort key: " + left); return left.isRecentlyIntrusive() ? -1 : 1; } final NotificationRecord leftProxy = left.getRankingProxy(); if (leftProxy == null) { throw new RuntimeException("left proxy cannot be null: " + left.getKey()); } final NotificationRecord rightProxy = right.getRankingProxy(); if (rightProxy == null) { throw new RuntimeException("right proxy cannot be null: " + right.getKey()); } } final String leftSortKey = left.getNotification().getSortKey(); if (right.getGlobalSortKey() == null) { final String rightSortKey = right.getNotification().getSortKey(); throw new IllegalStateException("Missing right global sort key: " + right); if (leftProxy != rightProxy) { // between groups, compare proxies return Integer.compare(leftProxy.getAuthoritativeRank(), rightProxy.getAuthoritativeRank()); } else if (TextUtils.isEmpty(leftSortKey) || TextUtils.isEmpty(rightSortKey)) { // missing sort keys, use prior rank return Integer.compare(left.getAuthoritativeRank(), right.getAuthoritativeRank()); } else { // use sort keys within group return leftSortKey.compareTo(rightSortKey); } } return left.getGlobalSortKey().compareTo(right.getGlobalSortKey()); } } } }
services/core/java/com/android/server/notification/NotificationManagerService.java +44 −60 Original line number Original line Diff line number Diff line Loading @@ -1605,6 +1605,8 @@ public class NotificationManagerService extends SystemService { @Override @Override public void run() { public void run() { synchronized (mNotificationList) { // === Scoring === // === Scoring === // 0. Sanitize inputs // 0. Sanitize inputs Loading Loading @@ -1653,7 +1655,6 @@ public class NotificationManagerService extends SystemService { return; return; } } synchronized (mNotificationList) { // Clear out group children of the old notification if the update causes the // Clear out group children of the old notification if the update causes the // group summary to go away. This happens when the old notification was a // group summary to go away. This happens when the old notification was a // summary and the new one isn't, or when the old notification was a summary // summary and the new one isn't, or when the old notification was a summary Loading Loading @@ -1688,24 +1689,7 @@ public class NotificationManagerService extends SystemService { } } applyZenModeLocked(r); applyZenModeLocked(r); try { mRankingHelper.sort(mNotificationList); mRankingHelper.sort(mNotificationList); } catch (RuntimeException ex) { // Don't crash the system server if something bad happened. Log.e(TAG, "Extreme badness during notification sort", ex); Log.e(TAG, "Current notification list: "); for (int ii=0; ii < mNotificationList.size(); ii++) { NotificationRecord nr = mNotificationList.get(ii); Log.e(TAG, String.format( " [%d] %s (group %s, rank %d, sortkey %s, proxy %s)", ii, nr, nr.getGroupKey(), nr.getAuthoritativeRank(), nr.getNotification().getSortKey(), nr.getRankingProxy())); } // STOPSHIP: remove once b/16626175 is found throw ex; } if (notification.icon != 0) { if (notification.icon != 0) { StatusBarNotification oldSbn = (old != null) ? old.sbn : null; StatusBarNotification oldSbn = (old != null) ? old.sbn : null; Loading
services/core/java/com/android/server/notification/NotificationRecord.java +7 −9 Original line number Original line Diff line number Diff line Loading @@ -63,9 +63,8 @@ public final class NotificationRecord { public boolean isUpdate; public boolean isUpdate; private int mPackagePriority; private int mPackagePriority; // The record that ranking should use for comparisons outside the group. private NotificationRecord mRankingProxy; private int mAuthoritativeRank; private int mAuthoritativeRank; private String mGlobalSortKey; @VisibleForTesting @VisibleForTesting public NotificationRecord(StatusBarNotification sbn, int score) public NotificationRecord(StatusBarNotification sbn, int score) Loading @@ -81,9 +80,8 @@ public final class NotificationRecord { mRecentlyIntrusive = previous.mRecentlyIntrusive; mRecentlyIntrusive = previous.mRecentlyIntrusive; mPackagePriority = previous.mPackagePriority; mPackagePriority = previous.mPackagePriority; mIntercept = previous.mIntercept; mIntercept = previous.mIntercept; mRankingProxy = previous.mRankingProxy; mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs()); mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs()); // Don't copy mGroupKey, recompute it, in case it has changed // Don't copy mGlobalSortKey, recompute it. } } public Notification getNotification() { return sbn.getNotification(); } public Notification getNotification() { return sbn.getNotification(); } Loading Loading @@ -158,7 +156,7 @@ public final class NotificationRecord { pw.println(prefix + " mRecentlyIntrusive=" + mRecentlyIntrusive); pw.println(prefix + " mRecentlyIntrusive=" + mRecentlyIntrusive); pw.println(prefix + " mPackagePriority=" + mPackagePriority); pw.println(prefix + " mPackagePriority=" + mPackagePriority); pw.println(prefix + " mIntercept=" + mIntercept); pw.println(prefix + " mIntercept=" + mIntercept); pw.println(prefix + " mRankingProxy=" + getRankingProxy().getKey()); pw.println(prefix + " mGlobalSortKey=" + mGlobalSortKey); pw.println(prefix + " mRankingTimeMs=" + mRankingTimeMs); pw.println(prefix + " mRankingTimeMs=" + mRankingTimeMs); } } Loading Loading @@ -265,12 +263,12 @@ public final class NotificationRecord { return sbn.getPostTime(); return sbn.getPostTime(); } } public NotificationRecord getRankingProxy() { public void setGlobalSortKey(String globalSortKey) { return mRankingProxy; mGlobalSortKey = globalSortKey; } } public void setRankingProxy(NotificationRecord proxy) { public String getGlobalSortKey() { mRankingProxy = proxy; return mGlobalSortKey; } } public void setAuthoritativeRank(int authoritativeRank) { public void setAuthoritativeRank(int authoritativeRank) { Loading
services/core/java/com/android/server/notification/RankingHelper.java +64 −22 Original line number Original line Diff line number Diff line Loading @@ -17,12 +17,12 @@ package com.android.server.notification; import android.app.Notification; import android.app.Notification; import android.content.Context; import android.content.Context; import android.net.Uri; import android.os.Handler; import android.os.Handler; import android.os.Message; import android.os.Message; import android.os.UserHandle; import android.os.UserHandle; import android.text.TextUtils; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; import android.util.Slog; import android.util.SparseIntArray; import android.util.SparseIntArray; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser; Loading @@ -33,6 +33,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.ArrayList; import java.util.Collections; import java.util.Collections; import java.util.Comparator; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit; public class RankingHelper implements RankingConfig { public class RankingHelper implements RankingConfig { Loading @@ -51,7 +52,7 @@ public class RankingHelper implements RankingConfig { private final NotificationSignalExtractor[] mSignalExtractors; private final NotificationSignalExtractor[] mSignalExtractors; private final NotificationComparator mPreliminaryComparator = new NotificationComparator(); private final NotificationComparator mPreliminaryComparator = new NotificationComparator(); private final NotificationComparator mFinalComparator = new GroupedNotificationComparator(); private final GlobalSortKeyComparator mFinalComparator = new GlobalSortKeyComparator(); // Package name to uid, to priority. Would be better as Table<String, Int, Int> // Package name to uid, to priority. Would be better as Table<String, Int, Int> private final ArrayMap<String, SparseIntArray> mPackagePriorities; private final ArrayMap<String, SparseIntArray> mPackagePriorities; Loading Loading @@ -168,36 +169,77 @@ public class RankingHelper implements RankingConfig { public void sort(ArrayList<NotificationRecord> notificationList) { public void sort(ArrayList<NotificationRecord> notificationList) { final int N = notificationList.size(); final int N = notificationList.size(); // clear group proxies // clear global sort keys for (int i = N - 1; i >= 0; i--) { for (int i = N - 1; i >= 0; i--) { notificationList.get(i).setRankingProxy(null); notificationList.get(i).setGlobalSortKey(null); } } try { // rank each record individually // rank each record individually Collections.sort(notificationList, mPreliminaryComparator); Collections.sort(notificationList, mPreliminaryComparator); } catch (RuntimeException ex) { // Don't crash the system server if something bad happened. Log.e(TAG, "Extreme badness during notification sort", ex); Log.e(TAG, "Current notification list: "); for (int i = 0; i < N; i++) { NotificationRecord nr = notificationList.get(i); Log.e(TAG, String.format( " [%d] %s (group %s, rank %d, sortkey %s)", i, nr, nr.getGroupKey(), nr.getAuthoritativeRank(), nr.getNotification().getSortKey())); } // STOPSHIP: remove once b/16626175 is found throw ex; } // record inidivdual ranking result and nominate proxies for each group synchronized (mProxyByGroupTmp) { // record individual ranking result and nominate proxies for each group for (int i = N - 1; i >= 0; i--) { for (int i = N - 1; i >= 0; i--) { final NotificationRecord record = notificationList.get(i); final NotificationRecord record = notificationList.get(i); record.setAuthoritativeRank(i); record.setAuthoritativeRank(i); final String groupKey = record.getGroupKey(); final String groupKey = record.getGroupKey(); boolean isGroupSummary = record.getNotification().getGroup() != null boolean isGroupSummary = record.getNotification().isGroupSummary(); && (record.getNotification().flags & Notification.FLAG_GROUP_SUMMARY) != 0; if (isGroupSummary || !mProxyByGroupTmp.containsKey(groupKey)) { if (isGroupSummary || mProxyByGroupTmp.get(groupKey) == null) { mProxyByGroupTmp.put(groupKey, record); mProxyByGroupTmp.put(groupKey, record); } } } } // assign nominated proxies to each notification // assign global sort key: // is_recently_intrusive:group_rank:is_group_summary:group_sort_key:rank for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) { final NotificationRecord record = notificationList.get(i); final NotificationRecord record = notificationList.get(i); record.setRankingProxy(mProxyByGroupTmp.get(record.getGroupKey())); NotificationRecord groupProxy = mProxyByGroupTmp.get(record.getGroupKey()); String groupSortKey = record.getNotification().getSortKey(); // We need to make sure the developer provided group sort key (gsk) is handled // correctly: // gsk="" < gsk=non-null-string < gsk=null // // We enforce this by using different prefixes for these three cases. String groupSortKeyPortion; if (groupSortKey == null) { groupSortKeyPortion = "nsk"; } else if (groupSortKey.equals("")) { groupSortKeyPortion = "esk"; } else { groupSortKeyPortion = "gsk=" + groupSortKey; } } // Do a second ranking pass, using group proxies Collections.sort(notificationList, mFinalComparator); boolean isGroupSummary = record.getNotification().isGroupSummary(); record.setGlobalSortKey( String.format("intrsv=%c:grnk=0x%04x:gsmry=%c:%s:rnk=0x%04x", record.isRecentlyIntrusive() ? '0' : '1', groupProxy.getAuthoritativeRank(), isGroupSummary ? '0' : '1', groupSortKeyPortion, record.getAuthoritativeRank())); } mProxyByGroupTmp.clear(); mProxyByGroupTmp.clear(); } } // Do a second ranking pass, using group proxies Collections.sort(notificationList, mFinalComparator); } public int indexOf(ArrayList<NotificationRecord> notificationList, NotificationRecord target) { public int indexOf(ArrayList<NotificationRecord> notificationList, NotificationRecord target) { return Collections.binarySearch(notificationList, target, mFinalComparator); return Collections.binarySearch(notificationList, target, mFinalComparator); } } Loading