desktop_notification_service.cc revision a02191e04bc25c4935f804f2c080ae28663d096d
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/desktop_notification_service.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/content_settings_details.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/content_settings_provider.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/host_content_settings_map.h"
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/api/notifications/notifications_api.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/infobars/confirm_infobar_delegate.h"
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/infobars/infobar.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/infobars/infobar_service.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/desktop_notification_service_factory.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/notification.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/notification_object_proxy.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/notification_ui_manager.h"
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h"
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/notifications/sync_notifier/chrome_notifier_service_factory.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/website_settings/permission_bubble_request.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/content_settings.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/content_settings_pattern.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/show_desktop_notification_params.h"
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h"
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/info_map.h"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h"
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension.h"
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/browser_resources.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/base/webui/web_ui_util.h"
55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ui/message_center/message_center_util.h"
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/message_center/notifier_settings.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing message_center::NotifierId;
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebTextDirection;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kChromeNowExtensionID[] = "pafkbggdmjlpgkdkcbjmhmfcdpncadgh";
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// NotificationPermissionRequest ---------------------------------------
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class NotificationPermissionRequest : public PermissionBubbleRequest {
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NotificationPermissionRequest(
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DesktopNotificationService* notification_service,
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const GURL& origin,
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::string16 display_name,
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int process_id,
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int route_id,
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int callback_context);
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~NotificationPermissionRequest();
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // PermissionBubbleDelegate:
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual int GetIconID() const OVERRIDE;
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual base::string16 GetMessageText() const OVERRIDE;
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual base::string16 GetMessageTextFragment() const OVERRIDE;
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual bool HasUserGesture() const OVERRIDE;
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual GURL GetRequestingHostname() const OVERRIDE;
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void PermissionGranted() OVERRIDE;
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void PermissionDenied() OVERRIDE;
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Cancelled() OVERRIDE;
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void RequestFinished() OVERRIDE;
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The notification service to be used.
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DesktopNotificationService* notification_service_;
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The origin we are asking for permissions on.
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL origin_;
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The display name for the origin to be displayed.  Will be different from
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // origin_ for extensions.
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 display_name_;
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The callback information that tells us how to respond to javascript via
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the correct RenderView.
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int process_id_;
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int route_id_;
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int callback_context_;
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Whether the user clicked one of the buttons.
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool action_taken_;
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NotificationPermissionRequest);
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)NotificationPermissionRequest::NotificationPermissionRequest(
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DesktopNotificationService* notification_service,
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const GURL& origin,
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::string16 display_name,
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int process_id,
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int route_id,
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int callback_context)
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : notification_service_(notification_service),
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      origin_(origin),
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      display_name_(display_name),
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      process_id_(process_id),
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      route_id_(route_id),
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      callback_context_(callback_context),
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      action_taken_(false) {}
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)NotificationPermissionRequest::~NotificationPermissionRequest() {}
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int NotificationPermissionRequest::GetIconID() const {
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return IDR_INFOBAR_DESKTOP_NOTIFICATIONS;
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 NotificationPermissionRequest::GetMessageText() const {
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_NOTIFICATION_PERMISSIONS,
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    display_name_);
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)NotificationPermissionRequest::GetMessageTextFragment() const {
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_NOTIFICATION_PERMISSIONS_FRAGMENT);
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool NotificationPermissionRequest::HasUserGesture() const {
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Currently notification permission requests are only issued on
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // user gesture.
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)GURL NotificationPermissionRequest::GetRequestingHostname() const {
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return origin_;
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NotificationPermissionRequest::PermissionGranted() {
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  action_taken_ = true;
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Allowed", 1);
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  notification_service_->GrantPermission(origin_);
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NotificationPermissionRequest::PermissionDenied() {
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  action_taken_ = true;
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Denied", 1);
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  notification_service_->DenyPermission(origin_);
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NotificationPermissionRequest::Cancelled() {
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NotificationPermissionRequest::RequestFinished() {
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!action_taken_)
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Ignored", 1);
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderViewHost* host = RenderViewHost::FromID(process_id_, route_id_);
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (host)
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    host->DesktopNotificationPermissionRequestDone(callback_context_);
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delete this;
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NotificationPermissionInfoBarDelegate --------------------------------------
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The delegate for the infobar shown when an origin requests notification
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// permissions.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NotificationPermissionInfoBarDelegate : public ConfirmInfoBarDelegate {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Creates a notification permission infobar and delegate and adds the infobar
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // to |infobar_service|.
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void Create(InfoBarService* infobar_service,
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     DesktopNotificationService* notification_service,
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const GURL& origin,
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     const base::string16& display_name,
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     int process_id,
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     int route_id,
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     int callback_context);
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationPermissionInfoBarDelegate(
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DesktopNotificationService* notification_service,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& origin,
201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& display_name,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int process_id,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int route_id,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int callback_context);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~NotificationPermissionInfoBarDelegate();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ConfirmInfoBarDelegate:
20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual int GetIconID() const OVERRIDE;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual Type GetInfoBarType() const OVERRIDE;
210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual base::string16 GetMessageText() const OVERRIDE;
211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual base::string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Accept() OVERRIDE;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Cancel() OVERRIDE;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The origin we are asking for permissions on.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL origin_;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The display name for the origin to be displayed.  Will be different from
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // origin_ for extensions.
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 display_name_;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The notification service to be used.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DesktopNotificationService* notification_service_;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The callback information that tells us how to respond to javascript via
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the correct RenderView.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int process_id_;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int route_id_;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int callback_context_;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether the user clicked one of the buttons.
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool action_taken_;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NotificationPermissionInfoBarDelegate);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationPermissionInfoBarDelegate::Create(
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InfoBarService* infobar_service,
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DesktopNotificationService* notification_service,
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& origin,
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& display_name,
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int process_id,
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int route_id,
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int callback_context) {
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      scoped_ptr<ConfirmInfoBarDelegate>(
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          new NotificationPermissionInfoBarDelegate(
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              notification_service, origin, display_name, process_id, route_id,
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              callback_context))));
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NotificationPermissionInfoBarDelegate::NotificationPermissionInfoBarDelegate(
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DesktopNotificationService* notification_service,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin,
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& display_name,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int process_id,
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int route_id,
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int callback_context)
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : ConfirmInfoBarDelegate(),
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      origin_(origin),
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      display_name_(display_name),
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notification_service_(notification_service),
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      process_id_(process_id),
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      route_id_(route_id),
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback_context_(callback_context),
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      action_taken_(false) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NotificationPermissionInfoBarDelegate::
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~NotificationPermissionInfoBarDelegate() {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!action_taken_)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Ignored", 1);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHost* host = RenderViewHost::FromID(process_id_, route_id_);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (host)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host->DesktopNotificationPermissionRequestDone(callback_context_);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int NotificationPermissionInfoBarDelegate::GetIconID() const {
28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return IDR_INFOBAR_DESKTOP_NOTIFICATIONS;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InfoBarDelegate::Type
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotificationPermissionInfoBarDelegate::GetInfoBarType() const {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PAGE_ACTION_TYPE;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 NotificationPermissionInfoBarDelegate::GetMessageText() const {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_NOTIFICATION_PERMISSIONS,
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    display_name_);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 NotificationPermissionInfoBarDelegate::GetButtonLabel(
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InfoBarButton button) const {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDS_NOTIFICATION_PERMISSION_YES : IDS_NOTIFICATION_PERMISSION_NO);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NotificationPermissionInfoBarDelegate::Accept() {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Allowed", 1);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_service_->GrantPermission(origin_);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  action_taken_ = true;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NotificationPermissionInfoBarDelegate::Cancel() {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Denied", 1);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_service_->DenyPermission(origin_);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  action_taken_ = true;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DesktopNotificationService -------------------------------------------------
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DesktopNotificationService::RegisterProfilePrefs(
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* registry) {
3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  registry->RegisterListPref(
3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      prefs::kMessageCenterDisabledExtensionIds,
3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  registry->RegisterListPref(
3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      prefs::kMessageCenterDisabledSystemComponentIds,
3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  registry->RegisterListPref(
3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      prefs::kMessageCenterEnabledSyncNotifierIds,
3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionWelcomeNotification::RegisterProfilePrefs(registry);
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 DesktopNotificationService::CreateDataUrl(
334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const GURL& icon_url,
335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& title,
336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& body,
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebTextDirection dir) {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int resource;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> subst;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (icon_url.is_valid()) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resource = IDR_NOTIFICATION_ICON_HTML;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    subst.push_back(icon_url.spec());
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(base::UTF16ToUTF8(title)));
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(base::UTF16ToUTF8(body)));
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // icon float position
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    subst.push_back(dir == blink::WebTextDirectionRightToLeft ?
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    "right" : "left");
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (title.empty() || body.empty()) {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resource = IDR_NOTIFICATION_1LINE_HTML;
350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16 line = title.empty() ? body : title;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Strings are div names in the template file.
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::string16 line_name =
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        title.empty() ? base::ASCIIToUTF16("description")
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      : base::ASCIIToUTF16("title");
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(base::UTF16ToUTF8(line_name)));
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(base::UTF16ToUTF8(line)));
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resource = IDR_NOTIFICATION_2LINE_HTML;
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(base::UTF16ToUTF8(title)));
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(base::UTF16ToUTF8(body)));
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // body text direction
363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  subst.push_back(dir == blink::WebTextDirectionRightToLeft ?
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  "rtl" : "ltr");
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CreateDataUrl(resource, subst);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 DesktopNotificationService::CreateDataUrl(
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int resource, const std::vector<std::string>& subst) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::StringPiece template_html(
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          resource));
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (template_html.empty()) {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "unable to load template. ID: " << resource;
378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return base::string16();
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string data = ReplaceStringPlaceholders(template_html, subst, NULL);
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::UTF8ToUTF16("data:text/html;charset=utf-8," +
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               net::EscapeQueryParamValue(data, false));
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string DesktopNotificationService::AddIconNotification(
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin_url,
389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& title,
390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& message,
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Image& icon,
392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& replace_id,
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotificationDelegate* delegate,
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile) {
395a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  Notification notification(origin_url, icon, title, message,
396a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                            blink::WebTextDirectionDefault,
397a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                            base::string16(), replace_id, delegate);
398a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  g_browser_process->notification_ui_manager()->Add(notification, profile);
399a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return notification.notification_id();
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DesktopNotificationService::DesktopNotificationService(
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Profile* profile,
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotificationUIManager* ui_manager)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : profile_(profile),
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_manager_(ui_manager) {
407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  OnStringListPrefChanged(
408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      prefs::kMessageCenterDisabledExtensionIds, &disabled_extension_ids_);
409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  OnStringListPrefChanged(
410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      prefs::kMessageCenterDisabledSystemComponentIds,
411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      &disabled_system_component_ids_);
412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  OnStringListPrefChanged(
413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      prefs::kMessageCenterEnabledSyncNotifierIds, &enabled_sync_notifier_ids_);
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  disabled_extension_id_pref_.Init(
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      prefs::kMessageCenterDisabledExtensionIds,
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_->GetPrefs(),
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(
418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          &DesktopNotificationService::OnStringListPrefChanged,
419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(this),
420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(prefs::kMessageCenterDisabledExtensionIds),
421eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(&disabled_extension_ids_)));
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  disabled_system_component_id_pref_.Init(
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kMessageCenterDisabledSystemComponentIds,
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_->GetPrefs(),
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(
426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          &DesktopNotificationService::OnStringListPrefChanged,
427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(this),
428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(prefs::kMessageCenterDisabledSystemComponentIds),
429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(&disabled_system_component_ids_)));
430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  enabled_sync_notifier_id_pref_.Init(
431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      prefs::kMessageCenterEnabledSyncNotifierIds,
432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      profile_->GetPrefs(),
433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(
434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          &DesktopNotificationService::OnStringListPrefChanged,
435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(this),
436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(prefs::kMessageCenterEnabledSyncNotifierIds),
437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(&enabled_sync_notifier_ids_)));
43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 content::Source<Profile>(profile_));
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DesktopNotificationService::~DesktopNotificationService() {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::GrantPermission(const GURL& origin) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ContentSettingsPattern primary_pattern =
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ContentSettingsPattern::FromURLNoWildcard(origin);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetContentSetting(
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      primary_pattern,
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ContentSettingsPattern::Wildcard(),
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NO_RESOURCE_IDENTIFIER,
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTING_ALLOW);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::DenyPermission(const GURL& origin) {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ContentSettingsPattern primary_pattern =
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ContentSettingsPattern::FromURLNoWildcard(origin);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetContentSetting(
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      primary_pattern,
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ContentSettingsPattern::Wildcard(),
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NO_RESOURCE_IDENTIFIER,
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTING_BLOCK);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContentSetting DesktopNotificationService::GetDefaultContentSetting(
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* provider_id) {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS, provider_id);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::SetDefaultContentSetting(
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ContentSetting setting) {
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetDefaultContentSetting(
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS, setting);
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::ResetToDefaultContentSetting() {
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetDefaultContentSetting(
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS, CONTENT_SETTING_DEFAULT);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::GetNotificationsSettings(
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ContentSettingsForOneType* settings) {
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->GetSettingsForOneType(
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NO_RESOURCE_IDENTIFIER,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      settings);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::ClearSetting(
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ContentSettingsPattern& pattern) {
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetContentSetting(
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pattern,
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ContentSettingsPattern::Wildcard(),
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NO_RESOURCE_IDENTIFIER,
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTING_DEFAULT);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::ResetAllOrigins() {
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->ClearSettingsForOneType(
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContentSetting DesktopNotificationService::GetContentSetting(
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin) {
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return profile_->GetHostContentSettingsMap()->GetContentSetting(
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      origin,
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      origin,
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NO_RESOURCE_IDENTIFIER);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::RequestPermission(
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin, int process_id, int route_id, int callback_context,
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContents* contents) {
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |origin| hasn't been seen before and the default content setting for
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notifications is "ask", show an infobar.
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The cache can only answer queries on the IO thread once it's initialized,
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so don't ask the cache.
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ContentSetting setting = GetContentSetting(origin);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (setting == CONTENT_SETTING_ASK) {
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (PermissionBubbleManager::Enabled()) {
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      PermissionBubbleManager* bubble_manager =
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          PermissionBubbleManager::FromWebContents(contents);
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bubble_manager->AddRequest(new NotificationPermissionRequest(this,
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              origin, DisplayNameForOriginInProcessId(origin, process_id),
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              process_id, route_id, callback_context));
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Show an info bar requesting permission.
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InfoBarService* infobar_service =
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        InfoBarService::FromWebContents(contents);
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // |infobar_service| may be NULL, e.g., if this request originated in a
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // browser action popup, extension background page, or any HTML that runs
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // outside of a tab.
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (infobar_service) {
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NotificationPermissionInfoBarDelegate::Create(
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          infobar_service, this,
5437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          origin, DisplayNameForOriginInProcessId(origin, process_id),
5447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          process_id, route_id, callback_context);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notify renderer immediately.
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHost* host = RenderViewHost::FromID(process_id, route_id);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (host)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host->DesktopNotificationPermissionRequestDone(callback_context);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_WIN)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::ShowNotification(
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Notification& notification) {
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetUIManager()->Add(notification, profile_);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DesktopNotificationService::CancelDesktopNotification(
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int process_id, int route_id, int notification_id) {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<NotificationObjectProxy> proxy(
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new NotificationObjectProxy(process_id, route_id, notification_id,
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  false));
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetUIManager()->CancelById(proxy->id());
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DesktopNotificationService::ShowDesktopNotification(
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::ShowDesktopNotificationHostMsgParams& params,
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int process_id, int route_id, DesktopNotificationSource source) {
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& origin = params.origin;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationObjectProxy* proxy =
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new NotificationObjectProxy(process_id, route_id,
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  params.notification_id,
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  source == WorkerNotification);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
580a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 display_source =
581a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      DisplayNameForOriginInProcessId(origin, process_id);
582a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Notification notification(origin, params.icon_url, params.title,
583a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      params.body, params.direction, display_source, params.replace_id,
584a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      proxy);
585a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
586a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // The webkit notification doesn't timeout.
587a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  notification.set_never_timeout(true);
588a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
589a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ShowNotification(notification);
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
593a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 DesktopNotificationService::DisplayNameForOriginInProcessId(
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GURL& origin, int process_id) {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the source is an extension, lookup the display name.
596a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (origin.SchemeIs(extensions::kExtensionScheme)) {
597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    extensions::InfoMap* extension_info_map =
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        extensions::ExtensionSystem::Get(profile_)->info_map();
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (extension_info_map) {
6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ExtensionSet extensions;
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extension_info_map->GetExtensionsWithAPIPermissionForSecurityOrigin(
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          origin, process_id, extensions::APIPermission::kNotification,
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          &extensions);
6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      for (extensions::ExtensionSet::const_iterator iter = extensions.begin();
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           iter != extensions.end(); ++iter) {
606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        NotifierId notifier_id(NotifierId::APPLICATION, (*iter)->id());
607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        if (IsNotifierEnabled(notifier_id))
6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          return base::UTF8ToUTF16((*iter)->name());
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::UTF8ToUTF16(origin.host());
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::NotifySettingsChange() {
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_DESKTOP_NOTIFICATION_SETTINGS_CHANGED,
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<DesktopNotificationService>(this),
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::NoDetails());
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NotificationUIManager* DesktopNotificationService::GetUIManager() {
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We defer setting ui_manager_ to the global singleton until we need it
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in order to avoid UI dependent construction during startup.
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ui_manager_)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui_manager_ = g_browser_process->notification_ui_manager();
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ui_manager_;
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool DesktopNotificationService::IsNotifierEnabled(
631eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const NotifierId& notifier_id) {
632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  switch (notifier_id.type) {
633eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case NotifierId::APPLICATION:
634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return disabled_extension_ids_.find(notifier_id.id) ==
635eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          disabled_extension_ids_.end();
636eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case NotifierId::WEB_PAGE:
637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return GetContentSetting(notifier_id.url) == CONTENT_SETTING_ALLOW;
638eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case NotifierId::SYSTEM_COMPONENT:
639424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#if defined(OS_CHROMEOS)
640a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return disabled_system_component_ids_.find(notifier_id.id) ==
641a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          disabled_system_component_ids_.end();
642424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#else
643a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // We do not disable system component notifications.
644a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return true;
645424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif
646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case NotifierId::SYNCED_NOTIFICATION_SERVICE:
647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return enabled_sync_notifier_ids_.find(notifier_id.id) !=
648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          enabled_sync_notifier_ids_.end();
649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  NOTREACHED();
652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return false;
653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DesktopNotificationService::SetNotifierEnabled(
656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const NotifierId& notifier_id,
657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    bool enabled) {
658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_NE(NotifierId::WEB_PAGE, notifier_id.type);
659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool add_new_item = false;
661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const char* pref_name = NULL;
662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<base::StringValue> id;
663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  switch (notifier_id.type) {
664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case NotifierId::APPLICATION:
665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      pref_name = prefs::kMessageCenterDisabledExtensionIds;
666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      add_new_item = !enabled;
667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      id.reset(new base::StringValue(notifier_id.id));
6681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      FirePermissionLevelChangedEvent(notifier_id, enabled);
669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case NotifierId::SYSTEM_COMPONENT:
671424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#if defined(OS_CHROMEOS)
672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      pref_name = prefs::kMessageCenterDisabledSystemComponentIds;
673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      add_new_item = !enabled;
674a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      id.reset(new base::StringValue(notifier_id.id));
675424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#else
676424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return;
677424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif
678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case NotifierId::SYNCED_NOTIFICATION_SERVICE:
680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      pref_name = prefs::kMessageCenterEnabledSyncNotifierIds;
681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // Adding a new item if |enabled| == true, since synced notification
682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // services are opt-in.
683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      add_new_item = enabled;
684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      id.reset(new base::StringValue(notifier_id.id));
685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    default:
687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      NOTREACHED();
688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(pref_name != NULL);
690eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ListPrefUpdate update(profile_->GetPrefs(), pref_name);
6927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::ListValue* const list = update.Get();
6937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (add_new_item) {
6947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // AppendIfNotPresent will delete |adding_value| when the same value
6957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // already exists.
6967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    list->AppendIfNotPresent(id.release());
6977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else {
6987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    list->Remove(*id, NULL);
699eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DesktopNotificationService::ShowWelcomeNotificationIfNecessary(
7038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const Notification& notification) {
704a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!chrome_now_welcome_notification_) {
7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    chrome_now_welcome_notification_ =
7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ExtensionWelcomeNotification::Create(kChromeNowExtensionID, profile_);
7078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
7088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (chrome_now_welcome_notification_) {
7105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    chrome_now_welcome_notification_->ShowWelcomeNotificationIfNecessary(
7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        notification);
7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
7138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
7148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
715eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DesktopNotificationService::OnStringListPrefChanged(
716eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const char* pref_name, std::set<std::string>* ids_field) {
717eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ids_field->clear();
7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Separate GetPrefs()->GetList() to analyze the crash. See crbug.com/322320
7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const PrefService* pref_service = profile_->GetPrefs();
7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(pref_service);
7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::ListValue* pref_list = pref_service->GetList(pref_name);
722eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (size_t i = 0; i < pref_list->GetSize(); ++i) {
723eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::string element;
724eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (pref_list->GetString(i, &element) && !element.empty())
725eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ids_field->insert(element);
726eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    else
727eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      LOG(WARNING) << i << "-th element is not a string for " << pref_name;
728eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DesktopNotificationService::Observe(
73290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int type,
73390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const content::NotificationSource& source,
73490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const content::NotificationDetails& details) {
73590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK_EQ(chrome::NOTIFICATION_EXTENSION_UNINSTALLED, type);
73690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
73790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  extensions::Extension* extension =
73890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      content::Details<extensions::Extension>(details).ptr();
739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  NotifierId notifier_id(NotifierId::APPLICATION, extension->id());
740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (IsNotifierEnabled(notifier_id))
74190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
74290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The settings for ephemeral apps will be persisted across cache evictions.
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (extension->is_ephemeral())
7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
7465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
747eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetNotifierEnabled(notifier_id, true);
74890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
7491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void DesktopNotificationService::FirePermissionLevelChangedEvent(
7511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const NotifierId& notifier_id, bool enabled) {
7521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK_EQ(NotifierId::APPLICATION, notifier_id.type);
7531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  extensions::api::notifications::PermissionLevel permission =
7541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      enabled ? extensions::api::notifications::PERMISSION_LEVEL_GRANTED
7551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              : extensions::api::notifications::PERMISSION_LEVEL_DENIED;
7561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<base::ListValue> args(new base::ListValue());
7571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  args->Append(new base::StringValue(
7581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extensions::api::notifications::ToString(permission)));
7591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<extensions::Event> event(new extensions::Event(
7601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extensions::api::notifications::OnPermissionLevelChanged::kEventName,
7611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      args.Pass()));
7621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  extensions::ExtensionSystem::Get(profile_)->event_router()->
7631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      DispatchEventToExtension(notifier_id.id, event.Pass());
764f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
765f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Tell the IO thread that this extension's permission for notifications
766f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // has changed.
767f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  extensions::InfoMap* extension_info_map =
768f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile_)->info_map();
769f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  BrowserThread::PostTask(
770f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      BrowserThread::IO, FROM_HERE,
771f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&extensions::InfoMap::SetNotificationsDisabled,
772f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 extension_info_map, notifier_id.id, !enabled));
773f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
775