| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.notifications; | 5 package org.chromium.chrome.browser.notifications; |
| 6 | 6 |
| 7 import android.annotation.TargetApi; |
| 7 import android.app.Notification; | 8 import android.app.Notification; |
| 8 import android.app.PendingIntent; | 9 import android.app.PendingIntent; |
| 9 import android.graphics.Bitmap; | 10 import android.graphics.Bitmap; |
| 10 import android.support.v4.app.NotificationCompat.Action; | 11 import android.graphics.drawable.Icon; |
| 12 import android.os.Build; |
| 11 | 13 |
| 12 import org.chromium.base.VisibleForTesting; | 14 import org.chromium.base.VisibleForTesting; |
| 13 | 15 |
| 14 import java.util.ArrayList; | 16 import java.util.ArrayList; |
| 15 import java.util.Arrays; | 17 import java.util.Arrays; |
| 16 import java.util.List; | 18 import java.util.List; |
| 17 | 19 |
| 18 import javax.annotation.Nullable; | 20 import javax.annotation.Nullable; |
| 19 | 21 |
| 20 /** | 22 /** |
| 21 * Abstract base class for building a notification. Stores all given arguments f
or later use. | 23 * Abstract base class for building a notification. Stores all given arguments f
or later use. |
| 22 */ | 24 */ |
| 23 public abstract class NotificationBuilderBase { | 25 public abstract class NotificationBuilderBase { |
| 26 protected static class Action { |
| 27 public int iconId; |
| 28 public Bitmap iconBitmap; |
| 29 public CharSequence title; |
| 30 public PendingIntent intent; |
| 31 |
| 32 Action(int iconId, CharSequence title, PendingIntent intent) { |
| 33 this.iconId = iconId; |
| 34 this.title = title; |
| 35 this.intent = intent; |
| 36 } |
| 37 |
| 38 Action(Bitmap iconBitmap, CharSequence title, PendingIntent intent) { |
| 39 this.iconBitmap = iconBitmap; |
| 40 this.title = title; |
| 41 this.intent = intent; |
| 42 } |
| 43 } |
| 44 |
| 24 /** | 45 /** |
| 25 * Maximum length of CharSequence inputs to prevent excessive memory consump
tion. At current | 46 * Maximum length of CharSequence inputs to prevent excessive memory consump
tion. At current |
| 26 * screen sizes we display about 500 characters at most, so this is a pretty
generous limit, and | 47 * screen sizes we display about 500 characters at most, so this is a pretty
generous limit, and |
| 27 * it matches what the Notification class does. | 48 * it matches what the Notification class does. |
| 28 */ | 49 */ |
| 29 @VisibleForTesting | 50 @VisibleForTesting |
| 30 static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024; | 51 static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024; |
| 31 | 52 |
| 32 /** | 53 /** |
| 33 * The maximum number of action buttons. One is for the settings button, and
two more slots are | 54 * The maximum number of author provided action buttons. The settings button
is not part of this |
| 34 * for developer provided buttons. | 55 * count. |
| 35 */ | 56 */ |
| 36 private static final int MAX_ACTION_BUTTONS = 3; | 57 private static final int MAX_AUTHOR_PROVIDED_ACTION_BUTTONS = 2; |
| 37 | 58 |
| 38 protected CharSequence mTitle; | 59 protected CharSequence mTitle; |
| 39 protected CharSequence mBody; | 60 protected CharSequence mBody; |
| 40 protected CharSequence mOrigin; | 61 protected CharSequence mOrigin; |
| 41 protected CharSequence mTickerText; | 62 protected CharSequence mTickerText; |
| 42 protected Bitmap mLargeIcon; | 63 protected Bitmap mLargeIcon; |
| 43 protected int mSmallIconId; | 64 protected int mSmallIconId; |
| 44 protected PendingIntent mContentIntent; | 65 protected PendingIntent mContentIntent; |
| 45 protected PendingIntent mDeleteIntent; | 66 protected PendingIntent mDeleteIntent; |
| 46 protected List<Action> mActions = new ArrayList<>(MAX_ACTION_BUTTONS); | 67 protected List<Action> mActions = new ArrayList<>(MAX_AUTHOR_PROVIDED_ACTION
_BUTTONS); |
| 47 protected Action mSettingsAction; | 68 protected Action mSettingsAction; |
| 48 protected int mDefaults = Notification.DEFAULT_ALL; | 69 protected int mDefaults = Notification.DEFAULT_ALL; |
| 49 protected long[] mVibratePattern; | 70 protected long[] mVibratePattern; |
| 50 protected long mTimestamp; | 71 protected long mTimestamp; |
| 51 | 72 |
| 52 /** | 73 /** |
| 53 * Combines all of the options that have been set and returns a new Notifica
tion object. | 74 * Combines all of the options that have been set and returns a new Notifica
tion object. |
| 54 */ | 75 */ |
| 55 public abstract Notification build(); | 76 public abstract Notification build(); |
| 56 | 77 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 mDeleteIntent = intent; | 139 mDeleteIntent = intent; |
| 119 return this; | 140 return this; |
| 120 } | 141 } |
| 121 | 142 |
| 122 /** | 143 /** |
| 123 * Adds an action to the notification. Actions are typically displayed as a
button adjacent to | 144 * Adds an action to the notification. Actions are typically displayed as a
button adjacent to |
| 124 * the notification content. | 145 * the notification content. |
| 125 */ | 146 */ |
| 126 public NotificationBuilderBase addAction( | 147 public NotificationBuilderBase addAction( |
| 127 int iconId, @Nullable CharSequence title, @Nullable PendingIntent in
tent) { | 148 int iconId, @Nullable CharSequence title, @Nullable PendingIntent in
tent) { |
| 128 if (mActions.size() == MAX_ACTION_BUTTONS) { | 149 if (mActions.size() == MAX_AUTHOR_PROVIDED_ACTION_BUTTONS) { |
| 129 throw new IllegalStateException( | 150 throw new IllegalStateException( |
| 130 "Cannot add more than " + MAX_ACTION_BUTTONS + " actions."); | 151 "Cannot add more than " + MAX_AUTHOR_PROVIDED_ACTION_BUTTONS
+ " actions."); |
| 131 } | 152 } |
| 132 mActions.add(new Action(iconId, limitLength(title), intent)); | 153 mActions.add(new Action(iconId, limitLength(title), intent)); |
| 133 return this; | 154 return this; |
| 134 } | 155 } |
| 135 | 156 |
| 136 /** | 157 /** |
| 158 * Adds an action to the notification. Actions are typically displayed as a
button adjacent to |
| 159 * the notification content. |
| 160 */ |
| 161 public NotificationBuilderBase addAction(@Nullable Bitmap iconBitmap, |
| 162 @Nullable CharSequence title, @Nullable PendingIntent intent) { |
| 163 if (mActions.size() == MAX_AUTHOR_PROVIDED_ACTION_BUTTONS) { |
| 164 throw new IllegalStateException( |
| 165 "Cannot add more than " + MAX_AUTHOR_PROVIDED_ACTION_BUTTONS
+ " actions."); |
| 166 } |
| 167 mActions.add(new Action(iconBitmap, limitLength(title), intent)); |
| 168 return this; |
| 169 } |
| 170 |
| 171 /** |
| 137 * Adds an action to the notification for opening the settings screen. | 172 * Adds an action to the notification for opening the settings screen. |
| 138 */ | 173 */ |
| 139 public NotificationBuilderBase addSettingsAction( | 174 public NotificationBuilderBase addSettingsAction( |
| 140 int iconId, @Nullable CharSequence title, @Nullable PendingIntent in
tent) { | 175 int iconId, @Nullable CharSequence title, @Nullable PendingIntent in
tent) { |
| 141 mSettingsAction = new Action(iconId, limitLength(title), intent); | 176 mSettingsAction = new Action(iconId, limitLength(title), intent); |
| 142 return this; | 177 return this; |
| 143 } | 178 } |
| 144 | 179 |
| 145 /** | 180 /** |
| 146 * Sets the default notification options that will be used. | 181 * Sets the default notification options that will be used. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 176 @Nullable | 211 @Nullable |
| 177 private static CharSequence limitLength(@Nullable CharSequence input) { | 212 private static CharSequence limitLength(@Nullable CharSequence input) { |
| 178 if (input == null) { | 213 if (input == null) { |
| 179 return input; | 214 return input; |
| 180 } | 215 } |
| 181 if (input.length() > MAX_CHARSEQUENCE_LENGTH) { | 216 if (input.length() > MAX_CHARSEQUENCE_LENGTH) { |
| 182 return input.subSequence(0, MAX_CHARSEQUENCE_LENGTH); | 217 return input.subSequence(0, MAX_CHARSEQUENCE_LENGTH); |
| 183 } | 218 } |
| 184 return input; | 219 return input; |
| 185 } | 220 } |
| 221 |
| 222 /** |
| 223 * Adds an action to {@code builder} using a {@code Bitmap} if a bitmap is p
rovided and the API |
| 224 * level is high enough, otherwise a resource id is used. |
| 225 */ |
| 226 @SuppressWarnings("deprecation") // For addAction(int, CharSequence, Pending
Intent) |
| 227 @TargetApi(Build.VERSION_CODES.M) // For the Icon class. |
| 228 protected static void addActionToBuilder(Notification.Builder builder, Actio
n action) { |
| 229 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && action.iconBitmap
!= null) { |
| 230 Icon icon = Icon.createWithBitmap(action.iconBitmap); |
| 231 builder.addAction( |
| 232 new Notification.Action.Builder(icon, action.title, action.i
ntent).build()); |
| 233 } else { |
| 234 builder.addAction(action.iconId, action.title, action.intent); |
| 235 } |
| 236 } |
| 186 } | 237 } |
| OLD | NEW |