diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 2b45723dae557..b31048cafbd72 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5011,9 +5011,13 @@ public class Notification implements Parcelable
boolean showProgress = handleProgressBar(contentView, ex, p);
boolean hasSecondLine = showProgress;
if (p.hasTitle()) {
- contentView.setViewVisibility(R.id.title, View.VISIBLE);
- contentView.setTextViewText(R.id.title, processTextSpans(p.title));
- setTextViewColorPrimary(contentView, R.id.title, p);
+ contentView.setViewVisibility(p.mTitleViewId, View.VISIBLE);
+ contentView.setTextViewText(p.mTitleViewId, processTextSpans(p.title));
+ setTextViewColorPrimary(contentView, p.mTitleViewId, p);
+ } else if (p.mTitleViewId != R.id.title) {
+ // This alternate title view ID is not cleared by resetStandardTemplate
+ contentView.setViewVisibility(p.mTitleViewId, View.GONE);
+ contentView.setTextViewText(p.mTitleViewId, null);
}
if (p.text != null && p.text.length() != 0
&& (!showProgress || p.mAllowTextWithProgress)) {
@@ -5441,6 +5445,11 @@ public class Notification implements Parcelable
// keep the divider visible between that title and the next text element.
return true;
}
+ if (p.mHideAppName) {
+ // The app name is being hidden, so we definitely want to return here.
+ // Assume that there is a title which will replace it in the header.
+ return p.hasTitle();
+ }
contentView.setViewVisibility(R.id.app_name_text, View.VISIBLE);
contentView.setTextViewText(R.id.app_name_text, loadHeaderAppName());
contentView.setTextColor(R.id.app_name_text, getSecondaryTextColor(p));
@@ -5817,7 +5826,7 @@ public class Notification implements Parcelable
*
* @hide
*/
- public RemoteViews makeNotificationHeader() {
+ public RemoteViews makeNotificationGroupHeader() {
return makeNotificationHeader(mParams.reset()
.viewType(StandardTemplateParams.VIEW_TYPE_GROUP_HEADER)
.fillTextsFrom(this));
@@ -6583,10 +6592,6 @@ public class Notification implements Parcelable
return R.layout.notification_template_material_conversation;
}
- private int getCallLayoutResource() {
- return R.layout.notification_template_material_call;
- }
-
private int getActionLayoutResource() {
return R.layout.notification_material_action;
}
@@ -9329,7 +9334,7 @@ public class Notification implements Parcelable
*/
@Override
public RemoteViews makeContentView(boolean increasedHeight) {
- return makeCallLayout();
+ return makeCallLayout(StandardTemplateParams.VIEW_TYPE_NORMAL);
}
/**
@@ -9337,14 +9342,14 @@ public class Notification implements Parcelable
*/
@Override
public RemoteViews makeHeadsUpContentView(boolean increasedHeight) {
- return makeCallLayout();
+ return makeCallLayout(StandardTemplateParams.VIEW_TYPE_HEADS_UP);
}
/**
* @hide
*/
public RemoteViews makeBigContentView() {
- return makeCallLayout();
+ return makeCallLayout(StandardTemplateParams.VIEW_TYPE_BIG);
}
@NonNull
@@ -9443,8 +9448,10 @@ public class Notification implements Parcelable
return resultActions;
}
- private RemoteViews makeCallLayout() {
+ private RemoteViews makeCallLayout(int viewType) {
+ final boolean isCollapsed = viewType == StandardTemplateParams.VIEW_TYPE_NORMAL;
Bundle extras = mBuilder.mN.extras;
+ CharSequence title = mPerson != null ? mPerson.getName() : null;
CharSequence text = mBuilder.processLegacyText(extras.getCharSequence(EXTRA_TEXT));
if (text == null) {
text = getDefaultText();
@@ -9452,20 +9459,30 @@ public class Notification implements Parcelable
// Bind standard template
StandardTemplateParams p = mBuilder.mParams.reset()
- .viewType(StandardTemplateParams.VIEW_TYPE_BIG)
+ .viewType(viewType)
.callStyleActions(true)
.allowTextWithProgress(true)
.hideLargeIcon(true)
+ .hideAppName(isCollapsed)
+ .titleViewId(R.id.conversation_text)
+ .title(title)
.text(text)
.summaryText(mBuilder.processLegacyText(mVerificationText));
mBuilder.mActions = getActionsListWithSystemActions();
- RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(
- mBuilder.getCallLayoutResource(), p, null /* result */);
+ final RemoteViews contentView;
+ if (isCollapsed) {
+ contentView = mBuilder.applyStandardTemplate(
+ R.layout.notification_template_material_call, p, null /* result */);
+ } else {
+ contentView = mBuilder.applyStandardTemplateWithActions(
+ R.layout.notification_template_material_big_call, p, null /* result */);
+ }
// Bind some extra conversation-specific header fields.
- mBuilder.setTextViewColorPrimary(contentView, R.id.conversation_text, p);
- mBuilder.setTextViewColorSecondary(contentView, R.id.app_name_divider, p);
- contentView.setViewVisibility(R.id.app_name_divider, View.VISIBLE);
+ if (!p.mHideAppName) {
+ mBuilder.setTextViewColorSecondary(contentView, R.id.app_name_divider, p);
+ contentView.setViewVisibility(R.id.app_name_divider, View.VISIBLE);
+ }
bindCallerVerification(contentView, p);
// Bind some custom CallLayout properties
@@ -12142,12 +12159,13 @@ public class Notification implements Parcelable
public static int VIEW_TYPE_NORMAL = 1;
public static int VIEW_TYPE_BIG = 2;
public static int VIEW_TYPE_HEADS_UP = 3;
- public static int VIEW_TYPE_MINIMIZED = 4;
- public static int VIEW_TYPE_PUBLIC = 5;
- public static int VIEW_TYPE_GROUP_HEADER = 6;
+ public static int VIEW_TYPE_MINIMIZED = 4; // header only for minimized state
+ public static int VIEW_TYPE_PUBLIC = 5; // header only for automatic public version
+ public static int VIEW_TYPE_GROUP_HEADER = 6; // header only for top of group
int mViewType = VIEW_TYPE_UNSPECIFIED;
boolean mHeaderless;
+ boolean mHideAppName;
boolean mHideTitle;
boolean mHideActions;
boolean mHideProgress;
@@ -12155,6 +12173,7 @@ public class Notification implements Parcelable
boolean mPromotePicture;
boolean mCallStyleActions;
boolean mAllowTextWithProgress;
+ int mTitleViewId;
int mTextViewId;
CharSequence title;
CharSequence text;
@@ -12168,6 +12187,7 @@ public class Notification implements Parcelable
final StandardTemplateParams reset() {
mViewType = VIEW_TYPE_UNSPECIFIED;
mHeaderless = false;
+ mHideAppName = false;
mHideTitle = false;
mHideActions = false;
mHideProgress = false;
@@ -12175,6 +12195,7 @@ public class Notification implements Parcelable
mPromotePicture = false;
mCallStyleActions = false;
mAllowTextWithProgress = false;
+ mTitleViewId = R.id.title;
mTextViewId = R.id.text;
title = null;
text = null;
@@ -12200,6 +12221,11 @@ public class Notification implements Parcelable
return this;
}
+ public StandardTemplateParams hideAppName(boolean hideAppName) {
+ mHideAppName = hideAppName;
+ return this;
+ }
+
final StandardTemplateParams hideActions(boolean hideActions) {
this.mHideActions = hideActions;
return this;
@@ -12235,6 +12261,11 @@ public class Notification implements Parcelable
return this;
}
+ public StandardTemplateParams titleViewId(int titleViewId) {
+ mTitleViewId = titleViewId;
+ return this;
+ }
+
public StandardTemplateParams textViewId(int textViewId) {
mTextViewId = textViewId;
return this;
diff --git a/core/java/com/android/internal/widget/CallLayout.java b/core/java/com/android/internal/widget/CallLayout.java
index 6cc5a4aacda59..83345dad8ed9a 100644
--- a/core/java/com/android/internal/widget/CallLayout.java
+++ b/core/java/com/android/internal/widget/CallLayout.java
@@ -100,7 +100,6 @@ public class CallLayout extends FrameLayout {
}
// TODO(b/179178086): crop/clip the icon to a circle?
mConversationIconView.setImageIcon(icon);
- mConversationText.setText(callerName);
}
@RemotableViewMethod
diff --git a/core/res/res/layout/notification_template_material_big_base.xml b/core/res/res/layout/notification_template_material_big_base.xml
index 2d1c3422ca368..b9a3625f9e452 100644
--- a/core/res/res/layout/notification_template_material_big_base.xml
+++ b/core/res/res/layout/notification_template_material_big_base.xml
@@ -27,7 +27,7 @@
android:id="@+id/notification_action_list_margin_target"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/notification_action_list_height"
+ android:layout_marginBottom="@dimen/notification_content_margin"
android:orientation="vertical"
>
diff --git a/core/res/res/layout/notification_template_material_big_call.xml b/core/res/res/layout/notification_template_material_big_call.xml
new file mode 100644
index 0000000000000..1d5046777e77e
--- /dev/null
+++ b/core/res/res/layout/notification_template_material_big_call.xml
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/res/res/layout/notification_template_material_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml
index 2954ba2a09033..86e7dec29e7df 100644
--- a/core/res/res/layout/notification_template_material_big_text.xml
+++ b/core/res/res/layout/notification_template_material_big_text.xml
@@ -31,7 +31,7 @@
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginTop="@dimen/notification_content_margin_top"
- android:layout_marginBottom="@dimen/notification_action_list_height"
+ android:layout_marginBottom="@dimen/notification_content_margin"
android:clipToPadding="false"
android:orientation="vertical"
>
diff --git a/core/res/res/layout/notification_template_material_call.xml b/core/res/res/layout/notification_template_material_call.xml
index 7b52ec30abe64..5d9e761842d84 100644
--- a/core/res/res/layout/notification_template_material_call.xml
+++ b/core/res/res/layout/notification_template_material_call.xml
@@ -1,5 +1,4 @@
-
-
-
+
+
-
+
+
+
+
+
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5a7b1faf36b25..7ccdb7192f178 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3115,6 +3115,7 @@
+
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 d3065aa36a5fa..8c21e767c5c95 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
@@ -349,7 +349,9 @@ public class NotificationContentView extends FrameLayout {
invalidateOutline();
selectLayout(false /* animate */, mForceSelectNextLayout /* force */);
mForceSelectNextLayout = false;
- updateExpandButtons(mExpandable);
+ // TODO(b/182314698): move this to onMeasure. This requires switching to getMeasuredHeight,
+ // and also requires revisiting all of the logic called earlier in this method.
+ updateExpandButtonsDuringLayout(mExpandable, true /* duringLayout */);
}
@Override
@@ -1344,9 +1346,7 @@ public class NotificationContentView extends FrameLayout {
}
ImageView bubbleButton = layout.findViewById(com.android.internal.R.id.bubble_button);
View actionContainer = layout.findViewById(com.android.internal.R.id.actions_container);
- LinearLayout actionContainerLayout =
- layout.findViewById(com.android.internal.R.id.actions_container_layout);
- if (bubbleButton == null || actionContainer == null || actionContainerLayout == null) {
+ if (bubbleButton == null || actionContainer == null) {
return;
}
boolean isPersonWithShortcut =
@@ -1589,6 +1589,10 @@ public class NotificationContentView extends FrameLayout {
}
public void updateExpandButtons(boolean expandable) {
+ updateExpandButtonsDuringLayout(expandable, false /* duringLayout */);
+ }
+
+ private void updateExpandButtonsDuringLayout(boolean expandable, boolean duringLayout) {
mExpandable = expandable;
// if the expanded child has the same height as the collapsed one we hide it.
if (mExpandedChild != null && mExpandedChild.getHeight() != 0) {
@@ -1602,14 +1606,15 @@ public class NotificationContentView extends FrameLayout {
expandable = false;
}
}
+ boolean requestLayout = duringLayout && mIsContentExpandable != expandable;
if (mExpandedChild != null) {
- mExpandedWrapper.updateExpandability(expandable, mExpandClickListener);
+ mExpandedWrapper.updateExpandability(expandable, mExpandClickListener, requestLayout);
}
if (mContractedChild != null) {
- mContractedWrapper.updateExpandability(expandable, mExpandClickListener);
+ mContractedWrapper.updateExpandability(expandable, mExpandClickListener, requestLayout);
}
if (mHeadsUpChild != null) {
- mHeadsUpWrapper.updateExpandability(expandable, mExpandClickListener);
+ mHeadsUpWrapper.updateExpandability(expandable, mExpandClickListener, requestLayout);
}
mIsContentExpandable = expandable;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
index fb0fdcccd4b13..383bb7e41a913 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
@@ -147,8 +147,11 @@ class NotificationConversationTemplateViewWrapper constructor(
override fun setRemoteInputVisible(visible: Boolean) =
conversationLayout.showHistoricMessages(visible)
- override fun updateExpandability(expandable: Boolean, onClickListener: View.OnClickListener?) =
- conversationLayout.updateExpandability(expandable, onClickListener)
+ override fun updateExpandability(
+ expandable: Boolean,
+ onClickListener: View.OnClickListener,
+ requestLayout: Boolean
+ ) = conversationLayout.updateExpandability(expandable, onClickListener)
override fun disallowSingleClick(x: Float, y: Float): Boolean {
val isOnExpandButton = expandBtnContainer.visibility == View.VISIBLE &&
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index bdafd232167d1..5a55545351d0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -261,7 +261,8 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
}
@Override
- public void updateExpandability(boolean expandable, View.OnClickListener onClickListener) {
+ public void updateExpandability(boolean expandable, View.OnClickListener onClickListener,
+ boolean requestLayout) {
mExpandButton.setVisibility(expandable ? View.VISIBLE : View.GONE);
mExpandButton.setOnClickListener(expandable ? onClickListener : null);
if (mAltExpandTarget != null) {
@@ -273,6 +274,13 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
if (mNotificationHeader != null) {
mNotificationHeader.setOnClickListener(expandable ? onClickListener : null);
}
+ // Unfortunately, the NotificationContentView has to layout its children in order to
+ // determine their heights, and that affects the button visibility. If that happens
+ // (thankfully it is rare) then we need to request layout of the expand button's parent
+ // in order to ensure it gets laid out correctly.
+ if (requestLayout) {
+ mExpandButton.getParent().requestLayout();
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
index 9ced12d32d27a..3a7b4618ad221 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
@@ -291,8 +291,10 @@ public abstract class NotificationViewWrapper implements TransformableView {
*
* @param expandable should this view be expandable
* @param onClickListener the listener to invoke when the expand affordance is clicked on
+ * @param requestLayout the expandability changed during onLayout, so a requestLayout required
*/
- public void updateExpandability(boolean expandable, View.OnClickListener onClickListener) {}
+ public void updateExpandability(boolean expandable, View.OnClickListener onClickListener,
+ boolean requestLayout) {}
/** Set the expanded state on the view wrapper */
public void setExpanded(boolean expanded) {}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index f65ae0c393316..1d307364d6615 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -324,7 +324,7 @@ public class NotificationChildrenContainer extends ViewGroup {
StatusBarNotification notification = mContainingNotification.getEntry().getSbn();
final Notification.Builder builder = Notification.Builder.recoverBuilder(getContext(),
notification.getNotification());
- RemoteViews header = builder.makeNotificationHeader();
+ RemoteViews header = builder.makeNotificationGroupHeader();
if (mNotificationHeader == null) {
mNotificationHeader = (NotificationHeaderView) header.apply(getContext(), this);
mNotificationHeader.findViewById(com.android.internal.R.id.expand_button)