From 8610de5c2661565121c4f60c1f05288f0ee5d30c Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Mon, 30 Nov 2020 14:51:38 -0500 Subject: [PATCH 1/2] Fix NPE that can occur on uiMode change if a group has a single child. Note that the ternary null check inside init is not necessary given the other change, but seems prudent. Fixes: 173777455 Fixes: 173650635 Test: manual -- use go/notify-apk to post a group of 2, dismiss 1, change font size. Observe SystemUI no longer crashes. Change-Id: I71a820a1ed2ac7ec71c4d9f78855ff264c5d5051 --- .../systemui/statusbar/NotificationGroupingUtil.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java index 0e6bcc58b7c0c..dbee0ee8f5d56 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java @@ -129,7 +129,7 @@ public class NotificationGroupingUtil { */ public void updateChildrenAppearance() { List notificationChildren = mRow.getAttachedChildren(); - if (notificationChildren == null) { + if (notificationChildren == null || !mRow.isSummaryWithChildren()) { return; } // Initialize the processors @@ -256,8 +256,8 @@ public class NotificationGroupingUtil { } public void init() { - mParentView = mParentRow.getNotificationViewWrapper().getNotificationHeader() - .findViewById(mId); + View header = mParentRow.getNotificationViewWrapper().getNotificationHeader(); + mParentView = header == null ? null : header.findViewById(mId); mParentData = mExtractor == null ? null : mExtractor.extractData(mParentRow); mApply = !mComparator.isEmpty(mParentView); } From 6ab1c6488eb0635eab8c7165c36ae38829cc090f Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Mon, 30 Nov 2020 14:12:39 -0500 Subject: [PATCH 2/2] Header population cleanup * Show the app name for minimized notifications without titles. * Don't show the summary separator when the summary text is an empty string. * Use TextUtils.isEmpty for clarity & add comment. * Make visibility reset of app_name_text consistent with others. Bug: 163626038 Test: manual Change-Id: I682a8054abb80f24044a2a9c204dfadd5e940860 --- core/java/android/app/Notification.java | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index d5572bf130c14..d5977e7711fdd 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -4874,6 +4874,7 @@ public class Notification implements Parcelable // Small icon doesn't need to be reset, as it's always set. Resetting would prevent // re-using the drawable when the notification is updated. contentView.setBoolean(R.id.expand_button, "setExpanded", false); + contentView.setViewVisibility(R.id.app_name_text, View.GONE); contentView.setTextViewText(R.id.app_name_text, null); contentView.setViewVisibility(R.id.chronometer, View.GONE); contentView.setViewVisibility(R.id.header_text, View.GONE); @@ -5150,9 +5151,14 @@ public class Notification implements Parcelable private void bindNotificationHeader(RemoteViews contentView, StandardTemplateParams p) { bindSmallIcon(contentView, p); - boolean hasTextToLeft = bindHeaderAppName(contentView, p); + // Populate text left-to-right so that separators are only shown between strings + boolean hasTextToLeft = bindHeaderAppName(contentView, p, false /* force */); hasTextToLeft |= bindHeaderTextSecondary(contentView, p, hasTextToLeft); hasTextToLeft |= bindHeaderText(contentView, p, hasTextToLeft); + if (!hasTextToLeft) { + // If there's still no text, force add the app name so there is some text. + hasTextToLeft |= bindHeaderAppName(contentView, p, true /* force */); + } bindHeaderChronometerAndTime(contentView, p, hasTextToLeft); bindProfileBadge(contentView, p); bindAlertedIcon(contentView, p); @@ -5216,7 +5222,7 @@ public class Notification implements Parcelable && mN.extras.getCharSequence(EXTRA_INFO_TEXT) != null) { summaryText = mN.extras.getCharSequence(EXTRA_INFO_TEXT); } - if (summaryText != null) { + if (!TextUtils.isEmpty(summaryText)) { // TODO: Remove the span entirely to only have the string with propper formating. contentView.setTextViewText(R.id.header_text, processTextSpans( processLegacyText(summaryText))); @@ -5288,13 +5294,13 @@ public class Notification implements Parcelable /** * @return true if the app name will be visible */ - private boolean bindHeaderAppName(RemoteViews contentView, StandardTemplateParams p) { - if (p.mViewType == StandardTemplateParams.VIEW_TYPE_MINIMIZED) { - contentView.setViewVisibility(R.id.app_name_text, View.GONE); + private boolean bindHeaderAppName(RemoteViews contentView, StandardTemplateParams p, + boolean force) { + if (p.mViewType == StandardTemplateParams.VIEW_TYPE_MINIMIZED && !force) { + // unless the force flag is set, don't show the app name in the minimized state. return false; } if (p.mHeaderless && p.hasTitle()) { - contentView.setViewVisibility(R.id.app_name_text, View.GONE); // the headerless template will have the TITLE in this position; return true to // keep the divider visible between that title and the next text element. return true; @@ -11104,7 +11110,9 @@ public class Notification implements Parcelable } final boolean hasTitle() { - return title != null && title.length() != 0 && !mHasCustomContent; + // We hide the title when the notification is a decorated custom view so that decorated + // custom views always have to include their own title. + return !TextUtils.isEmpty(title) && !mHasCustomContent; } final StandardTemplateParams viewType(int viewType) {