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

Side by Side Diff: ui/arc/notification/arc_notification_item.cc

Issue 2066853002: arc: Show custom notification via notification surface (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@notification-exo
Patch Set: add comment for use_custom_notification Created 4 years, 6 months 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 unified diff | Download patch
OLDNEW
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 #include "ui/arc/notification/arc_notification_item.h" 5 #include "ui/arc/notification/arc_notification_item.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/memory/ptr_util.h"
10 #include "base/strings/string16.h" 11 #include "base/strings/string16.h"
11 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
12 #include "base/task_runner.h" 13 #include "base/task_runner.h"
13 #include "base/task_runner_util.h" 14 #include "base/task_runner_util.h"
14 #include "base/threading/worker_pool.h" 15 #include "base/threading/worker_pool.h"
15 #include "components/arc/bitmap/bitmap_type_converters.h" 16 #include "components/arc/bitmap/bitmap_type_converters.h"
16 #include "third_party/skia/include/core/SkCanvas.h" 17 #include "third_party/skia/include/core/SkCanvas.h"
17 #include "third_party/skia/include/core/SkPaint.h" 18 #include "third_party/skia/include/core/SkPaint.h"
18 #include "ui/gfx/codec/png_codec.h" 19 #include "ui/gfx/codec/png_codec.h"
19 #include "ui/gfx/geometry/size.h" 20 #include "ui/gfx/geometry/size.h"
20 #include "ui/gfx/image/image.h" 21 #include "ui/gfx/image/image.h"
21 #include "ui/gfx/text_elider.h" 22 #include "ui/gfx/text_elider.h"
22 #include "ui/message_center/message_center_style.h" 23 #include "ui/message_center/message_center_style.h"
23 #include "ui/message_center/notification.h" 24 #include "ui/message_center/notification.h"
24 #include "ui/message_center/notification_types.h" 25 #include "ui/message_center/notification_types.h"
25 #include "ui/message_center/notifier_settings.h" 26 #include "ui/message_center/notifier_settings.h"
26 27
27 namespace arc { 28 namespace arc {
28 29
29 namespace { 30 namespace {
30 31
31 static const char kNotifierId[] = "ARC_NOTIFICATION"; 32 constexpr char kNotifierId[] = "ARC_NOTIFICATION";
32 33 constexpr char kNotificationIdPrefix[] = "ARC_NOTIFICATION_";
33 static const char kNotificationIdPrefix[] = "ARC_NOTIFICATION_";
34 34
35 SkBitmap DecodeImage(const std::vector<uint8_t>& data) { 35 SkBitmap DecodeImage(const std::vector<uint8_t>& data) {
36 DCHECK(base::WorkerPool::RunsTasksOnCurrentThread()); 36 DCHECK(base::WorkerPool::RunsTasksOnCurrentThread());
37 DCHECK(!data.empty()); // empty string should be handled in caller. 37 DCHECK(!data.empty()); // empty string should be handled in caller.
38 38
39 // We may decode an image in the browser process since it has been generated 39 // We may decode an image in the browser process since it has been generated
40 // in NotificationListerService in Android and should be safe. 40 // in NotificationListerService in Android and should be safe.
41 SkBitmap bitmap; 41 SkBitmap bitmap;
42 gfx::PNGCodec::Decode(&data[0], data.size(), &bitmap); 42 gfx::PNGCodec::Decode(&data[0], data.size(), &bitmap);
43 return bitmap; 43 return bitmap;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 SkPaint paint; 79 SkPaint paint;
80 paint.setFilterQuality(kHigh_SkFilterQuality); 80 paint.setFilterQuality(kHigh_SkFilterQuality);
81 SkCanvas container_image(container_bitmap); 81 SkCanvas container_image(container_bitmap);
82 container_image.drawColor(message_center::kImageBackgroundColor); 82 container_image.drawColor(message_center::kImageBackgroundColor);
83 container_image.drawBitmapRect( 83 container_image.drawBitmapRect(
84 original_bitmap, source_rect, SkRect::MakeSize(container_size), &paint); 84 original_bitmap, source_rect, SkRect::MakeSize(container_size), &paint);
85 85
86 return container_bitmap; 86 return container_bitmap;
87 } 87 }
88 88
89 // Converts from Android notification priority to Chrome notification priority.
90 // On Android, PRIORITY_DEFAULT does not pop up, so this maps PRIORITY_DEFAULT
91 // to Chrome's -1 to adapt that behavior. Also, this maps PRIORITY_LOW and _HIGH
92 // to -2 and 0 respectively to adjust the value with keeping the order among
93 // _LOW, _DEFAULT and _HIGH.
94 int convertAndroidPriority(const int android_priority) {
95 switch (android_priority) {
96 case -2: // PRIORITY_MIN
97 case -1: // PRIORITY_LOW
98 return -2;
99 case 0: // PRIORITY_DEFAULT
100 return -1;
101 case 1: // PRIORITY_HIGH
102 return 0;
103 case 2: // PRIORITY_MAX
104 return 2;
105 default:
106 NOTREACHED() << "Invalid Priority: " << android_priority;
107 return 0;
108 }
109 }
110
111 class ArcNotificationDelegate : public message_center::NotificationDelegate { 89 class ArcNotificationDelegate : public message_center::NotificationDelegate {
112 public: 90 public:
113 explicit ArcNotificationDelegate(base::WeakPtr<ArcNotificationItem> item) 91 explicit ArcNotificationDelegate(base::WeakPtr<ArcNotificationItem> item)
114 : item_(item) {} 92 : item_(item) {}
115 93
116 void Close(bool by_user) override { 94 void Close(bool by_user) override {
117 if (item_) 95 if (item_)
118 item_->Close(by_user); 96 item_->Close(by_user);
119 } 97 }
120 98
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 137
160 void ArcNotificationItem::UpdateWithArcNotificationData( 138 void ArcNotificationItem::UpdateWithArcNotificationData(
161 const mojom::ArcNotificationData& data) { 139 const mojom::ArcNotificationData& data) {
162 DCHECK(thread_checker_.CalledOnValidThread()); 140 DCHECK(thread_checker_.CalledOnValidThread());
163 DCHECK(notification_key_ == data.key); 141 DCHECK(notification_key_ == data.key);
164 142
165 // Check if a decode task is on-going or not. If |notification_| is non-null, 143 // Check if a decode task is on-going or not. If |notification_| is non-null,
166 // a decode task is on-going asynchronously. Otherwise, there is no task. 144 // a decode task is on-going asynchronously. Otherwise, there is no task.
167 // TODO(yoshiki): Refactor and remove this check by omitting image decoding 145 // TODO(yoshiki): Refactor and remove this check by omitting image decoding
168 // from here. 146 // from here.
169 if (notification_) { 147 if (CacheArcNotificationData(data))
170 // Store the latest data to the |newer_data_| property and returns, if the
171 // previous decode is still in progress.
172 // If old |newer_data_| has been stored, discard the old one.
173 newer_data_ = data.Clone();
174 return; 148 return;
175 }
176 149
177 message_center::RichNotificationData rich_data; 150 message_center::RichNotificationData rich_data;
178 message_center::NotificationType type; 151 message_center::NotificationType type;
179 152
180 switch (data.type) { 153 switch (data.type) {
181 case mojom::ArcNotificationType::BASIC: 154 case mojom::ArcNotificationType::BASIC:
182 type = message_center::NOTIFICATION_TYPE_BASE_FORMAT; 155 type = message_center::NOTIFICATION_TYPE_BASE_FORMAT;
183 break; 156 break;
184 case mojom::ArcNotificationType::LIST: 157 case mojom::ArcNotificationType::LIST:
185 type = message_center::NOTIFICATION_TYPE_MULTIPLE; 158 type = message_center::NOTIFICATION_TYPE_MULTIPLE;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 202
230 for (size_t i = 0; i < data.buttons.size(); i++) { 203 for (size_t i = 0; i < data.buttons.size(); i++) {
231 rich_data.buttons.emplace_back( 204 rich_data.buttons.emplace_back(
232 base::UTF8ToUTF16(data.buttons.at(i)->label.get())); 205 base::UTF8ToUTF16(data.buttons.at(i)->label.get()));
233 } 206 }
234 207
235 // If the client is old (version < 1), both |no_clear| and |ongoing_event| 208 // If the client is old (version < 1), both |no_clear| and |ongoing_event|
236 // are false. 209 // are false.
237 rich_data.pinned = (data.no_clear || data.ongoing_event); 210 rich_data.pinned = (data.no_clear || data.ongoing_event);
238 211
239 rich_data.priority = convertAndroidPriority(data.priority); 212 rich_data.priority = ConvertAndroidPriority(data.priority);
240 213
241 // The identifier of the notifier, which is used to distinguish the notifiers 214 // The identifier of the notifier, which is used to distinguish the notifiers
242 // in the message center. 215 // in the message center.
243 message_center::NotifierId notifier_id( 216 message_center::NotifierId notifier_id(
244 message_center::NotifierId::SYSTEM_COMPONENT, kNotifierId); 217 message_center::NotifierId::SYSTEM_COMPONENT, kNotifierId);
245 notifier_id.profile_id = profile_id_.GetUserEmail(); 218 notifier_id.profile_id = profile_id_.GetUserEmail();
246 219
247 DCHECK(!data.title.is_null()); 220 DCHECK(!data.title.is_null());
248 DCHECK(!data.message.is_null()); 221 DCHECK(!data.message.is_null());
249 notification_.reset(new message_center::Notification( 222 SetNotification(base::WrapUnique(new message_center::Notification(
250 type, notification_id_, base::UTF8ToUTF16(data.title.get()), 223 type, notification_id_, base::UTF8ToUTF16(data.title.get()),
251 base::UTF8ToUTF16(data.message.get()), 224 base::UTF8ToUTF16(data.message.get()),
252 gfx::Image(), // icon image: Will be overriden later. 225 gfx::Image(), // icon image: Will be overriden later.
253 base::UTF8ToUTF16("arc"), // display source 226 base::UTF8ToUTF16("arc"), // display source
254 GURL(), // empty origin url, for system component 227 GURL(), // empty origin url, for system component
255 notifier_id, rich_data, 228 notifier_id, rich_data,
256 new ArcNotificationDelegate(weak_ptr_factory_.GetWeakPtr()))); 229 new ArcNotificationDelegate(weak_ptr_factory_.GetWeakPtr()))));
257 230
258 DCHECK(!data.icon_data.is_null()); 231 DCHECK(!data.icon_data.is_null());
259 if (data.icon_data.size() == 0) { 232 if (data.icon_data.size() == 0) {
260 OnImageDecoded(SkBitmap()); // Pass an empty bitmap. 233 OnImageDecoded(SkBitmap()); // Pass an empty bitmap.
261 return; 234 return;
262 } 235 }
263 236
264 // TODO(yoshiki): Remove decoding by passing a bitmap directly from Android. 237 // TODO(yoshiki): Remove decoding by passing a bitmap directly from Android.
265 base::PostTaskAndReplyWithResult( 238 base::PostTaskAndReplyWithResult(
266 base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE, 239 base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE,
(...skipping 23 matching lines...) Expand all
290 263
291 void ArcNotificationItem::Click() { 264 void ArcNotificationItem::Click() {
292 manager_->SendNotificationClickedOnChrome(notification_key_); 265 manager_->SendNotificationClickedOnChrome(notification_key_);
293 } 266 }
294 267
295 void ArcNotificationItem::ButtonClick(int button_index) { 268 void ArcNotificationItem::ButtonClick(int button_index) {
296 manager_->SendNotificationButtonClickedOnChrome( 269 manager_->SendNotificationButtonClickedOnChrome(
297 notification_key_, button_index); 270 notification_key_, button_index);
298 } 271 }
299 272
300 void ArcNotificationItem::OnImageDecoded(const SkBitmap& bitmap) { 273 // Converts from Android notification priority to Chrome notification priority.
301 DCHECK(thread_checker_.CalledOnValidThread()); 274 // On Android, PRIORITY_DEFAULT does not pop up, so this maps PRIORITY_DEFAULT
275 // to Chrome's -1 to adapt that behavior. Also, this maps PRIORITY_LOW and _HIGH
276 // to -2 and 0 respectively to adjust the value with keeping the order among
277 // _LOW, _DEFAULT and _HIGH.
278 // static
279 int ArcNotificationItem::ConvertAndroidPriority(int android_priority) {
280 switch (android_priority) {
281 case -2: // PRIORITY_MIN
282 case -1: // PRIORITY_LOW
283 return -2;
284 case 0: // PRIORITY_DEFAULT
285 return -1;
286 case 1: // PRIORITY_HIGH
287 return 0;
288 case 2: // PRIORITY_MAX
289 return 2;
290 default:
291 NOTREACHED() << "Invalid Priority: " << android_priority;
292 return 0;
293 }
294 }
302 295
303 gfx::Image image = gfx::Image::CreateFrom1xBitmap(bitmap); 296 bool ArcNotificationItem::CacheArcNotificationData(
304 notification_->set_icon(image); 297 const mojom::ArcNotificationData& data) {
298 if (!notification_)
299 return false;
305 300
301 // Store the latest data to the |newer_data_| property if there is a pending
302 // |notification_|.
303 // If old |newer_data_| has been stored, discard the old one.
304 newer_data_ = data.Clone();
305 return true;
306 }
307
308 void ArcNotificationItem::SetNotification(
309 std::unique_ptr<message_center::Notification> notification) {
310 notification_ = std::move(notification);
311 }
312
313 void ArcNotificationItem::AddToMessageCenter() {
306 DCHECK(notification_); 314 DCHECK(notification_);
307 message_center_->AddNotification(std::move(notification_)); 315 message_center_->AddNotification(std::move(notification_));
308 316
309 if (newer_data_) { 317 if (newer_data_) {
310 // There is the newer data, so updates again. 318 // There is the newer data, so updates again.
311 mojom::ArcNotificationDataPtr data(std::move(newer_data_)); 319 mojom::ArcNotificationDataPtr data(std::move(newer_data_));
312 UpdateWithArcNotificationData(*data); 320 UpdateWithArcNotificationData(*data);
313 } 321 }
314 } 322 }
315 323
324 bool ArcNotificationItem::CalledOnValidThread() const {
325 return thread_checker_.CalledOnValidThread();
326 }
327
328 void ArcNotificationItem::OnImageDecoded(const SkBitmap& bitmap) {
329 DCHECK(thread_checker_.CalledOnValidThread());
330
331 gfx::Image image = gfx::Image::CreateFrom1xBitmap(bitmap);
332 notification_->set_icon(image);
333 AddToMessageCenter();
334 }
335
316 } // namespace arc 336 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698