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 |