OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/browser/services/gcm/push_messaging_service_impl.h" | 5 #include "chrome/browser/services/gcm/push_messaging_service_impl.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/prefs/pref_service.h" | 11 #include "base/prefs/pref_service.h" |
12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
13 #include "base/strings/utf_string_conversions.h" | |
14 #include "chrome/browser/browser_process.h" | |
15 #include "chrome/browser/notifications/notification_ui_manager.h" | |
Peter Beverloo
2015/01/09 19:48:05
This include isn't used.
johnme
2015/01/09 19:52:32
It's used by the following line:
int notification
| |
16 #include "chrome/browser/notifications/platform_notification_service_impl.h" | |
13 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
14 #include "chrome/browser/services/gcm/gcm_profile_service.h" | 18 #include "chrome/browser/services/gcm/gcm_profile_service.h" |
15 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" | 19 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" |
16 #include "chrome/browser/services/gcm/push_messaging_application_id.h" | 20 #include "chrome/browser/services/gcm/push_messaging_application_id.h" |
17 #include "chrome/browser/services/gcm/push_messaging_constants.h" | 21 #include "chrome/browser/services/gcm/push_messaging_constants.h" |
18 #include "chrome/browser/services/gcm/push_messaging_permission_context.h" | 22 #include "chrome/browser/services/gcm/push_messaging_permission_context.h" |
19 #include "chrome/browser/services/gcm/push_messaging_permission_context_factory. h" | 23 #include "chrome/browser/services/gcm/push_messaging_permission_context_factory. h" |
20 #include "chrome/common/chrome_switches.h" | 24 #include "chrome/common/chrome_switches.h" |
21 #include "chrome/common/pref_names.h" | 25 #include "chrome/common/pref_names.h" |
26 #include "chrome/grit/generated_resources.h" | |
27 #include "components/content_settings/core/browser/host_content_settings_map.h" | |
28 #include "components/content_settings/core/common/content_settings_types.h" | |
Peter Beverloo
2015/01/09 19:48:05
nit: these two includes don't seem to be used?
johnme
2015/01/09 19:52:32
Done.
| |
22 #include "components/content_settings/core/common/permission_request_id.h" | 29 #include "components/content_settings/core/common/permission_request_id.h" |
23 #include "components/gcm_driver/gcm_driver.h" | 30 #include "components/gcm_driver/gcm_driver.h" |
24 #include "components/pref_registry/pref_registry_syncable.h" | 31 #include "components/pref_registry/pref_registry_syncable.h" |
25 #include "content/public/browser/browser_context.h" | 32 #include "content/public/browser/browser_context.h" |
26 #include "content/public/browser/render_frame_host.h" | 33 #include "content/public/browser/render_frame_host.h" |
27 #include "content/public/browser/web_contents.h" | 34 #include "content/public/browser/web_contents.h" |
35 #include "content/public/common/child_process_host.h" | |
36 #include "content/public/common/platform_notification_data.h" | |
37 #include "third_party/skia/include/core/SkBitmap.h" | |
38 #include "ui/base/l10n/l10n_util.h" | |
28 | 39 |
29 namespace gcm { | 40 namespace gcm { |
30 | 41 |
31 namespace { | 42 namespace { |
32 const int kMaxRegistrations = 1000000; | 43 const int kMaxRegistrations = 1000000; |
33 | 44 |
34 blink::WebPushPermissionStatus ToPushPermission(ContentSetting setting) { | 45 blink::WebPushPermissionStatus ToPushPermission(ContentSetting setting) { |
35 switch (setting) { | 46 switch (setting) { |
36 case CONTENT_SETTING_ALLOW: | 47 case CONTENT_SETTING_ALLOW: |
37 return blink::WebPushPermissionStatusGranted; | 48 return blink::WebPushPermissionStatusGranted; |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 // { | 156 // { |
146 // "registration_ids": ["FOO", "BAR"], | 157 // "registration_ids": ["FOO", "BAR"], |
147 // "data": { | 158 // "data": { |
148 // "data": "BAZ", | 159 // "data": "BAZ", |
149 // }, | 160 // }, |
150 // "delay_while_idle": true, | 161 // "delay_while_idle": true, |
151 // } | 162 // } |
152 // TODO(johnme): Make sure this is clearly documented for developers. | 163 // TODO(johnme): Make sure this is clearly documented for developers. |
153 PushMessagingApplicationId application_id = | 164 PushMessagingApplicationId application_id = |
154 PushMessagingApplicationId::Parse(app_id); | 165 PushMessagingApplicationId::Parse(app_id); |
155 DCHECK(application_id.IsValid()); | |
156 GCMClient::MessageData::const_iterator it = message.data.find("data"); | 166 GCMClient::MessageData::const_iterator it = message.data.find("data"); |
157 if (application_id.IsValid() && it != message.data.end()) { | 167 if (application_id.IsValid() && it != message.data.end()) { |
158 if (!HasPermission(application_id.origin)) { | 168 if (!HasPermission(application_id.origin)) { |
159 // The |origin| lost push permission. We need to unregister and drop this | 169 // The |origin| lost push permission. We need to unregister and drop this |
160 // message. | 170 // message. |
161 Unregister(application_id, UnregisterCallback()); | 171 Unregister(application_id, UnregisterCallback()); |
162 return; | 172 return; |
163 } | 173 } |
164 | 174 |
165 const std::string& data = it->second; | 175 const std::string& data = it->second; |
(...skipping 19 matching lines...) Expand all Loading... | |
185 | 195 |
186 void PushMessagingServiceImpl::DeliverMessageCallback( | 196 void PushMessagingServiceImpl::DeliverMessageCallback( |
187 const PushMessagingApplicationId& application_id, | 197 const PushMessagingApplicationId& application_id, |
188 const GCMClient::IncomingMessage& message, | 198 const GCMClient::IncomingMessage& message, |
189 content::PushDeliveryStatus status) { | 199 content::PushDeliveryStatus status) { |
190 // TODO(mvanouwerkerk): UMA logging. | 200 // TODO(mvanouwerkerk): UMA logging. |
191 // TODO(mvanouwerkerk): Show a warning in the developer console of the | 201 // TODO(mvanouwerkerk): Show a warning in the developer console of the |
192 // Service Worker corresponding to app_id (and/or on an internals page). | 202 // Service Worker corresponding to app_id (and/or on an internals page). |
193 // TODO(mvanouwerkerk): Is there a way to recover from failure? | 203 // TODO(mvanouwerkerk): Is there a way to recover from failure? |
194 switch (status) { | 204 switch (status) { |
205 // Call RequireUserVisibleUX if the message was delivered to the Service | |
206 // Worker JS, even if the website's event handler failed (to prevent sites | |
207 // deliberately failing in order to avoid having to show notifications). | |
195 case content::PUSH_DELIVERY_STATUS_SUCCESS: | 208 case content::PUSH_DELIVERY_STATUS_SUCCESS: |
209 case content::PUSH_DELIVERY_STATUS_EVENT_WAITUNTIL_REJECTED: | |
210 RequireUserVisibleUX(application_id); | |
211 break; | |
196 case content::PUSH_DELIVERY_STATUS_INVALID_MESSAGE: | 212 case content::PUSH_DELIVERY_STATUS_INVALID_MESSAGE: |
197 case content::PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR: | 213 case content::PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR: |
198 case content::PUSH_DELIVERY_STATUS_EVENT_WAITUNTIL_REJECTED: | |
199 break; | 214 break; |
200 case content::PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER: | 215 case content::PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER: |
201 Unregister(application_id, UnregisterCallback()); | 216 Unregister(application_id, UnregisterCallback()); |
202 break; | 217 break; |
203 } | 218 } |
204 } | 219 } |
205 | 220 |
221 void PushMessagingServiceImpl::RequireUserVisibleUX( | |
222 const PushMessagingApplicationId& application_id) { | |
223 #if defined(ENABLE_NOTIFICATIONS) | |
224 // TODO(johnme): Add test. | |
225 // TODO(johnme): Relax this heuristic slightly. | |
226 int notification_count = g_browser_process->notification_ui_manager()-> | |
227 GetAllIdsByProfileAndSourceOrigin(profile_, application_id.origin).size(); | |
228 if (notification_count > 0) | |
229 return; | |
230 | |
231 // If we haven't returned yet, the site failed to show a notification, so we | |
232 // will show a generic notification. See https://crbug.com/437277 | |
233 // TODO(johnme): The generic notification should probably automatically close | |
234 // itself when the next push message arrives? | |
235 content::PlatformNotificationData notification_data; | |
236 // TODO(johnme): Switch to FormatOriginForDisplay from crbug.com/402698 | |
237 notification_data.title = l10n_util::GetStringFUTF16( | |
238 IDS_PUSH_MESSAGING_GENERIC_NOTIFICATION_TITLE, | |
239 base::UTF8ToUTF16(origin.host())); | |
240 notification_data.direction = | |
241 content::PlatformNotificationData::NotificationDirectionLeftToRight; | |
242 notification_data.body = | |
243 l10n_util::GetStringUTF16(IDS_PUSH_MESSAGING_GENERIC_NOTIFICATION_BODY); | |
244 notification_data.tag = | |
245 base::ASCIIToUTF16("user_visible_auto_notification"); | |
246 notification_data.icon = GURL(); // TODO(johnme): Better icon? | |
247 PlatformNotificationServiceImpl::GetInstance()->DisplayPersistentNotification( | |
248 profile_, | |
249 application_id.service_worker_registration_id, | |
250 application_id.origin, | |
251 SkBitmap() /* icon */, | |
252 notification_data, | |
253 content::ChildProcessHost::kInvalidUniqueID /* render_process_id */); | |
254 #endif | |
255 } | |
256 | |
206 void PushMessagingServiceImpl::OnMessagesDeleted(const std::string& app_id) { | 257 void PushMessagingServiceImpl::OnMessagesDeleted(const std::string& app_id) { |
207 // TODO(mvanouwerkerk): Fire push error event on the Service Worker | 258 // TODO(mvanouwerkerk): Fire push error event on the Service Worker |
208 // corresponding to app_id. | 259 // corresponding to app_id. |
209 } | 260 } |
210 | 261 |
211 void PushMessagingServiceImpl::OnSendError( | 262 void PushMessagingServiceImpl::OnSendError( |
212 const std::string& app_id, | 263 const std::string& app_id, |
213 const GCMClient::SendErrorDetails& send_error_details) { | 264 const GCMClient::SendErrorDetails& send_error_details) { |
214 NOTREACHED() << "The Push API shouldn't have sent messages upstream"; | 265 NOTREACHED() << "The Push API shouldn't have sent messages upstream"; |
215 } | 266 } |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
458 } | 509 } |
459 | 510 |
460 void PushMessagingServiceImpl::AddAppHandlerIfNecessary() { | 511 void PushMessagingServiceImpl::AddAppHandlerIfNecessary() { |
461 if (gcm_profile_service_->driver()->GetAppHandler( | 512 if (gcm_profile_service_->driver()->GetAppHandler( |
462 kPushMessagingApplicationIdPrefix) != this) | 513 kPushMessagingApplicationIdPrefix) != this) |
463 gcm_profile_service_->driver()->AddAppHandler( | 514 gcm_profile_service_->driver()->AddAppHandler( |
464 kPushMessagingApplicationIdPrefix, this); | 515 kPushMessagingApplicationIdPrefix, this); |
465 } | 516 } |
466 | 517 |
467 } // namespace gcm | 518 } // namespace gcm |
OLD | NEW |