Inline replace notification views when layout changes
Instead of going through a full remove / add when a notification
is updated with a different layout, only re-inflate the inner views.
Bug: 15869868
Change-Id: Ie18c431e7b3e2a6209d4a9b6418b3150781a063f
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 17757ff..df3e25d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -897,15 +897,15 @@
protected void onShowSearchPanel() {
}
- public boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
+ private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
return inflateViews(entry, parent, false);
}
- public boolean inflateViewsForHeadsUp(NotificationData.Entry entry, ViewGroup parent) {
+ protected boolean inflateViewsForHeadsUp(NotificationData.Entry entry, ViewGroup parent) {
return inflateViews(entry, parent, true);
}
- public boolean inflateViews(NotificationData.Entry entry, ViewGroup parent, boolean isHeadsUp) {
+ private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent, boolean isHeadsUp) {
int maxHeight = mRowMaxHeight;
StatusBarNotification sbn = entry.notification;
RemoteViews contentView = sbn.getNotification().contentView;
@@ -927,11 +927,30 @@
Notification publicNotification = sbn.getNotification().publicVersion;
- // create the row view
- LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- ExpandableNotificationRow row = (ExpandableNotificationRow) inflater.inflate(
- R.layout.status_bar_notification_row, parent, false);
+ ExpandableNotificationRow row;
+
+ // Stash away previous user expansion state so we can restore it at
+ // the end.
+ boolean hasUserChangedExpansion = false;
+ boolean userExpanded = false;
+ boolean userLocked = false;
+
+ if (entry.row != null) {
+ row = entry.row;
+ hasUserChangedExpansion = row.hasUserChangedExpansion();
+ userExpanded = row.isUserExpanded();
+ userLocked = row.isUserLocked();
+ row.reset();
+ if (hasUserChangedExpansion) {
+ row.setUserExpanded(userExpanded);
+ }
+ } else {
+ // create the row view
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ row = (ExpandableNotificationRow) inflater.inflate(R.layout.status_bar_notification_row,
+ parent, false);
+ }
// for blaming (see SwipeHelper.setLongPressListener)
row.setTag(sbn.getPackageName());
@@ -1077,6 +1096,14 @@
applyLegacyRowBackground(sbn, entry);
+ // Restore previous flags.
+ if (hasUserChangedExpansion) {
+ // Note: setUserExpanded() conveniently ignores calls with
+ // userExpanded=true if !isExpandable().
+ row.setUserExpanded(userExpanded);
+ }
+ row.setUserLocked(userLocked);
+
return true;
}
@@ -1317,12 +1344,13 @@
RankingMap ranking);
protected abstract void updateNotificationRanking(RankingMap ranking);
public abstract void removeNotification(String key, RankingMap ranking);
+
public void updateNotification(StatusBarNotification notification, RankingMap ranking) {
if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")");
final String key = notification.getKey();
boolean wasHeadsUp = isHeadsUp(key);
- NotificationData.Entry oldEntry;
+ Entry oldEntry;
if (wasHeadsUp) {
oldEntry = mHeadsUpNotificationView.getEntry();
} else {
@@ -1363,8 +1391,7 @@
+ " publicView=" + publicContentView);
}
- // Can we just reapply the RemoteViews in place? If when didn't change, the order
- // didn't change.
+ // Can we just reapply the RemoteViews in place?
// 1U is never null
boolean contentsUnchanged = oldEntry.expanded != null
@@ -1477,15 +1504,9 @@
addNotification(notification, ranking); //this will pop the headsup
} else {
if (DEBUG) Log.d(TAG, "rebuilding update in place for key: " + key);
- removeNotificationViews(key, ranking);
- addNotificationViews(notification, ranking);
- final NotificationData.Entry newEntry = mNotificationData.findByKey(key);
- final boolean userChangedExpansion = oldEntry.row.hasUserChangedExpansion();
- if (userChangedExpansion) {
- boolean userExpanded = oldEntry.row.isUserExpanded();
- newEntry.row.setUserExpanded(userExpanded);
- newEntry.row.notifyHeightChanged();
- }
+ oldEntry.notification = notification;
+ inflateViews(oldEntry, mStackScroller, wasHeadsUp);
+ updateNotifications();
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index c6000af..280bade 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -58,6 +58,23 @@
super(context, attrs);
}
+ /**
+ * Resets this view so it can be re-used for an updated notification.
+ */
+ public void reset() {
+ mRowMinHeight = 0;
+ mRowMaxHeight = 0;
+ mExpandable = false;
+ mHasUserChangedExpansion = false;
+ mUserLocked = false;
+ mShowingPublic = false;
+ mIsSystemExpanded = false;
+ mExpansionDisabled = false;
+ mPublicLayout.reset();
+ mPrivateLayout.reset();
+ mMaxExpandHeight = 0;
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@@ -110,6 +127,7 @@
* @param userExpanded whether the user wants this notification to be expanded
*/
public void setUserExpanded(boolean userExpanded) {
+ if (userExpanded && !mExpandable) return;
mHasUserChangedExpansion = true;
mUserExpanded = userExpanded;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index f919501..f3aba0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -51,13 +51,12 @@
private boolean mContractedVisible = true;
- private Paint mFadePaint = new Paint();
+ private final Paint mFadePaint = new Paint();
public NotificationContentView(Context context, AttributeSet attrs) {
super(context, attrs);
- mSmallHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
- mActualHeight = mSmallHeight;
mFadePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD));
+ reset();
}
@Override
@@ -66,6 +65,15 @@
updateClipping();
}
+ public void reset() {
+ removeAllViews();
+ mContractedChild = null;
+ mExpandedChild = null;
+ mSmallHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
+ mActualHeight = mSmallHeight;
+ mContractedVisible = true;
+ }
+
public void setContractedChild(View child) {
if (mContractedChild != null) {
removeView(mContractedChild);