diff options
| author | Selim Cinek <cinek@google.com> | 2018-04-24 09:10:38 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-04-24 09:10:38 +0000 |
| commit | 53790c1c8faf81aa4ee534b119519090b2bbd94f (patch) | |
| tree | 299c9a41c53468a7d87b6f8aef9184bc44b4ad76 /core/java/android | |
| parent | 5f18904a007cd4005bc6ae6e5e8cbe0944e31010 (diff) | |
| parent | 1c72fa0249c364143d0818d129b6dc7f70054752 (diff) | |
Merge changes from topic "notification_reply_action" into pi-dev
* changes:
Cleaned up the paddings of the messaging layout and smart replies
Changed the size of the largeIcon
Moved the disabling from alpha to manual color blending
Updated the color of the reply button to be more neutral
Updated the reply icon
Disabled reply action when pending intents are cancelled
Split the reply icon permanently from the right icon
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/Notification.java | 315 | ||||
| -rw-r--r-- | core/java/android/app/PendingIntent.java | 87 | ||||
| -rw-r--r-- | core/java/android/widget/RemoteViews.java | 23 |
3 files changed, 316 insertions, 109 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 4b153782aec7..eeec7caad7ee 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -3154,10 +3154,14 @@ public class Notification implements Parcelable private int mCachedContrastColor = COLOR_INVALID; private int mCachedContrastColorIsFor = COLOR_INVALID; /** - * Caches a ambient version of {@link #mCachedContrastColorIsFor}. + * Caches a ambient version of {@link #mCachedAmbientColorIsFor}. */ private int mCachedAmbientColor = COLOR_INVALID; private int mCachedAmbientColorIsFor = COLOR_INVALID; + /** + * A neutral color color that can be used for icons. + */ + private int mNeutralColor = COLOR_INVALID; /** * Caches an instance of StandardTemplateParams. Note that this may have been used before, @@ -4299,7 +4303,6 @@ public class Notification implements Parcelable private void resetStandardTemplate(RemoteViews contentView) { resetNotificationHeader(contentView); - resetContentMargins(contentView); contentView.setViewVisibility(R.id.right_icon, View.GONE); contentView.setViewVisibility(R.id.title, View.GONE); contentView.setTextViewText(R.id.title, null); @@ -4331,24 +4334,23 @@ public class Notification implements Parcelable mN.mUsesStandardHeader = false; } - private void resetContentMargins(RemoteViews contentView) { - contentView.setViewLayoutMarginEndDimen(R.id.line1, 0); - contentView.setViewLayoutMarginEndDimen(R.id.text, 0); - } - - private RemoteViews applyStandardTemplate(int resId) { - return applyStandardTemplate(resId, mParams.reset().fillTextsFrom(this)); + private RemoteViews applyStandardTemplate(int resId, TemplateBindResult result) { + return applyStandardTemplate(resId, mParams.reset().fillTextsFrom(this), + result); } /** * @param hasProgress whether the progress bar should be shown and set + * @param result */ - private RemoteViews applyStandardTemplate(int resId, boolean hasProgress) { + private RemoteViews applyStandardTemplate(int resId, boolean hasProgress, + TemplateBindResult result) { return applyStandardTemplate(resId, mParams.reset().hasProgress(hasProgress) - .fillTextsFrom(this)); + .fillTextsFrom(this), result); } - private RemoteViews applyStandardTemplate(int resId, StandardTemplateParams p) { + private RemoteViews applyStandardTemplate(int resId, StandardTemplateParams p, + TemplateBindResult result) { RemoteViews contentView = new BuilderRemoteViews(mContext.getApplicationInfo(), resId); resetStandardTemplate(contentView); @@ -4356,7 +4358,7 @@ public class Notification implements Parcelable final Bundle ex = mN.extras; updateBackgroundColor(contentView); bindNotificationHeader(contentView, p.ambient, p.headerTextSecondary); - bindLargeIcon(contentView, p.hideLargeIcon || p.ambient, p.alwaysShowReply); + bindLargeIconAndReply(contentView, p, result); boolean showProgress = handleProgressBar(p.hasProgress, contentView, ex); if (p.title != null) { contentView.setViewVisibility(R.id.title, View.VISIBLE); @@ -4552,8 +4554,58 @@ public class Notification implements Parcelable } } - private void bindLargeIcon(RemoteViews contentView, boolean hideLargeIcon, - boolean alwaysShowReply) { + private void bindLargeIconAndReply(RemoteViews contentView, StandardTemplateParams p, + TemplateBindResult result) { + boolean largeIconShown = bindLargeIcon(contentView, p.hideLargeIcon || p.ambient); + boolean replyIconShown = bindReplyIcon(contentView, p.hideReplyIcon || p.ambient); + contentView.setViewVisibility(R.id.right_icon_container, + largeIconShown || replyIconShown ? View.VISIBLE : View.GONE); + int marginEnd = calculateMarginEnd(largeIconShown, replyIconShown); + contentView.setViewLayoutMarginEnd(R.id.line1, marginEnd); + contentView.setViewLayoutMarginEnd(R.id.text, marginEnd); + contentView.setViewLayoutMarginEnd(R.id.progress, marginEnd); + if (result != null) { + result.setIconMarginEnd(marginEnd); + } + } + + private int calculateMarginEnd(boolean largeIconShown, boolean replyIconShown) { + int marginEnd = 0; + int contentMargin = mContext.getResources().getDimensionPixelSize( + R.dimen.notification_content_margin_end); + int iconSize = mContext.getResources().getDimensionPixelSize( + R.dimen.notification_right_icon_size); + if (replyIconShown) { + // The size of the reply icon + marginEnd += iconSize; + + int replyInset = mContext.getResources().getDimensionPixelSize( + R.dimen.notification_reply_inset); + // We're subtracting the inset of the reply icon to make sure it's + // aligned nicely on the right, and remove it from the following padding + marginEnd -= replyInset * 2; + } + if (largeIconShown) { + // adding size of the right icon + marginEnd += iconSize; + + if (replyIconShown) { + // We also add some padding to the reply icon if it's around + marginEnd += contentMargin; + } + } + if (replyIconShown || largeIconShown) { + // The padding to the content + marginEnd += contentMargin; + } + return marginEnd; + } + + /** + * Bind the large icon. + * @return if the largeIcon is visible + */ + private boolean bindLargeIcon(RemoteViews contentView, boolean hideLargeIcon) { if (mN.mLargeIcon == null && mN.largeIcon != null) { mN.mLargeIcon = Icon.createWithBitmap(mN.largeIcon); } @@ -4562,51 +4614,35 @@ public class Notification implements Parcelable contentView.setViewVisibility(R.id.right_icon, View.VISIBLE); contentView.setImageViewIcon(R.id.right_icon, mN.mLargeIcon); processLargeLegacyIcon(mN.mLargeIcon, contentView); - int endMargin = R.dimen.notification_content_picture_margin; - contentView.setViewLayoutMarginEndDimen(R.id.line1, endMargin); - contentView.setViewLayoutMarginEndDimen(R.id.text, endMargin); - contentView.setViewLayoutMarginEndDimen(R.id.progress, endMargin); } - // Bind the reply action - Action action = findReplyAction(); + return showLargeIcon; + } - boolean actionVisible = action != null && (showLargeIcon || alwaysShowReply); - int replyId = showLargeIcon ? R.id.reply_icon_action : R.id.right_icon; + /** + * Bind the reply icon. + * @return if the reply icon is visible + */ + private boolean bindReplyIcon(RemoteViews contentView, boolean hideReplyIcon) { + boolean actionVisible = !hideReplyIcon; + Action action = null; if (actionVisible) { - // We're only showing the icon as big if we're hiding the large icon - int contrastColor = resolveContrastColor(); - int iconColor; - if (showLargeIcon) { - contentView.setDrawableTint(R.id.reply_icon_action, - true /* targetBackground */, - contrastColor, PorterDuff.Mode.SRC_ATOP); - contentView.setOnClickPendingIntent(R.id.right_icon, - action.actionIntent); - contentView.setRemoteInputs(R.id.right_icon, action.mRemoteInputs); - iconColor = NotificationColorUtil.isColorLight(contrastColor) - ? Color.BLACK : Color.WHITE; - } else { - contentView.setImageViewResource(R.id.right_icon, - R.drawable.ic_reply_notification_large); - contentView.setViewVisibility(R.id.right_icon, View.VISIBLE); - iconColor = contrastColor; - } - contentView.setDrawableTint(replyId, + action = findReplyAction(); + actionVisible = action != null; + } + if (actionVisible) { + contentView.setViewVisibility(R.id.reply_icon_action, View.VISIBLE); + contentView.setDrawableTint(R.id.reply_icon_action, false /* targetBackground */, - iconColor, + getNeutralColor(), PorterDuff.Mode.SRC_ATOP); - contentView.setOnClickPendingIntent(replyId, - action.actionIntent); - contentView.setRemoteInputs(replyId, action.mRemoteInputs); + contentView.setOnClickPendingIntent(R.id.reply_icon_action, action.actionIntent); + contentView.setRemoteInputs(R.id.reply_icon_action, action.mRemoteInputs); } else { - contentView.setRemoteInputs(R.id.right_icon, null); + contentView.setRemoteInputs(R.id.reply_icon_action, null); } - contentView.setViewVisibility(R.id.reply_icon_action, actionVisible && showLargeIcon - ? View.VISIBLE - : View.GONE); - contentView.setViewVisibility(R.id.right_icon_container, actionVisible || showLargeIcon - ? View.VISIBLE - : View.GONE); + contentView.setViewVisibility(R.id.reply_icon_action, + actionVisible ? View.VISIBLE : View.GONE); + return actionVisible; } private Action findReplyAction() { @@ -4641,8 +4677,7 @@ public class Notification implements Parcelable } private void bindActivePermissions(RemoteViews contentView, boolean ambient) { - int color = ambient ? resolveAmbientColor() - : isColorized() ? getPrimaryTextColor() : resolveContrastColor(); + int color = ambient ? resolveAmbientColor() : getNeutralColor(); contentView.setDrawableTint(R.id.camera, false, color, PorterDuff.Mode.SRC_ATOP); contentView.setDrawableTint(R.id.mic, false, color, PorterDuff.Mode.SRC_ATOP); contentView.setDrawableTint(R.id.overlay, false, color, PorterDuff.Mode.SRC_ATOP); @@ -4793,13 +4828,15 @@ public class Notification implements Parcelable R.dimen.notification_content_margin); } - private RemoteViews applyStandardTemplateWithActions(int layoutId) { - return applyStandardTemplateWithActions(layoutId, mParams.reset().fillTextsFrom(this)); + private RemoteViews applyStandardTemplateWithActions(int layoutId, + TemplateBindResult result) { + return applyStandardTemplateWithActions(layoutId, mParams.reset().fillTextsFrom(this), + result); } private RemoteViews applyStandardTemplateWithActions(int layoutId, - StandardTemplateParams p) { - RemoteViews big = applyStandardTemplate(layoutId, p); + StandardTemplateParams p, TemplateBindResult result) { + RemoteViews big = applyStandardTemplate(layoutId, p, result); resetStandardTemplateWithActions(big); @@ -4915,7 +4952,7 @@ public class Notification implements Parcelable return styleView; } } - return applyStandardTemplate(getBaseLayoutResource()); + return applyStandardTemplate(getBaseLayoutResource(), null /* result */); } private boolean useExistingRemoteView() { @@ -4934,7 +4971,8 @@ public class Notification implements Parcelable result = mStyle.makeBigContentView(); hideLine1Text(result); } else if (mActions.size() != 0) { - result = applyStandardTemplateWithActions(getBigBaseLayoutResource()); + result = applyStandardTemplateWithActions(getBigBaseLayoutResource(), + null /* result */); } makeHeaderExpanded(result); return result; @@ -4971,7 +5009,8 @@ public class Notification implements Parcelable public RemoteViews makeAmbientNotification() { RemoteViews ambient = applyStandardTemplateWithActions( R.layout.notification_template_material_ambient, - mParams.reset().ambient(true).fillTextsFrom(this).hasProgress(false)); + mParams.reset().ambient(true).fillTextsFrom(this).hasProgress(false), + null /* result */); return ambient; } @@ -5014,7 +5053,7 @@ public class Notification implements Parcelable return null; } - return applyStandardTemplateWithActions(getBigBaseLayoutResource()); + return applyStandardTemplateWithActions(getBigBaseLayoutResource(), null /* result */); } /** @@ -5362,6 +5401,20 @@ public class Notification implements Parcelable return mCachedContrastColor = color; } + int resolveNeutralColor() { + if (mNeutralColor != COLOR_INVALID) { + return mNeutralColor; + } + int background = mContext.getColor( + com.android.internal.R.color.notification_material_background_color); + mNeutralColor = NotificationColorUtil.resolveDefaultColor(mContext, background); + if (Color.alpha(mNeutralColor) < 255) { + // alpha doesn't go well for color filters, so let's blend it manually + mNeutralColor = NotificationColorUtil.compositeColors(mNeutralColor, background); + } + return mNeutralColor; + } + int resolveAmbientColor() { if (mCachedAmbientColorIsFor == mN.color && mCachedAmbientColorIsFor != COLOR_INVALID) { return mCachedAmbientColor; @@ -5594,6 +5647,17 @@ public class Notification implements Parcelable } /** + * Gets a neutral color that can be used for icons or similar that should not stand out. + */ + private int getNeutralColor() { + if (isColorized()) { + return getSecondaryTextColor(); + } else { + return resolveNeutralColor(); + } + } + + /** * Same as getBackgroundColor but also resolved the default color to the background. */ private int resolveBackgroundColor() { @@ -5895,6 +5959,18 @@ public class Notification implements Parcelable } protected RemoteViews getStandardView(int layoutId) { + return getStandardView(layoutId, null); + } + + /** + * Get the standard view for this style. + * + * @param layoutId The layout id to use + * @param result The result where template bind information is saved. + * @return A remoteView for this style. + * @hide + */ + protected RemoteViews getStandardView(int layoutId, TemplateBindResult result) { checkBuilder(); // Nasty. @@ -5904,7 +5980,7 @@ public class Notification implements Parcelable mBuilder.setContentTitle(mBigContentTitle); } - RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(layoutId); + RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(layoutId, result); mBuilder.getAllExtras().putCharSequence(EXTRA_TITLE, oldBuilderContentTitle); @@ -6201,7 +6277,8 @@ public class Notification implements Parcelable mBuilder.mN.largeIcon = null; } - RemoteViews contentView = getStandardView(mBuilder.getBigPictureLayoutResource()); + RemoteViews contentView = getStandardView(mBuilder.getBigPictureLayoutResource(), + null /* result */); if (mSummaryTextSet) { contentView.setTextViewText(R.id.text, mBuilder.processTextSpans( mBuilder.processLegacyText(mSummaryText))); @@ -6388,7 +6465,9 @@ public class Notification implements Parcelable CharSequence text = mBuilder.getAllExtras().getCharSequence(EXTRA_TEXT); mBuilder.getAllExtras().putCharSequence(EXTRA_TEXT, null); - RemoteViews contentView = getStandardView(mBuilder.getBigTextLayoutResource()); + TemplateBindResult result = new TemplateBindResult(); + RemoteViews contentView = getStandardView(mBuilder.getBigTextLayoutResource(), result); + contentView.setInt(R.id.big_text, "setImageEndMargin", result.getIconMarginEnd()); mBuilder.getAllExtras().putCharSequence(EXTRA_TEXT, text); @@ -6771,7 +6850,7 @@ public class Notification implements Parcelable mBuilder.mOriginalActions = mBuilder.mActions; mBuilder.mActions = new ArrayList<>(); RemoteViews remoteViews = makeMessagingView(true /* displayImagesAtEnd */, - true /* showReplyIcon */); + false /* hideLargeIcon */); mBuilder.mActions = mBuilder.mOriginalActions; mBuilder.mOriginalActions = null; return remoteViews; @@ -6858,7 +6937,7 @@ public class Notification implements Parcelable */ @Override public RemoteViews makeBigContentView() { - return makeMessagingView(false /* displayImagesAtEnd */, false /* showReplyIcon */); + return makeMessagingView(false /* displayImagesAtEnd */, true /* hideLargeIcon */); } /** @@ -6866,11 +6945,11 @@ public class Notification implements Parcelable * * @param displayImagesAtEnd should images be displayed at the end of the content instead * of inline. - * @param showReplyIcon Should the reply affordance be shown at the end of the notification + * @param hideRightIcons Should the reply affordance be shown at the end of the notification * @return the created remoteView. */ @NonNull - private RemoteViews makeMessagingView(boolean displayImagesAtEnd, boolean showReplyIcon) { + private RemoteViews makeMessagingView(boolean displayImagesAtEnd, boolean hideRightIcons) { CharSequence conversationTitle = !TextUtils.isEmpty(super.mBigContentTitle) ? super.mBigContentTitle : mConversationTitle; @@ -6881,20 +6960,18 @@ public class Notification implements Parcelable nameReplacement = conversationTitle; conversationTitle = null; } - boolean hideLargeIcon = !showReplyIcon || isOneToOne; + TemplateBindResult bindResult = new TemplateBindResult(); RemoteViews contentView = mBuilder.applyStandardTemplateWithActions( mBuilder.getMessagingLayoutResource(), mBuilder.mParams.reset().hasProgress(false).title(conversationTitle).text(null) - .hideLargeIcon(hideLargeIcon) - .headerTextSecondary(conversationTitle) - .alwaysShowReply(showReplyIcon)); + .hideLargeIcon(hideRightIcons || isOneToOne) + .hideReplyIcon(hideRightIcons) + .headerTextSecondary(conversationTitle), + bindResult); addExtras(mBuilder.mN.extras); // also update the end margin if there is an image - int endMargin = R.dimen.notification_content_margin_end; - if (showReplyIcon) { - endMargin = R.dimen.notification_content_plus_picture_margin_end; - } - contentView.setViewLayoutMarginEndDimen(R.id.notification_main_column, endMargin); + contentView.setViewLayoutMarginEnd(R.id.notification_messaging, + bindResult.getIconMarginEnd()); contentView.setInt(R.id.status_bar_latest_event_content, "setLayoutColor", mBuilder.resolveContrastColor()); contentView.setBoolean(R.id.status_bar_latest_event_content, "setDisplayImagesAtEnd", @@ -6966,7 +7043,7 @@ public class Notification implements Parcelable @Override public RemoteViews makeHeadsUpContentView(boolean increasedHeight) { RemoteViews remoteViews = makeMessagingView(true /* displayImagesAtEnd */, - false /* showReplyIcon */); + true /* hideLargeIcon */); remoteViews.setInt(R.id.notification_messaging, "setMaxDisplayedLines", 1); return remoteViews; } @@ -7349,7 +7426,8 @@ public class Notification implements Parcelable CharSequence oldBuilderContentText = mBuilder.mN.extras.getCharSequence(EXTRA_TEXT); mBuilder.getAllExtras().putCharSequence(EXTRA_TEXT, null); - RemoteViews contentView = getStandardView(mBuilder.getInboxLayoutResource()); + TemplateBindResult result = new TemplateBindResult(); + RemoteViews contentView = getStandardView(mBuilder.getInboxLayoutResource(), result); mBuilder.getAllExtras().putCharSequence(EXTRA_TEXT, oldBuilderContentText); @@ -7378,7 +7456,8 @@ public class Notification implements Parcelable mBuilder.processTextSpans(mBuilder.processLegacyText(str))); mBuilder.setTextViewColorSecondary(contentView, rowIds[i]); contentView.setViewPadding(rowIds[i], 0, topPadding, 0, 0); - handleInboxImageMargin(contentView, rowIds[i], first); + handleInboxImageMargin(contentView, rowIds[i], first, + result.getIconMarginEnd()); if (first) { onlyViewId = rowIds[i]; } else { @@ -7410,17 +7489,18 @@ public class Notification implements Parcelable return !Objects.equals(getLines(), newS.getLines()); } - private void handleInboxImageMargin(RemoteViews contentView, int id, boolean first) { + private void handleInboxImageMargin(RemoteViews contentView, int id, boolean first, + int marginEndValue) { int endMargin = 0; if (first) { final int max = mBuilder.mN.extras.getInt(EXTRA_PROGRESS_MAX, 0); final boolean ind = mBuilder.mN.extras.getBoolean(EXTRA_PROGRESS_INDETERMINATE); boolean hasProgress = max != 0 || ind; - if (mBuilder.mN.hasLargeIcon() && !hasProgress) { - endMargin = R.dimen.notification_content_picture_margin; + if (!hasProgress) { + endMargin = marginEndValue; } } - contentView.setViewLayoutMarginEndDimen(id, endMargin); + contentView.setViewLayoutMarginEnd(id, endMargin); } } @@ -7609,7 +7689,8 @@ public class Notification implements Parcelable private RemoteViews makeMediaContentView() { RemoteViews view = mBuilder.applyStandardTemplate( - R.layout.notification_template_material_media, false /* hasProgress */); + R.layout.notification_template_material_media, false, /* hasProgress */ + null /* result */); final int numActions = mBuilder.mActions.size(); final int N = mActionsToShowInCompact == null @@ -7633,7 +7714,7 @@ public class Notification implements Parcelable // handle the content margin int endMargin = R.dimen.notification_content_margin_end; if (mBuilder.mN.hasLargeIcon()) { - endMargin = R.dimen.notification_content_plus_picture_margin_end; + endMargin = R.dimen.notification_media_image_margin_end; } view.setViewLayoutMarginEndDimen(R.id.notification_main_column, endMargin); return view; @@ -7654,8 +7735,7 @@ public class Notification implements Parcelable return null; } RemoteViews big = mBuilder.applyStandardTemplate( - R.layout.notification_template_material_big_media, - false); + R.layout.notification_template_material_big_media, false, null /* result */); if (actionCount > 0) { big.removeAllViews(com.android.internal.R.id.media_actions); @@ -7751,16 +7831,18 @@ public class Notification implements Parcelable if (mBuilder.mActions.size() == 0) { return makeStandardTemplateWithCustomContent(headsUpContentView); } + TemplateBindResult result = new TemplateBindResult(); RemoteViews remoteViews = mBuilder.applyStandardTemplateWithActions( - mBuilder.getBigBaseLayoutResource()); - buildIntoRemoteViewContent(remoteViews, headsUpContentView); + mBuilder.getBigBaseLayoutResource(), result); + buildIntoRemoteViewContent(remoteViews, headsUpContentView, result); return remoteViews; } private RemoteViews makeStandardTemplateWithCustomContent(RemoteViews customContent) { + TemplateBindResult result = new TemplateBindResult(); RemoteViews remoteViews = mBuilder.applyStandardTemplate( - mBuilder.getBaseLayoutResource()); - buildIntoRemoteViewContent(remoteViews, customContent); + mBuilder.getBaseLayoutResource(), result); + buildIntoRemoteViewContent(remoteViews, customContent, result); return remoteViews; } @@ -7771,14 +7853,15 @@ public class Notification implements Parcelable if (mBuilder.mActions.size() == 0) { return makeStandardTemplateWithCustomContent(bigContentView); } + TemplateBindResult result = new TemplateBindResult(); RemoteViews remoteViews = mBuilder.applyStandardTemplateWithActions( - mBuilder.getBigBaseLayoutResource()); - buildIntoRemoteViewContent(remoteViews, bigContentView); + mBuilder.getBigBaseLayoutResource(), result); + buildIntoRemoteViewContent(remoteViews, bigContentView, result); return remoteViews; } private void buildIntoRemoteViewContent(RemoteViews remoteViews, - RemoteViews customContent) { + RemoteViews customContent, TemplateBindResult result) { if (customContent != null) { // Need to clone customContent before adding, because otherwise it can no longer be // parceled independently of remoteViews. @@ -7788,11 +7871,10 @@ public class Notification implements Parcelable remoteViews.setReapplyDisallowed(); } // also update the end margin if there is an image - int endMargin = R.dimen.notification_content_margin_end; - if (mBuilder.mN.hasLargeIcon()) { - endMargin = R.dimen.notification_content_plus_picture_margin_end; - } - remoteViews.setViewLayoutMarginEndDimen(R.id.notification_main_column, endMargin); + Resources resources = mBuilder.mContext.getResources(); + int endMargin = resources.getDimensionPixelSize( + R.dimen.notification_content_margin_end) + result.getIconMarginEnd(); + remoteViews.setViewLayoutMarginEnd(R.id.notification_main_column, endMargin); } /** @@ -9396,6 +9478,25 @@ public class Notification implements Parcelable } } + /** + * A result object where information about the template that was created is saved. + */ + private static class TemplateBindResult { + int mIconMarginEnd; + + /** + * Get the margin end that needs to be added to any fields that may overlap + * with the right actions. + */ + public int getIconMarginEnd() { + return mIconMarginEnd; + } + + public void setIconMarginEnd(int iconMarginEnd) { + this.mIconMarginEnd = iconMarginEnd; + } + } + private static class StandardTemplateParams { boolean hasProgress = true; boolean ambient = false; @@ -9403,7 +9504,7 @@ public class Notification implements Parcelable CharSequence text; CharSequence headerTextSecondary; boolean hideLargeIcon; - public boolean alwaysShowReply; + boolean hideReplyIcon; final StandardTemplateParams reset() { hasProgress = true; @@ -9434,13 +9535,13 @@ public class Notification implements Parcelable return this; } - final StandardTemplateParams alwaysShowReply(boolean alwaysShowReply) { - this.alwaysShowReply = alwaysShowReply; + final StandardTemplateParams hideLargeIcon(boolean hideLargeIcon) { + this.hideLargeIcon = hideLargeIcon; return this; } - final StandardTemplateParams hideLargeIcon(boolean hideLargeIcon) { - this.hideLargeIcon = hideLargeIcon; + final StandardTemplateParams hideReplyIcon(boolean hideReplyIcon) { + this.hideReplyIcon = hideReplyIcon; return this; } diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index 315259bdf388..bdaf80e374df 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -33,8 +33,11 @@ import android.os.Parcelable; import android.os.RemoteException; import android.os.UserHandle; import android.util.AndroidException; +import android.util.ArraySet; import android.util.proto.ProtoOutputStream; +import com.android.internal.os.IResultReceiver; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -93,7 +96,9 @@ import java.lang.annotation.RetentionPolicy; */ public final class PendingIntent implements Parcelable { private final IIntentSender mTarget; + private IResultReceiver mCancelReceiver; private IBinder mWhitelistToken; + private ArraySet<CancelListener> mCancelListeners; /** @hide */ @IntDef(flag = true, @@ -964,6 +969,74 @@ public final class PendingIntent implements Parcelable { } /** + * Register a listener to when this pendingIntent is cancelled. There are no guarantees on which + * thread a listener will be called and it's up to the caller to synchronize. This may + * trigger a synchronous binder call so should therefore usually be called on a background + * thread. + * + * @hide + */ + public void registerCancelListener(CancelListener cancelListener) { + synchronized (this) { + if (mCancelReceiver == null) { + mCancelReceiver = new IResultReceiver.Stub() { + @Override + public void send(int resultCode, Bundle resultData) throws RemoteException { + notifyCancelListeners(); + } + }; + } + if (mCancelListeners == null) { + mCancelListeners = new ArraySet<>(); + } + boolean wasEmpty = mCancelListeners.isEmpty(); + mCancelListeners.add(cancelListener); + if (wasEmpty) { + try { + ActivityManager.getService().registerIntentSenderCancelListener(mTarget, + mCancelReceiver); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + } + + private void notifyCancelListeners() { + ArraySet<CancelListener> cancelListeners; + synchronized (this) { + cancelListeners = new ArraySet<>(mCancelListeners); + } + int size = cancelListeners.size(); + for (int i = 0; i < size; i++) { + cancelListeners.valueAt(i).onCancelled(this); + } + } + + /** + * Un-register a listener to when this pendingIntent is cancelled. + * + * @hide + */ + public void unregisterCancelListener(CancelListener cancelListener) { + synchronized (this) { + if (mCancelListeners == null) { + return; + } + boolean wasEmpty = mCancelListeners.isEmpty(); + mCancelListeners.remove(cancelListener); + if (mCancelListeners.isEmpty() && !wasEmpty) { + try { + ActivityManager.getService().unregisterIntentSenderCancelListener(mTarget, + mCancelReceiver); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + } + + /** * Return the user handle of the application that created this * PendingIntent, that is the user under which you will actually be * sending the Intent. The returned UserHandle is supplied by the system, so @@ -1184,4 +1257,18 @@ public final class PendingIntent implements Parcelable { public IBinder getWhitelistToken() { return mWhitelistToken; } + + /** + * A listener to when a pending intent is cancelled + * + * @hide + */ + public interface CancelListener { + /** + * Called when a Pending Intent is cancelled. + * + * @param intent The intent that was cancelled. + */ + void onCancelled(PendingIntent intent); + } } diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index b6bd14ed5efd..5ecbf90a4eca 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -946,6 +946,7 @@ public class RemoteViews implements Parcelable, Filter { } }; } + target.setTagInternal(R.id.pending_intent_tag, pendingIntent); target.setOnClickListener(listener); } @@ -1999,6 +2000,7 @@ public class RemoteViews implements Parcelable, Filter { /** Set width */ public static final int LAYOUT_WIDTH = 2; public static final int LAYOUT_MARGIN_BOTTOM_DIMEN = 3; + public static final int LAYOUT_MARGIN_END = 4; final int mProperty; final int mValue; @@ -2036,11 +2038,14 @@ public class RemoteViews implements Parcelable, Filter { if (layoutParams == null) { return; } + int value = mValue; switch (mProperty) { case LAYOUT_MARGIN_END_DIMEN: + value = resolveDimenPixelOffset(target, mValue); + // fall-through + case LAYOUT_MARGIN_END: if (layoutParams instanceof ViewGroup.MarginLayoutParams) { - int resolved = resolveDimenPixelOffset(target, mValue); - ((ViewGroup.MarginLayoutParams) layoutParams).setMarginEnd(resolved); + ((ViewGroup.MarginLayoutParams) layoutParams).setMarginEnd(value); target.setLayoutParams(layoutParams); } break; @@ -2980,6 +2985,20 @@ public class RemoteViews implements Parcelable, Filter { } /** + * Equivalent to calling {@link android.view.ViewGroup.MarginLayoutParams#setMarginEnd(int)}. + * Only works if the {@link View#getLayoutParams()} supports margins. + * Hidden for now since we don't want to support this for all different layout margins yet. + * + * @param viewId The id of the view to change + * @param endMargin a value in pixels for the end margin. + * @hide + */ + public void setViewLayoutMarginEnd(int viewId, @DimenRes int endMargin) { + addAction(new LayoutParamAction(viewId, LayoutParamAction.LAYOUT_MARGIN_END, + endMargin)); + } + + /** * Equivalent to setting {@link android.view.ViewGroup.MarginLayoutParams#bottomMargin}. * * @param bottomMarginDimen a dimen resource to read the margin from or 0 to clear the margin. |
