diff options
12 files changed, 215 insertions, 73 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 2b45723dae55..b31048cafbd7 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 6cc5a4aacda5..83345dad8ed9 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 2d1c3422ca36..b9a3625f9e45 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 000000000000..1d5046777e77 --- /dev/null +++ b/core/res/res/layout/notification_template_material_big_call.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<com.android.internal.widget.CallLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/status_bar_latest_event_content" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:clipChildren="false" + android:tag="call" + android:theme="@style/Theme.DeviceDefault.Notification" + > + + <!-- CallLayout shares visual appearance with ConversationLayout, so shares layouts --> + <include layout="@layout/notification_template_conversation_icon_container" /> + + <LinearLayout + android:id="@+id/notification_action_list_margin_target" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/notification_content_margin" + android:orientation="vertical" + > + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_weight="1" + android:orientation="horizontal" + > + + <LinearLayout + android:id="@+id/notification_main_column" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_marginStart="@dimen/conversation_content_start" + android:orientation="vertical" + android:minHeight="68dp" + > + + <include + layout="@layout/notification_template_conversation_header" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + /> + + <include layout="@layout/notification_template_text_multiline" /> + + <include + android:layout_width="match_parent" + android:layout_height="@dimen/notification_progress_bar_height" + android:layout_marginTop="@dimen/notification_progress_margin_top" + layout="@layout/notification_template_progress" + /> + </LinearLayout> + + <FrameLayout + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:minWidth="@dimen/notification_content_margin_end" + > + + <include + layout="@layout/notification_expand_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + /> + + </FrameLayout> + + </LinearLayout> + + <ViewStub + android:layout="@layout/notification_material_reply_text" + android:id="@+id/notification_material_reply_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + /> + + <include + layout="@layout/notification_template_smart_reply_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/notification_content_margin_start" + android:layout_marginEnd="@dimen/notification_content_margin_end" + android:layout_marginTop="@dimen/notification_content_margin" + /> + + <include layout="@layout/notification_material_action_list" /> + + </LinearLayout> + +</com.android.internal.widget.CallLayout> 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 2954ba2a0903..86e7dec29e7d 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 7b52ec30abe6..5d9e761842d8 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 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright (C) 2021 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,7 +18,6 @@ android:id="@+id/status_bar_latest_event_content" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" android:clipChildren="false" android:tag="call" android:theme="@style/Theme.DeviceDefault.Notification" @@ -29,58 +27,46 @@ <include layout="@layout/notification_template_conversation_icon_container" /> <LinearLayout - android:id="@+id/notification_action_list_margin_target" + xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginBottom="@dimen/notification_action_list_height" - android:orientation="vertical" + android:layout_height="80dp" + android:orientation="horizontal" > <LinearLayout + android:id="@+id/notification_main_column" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" - android:layout_gravity="top" - android:orientation="horizontal" + android:layout_marginStart="@dimen/conversation_content_start" + android:orientation="vertical" + android:minHeight="68dp" > - <LinearLayout - android:id="@+id/notification_main_column" - android:layout_width="match_parent" + <include + layout="@layout/notification_template_conversation_header" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_weight="1" - android:layout_marginStart="@dimen/conversation_content_start" - android:layout_marginEnd="@dimen/notification_content_margin_end" - android:orientation="vertical" - android:minHeight="68dp" - > + /> - <include - layout="@layout/notification_template_conversation_header" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - /> + <include layout="@layout/notification_template_text" /> - <include layout="@layout/notification_template_text" /> + </LinearLayout> - <include - android:layout_width="match_parent" - android:layout_height="@dimen/notification_progress_bar_height" - android:layout_marginTop="@dimen/notification_progress_margin_top" - layout="@layout/notification_template_progress" - /> - </LinearLayout> + <FrameLayout + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:minWidth="@dimen/notification_content_margin_end" + > - <!-- TODO(b/179178086): remove padding from main column when this is visible --> - <include layout="@layout/notification_expand_button" + <include + layout="@layout/notification_expand_button" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="top|end" + android:layout_gravity="center_vertical" /> - </LinearLayout> - - <include layout="@layout/notification_material_action_list" /> + </FrameLayout> </LinearLayout> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 5a7b1faf36b2..7ccdb7192f17 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3115,6 +3115,7 @@ <!-- Notifications: CallStyle --> <java-symbol type="layout" name="notification_template_material_call" /> + <java-symbol type="layout" name="notification_template_material_big_call" /> <java-symbol type="string" name="call_notification_answer_action" /> <java-symbol type="string" name="call_notification_decline_action" /> <java-symbol type="string" name="call_notification_hang_up_action" /> 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 d3065aa36a5f..8c21e767c5c9 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 fb0fdcccd4b1..383bb7e41a91 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 bdafd232167d..5a55545351d0 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 9ced12d32d27..3a7b4618ad22 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 f65ae0c39331..1d307364d661 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) |