summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/values/config.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java134
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java62
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java200
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java9
16 files changed, 372 insertions, 187 deletions
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 38293bf2defd..61210d3e0011 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -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>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 289277e63760..f782fab7e49f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -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;
@@ -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);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 4a27a4ed31a1..b6b149dd049a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -124,7 +124,7 @@ public class NotificationEntryManager implements
@Inject
public NotificationEntryManager(Context context) {
- mNotificationData = new NotificationData();
+ mNotificationData = new NotificationData(context);
}
/** Adds a {@link NotificationEntryListener}. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
index 1af47dd0f4c0..dfbbf987dd96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
@@ -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);
@@ -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;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
index 727e245ae38b..aacb2dd0682f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
@@ -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;
@@ -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;
@@ -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);
@@ -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;
@@ -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();
- }
+ int aRank = getRank(a.key);
+ int bRank = getRank(b.key);
- String mediaNotification = getMediaManager().getMediaNotificationKey();
+ boolean aMedia = isImportantMedia(a);
+ boolean bMedia = isImportantMedia(b);
- // 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 = isSystemMax(a);
+ boolean bSystemMax = isSystemMax(b);
- boolean aSystemMax = aImportance >= NotificationManager.IMPORTANCE_HIGH
- && isSystemNotification(na);
- boolean bSystemMax = bImportance >= NotificationManager.IMPORTANCE_HIGH
- && isSystemNotification(nb);
+ boolean aHeadsUp = a.isRowHeadsUp();
+ boolean bHeadsUp = b.isRowHeadsUp();
-
- boolean aHeadsUp = a.getRow().isHeadsUp();
- boolean bHeadsUp = b.getRow().isHeadsUp();
-
- // 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());
-
- 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
@@ -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);
@@ -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);
@@ -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));
+ 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 {
- Collections.sort(mSortedAndFiltered, mRankingComparator);
+ e.setBucket(BUCKET_SILENT);
}
}
@@ -466,6 +483,19 @@ public class NotificationData {
}
/**
+ * 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.
*/
public interface KeyguardEnvironment {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index 71cdcf748679..a33d23c0b5d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -21,6 +21,7 @@ import static android.app.Notification.CATEGORY_CALL;
import static android.app.Notification.CATEGORY_EVENT;
import static android.app.Notification.CATEGORY_MESSAGE;
import static android.app.Notification.CATEGORY_REMINDER;
+import static android.app.Notification.EXTRA_MESSAGES;
import static android.app.Notification.FLAG_BUBBLE;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
@@ -29,6 +30,8 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICAT
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING;
+
import android.annotation.NonNull;
import android.app.Notification;
import android.app.Notification.MessagingStyle.Message;
@@ -38,6 +41,7 @@ import android.app.Person;
import android.content.Context;
import android.graphics.drawable.Icon;
import android.os.Bundle;
+import android.os.Parcelable;
import android.os.SystemClock;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.SnoozeCriterion;
@@ -58,6 +62,7 @@ import com.android.systemui.statusbar.notification.InflationException;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag;
import com.android.systemui.statusbar.notification.row.NotificationGuts;
+import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager;
import java.util.ArrayList;
import java.util.List;
@@ -99,6 +104,7 @@ public final class NotificationEntry {
public int targetSdk;
private long lastFullScreenIntentLaunchTime = NOT_LAUNCHED_YET;
public CharSequence remoteInputText;
+ private final List<Person> mAssociatedPeople = new ArrayList<>();
/**
* If {@link android.app.RemoteInput#getEditChoicesBeforeSending} is enabled, and the user is
@@ -140,12 +146,11 @@ public final class NotificationEntry {
*/
private boolean mHighPriority;
- private boolean mIsTopBucket;
-
private boolean mSensitive = true;
private Runnable mOnSensitiveChangedListener;
private boolean mAutoHeadsUp;
private boolean mPulseSupressed;
+ private int mBucket = BUCKET_ALERTING;
public NotificationEntry(
@NonNull StatusBarNotification sbn,
@@ -173,11 +178,12 @@ public final class NotificationEntry {
* TODO: Make this package-private
*/
public void setNotification(StatusBarNotification sbn) {
- if (!sbn.getKey().equals(key)) {
+ if (sbn.getKey() != null && key != null && !sbn.getKey().equals(key)) {
throw new IllegalArgumentException("New key " + sbn.getKey()
+ " doesn't match existing key " + key);
}
notification = sbn;
+ updatePeopleList();
}
/**
@@ -263,20 +269,39 @@ public final class NotificationEntry {
this.mHighPriority = highPriority;
}
- /**
- * @return True if the notif should appear in the "top" or "important" section of notifications
- * (as opposed to the "bottom" or "silent" section). This is usually the same as
- * {@link #isHighPriority()}, but there are certain exceptions, such as media notifs.
- */
- public boolean isTopBucket() {
- return mIsTopBucket;
+ public boolean isBubble() {
+ return (notification.getNotification().flags & FLAG_BUBBLE) != 0;
}
- public void setIsTopBucket(boolean isTopBucket) {
- mIsTopBucket = isTopBucket;
+
+ private void updatePeopleList() {
+ mAssociatedPeople.clear();
+
+ Bundle extras = notification.getNotification().extras;
+ if (extras == null) {
+ return;
+ }
+
+ List<Person> p = extras.getParcelableArrayList(Notification.EXTRA_PEOPLE_LIST);
+
+ if (p != null) {
+ mAssociatedPeople.addAll(p);
+ }
+
+ if (Notification.MessagingStyle.class.equals(
+ notification.getNotification().getNotificationStyle())) {
+ final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES);
+ if (!ArrayUtils.isEmpty(messages)) {
+ for (Notification.MessagingStyle.Message message :
+ Notification.MessagingStyle.Message
+ .getMessagesFromBundleArray(messages)) {
+ mAssociatedPeople.add(message.getSenderPerson());
+ }
+ }
+ }
}
- public boolean isBubble() {
- return (notification.getNotification().flags & FLAG_BUBBLE) != 0;
+ boolean hasAssociatedPeople() {
+ return mAssociatedPeople.size() > 0;
}
/**
@@ -295,6 +320,15 @@ public final class NotificationEntry {
}
}
+ @NotificationSectionsManager.PriorityBucket
+ public int getBucket() {
+ return mBucket;
+ }
+
+ public void setBucket(@NotificationSectionsManager.PriorityBucket int bucket) {
+ mBucket = bucket;
+ }
+
public ExpandableNotificationRow getRow() {
return row;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
index 422184699952..ec0c6348fd89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
@@ -16,11 +16,10 @@
package com.android.systemui.statusbar.notification.stack;
-import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.NUM_SECTIONS;
-
-
+import android.content.Context;
import android.util.MathUtils;
+import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -51,11 +50,14 @@ public class NotificationRoundnessManager implements OnHeadsUpChangedListener {
private float mAppearFraction;
@Inject
- NotificationRoundnessManager(KeyguardBypassController keyguardBypassController) {
- mFirstInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
- mLastInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
- mTmpFirstInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
- mTmpLastInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
+ NotificationRoundnessManager(
+ KeyguardBypassController keyguardBypassController,
+ Context context) {
+ int numberOfSections = NotificationData.getNotificationBuckets(context).length;
+ mFirstInSectionViews = new ActivatableNotificationView[numberOfSections];
+ mLastInSectionViews = new ActivatableNotificationView[numberOfSections];
+ mTmpFirstInSectionViews = new ActivatableNotificationView[numberOfSections];
+ mTmpLastInSectionViews = new ActivatableNotificationView[numberOfSections];
mBypassController = keyguardBypassController;
}
@@ -157,7 +159,7 @@ public class NotificationRoundnessManager implements OnHeadsUpChangedListener {
public void updateRoundedChildren(NotificationSection[] sections) {
boolean anyChanged = false;
- for (int i = 0; i < NUM_SECTIONS; i++) {
+ for (int i = 0; i < sections.length; i++) {
mTmpFirstInSectionViews[i] = mFirstInSectionViews[i];
mTmpLastInSectionViews[i] = mLastInSectionViews[i];
mFirstInSectionViews[i] = sections[i].getFirstVisibleChild();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
index f39ed2e89432..9d456ef785a8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
@@ -33,6 +33,7 @@ import com.android.systemui.statusbar.notification.row.ActivatableNotificationVi
* bounds change.
*/
class NotificationSection {
+ private @NotificationSectionsManager.PriorityBucket int mBucket;
private View mOwningView;
private Rect mBounds = new Rect();
private Rect mCurrentBounds = new Rect(-1, -1, -1, -1);
@@ -43,8 +44,9 @@ class NotificationSection {
private ActivatableNotificationView mFirstVisibleChild;
private ActivatableNotificationView mLastVisibleChild;
- NotificationSection(View owningView) {
+ NotificationSection(View owningView, @NotificationSectionsManager.PriorityBucket int bucket) {
mOwningView = owningView;
+ mBucket = bucket;
}
public void cancelAnimators() {
@@ -72,6 +74,11 @@ class NotificationSection {
return mBottomAnimator != null || mTopAnimator != null;
}
+ @NotificationSectionsManager.PriorityBucket
+ public int getBucket() {
+ return mBucket;
+ }
+
public void startBackgroundAnimation(boolean animateTop, boolean animateBottom) {
// Left and right bounds are always applied immediately.
mCurrentBounds.left = mBounds.left;
@@ -199,12 +206,16 @@ class NotificationSection {
return mLastVisibleChild;
}
- public void setFirstVisibleChild(ActivatableNotificationView child) {
+ public boolean setFirstVisibleChild(ActivatableNotificationView child) {
+ boolean changed = mFirstVisibleChild != child;
mFirstVisibleChild = child;
+ return changed;
}
- public void setLastVisibleChild(ActivatableNotificationView child) {
+ public boolean setLastVisibleChild(ActivatableNotificationView child) {
+ boolean changed = mLastVisibleChild != child;
mLastVisibleChild = child;
+ return changed;
}
public void resetCurrentBounds() {
@@ -291,5 +302,4 @@ class NotificationSection {
mBounds.bottom = bottom;
return bottom;
}
-
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
index d119fb79e4c6..d0444ae81b89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
@@ -18,6 +18,10 @@ package com.android.systemui.statusbar.notification.stack;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Intent;
import android.provider.Settings;
@@ -34,23 +38,31 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
+import java.lang.annotation.Retention;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Manages the boundaries of the two notification sections (high priority and low priority). Also
* shows/hides the headers for those sections where appropriate.
*
* TODO: Move remaining sections logic from NSSL into this class.
*/
-class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvider {
+public class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvider {
+
+ private static final String TAG = "NotifSectionsManager";
+ private static final boolean DEBUG = false;
+
private final NotificationStackScrollLayout mParent;
private final ActivityStarter mActivityStarter;
private final StatusBarStateController mStatusBarStateController;
private final ConfigurationController mConfigurationController;
- private final boolean mUseMultipleSections;
+ private final int mNumberOfSections;
private boolean mInitialized = false;
private SectionHeaderView mGentleHeader;
private boolean mGentleHeaderVisible = false;
- @Nullable private ExpandableNotificationRow mFirstGentleNotif;
+
@Nullable private View.OnClickListener mOnClearGentleNotifsClickListener;
NotificationSectionsManager(
@@ -58,12 +70,21 @@ class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvide
ActivityStarter activityStarter,
StatusBarStateController statusBarStateController,
ConfigurationController configurationController,
- boolean useMultipleSections) {
+ int numberOfSections) {
mParent = parent;
mActivityStarter = activityStarter;
mStatusBarStateController = statusBarStateController;
mConfigurationController = configurationController;
- mUseMultipleSections = useMultipleSections;
+ mNumberOfSections = numberOfSections;
+ }
+
+ NotificationSection[] createSectionsForBuckets(int[] buckets) {
+ NotificationSection[] sections = new NotificationSection[buckets.length];
+ for (int i = 0; i < buckets.length; i++) {
+ sections[i] = new NotificationSection(mParent, buckets[i] /* bucket */);
+ }
+
+ return sections;
}
/** Must be called before use. */
@@ -111,8 +132,38 @@ class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvide
}
@Override
- public boolean beginsSection(View view) {
- return view == getFirstLowPriorityChild();
+ public boolean beginsSection(@NonNull View view, @Nullable View previous) {
+ boolean begin = false;
+ if (view instanceof ExpandableNotificationRow) {
+ if (previous instanceof ExpandableNotificationRow) {
+ // If we're drawing the first non-person notification, break out a section
+ ExpandableNotificationRow curr = (ExpandableNotificationRow) view;
+ ExpandableNotificationRow prev = (ExpandableNotificationRow) previous;
+
+ begin = curr.getEntry().getBucket() != prev.getEntry().getBucket();
+ }
+ }
+
+ if (!begin) {
+ begin = view == mGentleHeader;
+ }
+
+ return begin;
+ }
+
+ private boolean isUsingMultipleSections() {
+ return mNumberOfSections > 1;
+ }
+
+ private @PriorityBucket int getBucket(ActivatableNotificationView view)
+ throws IllegalArgumentException {
+ if (view instanceof ExpandableNotificationRow) {
+ return ((ExpandableNotificationRow) view).getEntry().getBucket();
+ } else if (view == mGentleHeader) {
+ return BUCKET_SILENT;
+ }
+
+ throw new IllegalArgumentException("I don't know how to find a bucket for this view :(");
}
/**
@@ -120,11 +171,10 @@ class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvide
* bookkeeping and adds/moves/removes section headers if appropriate.
*/
void updateSectionBoundaries() {
- if (!mUseMultipleSections) {
+ if (!isUsingMultipleSections()) {
return;
}
- mFirstGentleNotif = null;
int firstGentleNotifIndex = -1;
final int n = mParent.getChildCount();
@@ -133,9 +183,8 @@ class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvide
if (child instanceof ExpandableNotificationRow
&& child.getVisibility() != View.GONE) {
ExpandableNotificationRow row = (ExpandableNotificationRow) child;
- if (!row.getEntry().isTopBucket()) {
+ if (row.getEntry().getBucket() == BUCKET_SILENT) {
firstGentleNotifIndex = i;
- mFirstGentleNotif = row;
break;
}
}
@@ -184,78 +233,73 @@ class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvide
}
/**
- * Updates the boundaries (as tracked by their first and last views) of the high and low
- * priority sections.
+ * Updates the boundaries (as tracked by their first and last views) of the priority sections.
*
* @return {@code true} If the last view in the top section changed (so we need to animate).
*/
- boolean updateFirstAndLastViewsInSections(
- final NotificationSection highPrioritySection,
- final NotificationSection lowPrioritySection,
- ActivatableNotificationView firstChild,
- ActivatableNotificationView lastChild) {
- if (mUseMultipleSections) {
- ActivatableNotificationView previousLastHighPriorityChild =
- highPrioritySection.getLastVisibleChild();
- ActivatableNotificationView previousFirstLowPriorityChild =
- lowPrioritySection.getFirstVisibleChild();
- ActivatableNotificationView lastHighPriorityChild = getLastHighPriorityChild();
- ActivatableNotificationView firstLowPriorityChild = getFirstLowPriorityChild();
- if (lastHighPriorityChild != null && firstLowPriorityChild != null) {
- highPrioritySection.setFirstVisibleChild(firstChild);
- highPrioritySection.setLastVisibleChild(lastHighPriorityChild);
- lowPrioritySection.setFirstVisibleChild(firstLowPriorityChild);
- lowPrioritySection.setLastVisibleChild(lastChild);
- } else if (lastHighPriorityChild != null) {
- highPrioritySection.setFirstVisibleChild(firstChild);
- highPrioritySection.setLastVisibleChild(lastChild);
- lowPrioritySection.setFirstVisibleChild(null);
- lowPrioritySection.setLastVisibleChild(null);
- } else {
- highPrioritySection.setFirstVisibleChild(null);
- highPrioritySection.setLastVisibleChild(null);
- lowPrioritySection.setFirstVisibleChild(firstChild);
- lowPrioritySection.setLastVisibleChild(lastChild);
+ boolean updateFirstAndLastViewsForAllSections(
+ NotificationSection[] sections,
+ List<ActivatableNotificationView> children) {
+
+ if (sections.length <= 0 || children.size() <= 0) {
+ for (NotificationSection s : sections) {
+ s.setFirstVisibleChild(null);
+ s.setLastVisibleChild(null);
}
- return lastHighPriorityChild != previousLastHighPriorityChild
- || firstLowPriorityChild != previousFirstLowPriorityChild;
- } else {
- highPrioritySection.setFirstVisibleChild(firstChild);
- highPrioritySection.setLastVisibleChild(lastChild);
return false;
}
- }
- @VisibleForTesting
- SectionHeaderView getGentleHeaderView() {
- return mGentleHeader;
- }
+ boolean changed = false;
+ ArrayList<ActivatableNotificationView> viewsInBucket = new ArrayList<>();
+ for (NotificationSection s : sections) {
+ int filter = s.getBucket();
+ viewsInBucket.clear();
- @Nullable
- private ActivatableNotificationView getFirstLowPriorityChild() {
- if (mGentleHeaderVisible) {
- return mGentleHeader;
- } else {
- return mFirstGentleNotif;
- }
- }
+ //TODO: do this in a single pass, and more better
+ for (ActivatableNotificationView v : children) {
+ if (getBucket(v) == filter) {
+ viewsInBucket.add(v);
+ }
- @Nullable
- private ActivatableNotificationView getLastHighPriorityChild() {
- ActivatableNotificationView lastChildBeforeGap = null;
- int childCount = mParent.getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = mParent.getChildAt(i);
- if (child.getVisibility() != View.GONE && child instanceof ExpandableNotificationRow) {
- ExpandableNotificationRow row = (ExpandableNotificationRow) child;
- if (!row.getEntry().isTopBucket()) {
- break;
+ if (viewsInBucket.size() >= 1) {
+ changed |= s.setFirstVisibleChild(viewsInBucket.get(0));
+ changed |= s.setLastVisibleChild(viewsInBucket.get(viewsInBucket.size() - 1));
} else {
- lastChildBeforeGap = row;
+ changed |= s.setFirstVisibleChild(null);
+ changed |= s.setLastVisibleChild(null);
}
}
}
- return lastChildBeforeGap;
+
+ if (DEBUG) {
+ logSections(sections);
+ }
+
+ return changed;
+ }
+
+ private void logSections(NotificationSection[] sections) {
+ for (int i = 0; i < sections.length; i++) {
+ NotificationSection s = sections[i];
+ ActivatableNotificationView first = s.getFirstVisibleChild();
+ String fs = first == null ? "(null)"
+ : (first instanceof ExpandableNotificationRow)
+ ? ((ExpandableNotificationRow) first).getEntry().key
+ : Integer.toHexString(System.identityHashCode(first));
+ ActivatableNotificationView last = s.getLastVisibleChild();
+ String ls = last == null ? "(null)"
+ : (last instanceof ExpandableNotificationRow)
+ ? ((ExpandableNotificationRow) last).getEntry().key
+ : Integer.toHexString(System.identityHashCode(last));
+ android.util.Log.d(TAG, "updateSections: f=" + fs + " s=" + i);
+ android.util.Log.d(TAG, "updateSections: l=" + ls + " s=" + i);
+ }
+ }
+
+
+ @VisibleForTesting
+ SectionHeaderView getGentleHeaderView() {
+ return mGentleHeader;
}
private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
@@ -279,4 +323,20 @@ class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvide
mOnClearGentleNotifsClickListener.onClick(v);
}
}
+
+ /**
+ * For now, declare the available notification buckets (sections) here so that other
+ * presentation code can decide what to do based on an entry's buckets
+ *
+ */
+ @Retention(SOURCE)
+ @IntDef(prefix = { "BUCKET_" }, value = {
+ BUCKET_PEOPLE,
+ BUCKET_ALERTING,
+ BUCKET_SILENT
+ })
+ public @interface PriorityBucket {}
+ public static final int BUCKET_PEOPLE = 0;
+ public static final int BUCKET_ALERTING = 1;
+ public static final int BUCKET_SILENT = 2;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 1c9b2256af9b..a67018ef9710 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.stack;
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT;
import static com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.ANCHOR_SCROLLING;
import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE;
import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY;
@@ -112,6 +113,7 @@ import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.ShadeViewRefactor;
import com.android.systemui.statusbar.notification.ShadeViewRefactor.RefactorComponent;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
@@ -172,7 +174,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
* Sentinel value for no current active pointer. Used by {@link #mActivePointerId}.
*/
private static final int INVALID_POINTER = -1;
- static final int NUM_SECTIONS = 2;
/**
* The distance in pixels between sections when the sections are directly adjacent (no visible
* gap is drawn between them). In this case we don't want to round their corners.
@@ -351,7 +352,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
return true;
}
};
- private NotificationSection[] mSections = new NotificationSection[NUM_SECTIONS];
+ private NotificationSection[] mSections;
private boolean mAnimateNextBackgroundTop;
private boolean mAnimateNextBackgroundBottom;
private boolean mAnimateNextSectionBoundsChange;
@@ -522,9 +523,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
mAllowLongPress = allowLongPress;
- for (int i = 0; i < NUM_SECTIONS; i++) {
- mSections[i] = new NotificationSection(this);
- }
mRoundnessManager = notificationRoundnessManager;
mHeadsUpManager = headsUpManager;
@@ -533,19 +531,21 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
mKeyguardBypassController = keyguardBypassController;
mFalsingManager = falsingManager;
+ int[] buckets = NotificationData.getNotificationBuckets(context);
mSectionsManager =
new NotificationSectionsManager(
this,
activityStarter,
statusBarStateController,
configurationController,
- NotificationUtils.useNewInterruptionModel(context));
+ buckets.length);
mSectionsManager.initialize(LayoutInflater.from(context));
mSectionsManager.setOnClearGentleNotifsClickListener(v -> {
// Leave the shade open if there will be other notifs left over to clear
final boolean closeShade = !hasActiveClearableNotifications(ROWS_HIGH_PRIORITY);
clearNotifications(ROWS_GENTLE, closeShade);
});
+ mSections = mSectionsManager.createSectionsForBuckets(buckets);
mAmbientState = new AmbientState(context, mSectionsManager, mHeadsUpManager);
mBgColor = context.getColor(R.color.notification_shade_background_color);
@@ -773,7 +773,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
protected void onDraw(Canvas canvas) {
if (mShouldDrawNotificationBackground
&& (mSections[0].getCurrentBounds().top
- < mSections[NUM_SECTIONS - 1].getCurrentBounds().bottom
+ < mSections[mSections.length - 1].getCurrentBounds().bottom
|| mAmbientState.isDozing())) {
drawBackground(canvas);
} else if (mInHeadsUpPinnedMode || mHeadsUpAnimatingAway) {
@@ -819,7 +819,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
int lockScreenLeft = mSidePaddings;
int lockScreenRight = getWidth() - mSidePaddings;
int lockScreenTop = mSections[0].getCurrentBounds().top;
- int lockScreenBottom = mSections[NUM_SECTIONS - 1].getCurrentBounds().bottom;
+ int lockScreenBottom = mSections[mSections.length - 1].getCurrentBounds().bottom;
int hiddenLeft = getWidth() / 2;
int hiddenTop = mTopPadding;
@@ -2636,6 +2636,21 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
return null;
}
+ //TODO: We shouldn't have to generate this list every time
+ private List<ActivatableNotificationView> getChildrenWithBackground() {
+ ArrayList<ActivatableNotificationView> children = new ArrayList<>();
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View child = getChildAt(i);
+ if (child.getVisibility() != View.GONE && child instanceof ActivatableNotificationView
+ && child != mShelf) {
+ children.add((ActivatableNotificationView) child);
+ }
+ }
+
+ return children;
+ }
+
/**
* Fling the scroll view
*
@@ -3198,8 +3213,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
ActivatableNotificationView firstChild = getFirstChildWithBackground();
ActivatableNotificationView lastChild = getLastChildWithBackground();
- boolean sectionViewsChanged = mSectionsManager.updateFirstAndLastViewsInSections(
- mSections[0], mSections[1], firstChild, lastChild);
+ boolean sectionViewsChanged = mSectionsManager.updateFirstAndLastViewsForAllSections(
+ mSections, getChildrenWithBackground());
if (mAnimationsEnabled && mIsExpanded) {
mAnimateNextBackgroundTop = firstChild != previousFirstChild;
@@ -5780,7 +5795,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
currentIndex++;
boolean beforeSpeedBump;
if (mHighPriorityBeforeSpeedBump) {
- beforeSpeedBump = row.getEntry().isTopBucket();
+ beforeSpeedBump = row.getEntry().getBucket() < BUCKET_SILENT;
} else {
beforeSpeedBump = !row.getEntry().isAmbient();
}
@@ -5838,9 +5853,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
case ROWS_ALL:
return true;
case ROWS_HIGH_PRIORITY:
- return row.getEntry().isTopBucket();
+ return row.getEntry().getBucket() < BUCKET_SILENT;
case ROWS_GENTLE:
- return !row.getEntry().isTopBucket();
+ return row.getEntry().getBucket() == BUCKET_SILENT;
default:
throw new IllegalArgumentException("Unknown selection: " + selection);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index ef8048487022..4b61064f4a54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.stack;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
@@ -411,8 +413,10 @@ public class StackScrollAlgorithm {
float currentYPosition,
boolean reverse) {
ExpandableView child = algorithmState.visibleChildren.get(i);
+ ExpandableView previousChild = i > 0 ? algorithmState.visibleChildren.get(i - 1) : null;
final boolean applyGapHeight =
- childNeedsGapHeight(ambientState.getSectionProvider(), algorithmState, i, child);
+ childNeedsGapHeight(
+ ambientState.getSectionProvider(), algorithmState, i, child, previousChild);
ExpandableViewState childViewState = child.getViewState();
childViewState.location = ExpandableViewState.LOCATION_UNKNOWN;
@@ -477,8 +481,11 @@ public class StackScrollAlgorithm {
SectionProvider sectionProvider,
StackScrollAlgorithmState algorithmState,
int visibleIndex,
- View child) {
- boolean needsGapHeight = sectionProvider.beginsSection(child) && visibleIndex > 0;
+ View child,
+ View previousChild) {
+
+ boolean needsGapHeight = sectionProvider.beginsSection(child, previousChild)
+ && visibleIndex > 0;
if (ANCHOR_SCROLLING) {
needsGapHeight &= visibleIndex != algorithmState.anchorViewIndex;
}
@@ -749,6 +756,6 @@ public class StackScrollAlgorithm {
* True if this view starts a new "section" of notifications, such as the gentle
* notifications section. False if sections are not enabled.
*/
- boolean beginsSection(View view);
+ boolean beginsSection(@NonNull View view, @Nullable View previous);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index 57dd8c94c790..a02764320b6c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -19,11 +19,12 @@ package com.android.systemui.statusbar;
import static android.content.Intent.ACTION_USER_SWITCHED;
import static android.provider.Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT;
+
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -166,7 +167,10 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1);
when(mNotificationData.isHighPriority(any())).thenReturn(false);
- assertTrue(mLockscreenUserManager.shouldShowOnKeyguard(mock(NotificationEntry.class)));
+ NotificationEntry entry = new NotificationEntryBuilder().build();
+ entry.setBucket(BUCKET_SILENT);
+
+ assertTrue(mLockscreenUserManager.shouldShowOnKeyguard(entry));
}
@Test
@@ -179,7 +183,9 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0);
when(mNotificationData.isHighPriority(any())).thenReturn(false);
- assertFalse(mLockscreenUserManager.shouldShowOnKeyguard(mock(NotificationEntry.class)));
+ NotificationEntry entry = new NotificationEntryBuilder().build();
+ entry.setBucket(BUCKET_SILENT);
+ assertFalse(mLockscreenUserManager.shouldShowOnKeyguard(entry));
}
private class TestNotificationLockscreenUserManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
index a145c1251f57..8d496a72e3b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
@@ -73,7 +73,7 @@ public class NotificationListControllerTest extends SysuiTestCase {
private DeviceProvisionedListener mProvisionedListener;
// TODO: Remove this once EntryManager no longer needs to be mocked
- private NotificationData mNotificationData = new NotificationData();
+ private NotificationData mNotificationData = new NotificationData(mContext);
private int mNextNotifId = 0;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
index 9bcbfbc836b3..ab7f960d6a15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
@@ -32,6 +32,8 @@ import static com.android.systemui.statusbar.notification.collection.Notificatio
import static com.android.systemui.statusbar.notification.collection.NotificationDataTest.TestableNotificationData.OVERRIDE_IMPORTANCE;
import static com.android.systemui.statusbar.notification.collection.NotificationDataTest.TestableNotificationData.OVERRIDE_RANK;
import static com.android.systemui.statusbar.notification.collection.NotificationDataTest.TestableNotificationData.OVERRIDE_VIS_EFFECTS;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT;
import static junit.framework.Assert.assertEquals;
@@ -48,6 +50,7 @@ import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Person;
+import android.content.Context;
import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
@@ -136,7 +139,7 @@ public class NotificationDataTest extends SysuiTestCase {
mDependency.injectTestDependency(KeyguardEnvironment.class, mEnvironment);
when(mEnvironment.isDeviceProvisioned()).thenReturn(true);
when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
- mNotificationData = new TestableNotificationData();
+ mNotificationData = new TestableNotificationData(mContext);
mNotificationData.updateRanking(mock(NotificationListenerService.RankingMap.class));
mRow = new NotificationTestHelper(getContext()).createRow();
Dependency.get(InitController.class).executePostInitTasks();
@@ -527,8 +530,7 @@ public class NotificationDataTest extends SysuiTestCase {
@Test
public void testSort_samePriorityUsesNMSRank() {
- // NMS rank says A and then B. But A is not high priority and B is, so B should sort in
- // front
+ // NMS rank says A and then B, and they are the same priority so use that rank
Notification aN = new Notification.Builder(mContext, "test")
.setStyle(new Notification.MessagingStyle(""))
.build();
@@ -571,8 +573,7 @@ public class NotificationDataTest extends SysuiTestCase {
}
@Test
- public void testSort_properlySetsIsTopBucket() {
-
+ public void testSort_properlySetsAlertingBucket() {
Notification notification = new Notification.Builder(mContext, "test")
.build();
NotificationEntry entry = new NotificationEntryBuilder()
@@ -591,11 +592,11 @@ public class NotificationDataTest extends SysuiTestCase {
entry.setRow(mRow);
mNotificationData.add(entry);
- assertTrue(entry.isTopBucket());
+ assertEquals(entry.getBucket(), BUCKET_ALERTING);
}
@Test
- public void testSort_properlySetsIsNotTopBucket() {
+ public void testSort_properlySetsSilentBucket() {
Notification notification = new Notification.Builder(mContext, "test")
.build();
@@ -613,10 +614,9 @@ public class NotificationDataTest extends SysuiTestCase {
mNotificationData.rankingOverrides.put(entry.key(), override);
entry.setRow(mRow);
-
mNotificationData.add(entry);
- assertFalse(entry.isTopBucket());
+ assertEquals(entry.getBucket(), BUCKET_SILENT);
}
private void initStatusBarNotification(boolean allowDuringSetup) {
@@ -631,8 +631,8 @@ public class NotificationDataTest extends SysuiTestCase {
}
public static class TestableNotificationData extends NotificationData {
- public TestableNotificationData() {
- super();
+ public TestableNotificationData(Context context) {
+ super(context);
}
public static final String OVERRIDE_RANK = "r";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
index 524ad85c3a98..addceb5def6e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
@@ -64,7 +64,7 @@ public class NotificationRoundnessManagerTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mRoundnessManager = new NotificationRoundnessManager(mBypassController);
+ mRoundnessManager = new NotificationRoundnessManager(mBypassController, mContext);
com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
NotificationTestHelper testHelper = new NotificationTestHelper(getContext());
mFirst = testHelper.createRow();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index 59d0f912d38e..56ed0e3a6af3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -18,6 +18,9 @@ package com.android.systemui.statusbar.notification.stack;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
@@ -74,7 +77,7 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
mActivityStarterDelegate,
mStatusBarStateController,
mConfigurationController,
- true);
+ 2);
// Required in order for the header inflation to work properly
when(mNssl.generateLayoutParams(any(AttributeSet.class)))
.thenReturn(new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
@@ -263,8 +266,8 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
when(notifRow.getVisibility()).thenReturn(View.VISIBLE);
when(notifRow.getEntry().isHighPriority())
.thenReturn(children[i] == ChildType.HIPRI);
- when(notifRow.getEntry().isTopBucket())
- .thenReturn(children[i] == ChildType.HIPRI);
+ when(notifRow.getEntry().getBucket()).thenReturn(
+ children[i] == ChildType.HIPRI ? BUCKET_ALERTING : BUCKET_SILENT);
when(notifRow.getParent()).thenReturn(mNssl);
child = notifRow;
break;