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

Side by Side Diff: chrome/browser/extensions/api/notifications/notifications_api.cc

Issue 2703213004: Migrate extension notifications to the new NotificationDisplayService (Closed)
Patch Set: another rebase Created 3 years, 8 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 "chrome/browser/extensions/api/notifications/notifications_api.h" 5 #include "chrome/browser/extensions/api/notifications/notifications_api.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/feature_list.h" 12 #include "base/feature_list.h"
13 #include "base/guid.h" 13 #include "base/guid.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/metrics/histogram_macros.h" 16 #include "base/metrics/histogram_macros.h"
17 #include "base/rand_util.h" 17 #include "base/rand_util.h"
18 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
20 #include "base/time/time.h" 20 #include "base/time/time.h"
21 #include "build/build_config.h" 21 #include "build/build_config.h"
22 #include "chrome/browser/browser_process.h" 22 #include "chrome/browser/extensions/api/notifications/extension_notification_dis play_helper.h"
23 #include "chrome/browser/extensions/api/notifications/extension_notification_dis play_helper_factory.h"
23 #include "chrome/browser/notifications/notification.h" 24 #include "chrome/browser/notifications/notification.h"
24 #include "chrome/browser/notifications/notification_ui_manager.h"
25 #include "chrome/browser/notifications/notifier_state_tracker.h" 25 #include "chrome/browser/notifications/notifier_state_tracker.h"
26 #include "chrome/browser/notifications/notifier_state_tracker_factory.h" 26 #include "chrome/browser/notifications/notifier_state_tracker_factory.h"
27 #include "chrome/browser/profiles/profile.h" 27 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/common/extensions/api/notifications/notification_style.h" 28 #include "chrome/common/extensions/api/notifications/notification_style.h"
29 #include "components/keyed_service/content/browser_context_keyed_service_shutdow n_notifier_factory.h" 29 #include "components/keyed_service/content/browser_context_keyed_service_shutdow n_notifier_factory.h"
30 #include "components/keyed_service/core/keyed_service_shutdown_notifier.h" 30 #include "components/keyed_service/core/keyed_service_shutdown_notifier.h"
31 #include "content/public/browser/render_process_host.h" 31 #include "content/public/browser/render_process_host.h"
32 #include "content/public/browser/render_view_host.h" 32 #include "content/public/browser/render_view_host.h"
33 #include "content/public/browser/web_contents.h" 33 #include "content/public/browser/web_contents.h"
34 #include "extensions/browser/app_window/app_window.h" 34 #include "extensions/browser/app_window/app_window.h"
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 }; 205 };
206 206
207 class NotificationsApiDelegate : public NotificationDelegate { 207 class NotificationsApiDelegate : public NotificationDelegate {
208 public: 208 public:
209 NotificationsApiDelegate(ChromeAsyncExtensionFunction* api_function, 209 NotificationsApiDelegate(ChromeAsyncExtensionFunction* api_function,
210 Profile* profile, 210 Profile* profile,
211 const std::string& extension_id, 211 const std::string& extension_id,
212 const std::string& id) 212 const std::string& id)
213 : api_function_(api_function), 213 : api_function_(api_function),
214 event_router_(EventRouter::Get(profile)), 214 event_router_(EventRouter::Get(profile)),
215 profile_(profile),
215 extension_id_(extension_id), 216 extension_id_(extension_id),
216 id_(id), 217 id_(id),
217 scoped_id_(CreateScopedIdentifier(extension_id, id)) { 218 scoped_id_(CreateScopedIdentifier(extension_id, id)) {
218 DCHECK(api_function_); 219 DCHECK(api_function_);
219 shutdown_notifier_subscription_ = 220 shutdown_notifier_subscription_ =
220 ShutdownNotifierFactory::GetInstance()->Get(profile)->Subscribe( 221 ShutdownNotifierFactory::GetInstance()->Get(profile)->Subscribe(
221 base::Bind(&NotificationsApiDelegate::Shutdown, 222 base::Bind(&NotificationsApiDelegate::Shutdown,
222 base::Unretained(this))); 223 base::Unretained(this)));
223 } 224 }
224 225
225 void Close(bool by_user) override { 226 void Close(bool by_user) override {
226 EventRouter::UserGestureState gesture = 227 EventRouter::UserGestureState gesture =
227 by_user ? EventRouter::USER_GESTURE_ENABLED 228 by_user ? EventRouter::USER_GESTURE_ENABLED
228 : EventRouter::USER_GESTURE_NOT_ENABLED; 229 : EventRouter::USER_GESTURE_NOT_ENABLED;
229 std::unique_ptr<base::ListValue> args(CreateBaseEventArgs()); 230 std::unique_ptr<base::ListValue> args(CreateBaseEventArgs());
230 args->AppendBoolean(by_user); 231 args->AppendBoolean(by_user);
231 SendEvent(events::NOTIFICATIONS_ON_CLOSED, 232 SendEvent(events::NOTIFICATIONS_ON_CLOSED,
232 notifications::OnClosed::kEventName, gesture, std::move(args)); 233 notifications::OnClosed::kEventName, gesture, std::move(args));
234
235 DCHECK(profile_);
236 ExtensionNotificationDisplayHelperFactory::GetForProfile(profile_)
237 ->EraseDataForNotificationId(scoped_id_);
233 } 238 }
234 239
235 void Click() override { 240 void Click() override {
236 std::unique_ptr<base::ListValue> args(CreateBaseEventArgs()); 241 std::unique_ptr<base::ListValue> args(CreateBaseEventArgs());
237 SendEvent(events::NOTIFICATIONS_ON_CLICKED, 242 SendEvent(events::NOTIFICATIONS_ON_CLICKED,
238 notifications::OnClicked::kEventName, 243 notifications::OnClicked::kEventName,
239 EventRouter::USER_GESTURE_ENABLED, std::move(args)); 244 EventRouter::USER_GESTURE_ENABLED, std::move(args));
240 } 245 }
241 246
242 bool HasClickedListener() override { 247 bool HasClickedListener() override {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 if (!event_router_) 300 if (!event_router_)
296 return; 301 return;
297 302
298 std::unique_ptr<Event> event( 303 std::unique_ptr<Event> event(
299 new Event(histogram_value, name, std::move(args))); 304 new Event(histogram_value, name, std::move(args)));
300 event->user_gesture = user_gesture; 305 event->user_gesture = user_gesture;
301 event_router_->DispatchEventToExtension(extension_id_, std::move(event)); 306 event_router_->DispatchEventToExtension(extension_id_, std::move(event));
302 } 307 }
303 308
304 void Shutdown() { 309 void Shutdown() {
310 shutdown_notifier_subscription_.reset();
305 event_router_ = nullptr; 311 event_router_ = nullptr;
306 shutdown_notifier_subscription_.reset(); 312 profile_ = nullptr;
307 } 313 }
308 314
309 std::unique_ptr<base::ListValue> CreateBaseEventArgs() { 315 std::unique_ptr<base::ListValue> CreateBaseEventArgs() {
310 std::unique_ptr<base::ListValue> args(new base::ListValue()); 316 std::unique_ptr<base::ListValue> args(new base::ListValue());
311 args->AppendString(id_); 317 args->AppendString(id_);
312 return args; 318 return args;
313 } 319 }
314 320
315 scoped_refptr<ChromeAsyncExtensionFunction> api_function_; 321 scoped_refptr<ChromeAsyncExtensionFunction> api_function_;
316 322
317 // Since this class is refcounted it may outlive the profile. We listen for 323 // Since this class is refcounted it may outlive the profile. We listen for
318 // profile-keyed service shutdown events and reset to nullptr at that time, 324 // profile-keyed service shutdown events and reset to nullptr at that time,
319 // so make sure to check for a valid pointer before use. 325 // so make sure to check for a valid pointer before use.
320 EventRouter* event_router_; 326 EventRouter* event_router_;
327 Profile* profile_;
Devlin 2017/04/10 21:23:55 Instead of profile_, maybe store ExtensionNotifica
Peter Beverloo 2017/04/11 14:19:25 Done.
321 328
322 const std::string extension_id_; 329 const std::string extension_id_;
323 const std::string id_; 330 const std::string id_;
324 const std::string scoped_id_; 331 const std::string scoped_id_;
325 332
326 std::unique_ptr<KeyedServiceShutdownNotifier::Subscription> 333 std::unique_ptr<KeyedServiceShutdownNotifier::Subscription>
327 shutdown_notifier_subscription_; 334 shutdown_notifier_subscription_;
328 335
329 DISALLOW_COPY_AND_ASSIGN(NotificationsApiDelegate); 336 DISALLOW_COPY_AND_ASSIGN(NotificationsApiDelegate);
330 }; 337 };
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 type, title, message, icon, 496 type, title, message, icon,
490 message_center::NotifierId(message_center::NotifierId::APPLICATION, 497 message_center::NotifierId(message_center::NotifierId::APPLICATION,
491 extension_->id()), 498 extension_->id()),
492 base::UTF8ToUTF16(extension_->name()), extension_->url(), 499 base::UTF8ToUTF16(extension_->name()), extension_->url(),
493 api_delegate->id(), optional_fields, api_delegate); 500 api_delegate->id(), optional_fields, api_delegate);
494 501
495 // Apply the "requireInteraction" flag. The value defaults to false. 502 // Apply the "requireInteraction" flag. The value defaults to false.
496 notification.set_never_timeout(options->require_interaction && 503 notification.set_never_timeout(options->require_interaction &&
497 *options->require_interaction); 504 *options->require_interaction);
498 505
499 g_browser_process->notification_ui_manager()->Add(notification, GetProfile()); 506 GetDisplayHelper()->Display(notification);
500 return true; 507 return true;
501 } 508 }
502 509
503 bool NotificationsApiFunction::UpdateNotification( 510 bool NotificationsApiFunction::UpdateNotification(
504 const std::string& id, 511 const std::string& id,
505 api::notifications::NotificationOptions* options, 512 api::notifications::NotificationOptions* options,
506 Notification* notification) { 513 Notification* notification) {
507 #if !defined(OS_CHROMEOS) 514 #if !defined(OS_CHROMEOS)
508 if (options->priority && 515 if (options->priority &&
509 *options->priority < message_center::DEFAULT_PRIORITY) { 516 *options->priority < message_center::DEFAULT_PRIORITY) {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 base::UTF8ToUTF16(api_item.title), 630 base::UTF8ToUTF16(api_item.title),
624 base::UTF8ToUTF16(api_item.message))); 631 base::UTF8ToUTF16(api_item.message)));
625 } 632 }
626 notification->set_items(items); 633 notification->set_items(items);
627 } 634 }
628 635
629 // Then override if it's already set. 636 // Then override if it's already set.
630 if (options->is_clickable.get()) 637 if (options->is_clickable.get())
631 notification->set_clickable(*options->is_clickable); 638 notification->set_clickable(*options->is_clickable);
632 639
633 g_browser_process->notification_ui_manager()->Update(*notification, 640 // It's safe to follow the regular path for adding a new notification as it's
634 GetProfile()); 641 // already been verified that there is a notification that can be updated.
642 GetDisplayHelper()->Display(*notification);
643
635 return true; 644 return true;
636 } 645 }
637 646
638 bool NotificationsApiFunction::AreExtensionNotificationsAllowed() const { 647 bool NotificationsApiFunction::AreExtensionNotificationsAllowed() const {
639 NotifierStateTracker* notifier_state_tracker = 648 NotifierStateTracker* notifier_state_tracker =
640 NotifierStateTrackerFactory::GetForProfile(GetProfile()); 649 NotifierStateTrackerFactory::GetForProfile(GetProfile());
641 650
642 return notifier_state_tracker->IsNotifierEnabled( 651 return notifier_state_tracker->IsNotifierEnabled(
643 message_center::NotifierId(message_center::NotifierId::APPLICATION, 652 message_center::NotifierId(message_center::NotifierId::APPLICATION,
644 extension_->id())); 653 extension_->id()));
645 } 654 }
646 655
647 bool NotificationsApiFunction::IsNotificationsApiEnabled() const { 656 bool NotificationsApiFunction::IsNotificationsApiEnabled() const {
648 return CanRunWhileDisabled() || AreExtensionNotificationsAllowed(); 657 return CanRunWhileDisabled() || AreExtensionNotificationsAllowed();
649 } 658 }
650 659
651 bool NotificationsApiFunction::CanRunWhileDisabled() const { 660 bool NotificationsApiFunction::CanRunWhileDisabled() const {
652 return false; 661 return false;
653 } 662 }
654 663
664 ExtensionNotificationDisplayHelper* NotificationsApiFunction::GetDisplayHelper()
665 const {
666 return ExtensionNotificationDisplayHelperFactory::GetForProfile(GetProfile());
667 }
668
655 bool NotificationsApiFunction::RunAsync() { 669 bool NotificationsApiFunction::RunAsync() {
656 if (IsNotificationsApiAvailable() && IsNotificationsApiEnabled()) { 670 if (IsNotificationsApiAvailable() && IsNotificationsApiEnabled()) {
657 return RunNotificationsApi(); 671 return RunNotificationsApi();
658 } else { 672 } else {
659 SendResponse(false); 673 SendResponse(false);
660 return true; 674 return true;
661 } 675 }
662 } 676 }
663 677
664 message_center::NotificationType 678 message_center::NotificationType
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 NotificationsUpdateFunction::~NotificationsUpdateFunction() { 735 NotificationsUpdateFunction::~NotificationsUpdateFunction() {
722 } 736 }
723 737
724 bool NotificationsUpdateFunction::RunNotificationsApi() { 738 bool NotificationsUpdateFunction::RunNotificationsApi() {
725 params_ = api::notifications::Update::Params::Create(*args_); 739 params_ = api::notifications::Update::Params::Create(*args_);
726 EXTENSION_FUNCTION_VALIDATE(params_.get()); 740 EXTENSION_FUNCTION_VALIDATE(params_.get());
727 741
728 // We are in update. If the ID doesn't exist, succeed but call the callback 742 // We are in update. If the ID doesn't exist, succeed but call the callback
729 // with "false". 743 // with "false".
730 const Notification* matched_notification = 744 const Notification* matched_notification =
731 g_browser_process->notification_ui_manager()->FindById( 745 GetDisplayHelper()->GetByNotificationId(
732 CreateScopedIdentifier(extension_->id(), params_->notification_id), 746 CreateScopedIdentifier(extension_->id(), params_->notification_id));
733 NotificationUIManager::GetProfileID(GetProfile())); 747
734 if (!matched_notification) { 748 if (!matched_notification) {
735 SetResult(base::MakeUnique<base::Value>(false)); 749 SetResult(base::MakeUnique<base::Value>(false));
736 SendResponse(true); 750 SendResponse(true);
737 return true; 751 return true;
738 } 752 }
739 753
740 // Copy the existing notification to get a writable version of it. 754 // Copy the existing notification to get a writable version of it.
741 Notification notification = *matched_notification; 755 Notification notification = *matched_notification;
742 756
743 // If we have trouble updating the notification (could be improper use of API 757 // If we have trouble updating the notification (could be improper use of API
(...skipping 15 matching lines...) Expand all
759 NotificationsClearFunction::NotificationsClearFunction() { 773 NotificationsClearFunction::NotificationsClearFunction() {
760 } 774 }
761 775
762 NotificationsClearFunction::~NotificationsClearFunction() { 776 NotificationsClearFunction::~NotificationsClearFunction() {
763 } 777 }
764 778
765 bool NotificationsClearFunction::RunNotificationsApi() { 779 bool NotificationsClearFunction::RunNotificationsApi() {
766 params_ = api::notifications::Clear::Params::Create(*args_); 780 params_ = api::notifications::Clear::Params::Create(*args_);
767 EXTENSION_FUNCTION_VALIDATE(params_.get()); 781 EXTENSION_FUNCTION_VALIDATE(params_.get());
768 782
769 bool cancel_result = g_browser_process->notification_ui_manager()->CancelById( 783 bool cancel_result = GetDisplayHelper()->Close(
770 CreateScopedIdentifier(extension_->id(), params_->notification_id), 784 CreateScopedIdentifier(extension_->id(), params_->notification_id));
771 NotificationUIManager::GetProfileID(GetProfile()));
772 785
773 SetResult(base::MakeUnique<base::Value>(cancel_result)); 786 SetResult(base::MakeUnique<base::Value>(cancel_result));
774 SendResponse(true); 787 SendResponse(true);
775 788
776 return true; 789 return true;
777 } 790 }
778 791
779 NotificationsGetAllFunction::NotificationsGetAllFunction() {} 792 NotificationsGetAllFunction::NotificationsGetAllFunction() {}
780 793
781 NotificationsGetAllFunction::~NotificationsGetAllFunction() {} 794 NotificationsGetAllFunction::~NotificationsGetAllFunction() {}
782 795
783 bool NotificationsGetAllFunction::RunNotificationsApi() { 796 bool NotificationsGetAllFunction::RunNotificationsApi() {
784 NotificationUIManager* notification_ui_manager =
785 g_browser_process->notification_ui_manager();
786 std::set<std::string> notification_ids = 797 std::set<std::string> notification_ids =
787 notification_ui_manager->GetAllIdsByProfileAndSourceOrigin( 798 GetDisplayHelper()->GetNotificationIdsForExtension(extension_->url());
788 NotificationUIManager::GetProfileID(GetProfile()), extension_->url());
789 799
790 std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue()); 800 std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
791 801
792 for (std::set<std::string>::iterator iter = notification_ids.begin(); 802 for (std::set<std::string>::iterator iter = notification_ids.begin();
793 iter != notification_ids.end(); iter++) { 803 iter != notification_ids.end(); iter++) {
794 result->SetBooleanWithoutPathExpansion( 804 result->SetBooleanWithoutPathExpansion(
795 StripScopeFromIdentifier(extension_->id(), *iter), true); 805 StripScopeFromIdentifier(extension_->id(), *iter), true);
796 } 806 }
797 807
798 SetResult(std::move(result)); 808 SetResult(std::move(result));
(...skipping 19 matching lines...) Expand all
818 : api::notifications::PERMISSION_LEVEL_DENIED; 828 : api::notifications::PERMISSION_LEVEL_DENIED;
819 829
820 SetResult( 830 SetResult(
821 base::MakeUnique<base::Value>(api::notifications::ToString(result))); 831 base::MakeUnique<base::Value>(api::notifications::ToString(result)));
822 SendResponse(true); 832 SendResponse(true);
823 833
824 return true; 834 return true;
825 } 835 }
826 836
827 } // namespace extensions 837 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698