Loading packages/SystemUI/res/values/config.xml +3 −0 Original line number Diff line number Diff line Loading @@ -480,4 +480,7 @@ <!-- Preferred refresh rate at keyguard, if supported by the display --> <integer name="config_keyguardRefreshRate">-1</integer> <!-- Whether or not to add a "people" notifications section --> <bool name="config_usePeopleFiltering">false</bool> </resources> packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java +2 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.statusbar; import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED; import static com.android.systemui.DejankUtils.whitelistIpcs; import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT; import android.app.ActivityManager; import android.app.KeyguardManager; Loading Loading @@ -316,7 +317,7 @@ public class NotificationLockscreenUserManagerImpl implements boolean exceedsPriorityThreshold; if (NotificationUtils.useNewInterruptionModel(mContext) && hideSilentNotificationsOnLockscreen()) { exceedsPriorityThreshold = entry.isTopBucket(); exceedsPriorityThreshold = entry.getBucket() != BUCKET_SILENT; } else { exceedsPriorityThreshold = !getEntryManager().getNotificationData().isAmbient(entry.key); Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -124,7 +124,7 @@ public class NotificationEntryManager implements @Inject public NotificationEntryManager(Context context) { mNotificationData = new NotificationData(); mNotificationData = new NotificationData(context); } /** Adds a {@link NotificationEntryListener}. */ Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java +14 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ public class NotificationUtils { private static final int[] sLocationOffset = new int[2]; @Nullable private static Boolean sUseNewInterruptionModel = null; @Nullable private static Boolean sUsePeopleFiltering = null; public static boolean isGrayscale(ImageView v, ContrastColorUtil colorUtil) { Object isGrayscale = v.getTag(R.id.icon_is_grayscale); Loading Loading @@ -87,4 +88,17 @@ public class NotificationUtils { } return sUseNewInterruptionModel; } /** * Caches and returns the value of the people filtering setting. Cannot change except through * process restarts. */ public static boolean usePeopleFiltering(Context context) { if (sUsePeopleFiltering == null) { sUsePeopleFiltering = context.getResources().getBoolean( R.bool.config_usePeopleFiltering); } return sUsePeopleFiltering; } } packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java +82 −52 Original line number Diff line number Diff line Loading @@ -16,10 +16,15 @@ package com.android.systemui.statusbar.notification.collection; import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING; import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE; import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.Person; import android.content.Context; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.SnoozeCriterion; Loading @@ -30,6 +35,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dependency; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.notification.NotificationFilter; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.policy.HeadsUpManager; Loading @@ -44,6 +50,7 @@ import java.util.Objects; * The list of currently displaying notifications. */ public class NotificationData { private static final String TAG = "NotificationData"; private final NotificationFilter mNotificationFilter = Dependency.get(NotificationFilter.class); Loading @@ -64,6 +71,11 @@ public class NotificationData { private RankingMap mRankingMap; private final Ranking mTmpRanking = new Ranking(); private final boolean mUsePeopleFiltering; public NotificationData(Context context) { mUsePeopleFiltering = NotificationUtils.usePeopleFiltering(context); } public void setHeadsUpManager(HeadsUpManager headsUpManager) { mHeadsUpManager = headsUpManager; Loading @@ -72,52 +84,25 @@ public class NotificationData { @VisibleForTesting protected final Comparator<NotificationEntry> mRankingComparator = new Comparator<NotificationEntry>() { private final Ranking mRankingA = new Ranking(); private final Ranking mRankingB = new Ranking(); @Override public int compare(NotificationEntry a, NotificationEntry b) { final StatusBarNotification na = a.notification; final StatusBarNotification nb = b.notification; int aImportance = NotificationManager.IMPORTANCE_DEFAULT; int bImportance = NotificationManager.IMPORTANCE_DEFAULT; int aRank = 0; int bRank = 0; if (mRankingMap != null) { // RankingMap as received from NoMan getRanking(a.key, mRankingA); getRanking(b.key, mRankingB); aImportance = mRankingA.getImportance(); bImportance = mRankingB.getImportance(); aRank = mRankingA.getRank(); bRank = mRankingB.getRank(); } String mediaNotification = getMediaManager().getMediaNotificationKey(); // IMPORTANCE_MIN media streams are allowed to drift to the bottom final boolean aMedia = a.key.equals(mediaNotification) && aImportance > NotificationManager.IMPORTANCE_MIN; final boolean bMedia = b.key.equals(mediaNotification) && bImportance > NotificationManager.IMPORTANCE_MIN; boolean aSystemMax = aImportance >= NotificationManager.IMPORTANCE_HIGH && isSystemNotification(na); boolean bSystemMax = bImportance >= NotificationManager.IMPORTANCE_HIGH && isSystemNotification(nb); int aRank = getRank(a.key); int bRank = getRank(b.key); boolean aMedia = isImportantMedia(a); boolean bMedia = isImportantMedia(b); boolean aHeadsUp = a.getRow().isHeadsUp(); boolean bHeadsUp = b.getRow().isHeadsUp(); boolean aSystemMax = isSystemMax(a); boolean bSystemMax = isSystemMax(b); // HACK: This should really go elsewhere, but it's currently not straightforward to // extract the comparison code and we're guaranteed to touch every element, so this is // the best place to set the buckets for the moment. a.setIsTopBucket(aHeadsUp || aMedia || aSystemMax || a.isHighPriority()); b.setIsTopBucket(bHeadsUp || bMedia || bSystemMax || b.isHighPriority()); boolean aHeadsUp = a.isRowHeadsUp(); boolean bHeadsUp = b.isRowHeadsUp(); if (aHeadsUp != bHeadsUp) { if (mUsePeopleFiltering && a.hasAssociatedPeople() != b.hasAssociatedPeople()) { return a.hasAssociatedPeople() ? -1 : 1; } else if (aHeadsUp != bHeadsUp) { return aHeadsUp ? -1 : 1; } else if (aHeadsUp) { // Provide consistent ranking with headsUpManager Loading Loading @@ -317,14 +302,6 @@ public class NotificationData { return Ranking.VISIBILITY_NO_OVERRIDE; } public int getImportance(String key) { if (mRankingMap != null) { getRanking(key, mTmpRanking); return mTmpRanking.getImportance(); } return NotificationManager.IMPORTANCE_UNSPECIFIED; } public List<SnoozeCriterion> getSnoozeCriteria(String key) { if (mRankingMap != null) { getRanking(key, mTmpRanking); Loading @@ -349,6 +326,22 @@ public class NotificationData { return 0; } private boolean isImportantMedia(NotificationEntry e) { int importance = e.ranking().getImportance(); boolean media = e.key.equals(getMediaManager().getMediaNotificationKey()) && importance > NotificationManager.IMPORTANCE_MIN; return media; } private boolean isSystemMax(NotificationEntry e) { int importance = e.ranking().getImportance(); boolean sys = importance >= NotificationManager.IMPORTANCE_HIGH && isSystemNotification(e.notification); return sys; } public boolean shouldHide(String key) { if (mRankingMap != null) { getRanking(key, mTmpRanking); Loading Loading @@ -414,13 +407,37 @@ public class NotificationData { } } if (mSortedAndFiltered.size() == 1) { // HACK: We need the comparator to run on all children in order to set the // isHighPriority field. If there is only one child, then the comparison won't be run, // so we have to trigger it manually. Get rid of this code as soon as possible. mRankingComparator.compare(mSortedAndFiltered.get(0), mSortedAndFiltered.get(0)); } else { Collections.sort(mSortedAndFiltered, mRankingComparator); int bucket = BUCKET_PEOPLE; for (NotificationEntry e : mSortedAndFiltered) { assignBucketForEntry(e); if (e.getBucket() < bucket) { android.util.Log.wtf(TAG, "Detected non-contiguous bucket!"); } bucket = e.getBucket(); } } private void assignBucketForEntry(NotificationEntry e) { boolean isHeadsUp = e.isRowHeadsUp(); boolean isMedia = isImportantMedia(e); boolean isSystemMax = isSystemMax(e); setBucket(e, isHeadsUp, isMedia, isSystemMax); } private void setBucket( NotificationEntry e, boolean isHeadsUp, boolean isMedia, boolean isSystemMax) { if (mUsePeopleFiltering && e.hasAssociatedPeople()) { e.setBucket(BUCKET_PEOPLE); } else if (isHeadsUp || isMedia || isSystemMax || e.isHighPriority()) { e.setBucket(BUCKET_ALERTING); } else { e.setBucket(BUCKET_SILENT); } } Loading Loading @@ -465,6 +482,19 @@ public class NotificationData { return "android".equals(sbnPackage) || "com.android.systemui".equals(sbnPackage); } /** * Get the current set of buckets for notification entries, as defined here */ public static int[] getNotificationBuckets(Context context) { if (NotificationUtils.usePeopleFiltering(context)) { return new int[]{BUCKET_PEOPLE, BUCKET_ALERTING, BUCKET_SILENT}; } else if (NotificationUtils.useNewInterruptionModel(context)) { return new int[]{BUCKET_ALERTING, BUCKET_SILENT}; } else { return new int[]{BUCKET_ALERTING}; } } /** * Provides access to keyguard state and user settings dependent data. */ Loading Loading
packages/SystemUI/res/values/config.xml +3 −0 Original line number Diff line number Diff line Loading @@ -480,4 +480,7 @@ <!-- Preferred refresh rate at keyguard, if supported by the display --> <integer name="config_keyguardRefreshRate">-1</integer> <!-- Whether or not to add a "people" notifications section --> <bool name="config_usePeopleFiltering">false</bool> </resources>
packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java +2 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.statusbar; import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED; import static com.android.systemui.DejankUtils.whitelistIpcs; import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT; import android.app.ActivityManager; import android.app.KeyguardManager; Loading Loading @@ -316,7 +317,7 @@ public class NotificationLockscreenUserManagerImpl implements boolean exceedsPriorityThreshold; if (NotificationUtils.useNewInterruptionModel(mContext) && hideSilentNotificationsOnLockscreen()) { exceedsPriorityThreshold = entry.isTopBucket(); exceedsPriorityThreshold = entry.getBucket() != BUCKET_SILENT; } else { exceedsPriorityThreshold = !getEntryManager().getNotificationData().isAmbient(entry.key); Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -124,7 +124,7 @@ public class NotificationEntryManager implements @Inject public NotificationEntryManager(Context context) { mNotificationData = new NotificationData(); mNotificationData = new NotificationData(context); } /** Adds a {@link NotificationEntryListener}. */ Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java +14 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ public class NotificationUtils { private static final int[] sLocationOffset = new int[2]; @Nullable private static Boolean sUseNewInterruptionModel = null; @Nullable private static Boolean sUsePeopleFiltering = null; public static boolean isGrayscale(ImageView v, ContrastColorUtil colorUtil) { Object isGrayscale = v.getTag(R.id.icon_is_grayscale); Loading Loading @@ -87,4 +88,17 @@ public class NotificationUtils { } return sUseNewInterruptionModel; } /** * Caches and returns the value of the people filtering setting. Cannot change except through * process restarts. */ public static boolean usePeopleFiltering(Context context) { if (sUsePeopleFiltering == null) { sUsePeopleFiltering = context.getResources().getBoolean( R.bool.config_usePeopleFiltering); } return sUsePeopleFiltering; } }
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java +82 −52 Original line number Diff line number Diff line Loading @@ -16,10 +16,15 @@ package com.android.systemui.statusbar.notification.collection; import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING; import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE; import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.Person; import android.content.Context; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.SnoozeCriterion; Loading @@ -30,6 +35,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dependency; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.notification.NotificationFilter; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.policy.HeadsUpManager; Loading @@ -44,6 +50,7 @@ import java.util.Objects; * The list of currently displaying notifications. */ public class NotificationData { private static final String TAG = "NotificationData"; private final NotificationFilter mNotificationFilter = Dependency.get(NotificationFilter.class); Loading @@ -64,6 +71,11 @@ public class NotificationData { private RankingMap mRankingMap; private final Ranking mTmpRanking = new Ranking(); private final boolean mUsePeopleFiltering; public NotificationData(Context context) { mUsePeopleFiltering = NotificationUtils.usePeopleFiltering(context); } public void setHeadsUpManager(HeadsUpManager headsUpManager) { mHeadsUpManager = headsUpManager; Loading @@ -72,52 +84,25 @@ public class NotificationData { @VisibleForTesting protected final Comparator<NotificationEntry> mRankingComparator = new Comparator<NotificationEntry>() { private final Ranking mRankingA = new Ranking(); private final Ranking mRankingB = new Ranking(); @Override public int compare(NotificationEntry a, NotificationEntry b) { final StatusBarNotification na = a.notification; final StatusBarNotification nb = b.notification; int aImportance = NotificationManager.IMPORTANCE_DEFAULT; int bImportance = NotificationManager.IMPORTANCE_DEFAULT; int aRank = 0; int bRank = 0; if (mRankingMap != null) { // RankingMap as received from NoMan getRanking(a.key, mRankingA); getRanking(b.key, mRankingB); aImportance = mRankingA.getImportance(); bImportance = mRankingB.getImportance(); aRank = mRankingA.getRank(); bRank = mRankingB.getRank(); } String mediaNotification = getMediaManager().getMediaNotificationKey(); // IMPORTANCE_MIN media streams are allowed to drift to the bottom final boolean aMedia = a.key.equals(mediaNotification) && aImportance > NotificationManager.IMPORTANCE_MIN; final boolean bMedia = b.key.equals(mediaNotification) && bImportance > NotificationManager.IMPORTANCE_MIN; boolean aSystemMax = aImportance >= NotificationManager.IMPORTANCE_HIGH && isSystemNotification(na); boolean bSystemMax = bImportance >= NotificationManager.IMPORTANCE_HIGH && isSystemNotification(nb); int aRank = getRank(a.key); int bRank = getRank(b.key); boolean aMedia = isImportantMedia(a); boolean bMedia = isImportantMedia(b); boolean aHeadsUp = a.getRow().isHeadsUp(); boolean bHeadsUp = b.getRow().isHeadsUp(); boolean aSystemMax = isSystemMax(a); boolean bSystemMax = isSystemMax(b); // HACK: This should really go elsewhere, but it's currently not straightforward to // extract the comparison code and we're guaranteed to touch every element, so this is // the best place to set the buckets for the moment. a.setIsTopBucket(aHeadsUp || aMedia || aSystemMax || a.isHighPriority()); b.setIsTopBucket(bHeadsUp || bMedia || bSystemMax || b.isHighPriority()); boolean aHeadsUp = a.isRowHeadsUp(); boolean bHeadsUp = b.isRowHeadsUp(); if (aHeadsUp != bHeadsUp) { if (mUsePeopleFiltering && a.hasAssociatedPeople() != b.hasAssociatedPeople()) { return a.hasAssociatedPeople() ? -1 : 1; } else if (aHeadsUp != bHeadsUp) { return aHeadsUp ? -1 : 1; } else if (aHeadsUp) { // Provide consistent ranking with headsUpManager Loading Loading @@ -317,14 +302,6 @@ public class NotificationData { return Ranking.VISIBILITY_NO_OVERRIDE; } public int getImportance(String key) { if (mRankingMap != null) { getRanking(key, mTmpRanking); return mTmpRanking.getImportance(); } return NotificationManager.IMPORTANCE_UNSPECIFIED; } public List<SnoozeCriterion> getSnoozeCriteria(String key) { if (mRankingMap != null) { getRanking(key, mTmpRanking); Loading @@ -349,6 +326,22 @@ public class NotificationData { return 0; } private boolean isImportantMedia(NotificationEntry e) { int importance = e.ranking().getImportance(); boolean media = e.key.equals(getMediaManager().getMediaNotificationKey()) && importance > NotificationManager.IMPORTANCE_MIN; return media; } private boolean isSystemMax(NotificationEntry e) { int importance = e.ranking().getImportance(); boolean sys = importance >= NotificationManager.IMPORTANCE_HIGH && isSystemNotification(e.notification); return sys; } public boolean shouldHide(String key) { if (mRankingMap != null) { getRanking(key, mTmpRanking); Loading Loading @@ -414,13 +407,37 @@ public class NotificationData { } } if (mSortedAndFiltered.size() == 1) { // HACK: We need the comparator to run on all children in order to set the // isHighPriority field. If there is only one child, then the comparison won't be run, // so we have to trigger it manually. Get rid of this code as soon as possible. mRankingComparator.compare(mSortedAndFiltered.get(0), mSortedAndFiltered.get(0)); } else { Collections.sort(mSortedAndFiltered, mRankingComparator); int bucket = BUCKET_PEOPLE; for (NotificationEntry e : mSortedAndFiltered) { assignBucketForEntry(e); if (e.getBucket() < bucket) { android.util.Log.wtf(TAG, "Detected non-contiguous bucket!"); } bucket = e.getBucket(); } } private void assignBucketForEntry(NotificationEntry e) { boolean isHeadsUp = e.isRowHeadsUp(); boolean isMedia = isImportantMedia(e); boolean isSystemMax = isSystemMax(e); setBucket(e, isHeadsUp, isMedia, isSystemMax); } private void setBucket( NotificationEntry e, boolean isHeadsUp, boolean isMedia, boolean isSystemMax) { if (mUsePeopleFiltering && e.hasAssociatedPeople()) { e.setBucket(BUCKET_PEOPLE); } else if (isHeadsUp || isMedia || isSystemMax || e.isHighPriority()) { e.setBucket(BUCKET_ALERTING); } else { e.setBucket(BUCKET_SILENT); } } Loading Loading @@ -465,6 +482,19 @@ public class NotificationData { return "android".equals(sbnPackage) || "com.android.systemui".equals(sbnPackage); } /** * Get the current set of buckets for notification entries, as defined here */ public static int[] getNotificationBuckets(Context context) { if (NotificationUtils.usePeopleFiltering(context)) { return new int[]{BUCKET_PEOPLE, BUCKET_ALERTING, BUCKET_SILENT}; } else if (NotificationUtils.useNewInterruptionModel(context)) { return new int[]{BUCKET_ALERTING, BUCKET_SILENT}; } else { return new int[]{BUCKET_ALERTING}; } } /** * Provides access to keyguard state and user settings dependent data. */ Loading