Merge "Show largeIcon on the left when grouped."
This commit is contained in:
committed by
Android (Google) Code Review
commit
8b819c0a03
@@ -30,6 +30,7 @@ import android.annotation.IdRes;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.Px;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SdkConstant;
|
||||
import android.annotation.SdkConstant.SdkConstantType;
|
||||
@@ -5105,33 +5106,29 @@ public class Notification implements Parcelable
|
||||
if (result == null) {
|
||||
result = new TemplateBindResult();
|
||||
}
|
||||
boolean largeIconShown = bindLargeIcon(contentView, p);
|
||||
final boolean largeIconShown = bindLargeIcon(contentView, p);
|
||||
calculateLargeIconMarginEnd(largeIconShown, result);
|
||||
if (p.mHeaderless) {
|
||||
// views in the headerless (collapsed) state
|
||||
contentView.setViewLayoutMarginEnd(R.id.notification_standard_view_column,
|
||||
result.getHeadingExtraMarginEnd());
|
||||
result.mHeadingExtraMarginSet.applyToView(contentView,
|
||||
R.id.notification_headerless_view_column);
|
||||
} else {
|
||||
// views in states with a header (big states)
|
||||
contentView.setInt(R.id.notification_header, "setTopLineExtraMarginEnd",
|
||||
result.getHeadingExtraMarginEnd());
|
||||
contentView.setViewLayoutMarginEnd(R.id.line1, result.getTitleMarginEnd());
|
||||
result.mHeadingExtraMarginSet.applyToView(contentView, R.id.notification_header);
|
||||
result.mTitleMarginSet.applyToView(contentView, R.id.line1);
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateLargeIconMarginEnd(boolean largeIconShown,
|
||||
@NonNull TemplateBindResult result) {
|
||||
int contentMargin = mContext.getResources().getDimensionPixelSize(
|
||||
final Resources resources = mContext.getResources();
|
||||
final int contentMargin = resources.getDimensionPixelOffset(
|
||||
R.dimen.notification_content_margin_end);
|
||||
int expanderSize = mContext.getResources().getDimensionPixelSize(
|
||||
final int expanderSize = resources.getDimensionPixelSize(
|
||||
R.dimen.notification_header_expand_icon_size) - contentMargin;
|
||||
int extraMarginEnd = 0;
|
||||
if (largeIconShown) {
|
||||
int iconSize = mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.notification_right_icon_size);
|
||||
extraMarginEnd = iconSize + contentMargin;
|
||||
}
|
||||
result.setRightIconState(largeIconShown, extraMarginEnd, expanderSize);
|
||||
final int extraMarginEndIfVisible = resources.getDimensionPixelSize(
|
||||
R.dimen.notification_right_icon_size) + contentMargin;
|
||||
result.setRightIconState(largeIconShown, extraMarginEndIfVisible, expanderSize);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7759,8 +7756,10 @@ public class Notification implements Parcelable
|
||||
addExtras(mBuilder.mN.extras);
|
||||
if (!isConversationLayout) {
|
||||
// also update the end margin if there is an image
|
||||
// NOTE: This template doesn't support moving this icon to the left, so we don't
|
||||
// need to fully apply the MarginSet
|
||||
contentView.setViewLayoutMarginEnd(R.id.notification_messaging,
|
||||
bindResult.getHeadingExtraMarginEnd());
|
||||
bindResult.mHeadingExtraMarginSet.getValue());
|
||||
}
|
||||
contentView.setInt(R.id.status_bar_latest_event_content, "setLayoutColor",
|
||||
mBuilder.isColorized(p)
|
||||
@@ -8757,9 +8756,8 @@ public class Notification implements Parcelable
|
||||
if (!headerless) {
|
||||
// also update the end margin to account for the large icon or expander
|
||||
Resources resources = mBuilder.mContext.getResources();
|
||||
int endMargin = resources.getDimensionPixelSize(
|
||||
R.dimen.notification_content_margin_end) + result.getTitleMarginEnd();
|
||||
remoteViews.setViewLayoutMarginEnd(R.id.notification_main_column, endMargin);
|
||||
result.mTitleMarginSet.applyToView(remoteViews, R.id.notification_main_column,
|
||||
resources.getDimensionPixelOffset(R.dimen.notification_content_margin_end));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10997,42 +10995,74 @@ public class Notification implements Parcelable
|
||||
*/
|
||||
private static class TemplateBindResult {
|
||||
boolean mRightIconVisible;
|
||||
int mRightIconMarginEnd;
|
||||
int mExpanderSize;
|
||||
|
||||
/**
|
||||
* @return the margin end that needs to be added to the heading so that it won't overlap
|
||||
* The margin end that needs to be added to the heading so that it won't overlap
|
||||
* with the large icon. This value includes the space required to accommodate the large
|
||||
* icon, but should be added to the space needed to accommodate the expander. This does
|
||||
* not include the 16dp content margin that all notification views must have.
|
||||
*/
|
||||
public int getHeadingExtraMarginEnd() {
|
||||
return mRightIconMarginEnd;
|
||||
}
|
||||
public final MarginSet mHeadingExtraMarginSet = new MarginSet();
|
||||
|
||||
/**
|
||||
* @return the margin end that needs to be added to the heading so that it won't overlap
|
||||
* The margin end that needs to be added to the heading so that it won't overlap
|
||||
* with the large icon. This value includes the space required to accommodate the large
|
||||
* icon as well as the expander. This does not include the 16dp content margin that all
|
||||
* notification views must have.
|
||||
*/
|
||||
public int getHeadingFullMarginEnd() {
|
||||
return mRightIconMarginEnd + mExpanderSize;
|
||||
}
|
||||
public final MarginSet mHeadingFullMarginSet = new MarginSet();
|
||||
|
||||
/**
|
||||
* @return the margin end that needs to be added to the title text of the big state
|
||||
* The margin end that needs to be added to the title text of the big state
|
||||
* so that it won't overlap with the large icon, but assuming the text can run under
|
||||
* the expander when that icon is not visible.
|
||||
*/
|
||||
public int getTitleMarginEnd() {
|
||||
return mRightIconVisible ? getHeadingFullMarginEnd() : 0;
|
||||
public final MarginSet mTitleMarginSet = new MarginSet();
|
||||
|
||||
public void setRightIconState(boolean visible, int marginEndIfVisible, int expanderSize) {
|
||||
mRightIconVisible = visible;
|
||||
mHeadingExtraMarginSet.setValues(0, marginEndIfVisible);
|
||||
mHeadingFullMarginSet.setValues(expanderSize, marginEndIfVisible + expanderSize);
|
||||
mTitleMarginSet.setValues(0, marginEndIfVisible + expanderSize);
|
||||
}
|
||||
|
||||
public void setRightIconState(boolean visible, int marginEnd, int expanderSize) {
|
||||
mRightIconVisible = visible;
|
||||
mRightIconMarginEnd = marginEnd;
|
||||
mExpanderSize = expanderSize;
|
||||
/**
|
||||
* This contains the end margins for a view when the right icon is visible or not. These
|
||||
* values are both needed so that NotificationGroupingUtil can 'move' the right_icon to the
|
||||
* left_icon and adjust the margins, and to undo that change as well.
|
||||
*/
|
||||
private class MarginSet {
|
||||
private int mValueIfGone;
|
||||
private int mValueIfVisible;
|
||||
|
||||
public void setValues(int valueIfGone, int valueIfVisible) {
|
||||
mValueIfGone = valueIfGone;
|
||||
mValueIfVisible = valueIfVisible;
|
||||
}
|
||||
|
||||
public void applyToView(@NonNull RemoteViews views, @IdRes int viewId) {
|
||||
applyToView(views, viewId, 0);
|
||||
}
|
||||
|
||||
public void applyToView(@NonNull RemoteViews views, @IdRes int viewId,
|
||||
@Px int extraMargin) {
|
||||
final int marginEnd = getValue() + extraMargin;
|
||||
if (viewId == R.id.notification_header) {
|
||||
views.setInt(R.id.notification_header, "setTopLineExtraMarginEnd", marginEnd);
|
||||
} else {
|
||||
views.setViewLayoutMarginEnd(viewId, marginEnd);
|
||||
}
|
||||
if (mRightIconVisible) {
|
||||
views.setIntTag(viewId, R.id.tag_margin_end_when_icon_visible,
|
||||
mValueIfVisible + extraMargin);
|
||||
views.setIntTag(viewId, R.id.tag_margin_end_when_icon_gone,
|
||||
mValueIfGone + extraMargin);
|
||||
}
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return mRightIconVisible ? mValueIfVisible : mValueIfGone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,18 @@
|
||||
android:theme="@style/Theme.DeviceDefault.Notification"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/left_icon"
|
||||
android:layout_width="@dimen/notification_left_icon_size"
|
||||
android:layout_height="@dimen/notification_left_icon_size"
|
||||
android:layout_gravity="center_vertical|start"
|
||||
android:layout_marginStart="@dimen/notification_left_icon_start"
|
||||
android:background="@drawable/notification_large_icon_outline"
|
||||
android:importantForAccessibility="no"
|
||||
android:scaleType="centerCrop"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<com.android.internal.widget.CachingIconView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/notification_icon_circle_size"
|
||||
|
||||
@@ -23,6 +23,18 @@
|
||||
android:tag="base"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/left_icon"
|
||||
android:layout_width="@dimen/notification_left_icon_size"
|
||||
android:layout_height="@dimen/notification_left_icon_size"
|
||||
android:layout_gravity="center_vertical|start"
|
||||
android:layout_marginStart="@dimen/notification_left_icon_start"
|
||||
android:background="@drawable/notification_large_icon_outline"
|
||||
android:importantForAccessibility="no"
|
||||
android:scaleType="centerCrop"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<com.android.internal.widget.CachingIconView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/notification_icon_circle_size"
|
||||
@@ -34,7 +46,7 @@
|
||||
/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/notification_standard_view_column"
|
||||
android:id="@+id/notification_headerless_view_column"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
|
||||
@@ -714,6 +714,10 @@
|
||||
<dimen name="notification_right_icon_headerless_margin">12dp</dimen>
|
||||
<!-- The top margin of the right icon in the "big" notification states -->
|
||||
<dimen name="notification_right_icon_big_margin_top">16dp</dimen>
|
||||
<!-- The size of the left icon -->
|
||||
<dimen name="notification_left_icon_size">@dimen/notification_icon_circle_size</dimen>
|
||||
<!-- The left padding of the left icon -->
|
||||
<dimen name="notification_left_icon_start">@dimen/notification_icon_circle_start</dimen>
|
||||
<!-- The alpha of a disabled notification button -->
|
||||
<item type="dimen" format="float" name="notification_action_disabled_alpha">0.5</item>
|
||||
|
||||
|
||||
@@ -194,6 +194,12 @@
|
||||
<!-- A tag used to save the index where the custom view is stored -->
|
||||
<item type="id" name="notification_custom_view_index_tag" />
|
||||
|
||||
<!-- A tag used to store the margin end for this view when the right icon is visible -->
|
||||
<item type="id" name="tag_margin_end_when_icon_gone" />
|
||||
|
||||
<!-- A tag used to store the margin end for this view when the right icon is gone -->
|
||||
<item type="id" name="tag_margin_end_when_icon_visible" />
|
||||
|
||||
<!-- Marks the "copy to clipboard" button in the ChooserActivity -->
|
||||
<item type="id" name="chooser_copy_button" />
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
<java-symbol type="id" name="inbox_text6" />
|
||||
<java-symbol type="id" name="status_bar_latest_event_content" />
|
||||
<java-symbol type="id" name="notification_main_column" />
|
||||
<java-symbol type="id" name="notification_standard_view_column" />
|
||||
<java-symbol type="id" name="notification_headerless_view_column" />
|
||||
<java-symbol type="id" name="sms_short_code_confirm_message" />
|
||||
<java-symbol type="id" name="sms_short_code_detail_layout" />
|
||||
<java-symbol type="id" name="sms_short_code_detail_message" />
|
||||
@@ -3070,6 +3070,8 @@
|
||||
<java-symbol type="dimen" name="notification_media_image_margin_end" />
|
||||
<java-symbol type="id" name="notification_action_list_margin_target" />
|
||||
<java-symbol type="dimen" name="notification_action_disabled_alpha" />
|
||||
<java-symbol type="id" name="tag_margin_end_when_icon_visible" />
|
||||
<java-symbol type="id" name="tag_margin_end_when_icon_gone" />
|
||||
|
||||
<!-- Override Wake Key Behavior When Screen is Off -->
|
||||
<java-symbol type="bool" name="config_wakeOnDpadKeyPress" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
* Copyright (C) 2020 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.
|
||||
@@ -11,19 +11,22 @@
|
||||
* 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
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.text.TextUtils;
|
||||
import android.view.NotificationHeaderView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.widget.CachingIconView;
|
||||
import com.android.internal.widget.ConversationLayout;
|
||||
import com.android.internal.widget.NotificationExpandButton;
|
||||
@@ -36,35 +39,38 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A Util to manage {@link android.view.NotificationHeaderView} objects and their redundancies.
|
||||
* A utility to manage notification views when they are placed in a group by adjusting elements
|
||||
* to reduce redundancies and occasionally tweak layouts to highlight the unique content.
|
||||
*/
|
||||
public class NotificationHeaderUtil {
|
||||
public class NotificationGroupingUtil {
|
||||
|
||||
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() {
|
||||
private static final TextViewComparator TEXT_VIEW_COMPARATOR = new TextViewComparator();
|
||||
private static final TextViewComparator APP_NAME_COMPARATOR = new AppNameComparator();
|
||||
private static final ViewComparator BADGE_COMPARATOR = new BadgeComparator();
|
||||
private static final VisibilityApplicator VISIBILITY_APPLICATOR = new VisibilityApplicator();
|
||||
private static final VisibilityApplicator APP_NAME_APPLICATOR = new AppNameApplicator();
|
||||
private static final ResultApplicator LEFT_ICON_APPLICATOR = new LeftIconApplicator();
|
||||
private static final DataExtractor ICON_EXTRACTOR = new DataExtractor() {
|
||||
@Override
|
||||
public Object extractData(ExpandableNotificationRow row) {
|
||||
return row.getEntry().getSbn().getNotification();
|
||||
}
|
||||
};
|
||||
private static final IconComparator sIconVisibilityComparator = new IconComparator() {
|
||||
private static final IconComparator ICON_VISIBILITY_COMPARATOR = new IconComparator() {
|
||||
public boolean compare(View parent, View child, Object parentData,
|
||||
Object childData) {
|
||||
return hasSameIcon(parentData, childData)
|
||||
&& hasSameColor(parentData, childData);
|
||||
}
|
||||
};
|
||||
private static final IconComparator sGreyComparator = new IconComparator() {
|
||||
private static final IconComparator GREY_COMPARATOR = new IconComparator() {
|
||||
public boolean compare(View parent, View child, Object parentData,
|
||||
Object childData) {
|
||||
return !hasSameIcon(parentData, childData)
|
||||
|| hasSameColor(parentData, childData);
|
||||
}
|
||||
};
|
||||
private final static ResultApplicator mGreyApplicator = new ResultApplicator() {
|
||||
private static final ResultApplicator GREY_APPLICATOR = new ResultApplicator() {
|
||||
@Override
|
||||
public void apply(View parent, View view, boolean apply, boolean reset) {
|
||||
CachingIconView icon = view.findViewById(com.android.internal.R.id.icon);
|
||||
@@ -80,87 +86,79 @@ public class NotificationHeaderUtil {
|
||||
};
|
||||
|
||||
private final ExpandableNotificationRow mRow;
|
||||
private final ArrayList<HeaderProcessor> mComparators = new ArrayList<>();
|
||||
private final ArrayList<Processor> mProcessors = new ArrayList<>();
|
||||
private final HashSet<Integer> mDividers = new HashSet<>();
|
||||
|
||||
public NotificationHeaderUtil(ExpandableNotificationRow row) {
|
||||
public NotificationGroupingUtil(ExpandableNotificationRow row) {
|
||||
mRow = row;
|
||||
// To hide the icons if they are the same and the color is the same
|
||||
mComparators.add(new HeaderProcessor(mRow,
|
||||
mProcessors.add(new Processor(mRow,
|
||||
com.android.internal.R.id.icon,
|
||||
sIconExtractor,
|
||||
sIconVisibilityComparator,
|
||||
sVisibilityApplicator));
|
||||
ICON_EXTRACTOR,
|
||||
ICON_VISIBILITY_COMPARATOR,
|
||||
VISIBILITY_APPLICATOR));
|
||||
// To grey them out the icons and expand button when the icons are not the same
|
||||
mComparators.add(new HeaderProcessor(mRow,
|
||||
com.android.internal.R.id.notification_header,
|
||||
sIconExtractor,
|
||||
sGreyComparator,
|
||||
mGreyApplicator));
|
||||
mComparators.add(new HeaderProcessor(mRow,
|
||||
mProcessors.add(new Processor(mRow,
|
||||
com.android.internal.R.id.status_bar_latest_event_content,
|
||||
ICON_EXTRACTOR,
|
||||
GREY_COMPARATOR,
|
||||
GREY_APPLICATOR));
|
||||
mProcessors.add(new Processor(mRow,
|
||||
com.android.internal.R.id.status_bar_latest_event_content,
|
||||
ICON_EXTRACTOR,
|
||||
ICON_VISIBILITY_COMPARATOR,
|
||||
LEFT_ICON_APPLICATOR));
|
||||
mProcessors.add(new Processor(mRow,
|
||||
com.android.internal.R.id.profile_badge,
|
||||
null /* Extractor */,
|
||||
new ViewComparator() {
|
||||
@Override
|
||||
public boolean compare(View parent, View child, Object parentData,
|
||||
Object childData) {
|
||||
return parent.getVisibility() != View.GONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty(View view) {
|
||||
if (view instanceof ImageView) {
|
||||
return ((ImageView) view).getDrawable() == null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
sVisibilityApplicator));
|
||||
mComparators.add(new HeaderProcessor(
|
||||
mRow,
|
||||
BADGE_COMPARATOR,
|
||||
VISIBILITY_APPLICATOR));
|
||||
mProcessors.add(new Processor(mRow,
|
||||
com.android.internal.R.id.app_name_text,
|
||||
null,
|
||||
sAppNameComparator,
|
||||
sAppNameApplicator));
|
||||
mComparators.add(HeaderProcessor.forTextView(mRow,
|
||||
com.android.internal.R.id.header_text));
|
||||
APP_NAME_COMPARATOR,
|
||||
APP_NAME_APPLICATOR));
|
||||
mProcessors.add(Processor.forTextView(mRow, com.android.internal.R.id.header_text));
|
||||
mDividers.add(com.android.internal.R.id.header_text_divider);
|
||||
mDividers.add(com.android.internal.R.id.header_text_secondary_divider);
|
||||
mDividers.add(com.android.internal.R.id.time_divider);
|
||||
}
|
||||
|
||||
public void updateChildrenHeaderAppearance() {
|
||||
/**
|
||||
* Update the appearance of the children in this group to reduce redundancies.
|
||||
*/
|
||||
public void updateChildrenAppearance() {
|
||||
List<ExpandableNotificationRow> notificationChildren = mRow.getAttachedChildren();
|
||||
if (notificationChildren == null) {
|
||||
return;
|
||||
}
|
||||
// Initialize the comparators
|
||||
for (int compI = 0; compI < mComparators.size(); compI++) {
|
||||
mComparators.get(compI).init();
|
||||
// Initialize the processors
|
||||
for (int compI = 0; compI < mProcessors.size(); compI++) {
|
||||
mProcessors.get(compI).init();
|
||||
}
|
||||
|
||||
// Compare all notification headers
|
||||
for (int i = 0; i < notificationChildren.size(); i++) {
|
||||
ExpandableNotificationRow row = notificationChildren.get(i);
|
||||
for (int compI = 0; compI < mComparators.size(); compI++) {
|
||||
mComparators.get(compI).compareToHeader(row);
|
||||
for (int compI = 0; compI < mProcessors.size(); compI++) {
|
||||
mProcessors.get(compI).compareToGroupParent(row);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the comparison to the row
|
||||
for (int i = 0; i < notificationChildren.size(); i++) {
|
||||
ExpandableNotificationRow row = notificationChildren.get(i);
|
||||
for (int compI = 0; compI < mComparators.size(); compI++) {
|
||||
mComparators.get(compI).apply(row);
|
||||
for (int compI = 0; compI < mProcessors.size(); compI++) {
|
||||
mProcessors.get(compI).apply(row);
|
||||
}
|
||||
// We need to sanitize the dividers since they might be off-balance now
|
||||
sanitizeHeaderViews(row);
|
||||
sanitizeTopLineViews(row);
|
||||
}
|
||||
}
|
||||
|
||||
private void sanitizeHeaderViews(ExpandableNotificationRow row) {
|
||||
private void sanitizeTopLineViews(ExpandableNotificationRow row) {
|
||||
if (row.isSummaryWithChildren()) {
|
||||
sanitizeHeader(row.getNotificationViewWrapper().getNotificationHeader());
|
||||
sanitizeTopLine(row.getNotificationViewWrapper().getNotificationHeader());
|
||||
return;
|
||||
}
|
||||
final NotificationContentView layout = row.getPrivateLayout();
|
||||
@@ -171,13 +169,11 @@ public class NotificationHeaderUtil {
|
||||
|
||||
private void sanitizeChild(View child) {
|
||||
if (child != null) {
|
||||
ViewGroup header = child.findViewById(
|
||||
com.android.internal.R.id.notification_top_line);
|
||||
sanitizeHeader(header);
|
||||
sanitizeTopLine(child.findViewById(R.id.notification_top_line));
|
||||
}
|
||||
}
|
||||
|
||||
private void sanitizeHeader(ViewGroup rowHeader) {
|
||||
private void sanitizeTopLine(ViewGroup rowHeader) {
|
||||
if (rowHeader == null) {
|
||||
return;
|
||||
}
|
||||
@@ -225,28 +221,31 @@ public class NotificationHeaderUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public void restoreNotificationHeader(ExpandableNotificationRow row) {
|
||||
for (int compI = 0; compI < mComparators.size(); compI++) {
|
||||
mComparators.get(compI).apply(row, true /* reset */);
|
||||
/**
|
||||
* Reset the modifications to this row for removing it from the group.
|
||||
*/
|
||||
public void restoreChildNotification(ExpandableNotificationRow row) {
|
||||
for (int compI = 0; compI < mProcessors.size(); compI++) {
|
||||
mProcessors.get(compI).apply(row, true /* reset */);
|
||||
}
|
||||
sanitizeHeaderViews(row);
|
||||
sanitizeTopLineViews(row);
|
||||
}
|
||||
|
||||
private static class HeaderProcessor {
|
||||
private static class Processor {
|
||||
private final int mId;
|
||||
private final DataExtractor mExtractor;
|
||||
private final ViewComparator mComparator;
|
||||
private final ResultApplicator mApplicator;
|
||||
private final ExpandableNotificationRow mParentRow;
|
||||
private boolean mApply;
|
||||
private View mParentView;
|
||||
private ViewComparator mComparator;
|
||||
private Object mParentData;
|
||||
|
||||
public static HeaderProcessor forTextView(ExpandableNotificationRow row, int id) {
|
||||
return new HeaderProcessor(row, id, null, sTextViewComparator, sVisibilityApplicator);
|
||||
public static Processor forTextView(ExpandableNotificationRow row, int id) {
|
||||
return new Processor(row, id, null, TEXT_VIEW_COMPARATOR, VISIBILITY_APPLICATOR);
|
||||
}
|
||||
|
||||
HeaderProcessor(ExpandableNotificationRow row, int id, DataExtractor extractor,
|
||||
Processor(ExpandableNotificationRow row, int id, DataExtractor extractor,
|
||||
ViewComparator comparator,
|
||||
ResultApplicator applicator) {
|
||||
mId = id;
|
||||
@@ -262,7 +261,7 @@ public class NotificationHeaderUtil {
|
||||
mParentData = mExtractor == null ? null : mExtractor.extractData(mParentRow);
|
||||
mApply = !mComparator.isEmpty(mParentView);
|
||||
}
|
||||
public void compareToHeader(ExpandableNotificationRow row) {
|
||||
public void compareToGroupParent(ExpandableNotificationRow row) {
|
||||
if (!mApply) {
|
||||
return;
|
||||
}
|
||||
@@ -308,8 +307,8 @@ public class NotificationHeaderUtil {
|
||||
|
||||
private interface ViewComparator {
|
||||
/**
|
||||
* @param parent the parent view
|
||||
* @param child the child view
|
||||
* @param parent the view with the given id in the group header
|
||||
* @param child the view with the given id in the child notification
|
||||
* @param parentData optional data for the parent
|
||||
* @param childData optional data for the child
|
||||
* @return whether to views are the same
|
||||
@@ -322,6 +321,21 @@ public class NotificationHeaderUtil {
|
||||
Object extractData(ExpandableNotificationRow row);
|
||||
}
|
||||
|
||||
private static class BadgeComparator implements ViewComparator {
|
||||
@Override
|
||||
public boolean compare(View parent, View child, Object parentData, Object childData) {
|
||||
return parent.getVisibility() != View.GONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty(View view) {
|
||||
if (view instanceof ImageView) {
|
||||
return ((ImageView) view).getDrawable() == null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TextViewComparator implements ViewComparator {
|
||||
@Override
|
||||
public boolean compare(View parent, View child, Object parentData, Object childData) {
|
||||
@@ -338,7 +352,7 @@ public class NotificationHeaderUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class IconComparator implements ViewComparator {
|
||||
private abstract static class IconComparator implements ViewComparator {
|
||||
@Override
|
||||
public boolean compare(View parent, View child, Object parentData, Object childData) {
|
||||
return false;
|
||||
@@ -366,6 +380,12 @@ public class NotificationHeaderUtil {
|
||||
}
|
||||
|
||||
private interface ResultApplicator {
|
||||
/**
|
||||
* @param parent the root view of the child notification
|
||||
* @param view the view with the given id in the child notification
|
||||
* @param apply whether the state should be applied or removed
|
||||
* @param reset if [de]application is the result of a reset
|
||||
*/
|
||||
void apply(View parent, View view, boolean apply, boolean reset);
|
||||
}
|
||||
|
||||
@@ -403,4 +423,54 @@ public class NotificationHeaderUtil {
|
||||
return super.compare(parent, child, parentData, childData);
|
||||
}
|
||||
}
|
||||
|
||||
private static class LeftIconApplicator implements ResultApplicator {
|
||||
|
||||
public static final int[] MARGIN_ADJUSTED_VIEWS = {
|
||||
R.id.notification_headerless_view_column,
|
||||
R.id.line1,
|
||||
R.id.notification_main_column,
|
||||
R.id.notification_header};
|
||||
|
||||
@Override
|
||||
public void apply(View parent, View child, boolean apply, boolean reset) {
|
||||
ImageView rightIcon = child.findViewById(com.android.internal.R.id.right_icon);
|
||||
ImageView leftIcon = child.findViewById(com.android.internal.R.id.left_icon);
|
||||
if (rightIcon == null || leftIcon == null) {
|
||||
return;
|
||||
}
|
||||
Drawable iconDrawable = rightIcon.getDrawable();
|
||||
if (iconDrawable == null) {
|
||||
return;
|
||||
}
|
||||
rightIcon.setVisibility(apply ? View.GONE : View.VISIBLE);
|
||||
leftIcon.setVisibility(apply ? View.VISIBLE : View.GONE);
|
||||
leftIcon.setImageDrawable(apply ? iconDrawable : null);
|
||||
|
||||
for (int viewId : MARGIN_ADJUSTED_VIEWS) {
|
||||
adjustMargins(!apply, child.findViewById(viewId));
|
||||
}
|
||||
}
|
||||
|
||||
void adjustMargins(boolean iconVisible, View target) {
|
||||
if (target == null) {
|
||||
return;
|
||||
}
|
||||
Integer value = (Integer) target.getTag(iconVisible
|
||||
? com.android.internal.R.id.tag_margin_end_when_icon_visible
|
||||
: com.android.internal.R.id.tag_margin_end_when_icon_gone);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
if (target instanceof NotificationHeaderView) {
|
||||
((NotificationHeaderView) target).setTopLineExtraMarginEnd(value);
|
||||
} else {
|
||||
ViewGroup.LayoutParams layoutParams = target.getLayoutParams();
|
||||
if (layoutParams instanceof ViewGroup.MarginLayoutParams) {
|
||||
((ViewGroup.MarginLayoutParams) layoutParams).setMarginEnd(value);
|
||||
target.setLayoutParams(layoutParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -558,7 +558,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
setChronometerRunning(true);
|
||||
}
|
||||
if (mNotificationParent != null) {
|
||||
mNotificationParent.updateChildrenHeaderAppearance();
|
||||
mNotificationParent.updateChildrenAppearance();
|
||||
}
|
||||
onAttachedChildrenCountChanged();
|
||||
// The public layouts expand button is always visible
|
||||
@@ -2337,7 +2337,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
}
|
||||
getShowingLayout().updateBackgroundColor(false /* animate */);
|
||||
mPrivateLayout.updateExpandButtons(isExpandable());
|
||||
updateChildrenHeaderAppearance();
|
||||
updateChildrenAppearance();
|
||||
updateChildrenVisibility();
|
||||
applyChildrenRoundness();
|
||||
}
|
||||
@@ -2382,9 +2382,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
return channels;
|
||||
}
|
||||
|
||||
public void updateChildrenHeaderAppearance() {
|
||||
/**
|
||||
* If this is a group, update the appearance of the children.
|
||||
*/
|
||||
public void updateChildrenAppearance() {
|
||||
if (mIsSummaryWithChildren) {
|
||||
mChildrenContainer.updateChildrenHeaderAppearance();
|
||||
mChildrenContainer.updateChildrenAppearance();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
|
||||
private ImageView mWorkProfileImage;
|
||||
private View mAudiblyAlertedIcon;
|
||||
private View mFeedbackIcon;
|
||||
private View mLeftIcon;
|
||||
private View mRightIcon;
|
||||
|
||||
private boolean mIsLowPriority;
|
||||
@@ -108,6 +109,7 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
|
||||
mAppNameText = mView.findViewById(com.android.internal.R.id.app_name_text);
|
||||
mExpandButton = mView.findViewById(com.android.internal.R.id.expand_button);
|
||||
mAltExpandTarget = mView.findViewById(com.android.internal.R.id.alternate_expand_target);
|
||||
mLeftIcon = mView.findViewById(com.android.internal.R.id.left_icon);
|
||||
mRightIcon = mView.findViewById(com.android.internal.R.id.right_icon);
|
||||
mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge);
|
||||
mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header);
|
||||
@@ -146,6 +148,9 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
|
||||
updateCropToPaddingForImageViews();
|
||||
Notification notification = row.getEntry().getSbn().getNotification();
|
||||
mIcon.setTag(ImageTransformState.ICON_TAG, notification.getSmallIcon());
|
||||
if (mLeftIcon != null) {
|
||||
mLeftIcon.setClipToOutline(true);
|
||||
}
|
||||
if (mRightIcon != null) {
|
||||
mRightIcon.setClipToOutline(true);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.widget.CachingIconView;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.CrossFadeHelper;
|
||||
import com.android.systemui.statusbar.NotificationHeaderUtil;
|
||||
import com.android.systemui.statusbar.NotificationGroupingUtil;
|
||||
import com.android.systemui.statusbar.notification.NotificationUtils;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
@@ -94,7 +94,7 @@ public class NotificationChildrenContainer extends ViewGroup {
|
||||
private NotificationViewWrapper mNotificationHeaderWrapper;
|
||||
private NotificationHeaderView mNotificationHeaderLowPriority;
|
||||
private NotificationViewWrapper mNotificationHeaderWrapperLowPriority;
|
||||
private NotificationHeaderUtil mHeaderUtil;
|
||||
private NotificationGroupingUtil mGroupingUtil;
|
||||
private ViewState mHeaderViewState;
|
||||
private int mClipBottomAmount;
|
||||
private boolean mIsLowPriority;
|
||||
@@ -299,7 +299,7 @@ public class NotificationChildrenContainer extends ViewGroup {
|
||||
row.setSystemChildExpanded(false);
|
||||
row.setUserLocked(false);
|
||||
if (!row.isRemoved()) {
|
||||
mHeaderUtil.restoreNotificationHeader(row);
|
||||
mGroupingUtil.restoreChildNotification(row);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,7 +341,7 @@ public class NotificationChildrenContainer extends ViewGroup {
|
||||
}
|
||||
recreateLowPriorityHeader(builder, isConversation);
|
||||
updateHeaderVisibility(false /* animate */);
|
||||
updateChildrenHeaderAppearance();
|
||||
updateChildrenAppearance();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -389,8 +389,11 @@ public class NotificationChildrenContainer extends ViewGroup {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateChildrenHeaderAppearance() {
|
||||
mHeaderUtil.updateChildrenHeaderAppearance();
|
||||
/**
|
||||
* Update the appearance of the children to reduce redundancies.
|
||||
*/
|
||||
public void updateChildrenAppearance() {
|
||||
mGroupingUtil.updateChildrenAppearance();
|
||||
}
|
||||
|
||||
public void updateGroupOverflow() {
|
||||
@@ -861,7 +864,7 @@ public class NotificationChildrenContainer extends ViewGroup {
|
||||
|
||||
public void setContainingNotification(ExpandableNotificationRow parent) {
|
||||
mContainingNotification = parent;
|
||||
mHeaderUtil = new NotificationHeaderUtil(mContainingNotification);
|
||||
mGroupingUtil = new NotificationGroupingUtil(mContainingNotification);
|
||||
}
|
||||
|
||||
public ExpandableNotificationRow getContainingNotification() {
|
||||
|
||||
Reference in New Issue
Block a user