diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index e40247ba2d9a6..2bf5368b691ba 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -4888,12 +4888,6 @@ public class Notification implements Parcelable mN.mUsesStandardHeader = false; } - private RemoteViews applyStandardTemplate(int resId, int viewType, - TemplateBindResult result) { - return applyStandardTemplate(resId, - mParams.reset().viewType(viewType).fillTextsFrom(this), result); - } - private RemoteViews applyStandardTemplate(int resId, StandardTemplateParams p, TemplateBindResult result) { p.headerless(resId == getBaseLayoutResource() @@ -4907,7 +4901,7 @@ public class Notification implements Parcelable bindNotificationHeader(contentView, p); bindLargeIconAndApplyMargin(contentView, p, result); boolean showProgress = handleProgressBar(contentView, ex, p); - if (p.title != null && p.title.length() > 0) { + if (p.title != null && p.title.length() > 0 && !p.mHasCustomContent) { contentView.setViewVisibility(R.id.title, View.VISIBLE); contentView.setTextViewText(R.id.title, processTextSpans(p.title)); setTextViewColorPrimary(contentView, R.id.title, p); @@ -5302,6 +5296,12 @@ public class Notification implements Parcelable contentView.setViewVisibility(R.id.app_name_text, View.GONE); return false; } + if (p.mHeaderless && !p.mHasCustomContent) { + 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; + } contentView.setViewVisibility(R.id.app_name_text, View.VISIBLE); contentView.setTextViewText(R.id.app_name_text, loadHeaderAppName()); if (isColorized(p)) { @@ -5356,12 +5356,6 @@ public class Notification implements Parcelable snoozeEnabled ? 0 : R.dimen.notification_content_margin); } - private RemoteViews applyStandardTemplateWithActions(int layoutId, int viewType, - TemplateBindResult result) { - return applyStandardTemplateWithActions(layoutId, - mParams.reset().viewType(viewType).fillTextsFrom(this), result); - } - private static List filterOutContextualActions( List actions) { List nonContextualActions = new ArrayList<>(); @@ -5499,8 +5493,10 @@ public class Notification implements Parcelable return styleView; } } - return applyStandardTemplate(getBaseLayoutResource(), - StandardTemplateParams.VIEW_TYPE_NORMAL, null /* result */); + StandardTemplateParams p = mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_NORMAL) + .fillTextsFrom(this); + return applyStandardTemplate(getBaseLayoutResource(), p, null /* result */); } private boolean useExistingRemoteView() { @@ -5520,14 +5516,27 @@ public class Notification implements Parcelable result = mStyle.makeBigContentView(); hideLine1Text(result); } - if (result == null) { - result = applyStandardTemplateWithActions(getBigBaseLayoutResource(), - StandardTemplateParams.VIEW_TYPE_BIG, null /* result */); + if (result == null && bigContentViewRequired()) { + StandardTemplateParams p = mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_BIG) + .fillTextsFrom(this); + result = applyStandardTemplateWithActions(getBigBaseLayoutResource(), p, + null /* result */); } makeHeaderExpanded(result); return result; } + private boolean bigContentViewRequired() { + // If the big content view has no content, we can exempt the app from having to show it. + // TODO(b/173550917): add an UNDO style then force this requirement on apps targeting S + boolean exempt = mN.contentView != null && mN.bigContentView == null + && mStyle == null && mActions.size() == 0 + && mN.extras.getCharSequence(EXTRA_TITLE) == null + && mN.extras.getCharSequence(EXTRA_TEXT) == null; + return !exempt; + } + /** * Construct a RemoteViews for the final notification header only. This will not be * colorized. @@ -8693,18 +8702,24 @@ public class Notification implements Parcelable return makeStandardTemplateWithCustomContent(headsUpContentView); } TemplateBindResult result = new TemplateBindResult(); + StandardTemplateParams p = mBuilder.mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_HEADS_UP) + .hasCustomContent(headsUpContentView != null) + .fillTextsFrom(mBuilder); RemoteViews remoteViews = mBuilder.applyStandardTemplateWithActions( - mBuilder.getHeadsUpBaseLayoutResource(), - StandardTemplateParams.VIEW_TYPE_HEADS_UP, result); + mBuilder.getHeadsUpBaseLayoutResource(), p, result); buildIntoRemoteViewContent(remoteViews, headsUpContentView, result, true); return remoteViews; } private RemoteViews makeStandardTemplateWithCustomContent(RemoteViews customContent) { TemplateBindResult result = new TemplateBindResult(); + StandardTemplateParams p = mBuilder.mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_NORMAL) + .hasCustomContent(customContent != null) + .fillTextsFrom(mBuilder); RemoteViews remoteViews = mBuilder.applyStandardTemplate( - mBuilder.getBaseLayoutResource(), - StandardTemplateParams.VIEW_TYPE_NORMAL, result); + mBuilder.getBaseLayoutResource(), p, result); buildIntoRemoteViewContent(remoteViews, customContent, result, true); return remoteViews; } @@ -8714,9 +8729,12 @@ public class Notification implements Parcelable ? mBuilder.mN.contentView : mBuilder.mN.bigContentView; TemplateBindResult result = new TemplateBindResult(); + StandardTemplateParams p = mBuilder.mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_BIG) + .hasCustomContent(bigContentView != null) + .fillTextsFrom(mBuilder); RemoteViews remoteViews = mBuilder.applyStandardTemplateWithActions( - mBuilder.getBigBaseLayoutResource(), - StandardTemplateParams.VIEW_TYPE_BIG, result); + mBuilder.getBigBaseLayoutResource(), p, result); buildIntoRemoteViewContent(remoteViews, bigContentView, result, false); return remoteViews; } @@ -11029,6 +11047,7 @@ public class Notification implements Parcelable int mViewType = VIEW_TYPE_UNSPECIFIED; boolean mHeaderless; + boolean mHasCustomContent; boolean hasProgress = true; CharSequence title; CharSequence text; @@ -11042,6 +11061,7 @@ public class Notification implements Parcelable final StandardTemplateParams reset() { mViewType = VIEW_TYPE_UNSPECIFIED; mHeaderless = false; + mHasCustomContent = false; hasProgress = true; title = null; text = null; @@ -11068,6 +11088,11 @@ public class Notification implements Parcelable return this; } + final StandardTemplateParams hasCustomContent(boolean hasCustomContent) { + this.mHasCustomContent = hasCustomContent; + return this; + } + final StandardTemplateParams title(CharSequence title) { this.title = title; return this; diff --git a/core/res/res/layout/notification_material_action_list.xml b/core/res/res/layout/notification_material_action_list.xml index 552a1bd6aa2ee..9662b8e35bf68 100644 --- a/core/res/res/layout/notification_material_action_list.xml +++ b/core/res/res/layout/notification_material_action_list.xml @@ -28,7 +28,6 @@ android:layout_height="wrap_content" android:gravity="end" android:orientation="horizontal" - android:paddingEnd="@dimen/bubble_gone_padding_end" android:background="@color/notification_action_list_background_color" > @@ -45,22 +44,34 @@ - + + + - + + diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml index a26473ad60102..4b67509db457e 100644 --- a/core/res/res/layout/notification_template_header.xml +++ b/core/res/res/layout/notification_template_header.xml @@ -50,16 +50,6 @@ android:theme="@style/Theme.DeviceDefault.Notification" > - - diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml index ded16b7edf87b..9d581729df722 100644 --- a/core/res/res/layout/notification_template_material_base.xml +++ b/core/res/res/layout/notification_template_material_base.xml @@ -68,6 +68,12 @@ android:theme="@style/Theme.DeviceDefault.Notification" > + + diff --git a/core/res/res/layout/notification_top_line_views.xml b/core/res/res/layout/notification_top_line_views.xml index 51974ac7dcf31..c71e8863502c2 100644 --- a/core/res/res/layout/notification_top_line_views.xml +++ b/core/res/res/layout/notification_top_line_views.xml @@ -14,12 +14,22 @@ ~ limitations under the License --> + + 8dp - - 3dp - - - 12dp + + 12dp 6dp @@ -744,6 +741,9 @@ 80dp 18dp + + 13dp 36dp diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 752bb5b37a30a..6e19290d97603 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3560,8 +3560,6 @@ - - diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java index 216b83f2b4d52..84818eea8a230 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java @@ -41,6 +41,7 @@ import java.util.Objects; public class NotificationHeaderUtil { private static final TextViewComparator sTextViewComparator = new TextViewComparator(); + private static final TextViewComparator sAppNameComparator = new AppNameComparator(); private static final VisibilityApplicator sVisibilityApplicator = new VisibilityApplicator(); private static final VisibilityApplicator sAppNameApplicator = new AppNameApplicator(); private static final DataExtractor sIconExtractor = new DataExtractor() { @@ -119,7 +120,7 @@ public class NotificationHeaderUtil { mRow, com.android.internal.R.id.app_name_text, null, - sTextViewComparator, + sAppNameComparator, sAppNameApplicator)); mComparators.add(HeaderProcessor.forTextView(mRow, com.android.internal.R.id.header_text)); @@ -389,4 +390,17 @@ public class NotificationHeaderUtil { super.apply(parent, view, apply, reset); } } + + private static class AppNameComparator extends TextViewComparator { + @Override + public boolean compare(View parent, View child, Object parentData, Object childData) { + if (isEmpty(child)) { + // In headerless notifications the AppName view exists but is usually GONE (and not + // populated). We need to treat this case as equal to the header in order to + // deduplicate the view. + return true; + } + return super.compare(parent, child, parentData, childData); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java index 328774550f243..74e6c003041e9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java @@ -1369,16 +1369,8 @@ public class NotificationContentView extends FrameLayout { bubbleButton.setOnClickListener(mContainingNotification.getBubbleClickListener()); bubbleButton.setVisibility(VISIBLE); actionContainer.setVisibility(VISIBLE); - - int paddingEnd = getResources().getDimensionPixelSize( - com.android.internal.R.dimen.bubble_visible_padding_end); - actionContainerLayout.setPaddingRelative(0, 0, paddingEnd, 0); } else { bubbleButton.setVisibility(GONE); - - int paddingEnd = getResources().getDimensionPixelSize( - com.android.internal.R.dimen.bubble_gone_padding_end); - actionContainerLayout.setPaddingRelative(0, 0, paddingEnd, 0); } }