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

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

Issue 1477733002: Add ArcNotificationManager for new ARC notification (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comments Created 4 years, 11 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ui/arc/notification/arc_notification_item.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "base/strings/string16.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/task_runner.h"
13 #include "base/task_runner_util.h"
14 #include "base/threading/worker_pool.h"
15 #include "third_party/WebKit/public/platform/WebData.h"
16 #include "third_party/WebKit/public/platform/WebImage.h"
17 #include "third_party/WebKit/public/platform/WebSize.h"
18 #include "ui/gfx/geometry/size.h"
19 #include "ui/gfx/image/image.h"
20 #include "ui/message_center/message_center_style.h"
21 #include "ui/message_center/notification.h"
22 #include "ui/message_center/notification_types.h"
23 #include "ui/message_center/notifier_settings.h"
24
25 namespace arc {
26
27 namespace {
28
29 // static
30 static const char kNotifierId[] = "ARC_NOTIFICATION";
31
32 // static
33 static const char kNotificationIdPrefix[] = "ARC_NOTIFICATION_";
34
35 // static
36 static const gfx::Size kNotificationIconSize(
37 message_center::kNotificationIconSize,
38 message_center::kNotificationIconSize);
dcheng 2016/01/07 19:24:21 Won't this generate a static initializer?
yoshiki 2016/01/08 10:32:58 You're right, this was wrong. This is removed in t
39
40 SkBitmap DecodeImage(const std::vector<uint8_t>& data) {
41 DCHECK(base::WorkerPool::RunsTasksOnCurrentThread());
42 DCHECK(!data.empty()); // empty string should be handled in caller.
43
44 // We may decode an image in the browser process since it has been generated
45 // in NotificationListerService in Android and should be safe.
46 const blink::WebImage& image = blink::WebImage::fromData(
dcheng 2016/01/07 19:24:21 Why not use //ui/gfx/codec? Using this directly i
yoshiki 2016/01/08 10:32:58 Thank you for letting me know. I'm using it!
47 blink::WebData(reinterpret_cast<const char*>(&data[0]), data.size()),
48 kNotificationIconSize);
49 return image.getSkBitmap();
50 }
51
52 class ArcNotificationDelegate : public message_center::NotificationDelegate {
53 public:
54 explicit ArcNotificationDelegate(base::WeakPtr<ArcNotificationItem> item)
55 : item_(item) {}
56
57 void Close(bool by_user) override {
58 if (item_)
59 item_->Close(by_user);
60 }
61
62 // Indicates all notifications have a click handler. This changes the mouse
63 // cursor on hover.
64 // TODO(yoshiki): Return the correct value according to the content intent
65 // and the flags.
66 bool HasClickedListener() override { return true; }
67
68 void Click() override {
69 if (item_)
70 item_->Click();
71 }
72
73 private:
74 // The destructor is private since this class is ref-counted.
75 ~ArcNotificationDelegate() override {}
76
77 base::WeakPtr<ArcNotificationItem> item_;
78
79 DISALLOW_COPY_AND_ASSIGN(ArcNotificationDelegate);
80 };
81
82 } // anonymous namespace
83
84 ArcNotificationItem::ArcNotificationItem(
85 ArcNotificationManager* manager,
86 message_center::MessageCenter* message_center,
87 const ArcNotificationData& data,
88 const AccountId& profile_id)
89 : manager_(manager),
90 message_center_(message_center),
91 profile_id_(profile_id),
92 notification_key_(data.key),
93 notification_id_(kNotificationIdPrefix + notification_key_),
94 weak_ptr_factory_(this) {}
95
96 void ArcNotificationItem::UpdateWithArcNotificationData(
97 const ArcNotificationData& data) {
98 DCHECK(thread_checker_.CalledOnValidThread());
99 DCHECK(notification_key_ == data.key);
100
101 // Check if a decode task is on-going or not. If |notification_| is non-null,
102 // a decode task is on-going asynchronously. Otherwise, there is no task.
103 // TODO(yoshiki): Refactor and remove this check by omitting image decoding
104 // from here.
105 if (notification_) {
106 // Store the latest data to the |newer_data_| property and returns, if the
107 // previous decode is still in progress.
108 // If old |newer_data_| has been stored, discard the old one.
109 newer_data_ = data.Clone();
110 return;
111 }
112
113 message_center::RichNotificationData rich_data;
114 message_center::NotificationType type;
115
116 switch (data.type) {
117 case ARC_NOTIFICATION_TYPE_BASIC:
118 type = message_center::NOTIFICATION_TYPE_SIMPLE;
119 break;
120 case ARC_NOTIFICATION_TYPE_IMAGE:
121 // TODO(yoshiki): Implement this types.
122 type = message_center::NOTIFICATION_TYPE_SIMPLE;
123 LOG(ERROR) << "Unsupported notification type: image";
124 break;
125 case ARC_NOTIFICATION_TYPE_PROGRESS:
126 type = message_center::NOTIFICATION_TYPE_PROGRESS;
127 rich_data.timestamp = base::Time::UnixEpoch() +
128 base::TimeDelta::FromMilliseconds(data.time);
129 rich_data.progress = std::max(
130 0, std::min(100, static_cast<int>(std::round(
131 static_cast<float>(data.progress_current) /
132 data.progress_max * 100))));
133 break;
134 }
135 DCHECK(0 <= data.type && data.type <= ARC_NOTIFICATION_TYPE_MAX)
136 << "Unsupported notification type: " << data.type;
137
138 // The identifier of the notifier, which is used to distinguish the notifiers
139 // in the message center.
140 message_center::NotifierId notifier_id(
141 message_center::NotifierId::SYSTEM_COMPONENT, kNotifierId);
142 notifier_id.profile_id = profile_id_.GetUserEmail();
143
144 DCHECK(!data.title.is_null());
145 DCHECK(!data.message.is_null());
146 notification_.reset(new message_center::Notification(
147 type, notification_id_, base::UTF8ToUTF16(data.title.get()),
148 base::UTF8ToUTF16(data.message.get()),
149 gfx::Image(), // icon image: Will be overriden later.
150 base::UTF8ToUTF16("arc"), // display source
151 GURL(), // empty origin url, for system component
152 notifier_id, rich_data,
153 new ArcNotificationDelegate(weak_ptr_factory_.GetWeakPtr())));
154
155 DCHECK(!data.icon_data.is_null());
156 if (data.icon_data.size() == 0) {
157 OnImageDecoded(SkBitmap()); // Pass an empty bitmap.
158 return;
159 }
160
161 std::string icon_data_str(data.icon_data.storage().begin(),
162 data.icon_data.storage().end()); // copy
163 // TODO(yoshiki): Remove decoding by passing a bitmap directly from Android.
164 base::PostTaskAndReplyWithResult(
165 base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE,
166 base::Bind(&DecodeImage, data.icon_data.storage()),
167 base::Bind(&ArcNotificationItem::OnImageDecoded,
168 weak_ptr_factory_.GetWeakPtr()));
169 }
170
171 ArcNotificationItem::~ArcNotificationItem() {}
172
173 void ArcNotificationItem::OnClosedFromAndroid() {
174 being_removed_by_manager_ = true; // Closing is initiated by the manager.
175 message_center_->RemoveNotification(notification_id_, true /* by_user */);
176 }
177
178 void ArcNotificationItem::Close(bool by_user) {
179 if (being_removed_by_manager_) {
180 // Closing is caused by the manager, so we don't need to nofify a close
181 // event to the manager.
182 return;
183 }
184
185 // Do not touch its any members afterwards, because this instance will be
186 // destroyed in the following call
187 manager_->SendNotificationRemovedFromChrome(notification_key_);
188 }
189
190 void ArcNotificationItem::Click() {
191 manager_->SendNotificationClickedOnChrome(notification_key_);
192 }
193
194 void ArcNotificationItem::OnImageDecoded(const SkBitmap& bitmap) {
195 DCHECK(thread_checker_.CalledOnValidThread());
196
197 gfx::Image image = gfx::Image::CreateFrom1xBitmap(bitmap);
198 notification_->set_icon(image);
199
200 DCHECK(notification_);
201 message_center_->AddNotification(std::move(notification_));
202
203 if (newer_data_) {
204 // There is the newer data, so re-updates again.
205 ArcNotificationDataPtr data(std::move(newer_data_));
206 UpdateWithArcNotificationData(*data);
207 }
208 }
209
210 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698