Merge changes I6e96864c,I6bc865d5,I15ca6994 into sc-dev

* changes:
  Hide app name from collapsed CallStyle.
  CallStyle now supports contextual actions (e.g. smart replies)
  Fix the layout issue with the expand button of the CallStyle
This commit is contained in:
Jeff DeCew
2021-03-15 13:18:03 +00:00
committed by Android (Google) Code Review
12 changed files with 218 additions and 76 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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"
>

View File

@@ -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>

View File

@@ -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"
>

View File

@@ -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"
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
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>
<!-- TODO(b/179178086): remove padding from main column when this is visible -->
<include layout="@layout/notification_expand_button"
<include
layout="@layout/notification_template_conversation_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|end"
/>
<include layout="@layout/notification_template_text" />
</LinearLayout>
<include layout="@layout/notification_material_action_list" />
<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"
android:layout_gravity="center_vertical"
/>
</FrameLayout>
</LinearLayout>

View File

@@ -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" />

View File

@@ -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;
}

View File

@@ -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 &&

View File

@@ -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

View File

@@ -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) {}

View File

@@ -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)