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

Side by Side Diff: components/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 5 years 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 2015 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 "components/arc/notification/arc_notification_item.h"
6
Luis Héctor Chávez 2015/12/17 23:11:41 lint nit: include <algorithm> and <vector>
7 #include "base/strings/string16.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "content/public/child/image_decoder_utils.h"
11 #include "ui/gfx/geometry/size.h"
12 #include "ui/gfx/image/image.h"
13 #include "ui/message_center/notification.h"
14 #include "ui/message_center/notification_types.h"
15 #include "ui/message_center/notifier_settings.h"
16
17 namespace arc {
18
19 namespace {
20
21 // static
22 static const char* kNotifierId = "ARC_NOTIFICATION";
23
24 // static
25 static const char* kNotificationIdPrefix = "ARC_NOTIFICATION_";
26
27 SkBitmap DecodeImage(const std::vector<uint8_t>& data) {
28 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
29 DCHECK(!data.empty()); // empty string should be handled in caller.
30
31 // We may decode an image in the browser process since it has been generated
32 // in ARC and should be safe.
33 return content::DecodeImage(&data[0], gfx::Size(), data.size());
34 }
35
36 class ArcNotificationDelegate : public message_center::NotificationDelegate {
37 public:
38 explicit ArcNotificationDelegate(
39 base::WeakPtr<ArcNotificationItem> item)
40 : item_(item) {}
41
42 void Close(bool by_user) override {
43 if (item_)
44 item_->Close(by_user);
45 }
46
47 // Indicates all notifications have a click handler. This changes the mouse
48 // cursor on hover.
49 // TODO(yoshiki): Return the correct value according to the content intent
50 // and the flags.
51 bool HasClickedListener() override { return true; }
52
53 void Click() override {
54 if (item_)
55 item_->Click();
56 }
57
58 private:
59 // The destractor is private since this class is ref-counted.
60 ~ArcNotificationDelegate() override {}
61
62 base::WeakPtr<ArcNotificationItem> item_;
63
64 DISALLOW_COPY_AND_ASSIGN(ArcNotificationDelegate);
65 };
66
67 } // anonymous namespace
68
69 ArcNotificationItem::ArcNotificationItem(
70 ArcNotificationManager* manager,
71 message_center::MessageCenter* message_center,
72 const ArcNotificationData& data,
73 const AccountId& profile_id)
74 : manager_(manager),
75 message_center_(message_center),
76 profile_id_(profile_id),
77 notification_key_(data.key),
78 notification_id_(kNotificationIdPrefix + notification_key_),
79 weak_ptr_factory_(this) {
80 }
81
82 void ArcNotificationItem::UpdateWithArcNotificationData(
83 const ArcNotificationData& data) {
84 DCHECK(notification_key_ == data.key);
85
86 // Checks if a decode task is on-going or not. If |notification_| is non-null,
87 // a decode task is on-going asynchronously. Otherwise, there is no task.
88 // TODO(yoshiki): Refactor and remove this check by omitting image decoding
89 // from here.
90 if (notification_) {
91 // Stores the latest data to the |newer_data_| property and returns, if the
92 // previous decode is still in progress.
93 // If old |newer_daa_| has been stored, discard the old one.
94 newer_data_ = data.Clone();
95 return;
96 }
97
98 message_center::RichNotificationData rich_data;
99 message_center::NotificationType type;
100 switch (data.type) {
101 case ARC_NOTIFICATION_TYPE_BASIC:
102 type = message_center::NOTIFICATION_TYPE_SIMPLE;
103 break;
104 case ARC_NOTIFICATION_TYPE_IMAGE:
105 // TODO(yoshiki): Implement this types.
106 type = message_center::NOTIFICATION_TYPE_SIMPLE;
107 break;
108 case ARC_NOTIFICATION_TYPE_PROGRESS:
109 type = message_center::NOTIFICATION_TYPE_PROGRESS;
110 rich_data.timestamp = base::Time::UnixEpoch() +
111 base::TimeDelta::FromMilliseconds(data.time);
112 rich_data.progress = std::max(
113 0, std::min(100, static_cast<int>(std::round(
114 static_cast<float>(data.progress_current) /
115 data.progress_max * 100))));
116 break;
117 }
118
119 // The identifier of the notifier, which is used to distinguish the notifiers
120 // in the message center.
121 message_center::NotifierId notifier_id(
122 message_center::NotifierId::SYSTEM_COMPONENT, kNotifierId);
123 notifier_id.profile_id = profile_id_.GetUserEmail();
124
125 DCHECK(!data.title.is_null());
126 DCHECK(!data.message.is_null());
127 notification_.reset(new message_center::Notification(
128 type, notification_id_, base::UTF8ToUTF16(data.title.get()),
129 base::UTF8ToUTF16(data.message.get()),
130 gfx::Image(), // Will be overriden by decoded image.
131 base::UTF8ToUTF16("arc"), // display source
132 GURL(), // empty origin url for system component
133 notifier_id, rich_data,
134 new ArcNotificationDelegate(weak_ptr_factory_.GetWeakPtr())));
135
136 DCHECK(!data.icon_data.is_null());
137 if (data.icon_data.size() == 0) {
138 OnImageDecoded(SkBitmap()); // Passes an empty bitmap.
139 return;
140 }
141
142 std::string icon_data_str(data.icon_data.storage().begin(),
143 data.icon_data.storage().end()); // copy
144 // TODO(yoshiki): Remove decoding by passing a bitmap directly from Android.
145 base::PostTaskAndReplyWithResult(
146 content::BrowserThread::GetBlockingPool(),
147 FROM_HERE,
148 base::Bind(&DecodeImage, data.icon_data.storage()),
149 base::Bind(&ArcNotificationItem::OnImageDecoded,
150 weak_ptr_factory_.GetWeakPtr()));
151 }
152
153 ArcNotificationItem::~ArcNotificationItem() {}
154
155 void ArcNotificationItem::OnClosedFromAndroid() {
156 being_removed_by_manager_ = true; // Closing is initiated by the manager.
157 message_center_->RemoveNotification(notification_id_, true /* by_user */);
158 }
159
160 void ArcNotificationItem::Close(bool by_user) {
161 if (being_removed_by_manager_) {
162 // Closing is caused by the manager, so we don't need to nofify a close
163 // event to the manager.
164 return;
165 }
166
167 // This instance may be destroied during this call.
168 // Don't use any properties in this method after this call.
169 manager_->SendNotificationRemovedFromChrome(notification_key_);
170 }
171
172 void ArcNotificationItem::Click() {
173 manager_->SendNotificationClickedOnChrome(notification_key_);
174 }
175
176 void ArcNotificationItem::OnImageDecoded(const SkBitmap& bitmap) {
177 gfx::Image image = gfx::Image::CreateFrom1xBitmap(bitmap);
178 notification_->set_icon(image);
179
180 DCHECK(notification_);
181 message_center_->AddNotification(std::move(notification_));
182
183 if (newer_data_) {
184 // There is the newer data, so re-updates again.
185 ArcNotificationDataPtr data(std::move(newer_data_));
186 UpdateWithArcNotificationData(*data);
187 }
188 }
189
190 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698