From a785a580345d7b607dcf390e77bd46356a9fc43f Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Mon, 22 Feb 2021 13:19:07 -0500 Subject: [PATCH] Add API to let apps color CallStyle notifications themselves. Fixes: 180925557 Test: visual inspection Test: atest NotificationTemplateTest Change-Id: I5f580083f1de192985b4764b894730789c2c2583 --- core/api/current.txt | 4 ++ core/java/android/app/Notification.java | 88 ++++++++++++++++++++----- core/res/res/values/config.xml | 3 + core/res/res/values/symbols.xml | 1 + 4 files changed, 81 insertions(+), 15 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 24a6c4a6bc39b..809334d805208 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -5610,6 +5610,7 @@ package android.app { field public static final int DEFAULT_LIGHTS = 4; // 0x4 field public static final int DEFAULT_SOUND = 1; // 0x1 field public static final int DEFAULT_VIBRATE = 2; // 0x2 + field public static final String EXTRA_ANSWER_COLOR = "android.answerColor"; field public static final String EXTRA_ANSWER_INTENT = "android.answerIntent"; field public static final String EXTRA_AUDIO_CONTENTS_URI = "android.audioContents"; field public static final String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri"; @@ -5621,6 +5622,7 @@ package android.app { field public static final String EXTRA_COLORIZED = "android.colorized"; field public static final String EXTRA_COMPACT_ACTIONS = "android.compactActions"; field public static final String EXTRA_CONVERSATION_TITLE = "android.conversationTitle"; + field public static final String EXTRA_DECLINE_COLOR = "android.declineColor"; field public static final String EXTRA_DECLINE_INTENT = "android.declineIntent"; field public static final String EXTRA_HANG_UP_INTENT = "android.hangUpIntent"; field public static final String EXTRA_HISTORIC_MESSAGES = "android.messages.historic"; @@ -5908,6 +5910,8 @@ package android.app { method @NonNull public static android.app.Notification.CallStyle forIncomingCall(@NonNull android.app.Person, @NonNull android.app.PendingIntent, @NonNull android.app.PendingIntent); method @NonNull public static android.app.Notification.CallStyle forOngoingCall(@NonNull android.app.Person, @NonNull android.app.PendingIntent); method @NonNull public static android.app.Notification.CallStyle forScreeningCall(@NonNull android.app.Person, @NonNull android.app.PendingIntent, @NonNull android.app.PendingIntent); + method @NonNull public android.app.Notification.CallStyle setAnswerButtonColorHint(@ColorInt int); + method @NonNull public android.app.Notification.CallStyle setDeclineButtonColorHint(@ColorInt int); method @NonNull public android.app.Notification.CallStyle setVerificationIcon(@Nullable android.graphics.drawable.Icon); method @NonNull public android.app.Notification.CallStyle setVerificationText(@Nullable CharSequence); } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 899cdb5eb572a..f7304fbee6d6c 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -1370,6 +1370,18 @@ public class Notification implements Parcelable */ public static final String EXTRA_HANG_UP_INTENT = "android.hangUpIntent"; + /** + * {@link #extras} key: the color used as a hint for the Answer action button of a + * {@link android.app.Notification.CallStyle} notification. This extra is a {@link ColorInt}. + */ + public static final String EXTRA_ANSWER_COLOR = "android.answerColor"; + + /** + * {@link #extras} key: the color used as a hint for the Decline or Hang Up action button of a + * {@link android.app.Notification.CallStyle} notification. This extra is a {@link ColorInt}. + */ + public static final String EXTRA_DECLINE_COLOR = "android.declineColor"; + /** * {@link #extras} key: whether the notification should be colorized as * supplied to {@link Builder#setColorized(boolean)}. @@ -5444,6 +5456,11 @@ public class Notification implements Parcelable return p.allowColorization && mN.isColorized(); } + private boolean isCallActionColorCustomizable(StandardTemplateParams p) { + return isColorized(p) && mContext.getResources().getBoolean( + R.bool.config_callNotificationActionColorsRequireColorized); + } + private void bindSmallIcon(RemoteViews contentView, StandardTemplateParams p) { if (mN.mSmallIcon == null && mN.icon != 0) { mN.mSmallIcon = Icon.createWithResource(mContext, mN.icon); @@ -9066,6 +9083,8 @@ public class Notification implements Parcelable private PendingIntent mAnswerIntent; private PendingIntent mDeclineIntent; private PendingIntent mHangUpIntent; + private Integer mAnswerButtonColor; + private Integer mDeclineButtonColor; private Icon mVerificationIcon; private CharSequence mVerificationText; @@ -9175,6 +9194,28 @@ public class Notification implements Parcelable return this; } + /** + * Optional color to be used as a hint for the Answer action button's color. + * The system may change this color to ensure sufficient contrast with the background. + * The system may choose to disregard this hint if the notification is not colorized. + */ + @NonNull + public CallStyle setAnswerButtonColorHint(@ColorInt int color) { + mAnswerButtonColor = color; + return this; + } + + /** + * Optional color to be used as a hint for the Decline or Hang Up action button's color. + * The system may change this color to ensure sufficient contrast with the background. + * The system may choose to disregard this hint if the notification is not colorized. + */ + @NonNull + public CallStyle setDeclineButtonColorHint(@ColorInt int color) { + mDeclineButtonColor = color; + return this; + } + /** * @hide */ @@ -9234,40 +9275,47 @@ public class Notification implements Parcelable } @NonNull - private Action makeNegativeAction() { + private Action makeNegativeAction(@NonNull StandardTemplateParams p) { if (mDeclineIntent == null) { - return makeAction(R.drawable.ic_call_decline, + return makeAction(p, R.drawable.ic_call_decline, R.string.call_notification_hang_up_action, - R.color.call_notification_decline_color, mHangUpIntent); + mDeclineButtonColor, R.color.call_notification_decline_color, + mHangUpIntent); } else { - return makeAction(R.drawable.ic_call_decline, + return makeAction(p, R.drawable.ic_call_decline, R.string.call_notification_decline_action, - R.color.call_notification_decline_color, mDeclineIntent); + mDeclineButtonColor, R.color.call_notification_decline_color, + mDeclineIntent); } } @Nullable - private Action makeAnswerAction() { - return mAnswerIntent == null ? null : makeAction(R.drawable.ic_call_answer, + private Action makeAnswerAction(@NonNull StandardTemplateParams p) { + return mAnswerIntent == null ? null : makeAction(p, R.drawable.ic_call_answer, R.string.call_notification_answer_action, - R.color.call_notification_answer_color, mAnswerIntent); + mAnswerButtonColor, R.color.call_notification_answer_color, + mAnswerIntent); } @NonNull - private Action makeAction(@DrawableRes int icon, @StringRes int title, - @ColorRes int colorRes, PendingIntent intent) { + private Action makeAction(@NonNull StandardTemplateParams p, + @DrawableRes int icon, @StringRes int title, + @ColorInt Integer colorInt, @ColorRes int defaultColorRes, PendingIntent intent) { + if (colorInt == null || !mBuilder.isCallActionColorCustomizable(p)) { + colorInt = mBuilder.mContext.getColor(defaultColorRes); + } Action action = new Action.Builder(Icon.createWithResource("", icon), new SpannableStringBuilder().append(mBuilder.mContext.getString(title), - new ForegroundColorSpan(mBuilder.mContext.getColor(colorRes)), + new ForegroundColorSpan(colorInt), SpannableStringBuilder.SPAN_INCLUSIVE_INCLUSIVE), intent).build(); action.getExtras().putBoolean(KEY_ACTION_PRIORITY, true); return action; } - private ArrayList makeActionsList() { - final Action negativeAction = makeNegativeAction(); - final Action answerAction = makeAnswerAction(); + private ArrayList makeActionsList(@NonNull StandardTemplateParams p) { + final Action negativeAction = makeNegativeAction(p); + final Action answerAction = makeAnswerAction(p); ArrayList actions = new ArrayList<>(MAX_ACTION_BUTTONS); final Action lastAction; @@ -9356,7 +9404,7 @@ public class Notification implements Parcelable // Create the buttons for the generated actions list. int i = 0; - for (Action action : makeActionsList()) { + for (Action action : makeActionsList(p)) { final RemoteViews button = mBuilder.generateActionButton(action, emphasizedMode, p); if (i > 0) { // Clear start margin from non-first buttons to reduce the gap between buttons. @@ -9421,6 +9469,12 @@ public class Notification implements Parcelable if (mHangUpIntent != null) { extras.putParcelable(EXTRA_HANG_UP_INTENT, mHangUpIntent); } + if (mAnswerButtonColor != null) { + extras.putInt(EXTRA_ANSWER_COLOR, mAnswerButtonColor); + } + if (mDeclineButtonColor != null) { + extras.putInt(EXTRA_DECLINE_COLOR, mDeclineButtonColor); + } fixTitleAndTextExtras(extras); } @@ -9447,6 +9501,10 @@ public class Notification implements Parcelable mAnswerIntent = extras.getParcelable(EXTRA_ANSWER_INTENT); mDeclineIntent = extras.getParcelable(EXTRA_DECLINE_INTENT); mHangUpIntent = extras.getParcelable(EXTRA_HANG_UP_INTENT); + mAnswerButtonColor = extras.containsKey(EXTRA_ANSWER_COLOR) + ? extras.getInt(EXTRA_ANSWER_COLOR) : null; + mDeclineButtonColor = extras.containsKey(EXTRA_DECLINE_COLOR) + ? extras.getInt(EXTRA_DECLINE_COLOR) : null; } /** diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 9a917b72a5fdb..592a3a1ff083f 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1173,6 +1173,9 @@ 2875 + + true + 100 diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index e73d6e3af3cbe..7ad05de1bdd0a 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2286,6 +2286,7 @@ +