| 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/notifications/platform_notification_service_impl.h" | 5 #include "chrome/browser/notifications/platform_notification_service_impl.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
| 12 #include "base/metrics/user_metrics_action.h" | 12 #include "base/metrics/user_metrics_action.h" |
| 13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "build/build_config.h" | 15 #include "build/build_config.h" |
| 16 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
| 17 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | 17 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| 18 #include "chrome/browser/notifications/notification_display_service_factory.h" | 18 #include "chrome/browser/notifications/notification_display_service_factory.h" |
| 19 #include "chrome/browser/notifications/notification_object_proxy.h" | 19 #include "chrome/browser/notifications/notification_object_proxy.h" |
| 20 #include "chrome/browser/notifications/notification_ui_manager.h" | 20 #include "chrome/browser/notifications/notification_ui_manager.h" |
| 21 #include "chrome/browser/notifications/persistent_notification_delegate.h" | 21 #include "chrome/browser/notifications/persistent_notification_delegate.h" |
| 22 #include "chrome/browser/permissions/permission_manager.h" | 22 #include "chrome/browser/permissions/permission_manager.h" |
| 23 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
| 24 #include "chrome/browser/profiles/profile_attributes_storage.h" | 24 #include "chrome/browser/profiles/profile_attributes_storage.h" |
| 25 #include "chrome/browser/profiles/profile_io_data.h" | 25 #include "chrome/browser/profiles/profile_io_data.h" |
| 26 #include "chrome/browser/profiles/profile_manager.h" | 26 #include "chrome/browser/profiles/profile_manager.h" |
| 27 #include "chrome/browser/ui/browser.h" | 27 #include "chrome/browser/ui/browser.h" |
| 28 #include "chrome/browser/ui/chrome_pages.h" | |
| 29 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" | |
| 30 #include "chrome/common/chrome_switches.h" | 28 #include "chrome/common/chrome_switches.h" |
| 31 #include "chrome/common/pref_names.h" | 29 #include "chrome/common/pref_names.h" |
| 32 #include "chrome/grit/generated_resources.h" | 30 #include "chrome/grit/generated_resources.h" |
| 33 #include "components/content_settings/core/browser/host_content_settings_map.h" | 31 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 34 #include "components/content_settings/core/common/content_settings.h" | 32 #include "components/content_settings/core/common/content_settings.h" |
| 35 #include "components/content_settings/core/common/content_settings_types.h" | 33 #include "components/content_settings/core/common/content_settings_types.h" |
| 36 #include "components/prefs/pref_service.h" | 34 #include "components/prefs/pref_service.h" |
| 37 #include "components/url_formatter/url_formatter.h" | 35 #include "components/url_formatter/url_formatter.h" |
| 38 #include "content/public/browser/browser_thread.h" | 36 #include "content/public/browser/browser_thread.h" |
| 39 #include "content/public/browser/desktop_notification_delegate.h" | 37 #include "content/public/browser/desktop_notification_delegate.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 namespace { | 74 namespace { |
| 77 | 75 |
| 78 // Invalid id for a renderer process. Used in cases where we need to check for | 76 // Invalid id for a renderer process. Used in cases where we need to check for |
| 79 // permission without having an associated renderer process yet. | 77 // permission without having an associated renderer process yet. |
| 80 const int kInvalidRenderProcessId = -1; | 78 const int kInvalidRenderProcessId = -1; |
| 81 | 79 |
| 82 void OnCloseNonPersistentNotificationProfileLoaded( | 80 void OnCloseNonPersistentNotificationProfileLoaded( |
| 83 const std::string& notification_id, | 81 const std::string& notification_id, |
| 84 Profile* profile) { | 82 Profile* profile) { |
| 85 NotificationDisplayServiceFactory::GetForProfile(profile)->Close( | 83 NotificationDisplayServiceFactory::GetForProfile(profile)->Close( |
| 86 notification_id); | 84 notification_operation_common::INPAGE_NOTIFICATION, notification_id); |
| 87 } | |
| 88 | |
| 89 // Callback to run once the profile has been loaded in order to perform a | |
| 90 // given |operation| in a notification. | |
| 91 void ProfileLoadedCallback( | |
| 92 PlatformNotificationServiceImpl::NotificationOperation operation, | |
| 93 const GURL& origin, | |
| 94 int64_t persistent_notification_id, | |
| 95 int action_index, | |
| 96 Profile* profile) { | |
| 97 if (!profile) { | |
| 98 // TODO(miguelg): Add UMA for this condition. | |
| 99 // Perhaps propagate this through PersistentNotificationStatus. | |
| 100 LOG(WARNING) << "Profile not loaded correctly"; | |
| 101 return; | |
| 102 } | |
| 103 | |
| 104 switch (operation) { | |
| 105 case PlatformNotificationServiceImpl::NOTIFICATION_CLICK: | |
| 106 PlatformNotificationServiceImpl::GetInstance() | |
| 107 ->OnPersistentNotificationClick(profile, persistent_notification_id, | |
| 108 origin, action_index); | |
| 109 break; | |
| 110 case PlatformNotificationServiceImpl::NOTIFICATION_CLOSE: | |
| 111 PlatformNotificationServiceImpl::GetInstance() | |
| 112 ->OnPersistentNotificationClose(profile, persistent_notification_id, | |
| 113 origin, true); | |
| 114 break; | |
| 115 case PlatformNotificationServiceImpl::NOTIFICATION_SETTINGS: | |
| 116 PlatformNotificationServiceImpl::GetInstance()->OpenNotificationSettings( | |
| 117 profile); | |
| 118 break; | |
| 119 } | |
| 120 } | 85 } |
| 121 | 86 |
| 122 // Callback used to close an non-persistent notification from blink. | 87 // Callback used to close an non-persistent notification from blink. |
| 123 void CancelNotification(const std::string& notification_id, | 88 void CancelNotification(const std::string& notification_id, |
| 124 std::string profile_id, | 89 std::string profile_id, |
| 125 bool incognito) { | 90 bool incognito) { |
| 126 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 91 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 127 DCHECK(profile_manager); | 92 DCHECK(profile_manager); |
| 128 profile_manager->LoadProfile( | 93 profile_manager->LoadProfile( |
| 129 profile_id, incognito, | 94 profile_id, incognito, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 141 | 106 |
| 142 PlatformNotificationServiceImpl::PlatformNotificationServiceImpl() | 107 PlatformNotificationServiceImpl::PlatformNotificationServiceImpl() |
| 143 : test_display_service_(nullptr) { | 108 : test_display_service_(nullptr) { |
| 144 #if BUILDFLAG(ENABLE_BACKGROUND) | 109 #if BUILDFLAG(ENABLE_BACKGROUND) |
| 145 pending_click_dispatch_events_ = 0; | 110 pending_click_dispatch_events_ = 0; |
| 146 #endif | 111 #endif |
| 147 } | 112 } |
| 148 | 113 |
| 149 PlatformNotificationServiceImpl::~PlatformNotificationServiceImpl() {} | 114 PlatformNotificationServiceImpl::~PlatformNotificationServiceImpl() {} |
| 150 | 115 |
| 151 void PlatformNotificationServiceImpl::ProcessPersistentNotificationOperation( | |
| 152 NotificationOperation operation, | |
| 153 const std::string& profile_id, | |
| 154 bool incognito, | |
| 155 const GURL& origin, | |
| 156 int64_t persistent_notification_id, | |
| 157 int action_index) { | |
| 158 ProfileManager* profile_manager = g_browser_process->profile_manager(); | |
| 159 DCHECK(profile_manager); | |
| 160 | |
| 161 profile_manager->LoadProfile( | |
| 162 profile_id, incognito, | |
| 163 base::Bind(&ProfileLoadedCallback, operation, origin, | |
| 164 persistent_notification_id, action_index)); | |
| 165 } | |
| 166 | |
| 167 void PlatformNotificationServiceImpl::OnPersistentNotificationClick( | 116 void PlatformNotificationServiceImpl::OnPersistentNotificationClick( |
| 168 BrowserContext* browser_context, | 117 BrowserContext* browser_context, |
| 169 int64_t persistent_notification_id, | 118 int64_t persistent_notification_id, |
| 170 const GURL& origin, | 119 const GURL& origin, |
| 171 int action_index) { | 120 int action_index) { |
| 172 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 121 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 173 blink::mojom::PermissionStatus permission_status = | 122 blink::mojom::PermissionStatus permission_status = |
| 174 CheckPermissionOnUIThread(browser_context, origin, | 123 CheckPermissionOnUIThread(browser_context, origin, |
| 175 kInvalidRenderProcessId); | 124 kInvalidRenderProcessId); |
| 176 | 125 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 | 283 |
| 335 Profile* profile = Profile::FromBrowserContext(browser_context); | 284 Profile* profile = Profile::FromBrowserContext(browser_context); |
| 336 DCHECK(profile); | 285 DCHECK(profile); |
| 337 DCHECK_EQ(0u, notification_data.actions.size()); | 286 DCHECK_EQ(0u, notification_data.actions.size()); |
| 338 DCHECK_EQ(0u, notification_resources.action_icons.size()); | 287 DCHECK_EQ(0u, notification_resources.action_icons.size()); |
| 339 | 288 |
| 340 NotificationObjectProxy* proxy = | 289 NotificationObjectProxy* proxy = |
| 341 new NotificationObjectProxy(browser_context, std::move(delegate)); | 290 new NotificationObjectProxy(browser_context, std::move(delegate)); |
| 342 Notification notification = CreateNotificationFromData( | 291 Notification notification = CreateNotificationFromData( |
| 343 profile, origin, notification_data, notification_resources, proxy); | 292 profile, origin, notification_data, notification_resources, proxy); |
| 344 GetNotificationDisplayService(profile)->Display(notification.delegate_id(), | 293 |
| 345 notification); | 294 GetNotificationDisplayService(profile)->Display( |
| 295 notification_operation_common::INPAGE_NOTIFICATION, |
| 296 notification.delegate_id(), notification); |
| 346 if (cancel_callback) { | 297 if (cancel_callback) { |
| 347 #if defined(OS_WIN) | 298 #if defined(OS_WIN) |
| 348 std::string profile_id = | 299 std::string profile_id = |
| 349 base::WideToUTF8(profile->GetPath().BaseName().value()); | 300 base::WideToUTF8(profile->GetPath().BaseName().value()); |
| 350 #elif defined(OS_POSIX) | 301 #elif defined(OS_POSIX) |
| 351 std::string profile_id = profile->GetPath().BaseName().value(); | 302 std::string profile_id = profile->GetPath().BaseName().value(); |
| 352 #endif | 303 #endif |
| 353 *cancel_callback = | 304 *cancel_callback = |
| 354 base::Bind(&CancelNotification, notification.delegate_id(), profile_id, | 305 base::Bind(&CancelNotification, notification.delegate_id(), profile_id, |
| 355 profile->IsOffTheRecord()); | 306 profile->IsOffTheRecord()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 378 settings_button_index); | 329 settings_button_index); |
| 379 | 330 |
| 380 Notification notification = CreateNotificationFromData( | 331 Notification notification = CreateNotificationFromData( |
| 381 profile, origin, notification_data, notification_resources, delegate); | 332 profile, origin, notification_data, notification_resources, delegate); |
| 382 | 333 |
| 383 // TODO(peter): Remove this mapping when we have reliable id generation for | 334 // TODO(peter): Remove this mapping when we have reliable id generation for |
| 384 // the message_center::Notification objects. | 335 // the message_center::Notification objects. |
| 385 persistent_notifications_[persistent_notification_id] = notification.id(); | 336 persistent_notifications_[persistent_notification_id] = notification.id(); |
| 386 | 337 |
| 387 GetNotificationDisplayService(profile)->Display( | 338 GetNotificationDisplayService(profile)->Display( |
| 339 notification_operation_common::PERSISTENT_NOTIFICATION, |
| 388 base::Int64ToString(delegate->persistent_notification_id()), | 340 base::Int64ToString(delegate->persistent_notification_id()), |
| 389 notification); | 341 notification); |
| 390 content::RecordAction( | 342 content::RecordAction( |
| 391 base::UserMetricsAction("Notifications.Persistent.Shown")); | 343 base::UserMetricsAction("Notifications.Persistent.Shown")); |
| 392 | 344 |
| 393 HostContentSettingsMapFactory::GetForProfile(profile)->UpdateLastUsage( | 345 HostContentSettingsMapFactory::GetForProfile(profile)->UpdateLastUsage( |
| 394 origin, origin, CONTENT_SETTINGS_TYPE_NOTIFICATIONS); | 346 origin, origin, CONTENT_SETTINGS_TYPE_NOTIFICATIONS); |
| 395 } | 347 } |
| 396 | 348 |
| 397 void PlatformNotificationServiceImpl::ClosePersistentNotification( | 349 void PlatformNotificationServiceImpl::ClosePersistentNotification( |
| 398 BrowserContext* browser_context, | 350 BrowserContext* browser_context, |
| 399 int64_t persistent_notification_id) { | 351 int64_t persistent_notification_id) { |
| 400 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 352 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 401 | 353 |
| 402 Profile* profile = Profile::FromBrowserContext(browser_context); | 354 Profile* profile = Profile::FromBrowserContext(browser_context); |
| 403 DCHECK(profile); | 355 DCHECK(profile); |
| 404 | 356 |
| 405 closed_notifications_.insert(persistent_notification_id); | 357 closed_notifications_.insert(persistent_notification_id); |
| 406 | 358 |
| 407 #if defined(OS_ANDROID) | 359 #if defined(OS_ANDROID) |
| 408 bool cancel_by_persistent_id = true; | 360 bool cancel_by_persistent_id = true; |
| 409 #else | 361 #else |
| 410 bool cancel_by_persistent_id = | 362 bool cancel_by_persistent_id = |
| 411 GetNotificationDisplayService(profile)->SupportsNotificationCenter(); | 363 GetNotificationDisplayService(profile)->SupportsNotificationCenter(); |
| 412 #endif | 364 #endif |
| 413 | 365 |
| 366 auto iter = persistent_notifications_.find(persistent_notification_id); |
| 367 if (iter == persistent_notifications_.end()) |
| 368 return; |
| 414 if (cancel_by_persistent_id) { | 369 if (cancel_by_persistent_id) { |
| 415 // TODO(peter): Remove this conversion when the notification ids are being | 370 // TODO(peter): Remove this conversion when the notification ids are being |
| 416 // generated by the caller of this method. | 371 // generated by the caller of this method. |
| 417 GetNotificationDisplayService(profile)->Close( | 372 GetNotificationDisplayService(profile)->Close( |
| 373 notification_operation_common::PERSISTENT_NOTIFICATION, |
| 418 base::Int64ToString(persistent_notification_id)); | 374 base::Int64ToString(persistent_notification_id)); |
| 375 } else { |
| 376 GetNotificationDisplayService(profile)->Close( |
| 377 notification_operation_common::PERSISTENT_NOTIFICATION, iter->second); |
| 419 } | 378 } |
| 420 | |
| 421 auto iter = persistent_notifications_.find(persistent_notification_id); | |
| 422 if (iter == persistent_notifications_.end()) | |
| 423 return; | |
| 424 | |
| 425 GetNotificationDisplayService(profile)->Close(iter->second); | |
| 426 | |
| 427 persistent_notifications_.erase(iter); | 379 persistent_notifications_.erase(iter); |
| 428 } | 380 } |
| 429 | 381 |
| 430 bool PlatformNotificationServiceImpl::GetDisplayedPersistentNotifications( | 382 bool PlatformNotificationServiceImpl::GetDisplayedPersistentNotifications( |
| 431 BrowserContext* browser_context, | 383 BrowserContext* browser_context, |
| 432 std::set<std::string>* displayed_notifications) { | 384 std::set<std::string>* displayed_notifications) { |
| 433 DCHECK(displayed_notifications); | 385 DCHECK(displayed_notifications); |
| 434 | 386 |
| 435 Profile* profile = Profile::FromBrowserContext(browser_context); | 387 Profile* profile = Profile::FromBrowserContext(browser_context); |
| 436 if (!profile || profile->AsTestingProfile()) | 388 if (!profile || profile->AsTestingProfile()) |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 } | 473 } |
| 522 | 474 |
| 523 NotificationDisplayService* | 475 NotificationDisplayService* |
| 524 PlatformNotificationServiceImpl::GetNotificationDisplayService( | 476 PlatformNotificationServiceImpl::GetNotificationDisplayService( |
| 525 Profile* profile) { | 477 Profile* profile) { |
| 526 if (test_display_service_ != nullptr) | 478 if (test_display_service_ != nullptr) |
| 527 return test_display_service_; | 479 return test_display_service_; |
| 528 return NotificationDisplayServiceFactory::GetForProfile(profile); | 480 return NotificationDisplayServiceFactory::GetForProfile(profile); |
| 529 } | 481 } |
| 530 | 482 |
| 531 void PlatformNotificationServiceImpl::OpenNotificationSettings( | |
| 532 BrowserContext* browser_context) { | |
| 533 #if defined(OS_ANDROID) | |
| 534 NOTIMPLEMENTED(); | |
| 535 #else | |
| 536 | |
| 537 Profile* profile = Profile::FromBrowserContext(browser_context); | |
| 538 DCHECK(profile); | |
| 539 | |
| 540 if (switches::SettingsWindowEnabled()) { | |
| 541 chrome::ShowContentSettingsExceptionsInWindow( | |
| 542 profile, CONTENT_SETTINGS_TYPE_NOTIFICATIONS); | |
| 543 } else { | |
| 544 chrome::ScopedTabbedBrowserDisplayer browser_displayer(profile); | |
| 545 chrome::ShowContentSettingsExceptions(browser_displayer.browser(), | |
| 546 CONTENT_SETTINGS_TYPE_NOTIFICATIONS); | |
| 547 } | |
| 548 | |
| 549 #endif // defined(OS_ANDROID) | |
| 550 } | |
| 551 | |
| 552 base::string16 PlatformNotificationServiceImpl::DisplayNameForContextMessage( | 483 base::string16 PlatformNotificationServiceImpl::DisplayNameForContextMessage( |
| 553 Profile* profile, | 484 Profile* profile, |
| 554 const GURL& origin) const { | 485 const GURL& origin) const { |
| 555 #if defined(ENABLE_EXTENSIONS) | 486 #if defined(ENABLE_EXTENSIONS) |
| 556 // If the source is an extension, lookup the display name. | 487 // If the source is an extension, lookup the display name. |
| 557 if (origin.SchemeIs(extensions::kExtensionScheme)) { | 488 if (origin.SchemeIs(extensions::kExtensionScheme)) { |
| 558 const extensions::Extension* extension = | 489 const extensions::Extension* extension = |
| 559 extensions::ExtensionRegistry::Get(profile)->GetExtensionById( | 490 extensions::ExtensionRegistry::Get(profile)->GetExtensionById( |
| 560 origin.host(), extensions::ExtensionRegistry::EVERYTHING); | 491 origin.host(), extensions::ExtensionRegistry::EVERYTHING); |
| 561 DCHECK(extension); | 492 DCHECK(extension); |
| 562 | 493 |
| 563 return base::UTF8ToUTF16(extension->name()); | 494 return base::UTF8ToUTF16(extension->name()); |
| 564 } | 495 } |
| 565 #endif | 496 #endif |
| 566 | 497 |
| 567 return base::string16(); | 498 return base::string16(); |
| 568 } | 499 } |
| 569 | 500 |
| 570 void PlatformNotificationServiceImpl::SetNotificationDisplayServiceForTesting( | 501 void PlatformNotificationServiceImpl::SetNotificationDisplayServiceForTesting( |
| 571 NotificationDisplayService* display_service) { | 502 NotificationDisplayService* display_service) { |
| 572 test_display_service_ = display_service; | 503 test_display_service_ = display_service; |
| 573 } | 504 } |
| OLD | NEW |