Enable surfacing of notification children
Yo Dawg, I herd you like notifications, so I put a
notification in your notification so you can be
interrupted while you are being interrupted.
Bug: 15869874
Bug: 15188947
Change-Id: I6c733d6f8e8a04f85036182f82d3e945c6feb5bc
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index 5214ab4..7072dcb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -100,6 +100,8 @@
}
}
});
+ } else {
+ group.summary.row.updateExpandButton();
}
}
}
@@ -116,11 +118,15 @@
}
if (notif.isGroupSummary()) {
group.summary = added;
+ group.expanded = added.row.areChildrenExpanded();
if (!group.children.isEmpty()) {
mListener.onGroupCreatedFromChildren(group);
}
} else {
group.children.add(added);
+ if (group.summary != null && group.children.size() == 1 && !group.expanded) {
+ group.summary.row.updateExpandButton();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 7513fc6..195da46 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1680,7 +1680,7 @@
}
@Override
- public void onHeightChanged(ExpandableView view) {
+ public void onHeightChanged(ExpandableView view, boolean needsAnimation) {
// Block update if we are in quick settings and just the top padding changed
// (i.e. view == null).
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index e5eb747..f3ec34a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -170,6 +170,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -524,6 +525,8 @@
goToLockedShade(null);
}
};
+ private HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>> mTmpChildOrderMap
+ = new HashMap<>();
@Override
public void start() {
@@ -664,6 +667,8 @@
R.id.notification_stack_scroller);
mStackScroller.setLongPressListener(getNotificationLongClicker());
mStackScroller.setPhoneStatusBar(this);
+ mStackScroller.setGroupManager(mGroupManager);
+ mGroupManager.setOnGroupChangeListener(mStackScroller);
mKeyguardIconOverflowContainer =
(NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
@@ -855,9 +860,20 @@
final ArrayList<View> viewsToHide = new ArrayList<View>(numChildren);
for (int i = 0; i < numChildren; i++) {
final View child = mStackScroller.getChildAt(i);
- if (mStackScroller.canChildBeDismissed(child)) {
- if (child.getVisibility() == View.VISIBLE) {
- viewsToHide.add(child);
+ if (child instanceof ExpandableNotificationRow) {
+ if (mStackScroller.canChildBeDismissed(child)) {
+ if (child.getVisibility() == View.VISIBLE) {
+ viewsToHide.add(child);
+ }
+ }
+ ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+ List<ExpandableNotificationRow> children = row.getNotificationChildren();
+ if (row.areChildrenExpanded() && children != null) {
+ for (ExpandableNotificationRow childRow : children) {
+ if (childRow.getVisibility() == View.VISIBLE) {
+ viewsToHide.add(childRow);
+ }
+ }
}
}
}
@@ -1296,10 +1312,23 @@
ent.row.setShowingLegacyBackground(true);
}
}
- toShow.add(ent.row);
+ if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) {
+ ExpandableNotificationRow summary = mGroupManager.getGroupSummary(
+ ent.row.getStatusBarNotification());
+ List<ExpandableNotificationRow> orderedChildren =
+ mTmpChildOrderMap.get(summary);
+ if (orderedChildren == null) {
+ orderedChildren = new ArrayList<>();
+ mTmpChildOrderMap.put(summary, orderedChildren);
+ }
+ orderedChildren.add(ent.row);
+ } else {
+ toShow.add(ent.row);
+ }
+
}
- ArrayList<View> toRemove = new ArrayList<View>();
+ ArrayList<View> toRemove = new ArrayList<>();
for (int i=0; i< mStackScroller.getChildCount(); i++) {
View child = mStackScroller.getChildAt(i);
if (!toShow.contains(child) && child instanceof ExpandableNotificationRow) {
@@ -1328,17 +1357,22 @@
continue;
}
- if (child == toShow.get(j)) {
- // Everything is well, advance both lists.
- j++;
- continue;
+ ExpandableNotificationRow targetChild = toShow.get(j);
+ if (child != targetChild) {
+ // Oops, wrong notification at this position. Put the right one
+ // here and advance both lists.
+ mStackScroller.changeViewPosition(targetChild, i);
}
-
- // Oops, wrong notification at this position. Put the right one
- // here and advance both lists.
- mStackScroller.changeViewPosition(toShow.get(j), i);
j++;
+
}
+
+ // lets handle the child notifications now
+ updateNotificationShadeForChildren();
+
+ // clear the map again for the next usage
+ mTmpChildOrderMap.clear();
+
updateRowStates();
updateSpeedbump();
updateClearAll();
@@ -1353,6 +1387,52 @@
mShadeUpdates.check();
}
+ private void updateNotificationShadeForChildren() {
+ ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
+ boolean orderChanged = false;
+ for (int i = 0; i < mStackScroller.getChildCount(); i++) {
+ View view = mStackScroller.getChildAt(i);
+ if (!(view instanceof ExpandableNotificationRow)) {
+ // We don't care about non-notification views.
+ continue;
+ }
+
+ ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
+ List<ExpandableNotificationRow> children = parent.getNotificationChildren();
+ List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
+
+ // lets first remove all undesired children
+ if (children != null) {
+ toRemove.clear();
+ for (ExpandableNotificationRow childRow : children) {
+ if (orderedChildren == null || !orderedChildren.contains(childRow)) {
+ toRemove.add(childRow);
+ }
+ }
+ for (ExpandableNotificationRow remove : toRemove) {
+ parent.removeChildNotification(remove);
+ mStackScroller.notifyGroupChildRemoved(remove);
+ }
+ }
+
+ // We now add all the children which are not in there already
+ for (int childIndex = 0; orderedChildren != null && childIndex < orderedChildren.size();
+ childIndex++) {
+ ExpandableNotificationRow childView = orderedChildren.get(childIndex);
+ if (children == null || !children.contains(childView)) {
+ parent.addChildNotification(childView, childIndex);
+ mStackScroller.notifyGroupChildAdded(childView);
+ }
+ }
+
+ // Finally after removing and adding has been beformed we can apply the order.
+ orderChanged |= parent.applyChildOrder(orderedChildren);
+ }
+ if (orderChanged) {
+ mStackScroller.generateChildOrderChangedEvent();
+ }
+ }
+
private boolean packageHasVisibilityOverride(String key) {
return mNotificationData.getVisibilityOverride(key)
!= NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
@@ -1379,6 +1459,10 @@
final int N = activeNotifications.size();
for (int i = 0; i < N; i++) {
Entry entry = activeNotifications.get(i);
+ boolean isChild = !isTopLevelChild(entry);
+ if (isChild) {
+ continue;
+ }
if (entry.row.getVisibility() != View.GONE &&
mNotificationData.isAmbient(entry.key)) {
speedbumpIndex = currentIndex;
@@ -1389,6 +1473,10 @@
mStackScroller.updateSpeedBumpIndex(speedbumpIndex);
}
+ public static boolean isTopLevelChild(Entry entry) {
+ return entry.row.getParent() instanceof NotificationStackScrollLayout;
+ }
+
@Override
protected void updateNotifications() {
mNotificationData.filterAndSort();
@@ -3074,7 +3162,7 @@
mLeaveOpenOnKeyguardHide = false;
if (mDraggedDownRow != null) {
mDraggedDownRow.setUserLocked(false);
- mDraggedDownRow.notifyHeightChanged();
+ mDraggedDownRow.notifyHeightChanged(false /* needsAnimation */);
mDraggedDownRow = null;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 798467f..c49f620 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -158,13 +158,16 @@
final int N = activeNotifications.size();
ArrayList<StatusBarIconView> toShow = new ArrayList<>(N);
- // Filter out ambient notifications.
+ // Filter out ambient notifications and notification children.
for (int i = 0; i < N; i++) {
NotificationData.Entry ent = activeNotifications.get(i);
if (notificationData.isAmbient(ent.key)
&& !NotificationData.showNotificationEvenIfUnprovisioned(ent.notification)) {
continue;
}
+ if (!PhoneStatusBar.isTopLevelChild(ent)) {
+ continue;
+ }
toShow.add(ent.icon);
}