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

Side by Side Diff: content/renderer/notification_provider.cc

Issue 554213003: Request the icon of a Web Notification in the renderer process. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removes now redundant code Created 6 years, 3 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/renderer/notification_provider.h" 5 #include "content/renderer/notification_provider.h"
6 6
7 #include "base/strings/string_util.h" 7 #include "base/strings/string_util.h"
8 #include "content/child/image_decoder.h"
8 #include "content/common/desktop_notification_messages.h" 9 #include "content/common/desktop_notification_messages.h"
9 #include "content/common/frame_messages.h" 10 #include "content/common/frame_messages.h"
10 #include "content/renderer/render_frame_impl.h" 11 #include "content/renderer/render_frame_impl.h"
12 #include "third_party/WebKit/public/platform/Platform.h"
11 #include "third_party/WebKit/public/platform/WebURL.h" 13 #include "third_party/WebKit/public/platform/WebURL.h"
14 #include "third_party/WebKit/public/platform/WebURLLoader.h"
15 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
12 #include "third_party/WebKit/public/web/WebDocument.h" 16 #include "third_party/WebKit/public/web/WebDocument.h"
13 #include "third_party/WebKit/public/web/WebLocalFrame.h" 17 #include "third_party/WebKit/public/web/WebLocalFrame.h"
14 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" 18 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
19 #include "third_party/skia/include/core/SkBitmap.h"
15 20
16 using blink::WebDocument; 21 using blink::WebDocument;
17 using blink::WebNotification; 22 using blink::WebNotification;
18 using blink::WebNotificationPresenter; 23 using blink::WebNotificationPresenter;
19 using blink::WebSecurityOrigin; 24 using blink::WebSecurityOrigin;
20 using blink::WebString; 25 using blink::WebString;
21 using blink::WebURL; 26 using blink::WebURL;
27 using blink::WebURLError;
28 using blink::WebURLLoader;
29 using blink::WebURLRequest;
22 using blink::WebUserGestureIndicator; 30 using blink::WebUserGestureIndicator;
23 31
24 namespace content { 32 namespace content {
25 33
26 NotificationProvider::NotificationProvider(RenderFrame* render_frame) 34 // NotificationProvider::IconDownloader ----------------------------------------
27 : RenderFrameObserver(render_frame) { 35
36 // Downloads the icon associated with a notification and decodes the received
37 // image. This must be completed before notifications are shown to the user.
38 class NotificationProvider::IconDownloader : public blink::WebURLLoaderClient {
39 typedef base::Callback<void(const WebNotification&,
40 const SkBitmap&)> DownloadCompletedCallback;
41
42 public:
43 IconDownloader(const WebNotification& notification,
44 const DownloadCompletedCallback& callback);
45
46 virtual ~IconDownloader();
47
48 // Downloads |image_url| and invokes |callback| with the decoded SkBitmap when
49 // the download has succeeded, or invokes |callback| with an empty SkBitmap
50 // in case the download has failed.
51 void Start();
52
53 // Cancels the current image download. The callback will not be invoked.
54 void Cancel();
55
56 // blink::WebURLLoaderClient implementation.
57 virtual void didReceiveData(WebURLLoader* loader,
58 const char* data,
59 int data_length,
60 int encoded_data_length) OVERRIDE;
61 virtual void didFinishLoading(WebURLLoader* loader,
62 double finish_time,
63 int64_t total_encoded_data_length) OVERRIDE;
64 virtual void didFail(WebURLLoader* loader, const WebURLError& error) OVERRIDE;
65
66 const WebNotification& notification() const {
67 return notification_;
68 }
69
70 private:
71 WebNotification notification_;
72 DownloadCompletedCallback callback_;
73
74 scoped_ptr<WebURLLoader> loader_;
75 bool completed_;
76
77 std::string buffer_;
78
79 DISALLOW_COPY_AND_ASSIGN(IconDownloader);
80 };
81
82 NotificationProvider::IconDownloader::IconDownloader(
83 const WebNotification& notification,
84 const DownloadCompletedCallback& callback)
85 : notification_(notification),
86 callback_(callback),
87 completed_(false) {}
88
89 NotificationProvider::IconDownloader::~IconDownloader() {}
90
91 void NotificationProvider::IconDownloader::Start() {
92 DCHECK(!loader_);
93
94 WebURLRequest request(notification_.iconURL());
95
96 loader_.reset(blink::Platform::current()->createURLLoader());
97 loader_->loadAsynchronously(request, this);
28 } 98 }
29 99
30 NotificationProvider::~NotificationProvider() { 100 void NotificationProvider::IconDownloader::Cancel() {
101 DCHECK(loader_);
102
103 completed_ = true;
104 loader_->cancel();
31 } 105 }
32 106
107 void NotificationProvider::IconDownloader::didReceiveData(
108 WebURLLoader* loader,
109 const char* data,
110 int data_length,
111 int encoded_data_length) {
112 DCHECK(!completed_);
113 DCHECK(data_length > 0);
114
115 buffer_.append(data, data_length);
116 }
117
118 void NotificationProvider::IconDownloader::didFinishLoading(
119 WebURLLoader* loader,
120 double finish_time,
121 int64_t total_encoded_data_length) {
122 DCHECK(!completed_);
123
124 ImageDecoder decoder;
125 SkBitmap icon = decoder.Decode(
126 reinterpret_cast<const unsigned char*>(buffer_.data()), buffer_.size());
127
128 callback_.Run(notification_, icon);
129 completed_ = true;
130 }
131
132 void NotificationProvider::IconDownloader::didFail(
133 WebURLLoader* loader, const WebURLError& error) {
134 if (completed_)
135 return;
136
137 callback_.Run(notification_, SkBitmap());
138 completed_ = true;
139 }
140
141 // NotificationProvider --------------------------------------------------------
142
143 NotificationProvider::NotificationProvider(RenderFrame* render_frame)
144 : RenderFrameObserver(render_frame) {}
145
146 NotificationProvider::~NotificationProvider() {}
147
33 bool NotificationProvider::show(const WebNotification& notification) { 148 bool NotificationProvider::show(const WebNotification& notification) {
149 if (notification.iconURL().isEmpty()) {
150 DisplayNotification(notification, SkBitmap());
151 return true;
152 }
153
154 scoped_ptr<IconDownloader> downloader(
155 new IconDownloader(notification,
156 base::Bind(&NotificationProvider::DisplayNotification,
157 base::Unretained(this))));
158
159 downloader->Start();
160
161 pending_notifications_.push_back(downloader.release());
162 return true;
163 }
164
165 void NotificationProvider::DisplayNotification(
166 const WebNotification& notification, const SkBitmap& icon) {
34 WebDocument document = render_frame()->GetWebFrame()->document(); 167 WebDocument document = render_frame()->GetWebFrame()->document();
35 int notification_id = manager_.RegisterNotification(notification); 168 int notification_id = manager_.RegisterNotification(notification);
36 169
170 // TODO: Remove the downloaded notification from |pending_notifications_|
171 // if it was triggered through there.
172
37 ShowDesktopNotificationHostMsgParams params; 173 ShowDesktopNotificationHostMsgParams params;
38 params.origin = GURL(document.securityOrigin().toString()); 174 params.origin = GURL(document.securityOrigin().toString());
39 params.icon_url = notification.iconURL(); 175 params.icon = icon;
40 params.title = notification.title(); 176 params.title = notification.title();
41 params.body = notification.body(); 177 params.body = notification.body();
42 params.direction = notification.direction(); 178 params.direction = notification.direction();
43 params.replace_id = notification.replaceId(); 179 params.replace_id = notification.replaceId();
44 return Send(new DesktopNotificationHostMsg_Show( 180
45 routing_id(), notification_id, params)); 181 Send(new DesktopNotificationHostMsg_Show(routing_id(),
182 notification_id,
183 params));
184 }
185
186 void NotificationProvider::CancelIconDownload(
187 const WebNotification& notification) {
46 } 188 }
47 189
48 void NotificationProvider::cancel(const WebNotification& notification) { 190 void NotificationProvider::cancel(const WebNotification& notification) {
49 int id; 191 int id;
50 bool id_found = manager_.GetId(notification, id); 192 bool id_found = manager_.GetId(notification, id);
51 // Won't be found if the notification has already been closed by the user. 193 // Won't be found if the notification has already been closed by the user,
194 // or if the notification's icon is still being requested.
52 if (id_found) 195 if (id_found)
53 Send(new DesktopNotificationHostMsg_Cancel(routing_id(), id)); 196 Send(new DesktopNotificationHostMsg_Cancel(routing_id(), id));
197 else
198 CancelIconDownload(notification);
54 } 199 }
55 200
56 void NotificationProvider::objectDestroyed( 201 void NotificationProvider::objectDestroyed(
57 const WebNotification& notification) { 202 const WebNotification& notification) {
58 int id; 203 int id;
59 bool id_found = manager_.GetId(notification, id); 204 bool id_found = manager_.GetId(notification, id);
60 // Won't be found if the notification has already been closed by the user. 205 // Won't be found if the notification has already been closed by the user.
61 if (id_found) 206 if (id_found)
62 manager_.UnregisterNotification(id); 207 manager_.UnregisterNotification(id);
208 else
209 CancelIconDownload(notification);
63 } 210 }
64 211
65 WebNotificationPresenter::Permission NotificationProvider::checkPermission( 212 WebNotificationPresenter::Permission NotificationProvider::checkPermission(
66 const WebSecurityOrigin& origin) { 213 const WebSecurityOrigin& origin) {
67 int permission = WebNotificationPresenter::PermissionNotAllowed; 214 int permission = WebNotificationPresenter::PermissionNotAllowed;
68 Send(new DesktopNotificationHostMsg_CheckPermission( 215 Send(new DesktopNotificationHostMsg_CheckPermission(
69 routing_id(), 216 routing_id(),
70 GURL(origin.toString()), 217 GURL(origin.toString()),
71 &permission)); 218 &permission));
72 return static_cast<WebNotificationPresenter::Permission>(permission); 219 return static_cast<WebNotificationPresenter::Permission>(permission);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 // the page before the associated toast was clicked on. 271 // the page before the associated toast was clicked on.
125 if (found) 272 if (found)
126 notification.dispatchClickEvent(); 273 notification.dispatchClickEvent();
127 } 274 }
128 275
129 void NotificationProvider::OnNavigate() { 276 void NotificationProvider::OnNavigate() {
130 manager_.Clear(); 277 manager_.Clear();
131 } 278 }
132 279
133 } // namespace content 280 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698