desktop_notification_service.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (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"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/notifications/notifications_api.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/infobars/confirm_infobar_delegate.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/infobars/infobar.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/infobars/infobar_service.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/notifications/desktop_notification_service_factory.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/notifications/notification.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/notification_object_proxy.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/notifications/notification_ui_manager.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#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"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/website_settings/permission_bubble_request.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/content_settings.h"
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/common/content_settings_pattern.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/url_constants.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h"
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (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"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/show_desktop_notification_params.h"
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/browser/event_router.h"
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/browser/extension_system.h"
43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "extensions/browser/info_map.h"
44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "extensions/common/constants.h"
45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "extensions/common/extension.h"
46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "extensions/common/extension_set.h"
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "grit/browser_resources.h"
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "grit/chromium_strings.h"
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "grit/generated_resources.h"
50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (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"
530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ui/base/webui/web_ui_util.h"
550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ui/message_center/message_center_util.h"
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/message_center/notifier_settings.h"
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using content::BrowserThread;
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using content::RenderViewHost;
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using content::WebContents;
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using message_center::NotifierId;
620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)using blink::WebTextDirection;
630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)const char kChromeNowExtensionID[] = "pafkbggdmjlpgkdkcbjmhmfcdpncadgh";
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// NotificationPermissionRequest ---------------------------------------
676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
68e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass NotificationPermissionRequest : public PermissionBubbleRequest {
69e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch public:
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NotificationPermissionRequest(
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DesktopNotificationService* notification_service,
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const GURL& origin,
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::string16 display_name,
740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      int process_id,
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      int route_id,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int callback_context);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~NotificationPermissionRequest();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PermissionBubbleDelegate:
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual int GetIconID() const OVERRIDE;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual base::string16 GetMessageText() const OVERRIDE;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual base::string16 GetMessageTextFragment() const OVERRIDE;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool HasUserGesture() const OVERRIDE;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual GURL GetRequestingHostname() const OVERRIDE;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void PermissionGranted() OVERRIDE;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void PermissionDenied() OVERRIDE;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Cancelled() OVERRIDE;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void RequestFinished() OVERRIDE;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The notification service to be used.
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DesktopNotificationService* notification_service_;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The origin we are asking for permissions on.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL origin_;
96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // The display name for the origin to be displayed.  Will be different from
98e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // origin_ for extensions.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::string16 display_name_;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The callback information that tells us how to respond to javascript via
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the correct RenderView.
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int process_id_;
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int route_id_;
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int callback_context_;
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Whether the user clicked one of the buttons.
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool action_taken_;
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NotificationPermissionRequest);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1130529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochNotificationPermissionRequest::NotificationPermissionRequest(
1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DesktopNotificationService* notification_service,
1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const GURL& origin,
1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::string16 display_name,
1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    int process_id,
1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    int route_id,
1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    int callback_context)
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    : notification_service_(notification_service),
1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      origin_(origin),
1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      display_name_(display_name),
1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      process_id_(process_id),
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      route_id_(route_id),
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      callback_context_(callback_context),
1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      action_taken_(false) {}
1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)NotificationPermissionRequest::~NotificationPermissionRequest() {}
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)int NotificationPermissionRequest::GetIconID() const {
1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return IDR_INFOBAR_DESKTOP_NOTIFICATIONS;
13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)base::string16 NotificationPermissionRequest::GetMessageText() const {
13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_NOTIFICATION_PERMISSIONS,
13623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                    display_name_);
13723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
13823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)base::string16
14023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)NotificationPermissionRequest::GetMessageTextFragment() const {
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_NOTIFICATION_PERMISSIONS_FRAGMENT);
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool NotificationPermissionRequest::HasUserGesture() const {
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Currently notification permission requests are only issued on
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // user gesture.
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return true;
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
149b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
150b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)GURL NotificationPermissionRequest::GetRequestingHostname() const {
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return origin_;
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void NotificationPermissionRequest::PermissionGranted() {
155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  action_taken_ = true;
156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Allowed", 1);
157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  notification_service_->GrantPermission(origin_);
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void NotificationPermissionRequest::PermissionDenied() {
161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  action_taken_ = true;
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Denied", 1);
163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  notification_service_->DenyPermission(origin_);
1646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void NotificationPermissionRequest::Cancelled() {
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void NotificationPermissionRequest::RequestFinished() {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!action_taken_)
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Ignored", 1);
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (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)}
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// NotificationPermissionInfoBarDelegate --------------------------------------
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The delegate for the infobar shown when an origin requests notification
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// permissions.
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class NotificationPermissionInfoBarDelegate : public ConfirmInfoBarDelegate {
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a notification permission infobar and delegate and adds the infobar
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to |infobar_service|.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Create(InfoBarService* infobar_service,
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     DesktopNotificationService* notification_service,
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     const GURL& origin,
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     const base::string16& display_name,
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     int process_id,
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     int route_id,
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     int callback_context);
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NotificationPermissionInfoBarDelegate(
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DesktopNotificationService* notification_service,
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const GURL& origin,
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const base::string16& display_name,
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      int process_id,
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      int route_id,
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      int callback_context);
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~NotificationPermissionInfoBarDelegate();
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // ConfirmInfoBarDelegate:
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual int GetIconID() const OVERRIDE;
2090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual Type GetInfoBarType() const OVERRIDE;
2100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual base::string16 GetMessageText() const OVERRIDE;
2110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual base::string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
2120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual bool Accept() OVERRIDE;
2130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual bool Cancel() OVERRIDE;
2140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // The origin we are asking for permissions on.
2160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  GURL origin_;
2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The display name for the origin to be displayed.  Will be different from
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // origin_ for extensions.
2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::string16 display_name_;
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The notification service to be used.
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DesktopNotificationService* notification_service_;
2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The callback information that tells us how to respond to javascript via
2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // the correct RenderView.
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int process_id_;
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int route_id_;
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int callback_context_;
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Whether the user clicked one of the buttons.
232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool action_taken_;
233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NotificationPermissionInfoBarDelegate);
235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// static
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid NotificationPermissionInfoBarDelegate::Create(
2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    InfoBarService* infobar_service,
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DesktopNotificationService* notification_service,
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const GURL& origin,
2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const base::string16& display_name,
2430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    int process_id,
2440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    int route_id,
2450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    int callback_context) {
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      scoped_ptr<ConfirmInfoBarDelegate>(
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          new NotificationPermissionInfoBarDelegate(
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              notification_service, origin, display_name, process_id, route_id,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              callback_context))));
2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NotificationPermissionInfoBarDelegate::NotificationPermissionInfoBarDelegate(
2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DesktopNotificationService* notification_service,
2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const GURL& origin,
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const base::string16& display_name,
2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int process_id,
2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int route_id,
2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int callback_context)
2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    : ConfirmInfoBarDelegate(),
2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      origin_(origin),
2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      display_name_(display_name),
2637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      notification_service_(notification_service),
2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      process_id_(process_id),
2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      route_id_(route_id),
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback_context_(callback_context),
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      action_taken_(false) {
268558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
269558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
270558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochNotificationPermissionInfoBarDelegate::
271ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ~NotificationPermissionInfoBarDelegate() {
272ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (!action_taken_)
273ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Ignored", 1);
274558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
275558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  RenderViewHost* host = RenderViewHost::FromID(process_id_, route_id_);
276558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (host)
277558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    host->DesktopNotificationPermissionRequestDone(callback_context_);
278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
279e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
2800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochint NotificationPermissionInfoBarDelegate::GetIconID() const {
281010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return IDR_INFOBAR_DESKTOP_NOTIFICATIONS;
2826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
2836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
284558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochInfoBarDelegate::Type
285558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    NotificationPermissionInfoBarDelegate::GetInfoBarType() const {
286558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return PAGE_ACTION_TYPE;
287558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
288558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
289558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbase::string16 NotificationPermissionInfoBarDelegate::GetMessageText() const {
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return l10n_util::GetStringFUTF16(IDS_NOTIFICATION_PERMISSIONS,
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    display_name_);
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)base::string16 NotificationPermissionInfoBarDelegate::GetButtonLabel(
295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    InfoBarButton button) const {
2960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
297e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      IDS_NOTIFICATION_PERMISSION_YES : IDS_NOTIFICATION_PERMISSION_NO);
2985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
299558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
300558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbool NotificationPermissionInfoBarDelegate::Accept() {
301558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Allowed", 1);
3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  notification_service_->GrantPermission(origin_);
3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  action_taken_ = true;
304c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  return true;
305558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
306558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
307558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbool NotificationPermissionInfoBarDelegate::Cancel() {
308558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Denied", 1);
309558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  notification_service_->DenyPermission(origin_);
310558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  action_taken_ = true;
311558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return true;
312558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
313558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
314558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
315558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// DesktopNotificationService -------------------------------------------------
316558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
317558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// static
318558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid DesktopNotificationService::RegisterProfilePrefs(
319558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    user_prefs::PrefRegistrySyncable* registry) {
3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  registry->RegisterListPref(
3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      prefs::kMessageCenterDisabledExtensionIds,
3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
323558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  registry->RegisterListPref(
324558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      prefs::kMessageCenterDisabledSystemComponentIds,
325558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
326558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  registry->RegisterListPref(
327558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      prefs::kMessageCenterEnabledSyncNotifierIds,
328558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
329558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ExtensionWelcomeNotification::RegisterProfilePrefs(registry);
330558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
331558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
332558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// static
333558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbase::string16 DesktopNotificationService::CreateDataUrl(
334558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    const GURL& icon_url,
33546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::string16& title,
33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::string16& body,
33746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    WebTextDirection dir) {
338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int resource;
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<std::string> subst;
340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (icon_url.is_valid()) {
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    resource = IDR_NOTIFICATION_ICON_HTML;
342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    subst.push_back(icon_url.spec());
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(base::UTF16ToUTF8(title)));
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(base::UTF16ToUTF8(body)));
345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // icon float position
346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    subst.push_back(dir == blink::WebTextDirectionRightToLeft ?
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    "right" : "left");
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else if (title.empty() || body.empty()) {
349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    resource = IDR_NOTIFICATION_1LINE_HTML;
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::string16 line = title.empty() ? body : title;
351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Strings are div names in the template file.
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::string16 line_name =
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        title.empty() ? base::ASCIIToUTF16("description")
354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      : base::ASCIIToUTF16("title");
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(base::UTF16ToUTF8(line_name)));
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    subst.push_back(net::EscapeForHTML(base::UTF16ToUTF8(line)));
357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    resource = IDR_NOTIFICATION_2LINE_HTML;
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    subst.push_back(net::EscapeForHTML(base::UTF16ToUTF8(title)));
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    subst.push_back(net::EscapeForHTML(base::UTF16ToUTF8(body)));
361d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
362d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // body text direction
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  subst.push_back(dir == blink::WebTextDirectionRightToLeft ?
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  "rtl" : "ltr");
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CreateDataUrl(resource, subst);
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 DesktopNotificationService::CreateDataUrl(
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int resource, const std::vector<std::string>& subst) {
372424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const base::StringPiece template_html(
373424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(
3740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          resource));
3750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (template_html.empty()) {
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    NOTREACHED() << "unable to load template. ID: " << resource;
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return base::string16();
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string data = ReplaceStringPlaceholders(template_html, subst, NULL);
3820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return base::UTF8ToUTF16("data:text/html;charset=utf-8," +
3830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               net::EscapeQueryParamValue(data, false));
3840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
3850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// static
3870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstd::string DesktopNotificationService::AddNotification(
3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const GURL& origin_url,
3893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const base::string16& title,
3903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const base::string16& message,
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GURL& icon_url,
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::string16& replace_id,
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotificationDelegate* delegate,
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Profile* profile) {
3953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (message_center::IsRichNotificationEnabled()) {
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // For message center create a non-HTML notification with |icon_url|.
3973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Notification notification(origin_url, icon_url, title, message,
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              blink::WebTextDirectionDefault,
3993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              base::string16(), replace_id, delegate);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_browser_process->notification_ui_manager()->Add(notification, profile);
4013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return notification.notification_id();
4023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate a data URL embedding the icon URL, title, and message.
4053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  GURL content_url(CreateDataUrl(
4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      icon_url, title, message, blink::WebTextDirectionDefault));
4073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Notification notification(
4085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      GURL(), content_url, base::string16(), replace_id, delegate);
4095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  g_browser_process->notification_ui_manager()->Add(notification, profile);
4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return notification.notification_id();
4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// static
4143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)std::string DesktopNotificationService::AddIconNotification(
4153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const GURL& origin_url,
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& title,
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& message,
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Image& icon,
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& replace_id,
420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NotificationDelegate* delegate,
421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Profile* profile) {
4223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (message_center::IsRichNotificationEnabled()) {
4233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // For message center create a non-HTML notification with |icon|.
4243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Notification notification(origin_url, icon, title, message,
4253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              blink::WebTextDirectionDefault,
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              base::string16(), replace_id, delegate);
4273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    g_browser_process->notification_ui_manager()->Add(notification, profile);
42890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return notification.notification_id();
4293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  GURL icon_url;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!icon.IsEmpty())
4333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    icon_url = GURL(webui::GetBitmapDataUrl(*icon.ToSkBitmap()));
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return AddNotification(
4353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      origin_url, title, message, icon_url, replace_id, delegate, profile);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
4393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void DesktopNotificationService::RemoveNotification(
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& notification_id) {
4413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    g_browser_process->notification_ui_manager()->CancelById(notification_id);
442d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
443d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DesktopNotificationService::DesktopNotificationService(
4453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Profile* profile,
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NotificationUIManager* ui_manager)
4473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    : profile_(profile),
448b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      ui_manager_(ui_manager) {
4493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  OnStringListPrefChanged(
450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      prefs::kMessageCenterDisabledExtensionIds, &disabled_extension_ids_);
451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  OnStringListPrefChanged(
452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      prefs::kMessageCenterDisabledSystemComponentIds,
453b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      &disabled_system_component_ids_);
4543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  OnStringListPrefChanged(
45590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      prefs::kMessageCenterEnabledSyncNotifierIds, &enabled_sync_notifier_ids_);
4563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  disabled_extension_id_pref_.Init(
45790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      prefs::kMessageCenterDisabledExtensionIds,
4583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      profile_->GetPrefs(),
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
4603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          &DesktopNotificationService::OnStringListPrefChanged,
46190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::Unretained(this),
4623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          base::Unretained(prefs::kMessageCenterDisabledExtensionIds),
46358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          base::Unretained(&disabled_extension_ids_)));
4643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  disabled_system_component_id_pref_.Init(
46558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      prefs::kMessageCenterDisabledSystemComponentIds,
46658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      profile_->GetPrefs(),
467d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      base::Bind(
468d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          &DesktopNotificationService::OnStringListPrefChanged,
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::Unretained(this),
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::Unretained(prefs::kMessageCenterDisabledSystemComponentIds),
47146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          base::Unretained(&disabled_system_component_ids_)));
47246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  enabled_sync_notifier_id_pref_.Init(
47346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      prefs::kMessageCenterEnabledSyncNotifierIds,
47446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      profile_->GetPrefs(),
47546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(
47646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          &DesktopNotificationService::OnStringListPrefChanged,
477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::Unretained(this),
478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::Unretained(prefs::kMessageCenterEnabledSyncNotifierIds),
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Unretained(&enabled_sync_notifier_ids_)));
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<Profile>(profile_));
48290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
4833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DesktopNotificationService::~DesktopNotificationService() {
4853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void DesktopNotificationService::GrantPermission(const GURL& origin) {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ContentSettingsPattern primary_pattern =
4893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ContentSettingsPattern::FromURLNoWildcard(origin);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetContentSetting(
4913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      primary_pattern,
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ContentSettingsPattern::Wildcard(),
4933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NO_RESOURCE_IDENTIFIER,
4953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      CONTENT_SETTING_ALLOW);
4964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DesktopNotificationService::DenyPermission(const GURL& origin) {
4993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ContentSettingsPattern primary_pattern =
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ContentSettingsPattern::FromURLNoWildcard(origin);
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetContentSetting(
5023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      primary_pattern,
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ContentSettingsPattern::Wildcard(),
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      NO_RESOURCE_IDENTIFIER,
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTING_BLOCK);
5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ContentSetting DesktopNotificationService::GetDefaultContentSetting(
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string* provider_id) {
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS, provider_id);
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
5143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DesktopNotificationService::SetDefaultContentSetting(
5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ContentSetting setting) {
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetDefaultContentSetting(
5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS, setting);
519b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
520b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void DesktopNotificationService::ResetToDefaultContentSetting() {
522b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetDefaultContentSetting(
5233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS, CONTENT_SETTING_DEFAULT);
5244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DesktopNotificationService::GetNotificationsSettings(
527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ContentSettingsForOneType* settings) {
528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  profile_->GetHostContentSettingsMap()->GetSettingsForOneType(
529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      NO_RESOURCE_IDENTIFIER,
531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      settings);
532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
53446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void DesktopNotificationService::ClearSetting(
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ContentSettingsPattern& pattern) {
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->SetContentSetting(
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pattern,
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ContentSettingsPattern::Wildcard(),
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NO_RESOURCE_IDENTIFIER,
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CONTENT_SETTING_DEFAULT);
542a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
544a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void DesktopNotificationService::ResetAllOrigins() {
545a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  profile_->GetHostContentSettingsMap()->ClearSettingsForOneType(
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
549558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochContentSetting DesktopNotificationService::GetContentSetting(
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& origin) {
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return profile_->GetHostContentSettingsMap()->GetContentSetting(
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      origin,
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      origin,
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NO_RESOURCE_IDENTIFIER);
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DesktopNotificationService::RequestPermission(
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& origin, int process_id, int route_id, int callback_context,
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* contents) {
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If |origin| hasn't been seen before and the default content setting for
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // notifications is "ask", show an infobar.
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The cache can only answer queries on the IO thread once it's initialized,
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so don't ask the cache.
565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ContentSetting setting = GetContentSetting(origin);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (setting == CONTENT_SETTING_ASK) {
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (PermissionBubbleManager::Enabled()) {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PermissionBubbleManager* bubble_manager =
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          PermissionBubbleManager::FromWebContents(contents);
5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bubble_manager->AddRequest(new NotificationPermissionRequest(this,
5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              origin, DisplayNameForOriginInProcessId(origin, process_id),
5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              process_id, route_id, callback_context));
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Show an info bar requesting permission.
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InfoBarService* infobar_service =
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        InfoBarService::FromWebContents(contents);
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // |infobar_service| may be NULL, e.g., if this request originated in a
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // browser action popup, extension background page, or any HTML that runs
581ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // outside of a tab.
582ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (infobar_service) {
583ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      NotificationPermissionInfoBarDelegate::Create(
584ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          infobar_service, this,
585ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          origin, DisplayNameForOriginInProcessId(origin, process_id),
586ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          process_id, route_id, callback_context);
587ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      return;
588ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
589ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify renderer immediately.
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenderViewHost* host = RenderViewHost::FromID(process_id, route_id);
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (host)
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host->DesktopNotificationPermissionRequestDone(callback_context);
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_WIN)
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DesktopNotificationService::ShowNotification(
5990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const Notification& notification) {
6000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  GetUIManager()->Add(notification, profile_);
6010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
6020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool DesktopNotificationService::CancelDesktopNotification(
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int process_id, int route_id, int notification_id) {
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<NotificationObjectProxy> proxy(
606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new NotificationObjectProxy(process_id, route_id, notification_id,
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  false));
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetUIManager()->CancelById(proxy->id());
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif  // OS_WIN
611f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool DesktopNotificationService::ShowDesktopNotification(
6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const content::ShowDesktopNotificationHostMsgParams& params,
6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int process_id, int route_id, DesktopNotificationSource source) {
615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL& origin = params.origin;
617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NotificationObjectProxy* proxy =
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new NotificationObjectProxy(process_id, route_id,
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  params.notification_id,
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  source == WorkerNotification);
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::string16 display_source =
62358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      DisplayNameForOriginInProcessId(origin, process_id);
62458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Notification notification(origin, params.icon_url, params.title,
62558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      params.body, params.direction, display_source, params.replace_id,
62658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      proxy);
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The webkit notification doesn't timeout.
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  notification.set_never_timeout(true);
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShowNotification(notification);
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::string16 DesktopNotificationService::DisplayNameForOriginInProcessId(
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin, int process_id) {
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the source is an extension, lookup the display name.
6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Message center prefers to use extension name if the notification
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is allowed by an extension.
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (NotificationUIManager::DelegatesToMessageCenter() ||
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      origin.SchemeIs(extensions::kExtensionScheme)) {
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    extensions::InfoMap* extension_info_map =
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        extensions::ExtensionSystem::Get(profile_)->info_map();
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (extension_info_map) {
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::ExtensionSet extensions;
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension_info_map->GetExtensionsWithAPIPermissionForSecurityOrigin(
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          origin, process_id, extensions::APIPermission::kNotification,
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &extensions);
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (extensions::ExtensionSet::const_iterator iter = extensions.begin();
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           iter != extensions.end(); ++iter) {
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NotifierId notifier_id(NotifierId::APPLICATION, (*iter)->id());
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (IsNotifierEnabled(notifier_id))
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          return base::UTF8ToUTF16((*iter)->name());
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::UTF8ToUTF16(origin.host());
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DesktopNotificationService::NotifySettingsChange() {
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::NotificationService::current()->Notify(
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_DESKTOP_NOTIFICATION_SETTINGS_CHANGED,
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::Source<DesktopNotificationService>(this),
6640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      content::NotificationService::NoDetails());
6650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
6660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)NotificationUIManager* DesktopNotificationService::GetUIManager() {
6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We defer setting ui_manager_ to the global singleton until we need it
6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // in order to avoid UI dependent construction during startup.
6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!ui_manager_)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui_manager_ = g_browser_process->notification_ui_manager();
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ui_manager_;
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DesktopNotificationService::IsNotifierEnabled(
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const NotifierId& notifier_id) {
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (notifier_id.type) {
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case NotifierId::APPLICATION:
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return disabled_extension_ids_.find(notifier_id.id) ==
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          disabled_extension_ids_.end();
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case NotifierId::WEB_PAGE:
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetContentSetting(notifier_id.url) == CONTENT_SETTING_ALLOW;
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case NotifierId::SYSTEM_COMPONENT:
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS)
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return disabled_system_component_ids_.find(notifier_id.id) ==
686a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          disabled_system_component_ids_.end();
687a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#else
688a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // We do not disable system component notifications.
6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
691a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case NotifierId::SYNCED_NOTIFICATION_SERVICE:
692a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return enabled_sync_notifier_ids_.find(notifier_id.id) !=
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          enabled_sync_notifier_ids_.end();
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DesktopNotificationService::SetNotifierEnabled(
7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const NotifierId& notifier_id,
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool enabled) {
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_NE(NotifierId::WEB_PAGE, notifier_id.type);
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool add_new_item = false;
706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const char* pref_name = NULL;
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::StringValue> id;
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (notifier_id.type) {
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NotifierId::APPLICATION:
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pref_name = prefs::kMessageCenterDisabledExtensionIds;
7117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      add_new_item = !enabled;
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      id.reset(new base::StringValue(notifier_id.id));
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FirePermissionLevelChangedEvent(notifier_id, enabled);
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NotifierId::SYSTEM_COMPONENT:
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
717cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pref_name = prefs::kMessageCenterDisabledSystemComponentIds;
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      add_new_item = !enabled;
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      id.reset(new base::StringValue(notifier_id.id));
720e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#else
721e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      return;
722e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#endif
723e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      break;
724e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    case NotifierId::SYNCED_NOTIFICATION_SERVICE:
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pref_name = prefs::kMessageCenterEnabledSyncNotifierIds;
7265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Adding a new item if |enabled| == true, since synced notification
7275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // services are opt-in.
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      add_new_item = enabled;
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      id.reset(new base::StringValue(notifier_id.id));
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(pref_name != NULL);
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ListPrefUpdate update(profile_->GetPrefs(), pref_name);
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ListValue* const list = update.Get();
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (add_new_item) {
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // AppendIfNotPresent will delete |adding_value| when the same value
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // already exists.
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    list->AppendIfNotPresent(id.release());
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list->Remove(*id, NULL);
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DesktopNotificationService::ShowWelcomeNotificationIfNecessary(
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Notification& notification) {
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!chrome_now_welcome_notification_ &&
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      message_center::IsRichNotificationEnabled()) {
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chrome_now_welcome_notification_ =
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ExtensionWelcomeNotification::Create(kChromeNowExtensionID, profile_);
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (chrome_now_welcome_notification_) {
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chrome_now_welcome_notification_->ShowWelcomeNotificationIfNecessary(
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        notification);
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DesktopNotificationService::OnStringListPrefChanged(
7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const char* pref_name, std::set<std::string>* ids_field) {
7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ids_field->clear();
7645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Separate GetPrefs()->GetList() to analyze the crash. See crbug.com/322320
7655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const PrefService* pref_service = profile_->GetPrefs();
7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(pref_service);
7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::ListValue* pref_list = pref_service->GetList(pref_name);
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < pref_list->GetSize(); ++i) {
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string element;
770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (pref_list->GetString(i, &element) && !element.empty())
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ids_field->insert(element);
7725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    else
7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LOG(WARNING) << i << "-th element is not a string for " << pref_name;
7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DesktopNotificationService::Observe(
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationSource& source,
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationDetails& details) {
7815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(chrome::NOTIFICATION_EXTENSION_UNINSTALLED, type);
7825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::Extension* extension =
7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      content::Details<extensions::Extension>(details).ptr();
7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NotifierId notifier_id(NotifierId::APPLICATION, extension->id());
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsNotifierEnabled(notifier_id))
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The settings for ephemeral apps will be persisted across cache evictions.
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (extension->is_ephemeral())
7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetNotifierEnabled(notifier_id, true);
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DesktopNotificationService::FirePermissionLevelChangedEvent(
7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const NotifierId& notifier_id, bool enabled) {
7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(NotifierId::APPLICATION, notifier_id.type);
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::api::notifications::PermissionLevel permission =
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      enabled ? extensions::api::notifications::PERMISSION_LEVEL_GRANTED
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              : extensions::api::notifications::PERMISSION_LEVEL_DENIED;
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::ListValue> args(new base::ListValue());
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  args->Append(new base::StringValue(
8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::api::notifications::ToString(permission)));
8055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<extensions::Event> event(new extensions::Event(
8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::api::notifications::OnPermissionLevelChanged::kEventName,
8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      args.Pass()));
8085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ExtensionSystem::Get(profile_)->event_router()->
8095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DispatchEventToExtension(notifier_id.id, event.Pass());
8105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Tell the IO thread that this extension's permission for notifications
8125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // has changed.
8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::InfoMap* extension_info_map =
8145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ExtensionSystem::Get(profile_)->info_map();
8155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BrowserThread::PostTask(
8165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&extensions::InfoMap::SetNotificationsDisabled,
8185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 extension_info_map, notifier_id.id, !enabled));
8195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)