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

Side by Side Diff: chrome/browser/push_messaging/push_messaging_service_impl.cc

Issue 1099093003: Push API: Forced notifications should use Notifications database (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Don't use BindToCurrentLoop yet Created 5 years, 7 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 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/push_messaging/push_messaging_service_impl.h" 5 #include "chrome/browser/push_messaging/push_messaging_service_impl.h"
6 6
7 #include <bitset> 7 #include <bitset>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/barrier_closure.h" 10 #include "base/barrier_closure.h"
(...skipping 19 matching lines...) Expand all
30 #include "chrome/common/chrome_switches.h" 30 #include "chrome/common/chrome_switches.h"
31 #include "chrome/common/pref_names.h" 31 #include "chrome/common/pref_names.h"
32 #include "chrome/grit/generated_resources.h" 32 #include "chrome/grit/generated_resources.h"
33 #include "components/content_settings/core/browser/host_content_settings_map.h" 33 #include "components/content_settings/core/browser/host_content_settings_map.h"
34 #include "components/content_settings/core/common/permission_request_id.h" 34 #include "components/content_settings/core/common/permission_request_id.h"
35 #include "components/gcm_driver/gcm_driver.h" 35 #include "components/gcm_driver/gcm_driver.h"
36 #include "components/pref_registry/pref_registry_syncable.h" 36 #include "components/pref_registry/pref_registry_syncable.h"
37 #include "components/rappor/rappor_utils.h" 37 #include "components/rappor/rappor_utils.h"
38 #include "content/public/browser/browser_context.h" 38 #include "content/public/browser/browser_context.h"
39 #include "content/public/browser/browser_thread.h" 39 #include "content/public/browser/browser_thread.h"
40 #include "content/public/browser/notification_database_data.h"
41 #include "content/public/browser/platform_notification_context.h"
40 #include "content/public/browser/render_frame_host.h" 42 #include "content/public/browser/render_frame_host.h"
41 #include "content/public/browser/service_worker_context.h" 43 #include "content/public/browser/service_worker_context.h"
42 #include "content/public/browser/storage_partition.h" 44 #include "content/public/browser/storage_partition.h"
43 #include "content/public/browser/web_contents.h" 45 #include "content/public/browser/web_contents.h"
44 #include "content/public/common/child_process_host.h" 46 #include "content/public/common/child_process_host.h"
45 #include "content/public/common/content_switches.h" 47 #include "content/public/common/content_switches.h"
46 #include "content/public/common/platform_notification_data.h" 48 #include "content/public/common/platform_notification_data.h"
47 #include "content/public/common/push_messaging_status.h" 49 #include "content/public/common/push_messaging_status.h"
48 #include "third_party/skia/include/core/SkBitmap.h" 50 #include "third_party/skia/include/core/SkBitmap.h"
49 #include "ui/base/l10n/l10n_util.h" 51 #include "ui/base/l10n/l10n_util.h"
50 52
51 #if defined(OS_ANDROID) 53 #if defined(OS_ANDROID)
52 #include "chrome/browser/ui/android/tab_model/tab_model.h" 54 #include "chrome/browser/ui/android/tab_model/tab_model.h"
53 #include "chrome/browser/ui/android/tab_model/tab_model_list.h" 55 #include "chrome/browser/ui/android/tab_model/tab_model_list.h"
54 #else 56 #else
55 #include "chrome/browser/ui/browser.h" 57 #include "chrome/browser/ui/browser.h"
56 #include "chrome/browser/ui/browser_iterator.h" 58 #include "chrome/browser/ui/browser_iterator.h"
57 #include "chrome/browser/ui/tabs/tab_strip_model.h" 59 #include "chrome/browser/ui/tabs/tab_strip_model.h"
58 #endif 60 #endif
59 61
62 using content::BrowserThread;
63
60 namespace { 64 namespace {
61 const int kMaxRegistrations = 1000000; 65 const int kMaxRegistrations = 1000000;
62 66
63 void RecordDeliveryStatus(content::PushDeliveryStatus status) { 67 void RecordDeliveryStatus(content::PushDeliveryStatus status) {
64 UMA_HISTOGRAM_ENUMERATION("PushMessaging.DeliveryStatus", 68 UMA_HISTOGRAM_ENUMERATION("PushMessaging.DeliveryStatus",
65 status, 69 status,
66 content::PUSH_DELIVERY_STATUS_LAST + 1); 70 content::PUSH_DELIVERY_STATUS_LAST + 1);
67 } 71 }
68 72
69 void RecordUserVisibleStatus(content::PushUserVisibleStatus status) { 73 void RecordUserVisibleStatus(content::PushUserVisibleStatus status) {
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 base::Bind(&UnregisterCallbackToClosure, 277 base::Bind(&UnregisterCallbackToClosure,
274 message_handled_closure)); 278 message_handled_closure));
275 break; 279 break;
276 } 280 }
277 RecordDeliveryStatus(status); 281 RecordDeliveryStatus(status);
278 } 282 }
279 283
280 void PushMessagingServiceImpl::RequireUserVisibleUX( 284 void PushMessagingServiceImpl::RequireUserVisibleUX(
281 const GURL& requesting_origin, int64 service_worker_registration_id, 285 const GURL& requesting_origin, int64 service_worker_registration_id,
282 const base::Closure& message_handled_closure) { 286 const base::Closure& message_handled_closure) {
287 DCHECK_CURRENTLY_ON(BrowserThread::UI);
283 #if defined(ENABLE_NOTIFICATIONS) 288 #if defined(ENABLE_NOTIFICATIONS)
284 // TODO(johnme): Relax this heuristic slightly. 289 // TODO(johnme): Relax this heuristic slightly.
285 PlatformNotificationServiceImpl* notification_service = 290 scoped_refptr<content::PlatformNotificationContext> notification_context =
286 PlatformNotificationServiceImpl::GetInstance(); 291 content::BrowserContext::GetStoragePartitionForSite(
287 // Can't use g_browser_process->notification_ui_manager(), since the test uses 292 profile_, requesting_origin)->GetPlatformNotificationContext();
288 // PlatformNotificationServiceImpl::SetNotificationUIManagerForTesting. 293 BrowserThread::PostTask(
289 // TODO(peter): Remove the need to use both APIs here once Notification.get() 294 BrowserThread::IO, FROM_HERE,
290 // is supported. 295 base::Bind(
291 int notification_count = notification_service->GetNotificationUIManager()-> 296 &content::PlatformNotificationContext
292 GetAllIdsByProfileAndSourceOrigin(profile_, requesting_origin).size(); 297 ::ReadAllNotificationDataForServiceWorkerRegistration,
298 notification_context,
299 requesting_origin, service_worker_registration_id,
300 base::Bind(
301 &PushMessagingServiceImpl::DidGetNotificationsShowingIOProxy,
302 weak_factory_.GetWeakPtr(),
303 requesting_origin, service_worker_registration_id,
304 message_handled_closure)));
305 #else
306 message_handled_closure.Run();
307 #endif // defined(ENABLE_NOTIFICATIONS)
308 }
309
310 void PushMessagingServiceImpl::DidGetNotificationsShowingIOProxy(
Peter Beverloo 2015/04/30 11:11:42 nit: // static
johnme 2015/04/30 13:30:12 Done.
311 const base::WeakPtr<PushMessagingServiceImpl>& ui_weak_ptr,
312 const GURL& requesting_origin,
313 int64 service_worker_registration_id,
314 const base::Closure& message_handled_closure,
315 bool success,
316 const std::vector<content::NotificationDatabaseData>& data) {
317 DCHECK_CURRENTLY_ON(BrowserThread::IO);
318 BrowserThread::PostTask(
319 BrowserThread::UI, FROM_HERE,
320 base::Bind(&PushMessagingServiceImpl::DidGetNotificationsShowing,
321 ui_weak_ptr,
322 requesting_origin, service_worker_registration_id,
323 message_handled_closure,
324 success, data));
325 }
326
327 void PushMessagingServiceImpl::DidGetNotificationsShowing(
328 const GURL& requesting_origin, int64 service_worker_registration_id,
329 const base::Closure& message_handled_closure,
330 bool success, const std::vector<content::NotificationDatabaseData>& data) {
331 DCHECK_CURRENTLY_ON(BrowserThread::UI);
293 // TODO(johnme): Hiding an existing notification should also count as a useful 332 // TODO(johnme): Hiding an existing notification should also count as a useful
294 // user-visible action done in response to a push message - but make sure that 333 // user-visible action done in response to a push message - but make sure that
295 // sending two messages in rapid succession which show then hide a 334 // sending two messages in rapid succession which show then hide a
296 // notification doesn't count. 335 // notification doesn't count.
336 int notification_count = success ? data.size() : 0;
297 bool notification_shown = notification_count > 0; 337 bool notification_shown = notification_count > 0;
298 338
299 bool notification_needed = true; 339 bool notification_needed = true;
300 // Sites with a currently visible tab don't need to show notifications. 340 // Sites with a currently visible tab don't need to show notifications.
301 #if defined(OS_ANDROID) 341 #if defined(OS_ANDROID)
302 for (auto it = TabModelList::begin(); it != TabModelList::end(); ++it) { 342 for (auto it = TabModelList::begin(); it != TabModelList::end(); ++it) {
303 Profile* profile = (*it)->GetProfile(); 343 Profile* profile = (*it)->GetProfile();
304 content::WebContents* active_web_contents = 344 content::WebContents* active_web_contents =
305 (*it)->GetActiveWebContents(); 345 (*it)->GetActiveWebContents();
306 #else 346 #else
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 base::Bind(&PushMessagingServiceImpl::DidGetNotificationsShown, 390 base::Bind(&PushMessagingServiceImpl::DidGetNotificationsShown,
351 weak_factory_.GetWeakPtr(), 391 weak_factory_.GetWeakPtr(),
352 requesting_origin, service_worker_registration_id, 392 requesting_origin, service_worker_registration_id,
353 notification_shown, notification_needed, 393 notification_shown, notification_needed,
354 message_handled_closure)); 394 message_handled_closure));
355 } else { 395 } else {
356 RecordUserVisibleStatus( 396 RecordUserVisibleStatus(
357 content::PUSH_USER_VISIBLE_STATUS_NOT_REQUIRED_AND_NOT_SHOWN); 397 content::PUSH_USER_VISIBLE_STATUS_NOT_REQUIRED_AND_NOT_SHOWN);
358 message_handled_closure.Run(); 398 message_handled_closure.Run();
359 } 399 }
360 #else
361 message_handled_closure.Run();
362 #endif // defined(ENABLE_NOTIFICATIONS)
363 } 400 }
364 401
365 static void IgnoreResult(bool unused) { 402 static void IgnoreResult(bool unused) {
366 } 403 }
367 404
368 void PushMessagingServiceImpl::DidGetNotificationsShown( 405 void PushMessagingServiceImpl::DidGetNotificationsShown(
369 const GURL& requesting_origin, int64 service_worker_registration_id, 406 const GURL& requesting_origin, int64 service_worker_registration_id,
370 bool notification_shown, bool notification_needed, 407 bool notification_shown, bool notification_needed,
371 const base::Closure& message_handled_closure, 408 const base::Closure& message_handled_closure,
372 const std::string& data, bool success, bool not_found) { 409 const std::string& data, bool success, bool not_found) {
410 DCHECK_CURRENTLY_ON(BrowserThread::UI);
373 content::ServiceWorkerContext* service_worker_context = 411 content::ServiceWorkerContext* service_worker_context =
374 content::BrowserContext::GetStoragePartitionForSite( 412 content::BrowserContext::GetStoragePartitionForSite(
375 profile_, requesting_origin)->GetServiceWorkerContext(); 413 profile_, requesting_origin)->GetServiceWorkerContext();
376 414
377 // We remember whether the last (up to) 10 pushes showed notifications. 415 // We remember whether the last (up to) 10 pushes showed notifications.
378 const size_t MISSED_NOTIFICATIONS_LENGTH = 10; 416 const size_t MISSED_NOTIFICATIONS_LENGTH = 10;
379 // data is a string like "0001000", where '0' means shown, and '1' means 417 // data is a string like "0001000", where '0' means shown, and '1' means
380 // needed but not shown. We manipulate it in bitset form. 418 // needed but not shown. We manipulate it in bitset form.
381 std::bitset<MISSED_NOTIFICATIONS_LENGTH> missed_notifications(data); 419 std::bitset<MISSED_NOTIFICATIONS_LENGTH> missed_notifications(data);
382 420
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 // TODO(johnme): The generic notification should probably automatically 460 // TODO(johnme): The generic notification should probably automatically
423 // close itself when the next push message arrives? 461 // close itself when the next push message arrives?
424 content::PlatformNotificationData notification_data; 462 content::PlatformNotificationData notification_data;
425 // TODO(johnme): Switch to FormatOriginForDisplay from crbug.com/402698 463 // TODO(johnme): Switch to FormatOriginForDisplay from crbug.com/402698
426 notification_data.title = base::UTF8ToUTF16(requesting_origin.host()); 464 notification_data.title = base::UTF8ToUTF16(requesting_origin.host());
427 notification_data.direction = 465 notification_data.direction =
428 content::PlatformNotificationData::NotificationDirectionLeftToRight; 466 content::PlatformNotificationData::NotificationDirectionLeftToRight;
429 notification_data.body = 467 notification_data.body =
430 l10n_util::GetStringUTF16(IDS_PUSH_MESSAGING_GENERIC_NOTIFICATION_BODY); 468 l10n_util::GetStringUTF16(IDS_PUSH_MESSAGING_GENERIC_NOTIFICATION_BODY);
431 notification_data.tag = kPushMessagingForcedNotificationTag; 469 notification_data.tag = kPushMessagingForcedNotificationTag;
432 notification_data.icon = GURL(); // TODO(johnme): Better icon? 470 notification_data.icon = GURL();
433 notification_data.silent = true; 471 notification_data.silent = true;
434 PlatformNotificationServiceImpl* notification_service = 472
435 PlatformNotificationServiceImpl::GetInstance(); 473 content::NotificationDatabaseData database_data;
436 notification_service->DisplayPersistentNotification( 474 database_data.origin = requesting_origin;
475 database_data.service_worker_registration_id =
476 service_worker_registration_id;
477 database_data.notification_data = notification_data;
478
479 scoped_refptr<content::PlatformNotificationContext> notification_context =
480 content::BrowserContext::GetStoragePartitionForSite(
481 profile_, requesting_origin)->GetPlatformNotificationContext();
482 BrowserThread::PostTask(
483 BrowserThread::IO, FROM_HERE,
484 base::Bind(
485 &content::PlatformNotificationContext::WriteNotificationData,
486 notification_context,
487 requesting_origin, database_data,
488 base::Bind(&PushMessagingServiceImpl::DidWriteNotificationDataIOProxy,
489 weak_factory_.GetWeakPtr(),
490 requesting_origin, notification_data,
491 message_handled_closure)));
492 }
493
494 void PushMessagingServiceImpl::DidWriteNotificationDataIOProxy(
495 const base::WeakPtr<PushMessagingServiceImpl>& ui_weak_ptr,
496 const GURL& requesting_origin,
497 const content::PlatformNotificationData& notification_data,
498 const base::Closure& message_handled_closure,
499 bool success,
500 int64_t persistent_notification_id) {
501 DCHECK_CURRENTLY_ON(BrowserThread::IO);
502 BrowserThread::PostTask(
503 BrowserThread::UI, FROM_HERE,
504 base::Bind(&PushMessagingServiceImpl::DidWriteNotificationData,
505 ui_weak_ptr,
506 requesting_origin, notification_data, message_handled_closure,
507 success, persistent_notification_id));
508 }
509
510 void PushMessagingServiceImpl::DidWriteNotificationData(
511 const GURL& requesting_origin,
512 const content::PlatformNotificationData& notification_data,
513 const base::Closure& message_handled_closure,
514 bool success,
515 int64_t persistent_notification_id) {
516 DCHECK_CURRENTLY_ON(BrowserThread::UI);
517 if (!success) {
518 DLOG(ERROR) << "Writing forced notification to database should rarely fail";
Peter Beverloo 2015/04/30 11:11:42 nit: s/rarely/not/.
johnme 2015/04/30 13:30:12 Done.
519 message_handled_closure.Run();
520 return;
521 }
522 PlatformNotificationServiceImpl::GetInstance()->DisplayPersistentNotification(
437 profile_, 523 profile_,
438 service_worker_registration_id, 524 persistent_notification_id,
439 requesting_origin, 525 requesting_origin,
440 SkBitmap() /* icon */, 526 SkBitmap() /* icon */,
441 notification_data); 527 notification_data);
442 message_handled_closure.Run(); 528 message_handled_closure.Run();
443 } 529 }
444 530
445 void PushMessagingServiceImpl::SetMessageCallbackForTesting( 531 void PushMessagingServiceImpl::SetMessageCallbackForTesting(
446 const base::Closure& callback) { 532 const base::Closure& callback) {
447 message_callback_for_testing_ = callback; 533 message_callback_for_testing_ = callback;
448 } 534 }
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 CONTENT_SETTING_ALLOW; 903 CONTENT_SETTING_ALLOW;
818 } 904 }
819 905
820 gcm::GCMDriver* PushMessagingServiceImpl::GetGCMDriver() const { 906 gcm::GCMDriver* PushMessagingServiceImpl::GetGCMDriver() const {
821 gcm::GCMProfileService* gcm_profile_service = 907 gcm::GCMProfileService* gcm_profile_service =
822 gcm::GCMProfileServiceFactory::GetForProfile(profile_); 908 gcm::GCMProfileServiceFactory::GetForProfile(profile_);
823 CHECK(gcm_profile_service); 909 CHECK(gcm_profile_service);
824 CHECK(gcm_profile_service->driver()); 910 CHECK(gcm_profile_service->driver());
825 return gcm_profile_service->driver(); 911 return gcm_profile_service->driver();
826 } 912 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698