desktop_notification_service.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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"
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/event_router.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/extensions/extension_info_map.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/infobars/confirm_infobar_delegate.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/infobars/infobar_service.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/desktop_notification_service_factory.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/notification.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/notification_object_proxy.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/notification_ui_manager.h"
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h"
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/notifications/sync_notifier/chrome_notifier_service_factory.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.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"
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/browser_resources.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/base/webui/web_ui_util.h"
50a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ui/message_center/message_center_util.h"
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/message_center/notifier_settings.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#if defined(OS_CHROMEOS)
54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ash/system/system_notifier.h"
55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif
56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing message_center::NotifierId;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebNotificationPresenter;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebTextDirection;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NotificationPermissionInfoBarDelegate --------------------------------------
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The delegate for the infobar shown when an origin requests notification
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// permissions.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NotificationPermissionInfoBarDelegate : public ConfirmInfoBarDelegate {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Creates a notification permission infobar delegate and adds it to
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |infobar_service|.
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void Create(InfoBarService* infobar_service,
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     DesktopNotificationService* notification_service,
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const GURL& origin,
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const string16& display_name,
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     int process_id,
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     int route_id,
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     int callback_context);
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationPermissionInfoBarDelegate(
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      InfoBarService* infobar_service,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DesktopNotificationService* notification_service,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& origin,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const string16& display_name,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int process_id,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int route_id,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int callback_context);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~NotificationPermissionInfoBarDelegate();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ConfirmInfoBarDelegate:
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual int GetIconID() const OVERRIDE;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual Type GetInfoBarType() const OVERRIDE;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual string16 GetMessageText() const OVERRIDE;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Accept() OVERRIDE;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Cancel() OVERRIDE;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The origin we are asking for permissions on.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL origin_;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The display name for the origin to be displayed.  Will be different from
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // origin_ for extensions.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 display_name_;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The notification service to be used.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DesktopNotificationService* notification_service_;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The callback information that tells us how to respond to javascript via
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the correct RenderView.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int process_id_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int route_id_;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int callback_context_;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether the user clicked one of the buttons.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool action_taken_;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NotificationPermissionInfoBarDelegate);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NotificationPermissionInfoBarDelegate::Create(
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InfoBarService* infobar_service,
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DesktopNotificationService* notification_service,
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& origin,
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const string16& display_name,
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int process_id,
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int route_id,
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int callback_context) {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new NotificationPermissionInfoBarDelegate(
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          infobar_service, notification_service, origin, display_name,
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          process_id, route_id, callback_context)));
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NotificationPermissionInfoBarDelegate::NotificationPermissionInfoBarDelegate(
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InfoBarService* infobar_service,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DesktopNotificationService* notification_service,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string16& display_name,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int process_id,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int route_id,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int callback_context)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : ConfirmInfoBarDelegate(infobar_service),
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      origin_(origin),
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      display_name_(display_name),
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notification_service_(notification_service),
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      process_id_(process_id),
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      route_id_(route_id),
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback_context_(callback_context),
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      action_taken_(false) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NotificationPermissionInfoBarDelegate::
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~NotificationPermissionInfoBarDelegate() {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!action_taken_)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Ignored", 1);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHost* host = RenderViewHost::FromID(process_id_, route_id_);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (host)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host->DesktopNotificationPermissionRequestDone(callback_context_);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int NotificationPermissionInfoBarDelegate::GetIconID() const {
16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return IDR_INFOBAR_DESKTOP_NOTIFICATIONS;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InfoBarDelegate::Type
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotificationPermissionInfoBarDelegate::GetInfoBarType() const {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PAGE_ACTION_TYPE;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 NotificationPermissionInfoBarDelegate::GetMessageText() const {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_NOTIFICATION_PERMISSIONS,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    display_name_);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 NotificationPermissionInfoBarDelegate::GetButtonLabel(
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InfoBarButton button) const {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDS_NOTIFICATION_PERMISSION_YES : IDS_NOTIFICATION_PERMISSION_NO);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NotificationPermissionInfoBarDelegate::Accept() {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Allowed", 1);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_service_->GrantPermission(origin_);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  action_taken_ = true;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NotificationPermissionInfoBarDelegate::Cancel() {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Denied", 1);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_service_->DenyPermission(origin_);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  action_taken_ = true;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DesktopNotificationService -------------------------------------------------
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DesktopNotificationService::RegisterProfilePrefs(
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* registry) {
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  registry->RegisterListPref(
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      prefs::kMessageCenterDisabledExtensionIds,
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  registry->RegisterListPref(
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      prefs::kMessageCenterDisabledSystemComponentIds,
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  registry->RegisterListPref(
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      prefs::kMessageCenterEnabledSyncNotifierIds,
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  WelcomeNotification::RegisterProfilePrefs(registry);
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 DesktopNotificationService::CreateDataUrl(
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& icon_url, const string16& title, const string16& body,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebTextDirection dir) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int resource;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> subst;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (icon_url.is_valid()) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resource = IDR_NOTIFICATION_ICON_HTML;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    subst.push_back(icon_url.spec());
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(UTF16ToUTF8(title)));
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(UTF16ToUTF8(body)));
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // icon float position
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    subst.push_back(dir == WebKit::WebTextDirectionRightToLeft ?
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    "right" : "left");
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (title.empty() || body.empty()) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resource = IDR_NOTIFICATION_1LINE_HTML;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 line = title.empty() ? body : title;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Strings are div names in the template file.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 line_name = title.empty() ? ASCIIToUTF16("description")
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       : ASCIIToUTF16("title");
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(UTF16ToUTF8(line_name)));
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(UTF16ToUTF8(line)));
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resource = IDR_NOTIFICATION_2LINE_HTML;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(UTF16ToUTF8(title)));
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(UTF16ToUTF8(body)));
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // body text direction
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(dir == WebKit::WebTextDirectionRightToLeft ?
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  "rtl" : "ltr");
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CreateDataUrl(resource, subst);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 DesktopNotificationService::CreateDataUrl(
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int resource, const std::vector<std::string>& subst) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::StringPiece template_html(
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          resource));
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (template_html.empty()) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "unable to load template. ID: " << resource;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return string16();
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string data = ReplaceStringPlaceholders(template_html, subst, NULL);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return UTF8ToUTF16("data:text/html;charset=utf-8," +
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      net::EscapeQueryParamValue(data, false));
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string DesktopNotificationService::AddNotification(
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin_url,
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string16& title,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string16& message,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& icon_url,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string16& replace_id,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotificationDelegate* delegate,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile) {
277a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (message_center::IsRichNotificationEnabled()) {
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // For message center create a non-HTML notification with |icon_url|.
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Notification notification(origin_url, icon_url, title, message,
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              WebKit::WebTextDirectionDefault,
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              string16(), replace_id, delegate);
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_browser_process->notification_ui_manager()->Add(notification, profile);
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return notification.notification_id();
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate a data URL embedding the icon URL, title, and message.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL content_url(CreateDataUrl(
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icon_url, title, message, WebKit::WebTextDirectionDefault));
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Notification notification(
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL(), content_url, string16(), replace_id, delegate);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_browser_process->notification_ui_manager()->Add(notification, profile);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return notification.notification_id();
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string DesktopNotificationService::AddIconNotification(
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin_url,
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string16& title,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string16& message,
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Image& icon,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string16& replace_id,
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotificationDelegate* delegate,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile) {
304a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (message_center::IsRichNotificationEnabled()) {
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // For message center create a non-HTML notification with |icon|.
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Notification notification(origin_url, icon, title, message,
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              WebKit::WebTextDirectionDefault,
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              string16(), replace_id, delegate);
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_browser_process->notification_ui_manager()->Add(notification, profile);
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return notification.notification_id();
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL icon_url;
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!icon.IsEmpty())
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    icon_url = GURL(webui::GetBitmapDataUrl(*icon.ToSkBitmap()));
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return AddNotification(
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      origin_url, title, message, icon_url, replace_id, delegate, profile);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::RemoveNotification(
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& notification_id) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_browser_process->notification_ui_manager()->CancelById(notification_id);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DesktopNotificationService::DesktopNotificationService(
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Profile* profile,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotificationUIManager* ui_manager)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : profile_(profile),
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_manager_(ui_manager) {
331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  OnStringListPrefChanged(
332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      prefs::kMessageCenterDisabledExtensionIds, &disabled_extension_ids_);
333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  OnStringListPrefChanged(
334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      prefs::kMessageCenterDisabledSystemComponentIds,
335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      &disabled_system_component_ids_);
336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  OnStringListPrefChanged(
337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      prefs::kMessageCenterEnabledSyncNotifierIds, &enabled_sync_notifier_ids_);
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  disabled_extension_id_pref_.Init(
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      prefs::kMessageCenterDisabledExtensionIds,
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_->GetPrefs(),
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(
342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          &DesktopNotificationService::OnStringListPrefChanged,
343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(this),
344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(prefs::kMessageCenterDisabledExtensionIds),
345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(&disabled_extension_ids_)));
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  disabled_system_component_id_pref_.Init(
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kMessageCenterDisabledSystemComponentIds,
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_->GetPrefs(),
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(
350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          &DesktopNotificationService::OnStringListPrefChanged,
351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(this),
352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(prefs::kMessageCenterDisabledSystemComponentIds),
353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(&disabled_system_component_ids_)));
354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  enabled_sync_notifier_id_pref_.Init(
355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      prefs::kMessageCenterEnabledSyncNotifierIds,
356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      profile_->GetPrefs(),
357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(
358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          &DesktopNotificationService::OnStringListPrefChanged,
359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(this),
360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(prefs::kMessageCenterEnabledSyncNotifierIds),
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Unretained(&enabled_sync_notifier_ids_)));
36290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 content::Source<Profile>(profile_));
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DesktopNotificationService::~DesktopNotificationService() {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::GrantPermission(const GURL& origin) {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ContentSettingsPattern primary_pattern =
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ContentSettingsPattern::FromURLNoWildcard(origin);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetContentSetting(
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      primary_pattern,
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ContentSettingsPattern::Wildcard(),
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NO_RESOURCE_IDENTIFIER,
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTING_ALLOW);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::DenyPermission(const GURL& origin) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ContentSettingsPattern primary_pattern =
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ContentSettingsPattern::FromURLNoWildcard(origin);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetContentSetting(
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      primary_pattern,
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ContentSettingsPattern::Wildcard(),
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NO_RESOURCE_IDENTIFIER,
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTING_BLOCK);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContentSetting DesktopNotificationService::GetDefaultContentSetting(
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* provider_id) {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS, provider_id);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::SetDefaultContentSetting(
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ContentSetting setting) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetDefaultContentSetting(
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS, setting);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::ResetToDefaultContentSetting() {
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetDefaultContentSetting(
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS, CONTENT_SETTING_DEFAULT);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::GetNotificationsSettings(
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ContentSettingsForOneType* settings) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->GetSettingsForOneType(
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NO_RESOURCE_IDENTIFIER,
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      settings);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::ClearSetting(
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ContentSettingsPattern& pattern) {
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetContentSetting(
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pattern,
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ContentSettingsPattern::Wildcard(),
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NO_RESOURCE_IDENTIFIER,
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTING_DEFAULT);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::ResetAllOrigins() {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->ClearSettingsForOneType(
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContentSetting DesktopNotificationService::GetContentSetting(
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin) {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return profile_->GetHostContentSettingsMap()->GetContentSetting(
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      origin,
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      origin,
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NO_RESOURCE_IDENTIFIER);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::RequestPermission(
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin, int process_id, int route_id, int callback_context,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContents* contents) {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |origin| hasn't been seen before and the default content setting for
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notifications is "ask", show an infobar.
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The cache can only answer queries on the IO thread once it's initialized,
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so don't ask the cache.
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ContentSetting setting = GetContentSetting(origin);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (setting == CONTENT_SETTING_ASK) {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Show an info bar requesting permission.
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InfoBarService* infobar_service =
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        InfoBarService::FromWebContents(contents);
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // |infobar_service| may be NULL, e.g., if this request originated in a
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // browser action popup, extension background page, or any HTML that runs
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // outside of a tab.
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (infobar_service) {
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NotificationPermissionInfoBarDelegate::Create(
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          infobar_service,
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          DesktopNotificationServiceFactory::GetForProfile(
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              Profile::FromBrowserContext(contents->GetBrowserContext())),
4607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          origin, DisplayNameForOriginInProcessId(origin, process_id),
4617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          process_id, route_id, callback_context);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notify renderer immediately.
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHost* host = RenderViewHost::FromID(process_id, route_id);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (host)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host->DesktopNotificationPermissionRequestDone(callback_context);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_WIN)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::ShowNotification(
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Notification& notification) {
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetUIManager()->Add(notification, profile_);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DesktopNotificationService::CancelDesktopNotification(
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int process_id, int route_id, int notification_id) {
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<NotificationObjectProxy> proxy(
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new NotificationObjectProxy(process_id, route_id, notification_id,
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  false));
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetUIManager()->CancelById(proxy->id());
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DesktopNotificationService::ShowDesktopNotification(
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::ShowDesktopNotificationHostMsgParams& params,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int process_id, int route_id, DesktopNotificationSource source) {
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& origin = params.origin;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationObjectProxy* proxy =
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new NotificationObjectProxy(process_id, route_id,
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  params.notification_id,
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  source == WorkerNotification);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  string16 display_source = DisplayNameForOriginInProcessId(origin, process_id);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params.is_html) {
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShowNotification(Notification(origin, params.contents_url, display_source,
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        params.replace_id, proxy));
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Notification notification(origin, params.icon_url, params.title,
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        params.body, params.direction, display_source, params.replace_id,
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        proxy);
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // The webkit notification doesn't timeout.
506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    notification.set_never_timeout(true);
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ShowNotification(notification);
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 DesktopNotificationService::DisplayNameForOriginInProcessId(
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GURL& origin, int process_id) {
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the source is an extension, lookup the display name.
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Message center prefers to use extension name if the notification
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // is allowed by an extension.
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (NotificationUIManager::DelegatesToMessageCenter() ||
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      origin.SchemeIs(extensions::kExtensionScheme)) {
519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ExtensionInfoMap* extension_info_map =
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        extensions::ExtensionSystem::Get(profile_)->info_map();
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (extension_info_map) {
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ExtensionSet extensions;
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extension_info_map->GetExtensionsWithAPIPermissionForSecurityOrigin(
524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          origin, process_id, extensions::APIPermission::kNotification,
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          &extensions);
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (ExtensionSet::const_iterator iter = extensions.begin();
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           iter != extensions.end(); ++iter) {
528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        NotifierId notifier_id(NotifierId::APPLICATION, (*iter)->id());
529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        if (IsNotifierEnabled(notifier_id))
530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          return UTF8ToUTF16((*iter)->name());
531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return UTF8ToUTF16(origin.host());
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::NotifySettingsChange() {
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_DESKTOP_NOTIFICATION_SETTINGS_CHANGED,
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<DesktopNotificationService>(this),
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::NoDetails());
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NotificationUIManager* DesktopNotificationService::GetUIManager() {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We defer setting ui_manager_ to the global singleton until we need it
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in order to avoid UI dependent construction during startup.
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ui_manager_)
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui_manager_ = g_browser_process->notification_ui_manager();
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ui_manager_;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
552eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool DesktopNotificationService::IsNotifierEnabled(
553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const NotifierId& notifier_id) {
554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  switch (notifier_id.type) {
555eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case NotifierId::APPLICATION:
556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return disabled_extension_ids_.find(notifier_id.id) ==
557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          disabled_extension_ids_.end();
558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case NotifierId::WEB_PAGE:
559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return GetContentSetting(notifier_id.url) == CONTENT_SETTING_ALLOW;
560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case NotifierId::SYSTEM_COMPONENT:
561424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#if defined(OS_CHROMEOS)
562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return disabled_system_component_ids_.find(
56358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          ash::system_notifier::SystemComponentTypeToString(
56458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              static_cast<ash::system_notifier::AshSystemComponentNotifierType>(
565424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                  notifier_id.system_component_type)))
566424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          == disabled_system_component_ids_.end();
567424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#else
568424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return false;
569424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif
570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case NotifierId::SYNCED_NOTIFICATION_SERVICE:
571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return enabled_sync_notifier_ids_.find(notifier_id.id) !=
572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          enabled_sync_notifier_ids_.end();
573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  NOTREACHED();
576eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return false;
577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DesktopNotificationService::SetNotifierEnabled(
580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const NotifierId& notifier_id,
581eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    bool enabled) {
582eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_NE(NotifierId::WEB_PAGE, notifier_id.type);
583eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool add_new_item = false;
585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const char* pref_name = NULL;
586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<base::StringValue> id;
587eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  switch (notifier_id.type) {
588eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case NotifierId::APPLICATION:
589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      pref_name = prefs::kMessageCenterDisabledExtensionIds;
590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      add_new_item = !enabled;
591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      id.reset(new base::StringValue(notifier_id.id));
5921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      FirePermissionLevelChangedEvent(notifier_id, enabled);
593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
594eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case NotifierId::SYSTEM_COMPONENT:
595424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#if defined(OS_CHROMEOS)
596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      pref_name = prefs::kMessageCenterDisabledSystemComponentIds;
597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      add_new_item = !enabled;
59858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      id.reset(new base::StringValue(
59958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          ash::system_notifier::SystemComponentTypeToString(
60058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              static_cast<ash::system_notifier::AshSystemComponentNotifierType>(
60158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  notifier_id.system_component_type))));
602424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#else
603424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return;
604424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif
605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case NotifierId::SYNCED_NOTIFICATION_SERVICE:
607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      pref_name = prefs::kMessageCenterEnabledSyncNotifierIds;
608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // Adding a new item if |enabled| == true, since synced notification
609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // services are opt-in.
610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      add_new_item = enabled;
611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      id.reset(new base::StringValue(notifier_id.id));
612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    default:
614eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      NOTREACHED();
615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
616eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(pref_name != NULL);
617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ListPrefUpdate update(profile_->GetPrefs(), pref_name);
6197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::ListValue* const list = update.Get();
6207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (add_new_item) {
6217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // AppendIfNotPresent will delete |adding_value| when the same value
6227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // already exists.
6237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    list->AppendIfNotPresent(id.release());
6247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else {
6257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    list->Remove(*id, NULL);
626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DesktopNotificationService::ShowWelcomeNotificationIfNecessary(
6308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const Notification& notification) {
6318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!welcome_notification && message_center::IsRichNotificationEnabled()) {
6328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    welcome_notification.reset(
6338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        new WelcomeNotification(profile_, g_browser_process->message_center()));
6348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
6358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (welcome_notification)
6378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    welcome_notification->ShowWelcomeNotificationIfNecessary(notification);
6388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
6398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DesktopNotificationService::OnStringListPrefChanged(
641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const char* pref_name, std::set<std::string>* ids_field) {
642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ids_field->clear();
643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const base::ListValue* pref_list = profile_->GetPrefs()->GetList(pref_name);
644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (size_t i = 0; i < pref_list->GetSize(); ++i) {
645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::string element;
646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (pref_list->GetString(i, &element) && !element.empty())
647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ids_field->insert(element);
648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    else
649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      LOG(WARNING) << i << "-th element is not a string for " << pref_name;
650eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKit::WebNotificationPresenter::Permission
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DesktopNotificationService::HasPermission(const GURL& origin) {
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostContentSettingsMap* host_content_settings_map =
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_->GetHostContentSettingsMap();
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ContentSetting setting = host_content_settings_map->GetContentSetting(
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      origin,
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      origin,
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NO_RESOURCE_IDENTIFIER);
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (setting == CONTENT_SETTING_ALLOW)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WebKit::WebNotificationPresenter::PermissionAllowed;
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (setting == CONTENT_SETTING_BLOCK)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WebKit::WebNotificationPresenter::PermissionDenied;
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (setting == CONTENT_SETTING_ASK)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WebKit::WebNotificationPresenter::PermissionNotAllowed;
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED() << "Invalid notifications settings value: " << setting;
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return WebKit::WebNotificationPresenter::PermissionNotAllowed;
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
67390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
67490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DesktopNotificationService::Observe(
67590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int type,
67690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const content::NotificationSource& source,
67790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const content::NotificationDetails& details) {
67890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK_EQ(chrome::NOTIFICATION_EXTENSION_UNINSTALLED, type);
67990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
68090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  extensions::Extension* extension =
68190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      content::Details<extensions::Extension>(details).ptr();
682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  NotifierId notifier_id(NotifierId::APPLICATION, extension->id());
683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (IsNotifierEnabled(notifier_id))
68490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
68590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetNotifierEnabled(notifier_id, true);
68790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
6881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
6891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void DesktopNotificationService::FirePermissionLevelChangedEvent(
6901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const NotifierId& notifier_id, bool enabled) {
6911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK_EQ(NotifierId::APPLICATION, notifier_id.type);
6921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  extensions::api::notifications::PermissionLevel permission =
6931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      enabled ? extensions::api::notifications::PERMISSION_LEVEL_GRANTED
6941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              : extensions::api::notifications::PERMISSION_LEVEL_DENIED;
6951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<base::ListValue> args(new base::ListValue());
6961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  args->Append(new base::StringValue(
6971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extensions::api::notifications::ToString(permission)));
6981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<extensions::Event> event(new extensions::Event(
6991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extensions::api::notifications::OnPermissionLevelChanged::kEventName,
7001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      args.Pass()));
7011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  extensions::ExtensionSystem::Get(profile_)->event_router()->
7021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      DispatchEventToExtension(notifier_id.id, event.Pass());
7031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
704