Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3832)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java

Issue 1441723002: Notification custom layouts: paint the button icon for Material. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Documentation tweaks. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java
index 56f067322507dee04ffe4be02b652bc94b2103c8..e8bca7457097cd0269a4f36b167d2190271b0df5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java
@@ -7,7 +7,13 @@
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Action;
@@ -17,6 +23,7 @@
import android.view.View;
import android.widget.RemoteViews;
+import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R;
@@ -60,7 +67,23 @@
* flexible amount of padding. If the font size is scaled up the applied padding will be scaled
* down towards 0.
*/
- private static final int MAX_SCALABLE_PADDING_DIP = 3;
+ private static final int MAX_SCALABLE_PADDING_DP = 3;
+
+ /**
+ * The amount of padding at the start of the button, either before an icon or before the text.
+ */
+ private static final int BUTTON_PADDING_START_DP = 8;
+
+ /**
+ * The amount of padding between the icon and text of a button. Used only if there is an icon.
+ */
+ private static final int BUTTON_ICON_PADDING_DP = 8;
+
+ /**
+ * The color named "secondary_text_default_material_light" with hex value #8a000000 converted to
Peter Beverloo 2015/11/16 11:18:12 nit: don't name the value (that's up to the style
Michael van Ouwerkerk 2015/11/17 12:00:23 Acknowledged.
+ * an int.
+ */
+ private static final int BUTTON_ICON_COLOR_MATERIAL = -1979711488;
Peter Beverloo 2015/11/16 11:18:13 _ID?
newt (away) 2015/11/16 17:50:09 You can just write this as "0x8a000000". Or you co
Michael van Ouwerkerk 2015/11/17 12:00:23 Done (the getColor part). Nice.
Michael van Ouwerkerk 2015/11/17 12:00:23 This number is not an id, it's a color value.
private final Context mContext;
@@ -101,21 +124,9 @@ public Notification build() {
view.setViewPadding(R.id.title, 0, scaledPadding, 0, 0);
view.setViewPadding(R.id.body, 0, scaledPadding, 0, scaledPadding);
}
+ addActionButtons(bigView);
- if (!mActions.isEmpty()) {
- bigView.setViewVisibility(R.id.button_divider, View.VISIBLE);
- bigView.setViewVisibility(R.id.buttons, View.VISIBLE);
- for (Action action : mActions) {
- RemoteViews button = new RemoteViews(
- mContext.getPackageName(), R.layout.web_notification_button);
- button.setTextViewCompoundDrawablesRelative(R.id.button, action.getIcon(), 0, 0, 0);
- button.setTextViewText(R.id.button, action.getTitle());
- button.setOnClickPendingIntent(R.id.button, action.getActionIntent());
- bigView.addView(R.id.buttons, button);
- }
- }
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ if (useMaterial()) {
compactView.setViewVisibility(R.id.small_icon_overlay, View.VISIBLE);
bigView.setViewVisibility(R.id.small_icon_overlay, View.VISIBLE);
} else {
@@ -207,6 +218,53 @@ public NotificationBuilder setVibrate(long[] pattern) {
return this;
}
+ /**
+ * If there are actions, shows the button related views, and adds a button for each action.
+ */
+ private void addActionButtons(RemoteViews bigView) {
+ if (mActions.isEmpty()) {
+ return;
+ }
+ bigView.setViewVisibility(R.id.button_divider, View.VISIBLE);
+ bigView.setViewVisibility(R.id.buttons, View.VISIBLE);
+ Resources resources = mContext.getResources();
+ DisplayMetrics metrics = resources.getDisplayMetrics();
+ boolean ltr = ApiCompatibilityUtils.getLayoutDirection(resources.getConfiguration())
Peter Beverloo 2015/11/16 11:18:13 LocalizationUtils.isLayoutRtl() It's much more co
newt (away) 2015/11/16 17:50:09 "isRtl" is the typical variable name in cases like
Michael van Ouwerkerk 2015/11/17 12:00:23 Done.
Michael van Ouwerkerk 2015/11/17 12:00:23 Done.
+ == View.LAYOUT_DIRECTION_LTR;
+ for (Action action : mActions) {
+ RemoteViews view =
+ new RemoteViews(mContext.getPackageName(), R.layout.web_notification_button);
+
+ if (action.getIcon() != 0) {
Peter Beverloo 2015/11/16 11:18:13 You mention in the XML file that a Bitmap is the f
Michael van Ouwerkerk 2015/11/17 12:00:23 Done.
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inMutable = true;
Peter Beverloo 2015/11/16 11:18:12 Why do we need this?
Michael van Ouwerkerk 2015/11/17 12:00:23 Only mutable bitmaps can be painted, otherwise an
+ Bitmap icon = BitmapFactory.decodeResource(resources, action.getIcon(), options);
+
+ // Currently the only button icon we use is the settings gear, which is known to
+ // have the correct color for Holo (white) but not for Material. Once we have web
+ // developer provided icons we'll need to decide how to process them, if at all.
+ if (useMaterial()) {
+ paintBitmap(icon, BUTTON_ICON_COLOR_MATERIAL);
newt (away) 2015/11/16 17:50:09 Could you use "setColorFilter" on the ImageButton
Michael van Ouwerkerk 2015/11/17 12:00:23 But how could we? We only have RemoteViews here, a
newt (away) 2015/11/17 20:04:40 setColorFilter(int) is @RemotableViewMethod, but i
Michael van Ouwerkerk 2015/11/18 14:08:40 The top view needs to be a Button, so that TalkBac
+ }
+ view.setImageViewBitmap(R.id.button_icon, icon);
+
+ // Set the padding of the button so the text does not overlap with the icon. Flip
+ // between left and right manually as RemoteViews does not expose a method that sets
+ // padding in a writing-direction independent way.
+ int buttonPadding =
+ dpToPx(BUTTON_PADDING_START_DP + BUTTON_ICON_PADDING_DP, metrics)
+ + icon.getWidth();
newt (away) 2015/11/16 17:50:08 Are we sure that the icon won't be unexpectedly wi
Michael van Ouwerkerk 2015/11/17 12:00:23 For now, we are sure it is ok, as we don't have we
+ int buttonPaddingLeft = ltr ? buttonPadding : 0;
+ int buttonPaddingRight = ltr ? 0 : buttonPadding;
+ view.setViewPadding(R.id.button, buttonPaddingLeft, 0, buttonPaddingRight, 0);
+ }
+
+ view.setTextViewText(R.id.button, action.getTitle());
+ view.setOnClickPendingIntent(R.id.button, action.getActionIntent());
+ bigView.addView(R.id.buttons, view);
+ }
+ }
+
@Nullable
private static CharSequence limitLength(@Nullable CharSequence input) {
if (input == null) {
@@ -252,7 +310,33 @@ static int calculateScaledPadding(float fontScale, DisplayMetrics displayMetrics
fontScale = Math.min(fontScale, FONT_SCALE_LARGE);
paddingScale = (FONT_SCALE_LARGE - fontScale) / (FONT_SCALE_LARGE - 1.0f);
}
- return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
- paddingScale * MAX_SCALABLE_PADDING_DIP, displayMetrics));
+ return dpToPx(paddingScale * MAX_SCALABLE_PADDING_DP, displayMetrics);
+ }
+
+ /**
+ * Converts a dp value to a px value.
+ */
+ private static int dpToPx(float value, DisplayMetrics displayMetrics) {
+ return Math.round(
+ TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, displayMetrics));
+ }
+
+ /**
+ * Whether to use the Material look and feel or fall back to Holo.
+ */
+ private static boolean useMaterial() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
+ }
+
+ /**
+ * Paints |bitmap| with |color| using |PorterDuff.Mode.MULTIPLY|.
+ */
+ @VisibleForTesting
+ static Bitmap paintBitmap(Bitmap bitmap, int color) {
+ Paint paint = new Paint();
+ paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
+ Canvas canvas = new Canvas(bitmap);
+ canvas.drawBitmap(bitmap, 0, 0, paint);
+ return bitmap;
}
}

Powered by Google App Engine
This is Rietveld 408576698