desktop_notification_service.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber// Use of this source code is governed by a BSD-style license that can be 3d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber// found in the LICENSE file. 4d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 5d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/browser/notifications/desktop_notification_service.h" 6d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 7d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "base/bind.h" 8d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "base/metrics/histogram.h" 9d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "base/prefs/scoped_user_pref_update.h" 10d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "base/strings/utf_string_conversions.h" 11d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "base/threading/thread.h" 12d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/browser/browser_process.h" 13d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/browser/chrome_notification_types.h" 14d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/browser/notifications/desktop_notification_profile_util.h" 15d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/browser/notifications/desktop_notification_service_factory.h" 16d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/browser/notifications/notification.h" 17d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/browser/notifications/notification_object_proxy.h" 18d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/browser/notifications/notification_ui_manager.h" 19d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h" 20d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/browser/notifications/sync_notifier/chrome_notifier_service_factory.h" 21d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/browser/profiles/profile.h" 22d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/browser/ui/browser.h" 23d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/common/pref_names.h" 24d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/common/url_constants.h" 25d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "components/pref_registry/pref_registry_syncable.h" 26d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "content/public/browser/browser_thread.h" 27d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "content/public/browser/desktop_notification_delegate.h" 28d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "content/public/browser/notification_service.h" 29d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "content/public/browser/render_frame_host.h" 30d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "content/public/browser/render_process_host.h" 31d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "content/public/browser/render_view_host.h" 32d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "content/public/browser/web_contents.h" 33d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "content/public/common/show_desktop_notification_params.h" 34d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "ui/base/webui/web_ui_util.h" 35d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "ui/message_center/notifier_settings.h" 36d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 37d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#if defined(ENABLE_EXTENSIONS) 38d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/browser/extensions/api/notifications/notifications_api.h" 39d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "chrome/browser/extensions/extension_service.h" 40d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "extensions/browser/event_router.h" 41d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "extensions/browser/extension_registry.h" 42d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "extensions/browser/extension_system.h" 43d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "extensions/browser/extension_util.h" 44d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "extensions/browser/info_map.h" 45d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "extensions/common/constants.h" 46d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "extensions/common/extension.h" 47d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include "extensions/common/extension_set.h" 48d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#endif 49d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 50d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberusing blink::WebTextDirection; 51d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberusing content::BrowserThread; 52d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberusing content::RenderViewHost; 53d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberusing content::WebContents; 54d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberusing message_center::NotifierId; 55d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 56d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubernamespace { 57d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 58d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubervoid CancelNotification(const std::string& id) { 59d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber g_browser_process->notification_ui_manager()->CancelById(id); 60d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 61d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 62d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} // namespace 63d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 64d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber// DesktopNotificationService ------------------------------------------------- 65d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 66d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber// static 67d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubervoid DesktopNotificationService::RegisterProfilePrefs( 68d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber user_prefs::PrefRegistrySyncable* registry) { 69d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber registry->RegisterListPref( 70d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber prefs::kMessageCenterDisabledExtensionIds, 71d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 72d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber registry->RegisterListPref( 73d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber prefs::kMessageCenterDisabledSystemComponentIds, 74d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 75d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 76d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 77d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber// static 78d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberstd::string DesktopNotificationService::AddIconNotification( 79d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const GURL& origin_url, 80d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const base::string16& title, 81d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const base::string16& message, 82d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const gfx::Image& icon, 83d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const base::string16& replace_id, 84d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber NotificationDelegate* delegate, 85d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber Profile* profile) { 86d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber Notification notification(message_center::NOTIFICATION_TYPE_SIMPLE, 87d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber origin_url, 88d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber title, 89d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber message, 90d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber icon, 91d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber blink::WebTextDirectionDefault, 92d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber message_center::NotifierId(origin_url), 93d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber base::string16(), 94d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber replace_id, 95d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber message_center::RichNotificationData(), 96d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber delegate); 97d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber g_browser_process->notification_ui_manager()->Add(notification, profile); 98d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return notification.delegate_id(); 99d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 100d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 101d9618f23226f46c752e56f712bc4b505117d8b4bAndreas HuberDesktopNotificationService::DesktopNotificationService(Profile* profile) 102d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber : PermissionContextBase(profile, CONTENT_SETTINGS_TYPE_NOTIFICATIONS), 103d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber profile_(profile), 104d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#if defined(ENABLE_EXTENSIONS) 105d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber extension_registry_observer_(this), 106d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#endif 107d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber weak_factory_(this) { 108d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber OnStringListPrefChanged( 109d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber prefs::kMessageCenterDisabledExtensionIds, &disabled_extension_ids_); 110d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber OnStringListPrefChanged( 111d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber prefs::kMessageCenterDisabledSystemComponentIds, 112d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber &disabled_system_component_ids_); 113d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber disabled_extension_id_pref_.Init( 114d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber prefs::kMessageCenterDisabledExtensionIds, 115d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber profile_->GetPrefs(), 116d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber base::Bind( 117d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber &DesktopNotificationService::OnStringListPrefChanged, 118d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber base::Unretained(this), 119d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber base::Unretained(prefs::kMessageCenterDisabledExtensionIds), 120d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber base::Unretained(&disabled_extension_ids_))); 121d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber disabled_system_component_id_pref_.Init( 122d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber prefs::kMessageCenterDisabledSystemComponentIds, 123d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber profile_->GetPrefs(), 124d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber base::Bind( 125d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber &DesktopNotificationService::OnStringListPrefChanged, 126d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber base::Unretained(this), 127d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber base::Unretained(prefs::kMessageCenterDisabledSystemComponentIds), 128d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber base::Unretained(&disabled_system_component_ids_))); 129d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#if defined(ENABLE_EXTENSIONS) 130d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber extension_registry_observer_.Add( 131d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber extensions::ExtensionRegistry::Get(profile_)); 132d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#endif 133d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 134d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 135d9618f23226f46c752e56f712bc4b505117d8b4bAndreas HuberDesktopNotificationService::~DesktopNotificationService() { 136d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 137d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 138d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubervoid DesktopNotificationService::RequestNotificationPermission( 139d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber content::WebContents* web_contents, 140d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const PermissionRequestID& request_id, 141d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const GURL& requesting_frame, 142d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber bool user_gesture, 143d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const NotificationPermissionCallback& callback) { 144d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 145d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber RequestPermission( 146d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber web_contents, 147d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber request_id, 148d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber requesting_frame, 149d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber user_gesture, 150d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber base::Bind(&DesktopNotificationService::OnNotificationPermissionRequested, 151d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber weak_factory_.GetWeakPtr(), 152d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber callback)); 153d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 154d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 155d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubervoid DesktopNotificationService::ShowDesktopNotification( 156d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const content::ShowDesktopNotificationHostMsgParams& params, 157d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber content::RenderFrameHost* render_frame_host, 158d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber scoped_ptr<content::DesktopNotificationDelegate> delegate, 159d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber base::Closure* cancel_callback) { 160d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 161d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const GURL& origin = params.origin; 162d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber NotificationObjectProxy* proxy = 163d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber new NotificationObjectProxy(render_frame_host, delegate.Pass()); 164d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 165d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber base::string16 display_source = DisplayNameForOriginInProcessId( 166d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber origin, render_frame_host->GetProcess()->GetID()); 167d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber Notification notification(origin, params.icon_url, params.title, 168d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber params.body, params.direction, display_source, params.replace_id, 169d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber proxy); 170d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 171d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber // The webkit notification doesn't timeout. 172d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber notification.set_never_timeout(true); 173d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 174d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber g_browser_process->notification_ui_manager()->Add(notification, profile_); 175d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (cancel_callback) 176d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber *cancel_callback = base::Bind(&CancelNotification, proxy->id()); 177d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 178d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber DesktopNotificationProfileUtil::UsePermission(profile_, origin); 179d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 180d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 181d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberbase::string16 DesktopNotificationService::DisplayNameForOriginInProcessId( 182d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const GURL& origin, int process_id) { 183d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#if defined(ENABLE_EXTENSIONS) 184d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber // If the source is an extension, lookup the display name. 185d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (origin.SchemeIs(extensions::kExtensionScheme)) { 186d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber extensions::InfoMap* extension_info_map = 187d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber extensions::ExtensionSystem::Get(profile_)->info_map(); 188d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (extension_info_map) { 189d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber extensions::ExtensionSet extensions; 190d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber extension_info_map->GetExtensionsWithAPIPermissionForSecurityOrigin( 191d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber origin, 192d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber process_id, 193d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber extensions::APIPermission::kNotifications, 194d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber &extensions); 195d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber for (extensions::ExtensionSet::const_iterator iter = extensions.begin(); 196d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber iter != extensions.end(); ++iter) { 197d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber NotifierId notifier_id(NotifierId::APPLICATION, (*iter)->id()); 198d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (IsNotifierEnabled(notifier_id)) 199d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return base::UTF8ToUTF16((*iter)->name()); 200d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 201d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 202d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 203d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#endif 204d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 205d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return base::UTF8ToUTF16(origin.host()); 206d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 207d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 208d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberbool DesktopNotificationService::IsNotifierEnabled( 209d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const NotifierId& notifier_id) { 210d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber switch (notifier_id.type) { 211d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber case NotifierId::APPLICATION: 212d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return disabled_extension_ids_.find(notifier_id.id) == 213d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber disabled_extension_ids_.end(); 214d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber case NotifierId::WEB_PAGE: 215d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return DesktopNotificationProfileUtil::GetContentSetting( 216d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber profile_, notifier_id.url) == CONTENT_SETTING_ALLOW; 217d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber case NotifierId::SYSTEM_COMPONENT: 218d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#if defined(OS_CHROMEOS) 219d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return disabled_system_component_ids_.find(notifier_id.id) == 220d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber disabled_system_component_ids_.end(); 221d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#else 222d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber // We do not disable system component notifications. 223d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return true; 224d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#endif 225d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 226d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 227d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber NOTREACHED(); 228d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return false; 229d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 230d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 231d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubervoid DesktopNotificationService::SetNotifierEnabled( 232d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const NotifierId& notifier_id, 233d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber bool enabled) { 234d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber DCHECK_NE(NotifierId::WEB_PAGE, notifier_id.type); 235d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 236d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber bool add_new_item = false; 237d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const char* pref_name = NULL; 238d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber scoped_ptr<base::StringValue> id; 239d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber switch (notifier_id.type) { 240d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber case NotifierId::APPLICATION: 241d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber pref_name = prefs::kMessageCenterDisabledExtensionIds; 242d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber add_new_item = !enabled; 243d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber id.reset(new base::StringValue(notifier_id.id)); 244d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber FirePermissionLevelChangedEvent(notifier_id, enabled); 245d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber break; 246d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber case NotifierId::SYSTEM_COMPONENT: 247d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#if defined(OS_CHROMEOS) 248d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber pref_name = prefs::kMessageCenterDisabledSystemComponentIds; 249d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber add_new_item = !enabled; 250d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber id.reset(new base::StringValue(notifier_id.id)); 251d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#else 252d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return; 253d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#endif 254d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber break; 255d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber default: 256d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber NOTREACHED(); 257d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 258d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber DCHECK(pref_name != NULL); 259d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 260d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber ListPrefUpdate update(profile_->GetPrefs(), pref_name); 261d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber base::ListValue* const list = update.Get(); 262d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (add_new_item) { 263d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber // AppendIfNotPresent will delete |adding_value| when the same value 264d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber // already exists. 265d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber list->AppendIfNotPresent(id.release()); 266d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } else { 267d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber list->Remove(*id, NULL); 268d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 269d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 270d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 271d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubervoid DesktopNotificationService::OnStringListPrefChanged( 272d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const char* pref_name, std::set<std::string>* ids_field) { 273d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber ids_field->clear(); 274d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber // Separate GetPrefs()->GetList() to analyze the crash. See crbug.com/322320 275d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const PrefService* pref_service = profile_->GetPrefs(); 276d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber CHECK(pref_service); 277d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const base::ListValue* pref_list = pref_service->GetList(pref_name); 278d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber for (size_t i = 0; i < pref_list->GetSize(); ++i) { 279d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber std::string element; 280d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (pref_list->GetString(i, &element) && !element.empty()) 281d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber ids_field->insert(element); 282d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber else 283d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber LOG(WARNING) << i << "-th element is not a string for " << pref_name; 284d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 285d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 286d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 287d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#if defined(ENABLE_EXTENSIONS) 288d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubervoid DesktopNotificationService::OnExtensionUninstalled( 289d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber content::BrowserContext* browser_context, 290d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const extensions::Extension* extension, 291d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber extensions::UninstallReason reason) { 292d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber NotifierId notifier_id(NotifierId::APPLICATION, extension->id()); 293d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (IsNotifierEnabled(notifier_id)) 294d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return; 295d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 296d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber // The settings for ephemeral apps will be persisted across cache evictions. 297d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (extensions::util::IsEphemeralApp(extension->id(), profile_)) 298d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return; 299d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 300d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber SetNotifierEnabled(notifier_id, true); 301d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 302d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#endif 303d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 304d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber// Unlike other permission types, granting a notification for a given origin 305d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber// will not take into account the |embedder_origin|, it will only be based 306d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber// on the requesting iframe origin. 307d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber// TODO(mukai) Consider why notifications behave differently than 308d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber// other permissions. crbug.com/416894 309void DesktopNotificationService::UpdateContentSetting( 310 const GURL& requesting_origin, 311 const GURL& embedder_origin, 312 bool allowed) { 313 if (allowed) { 314 DesktopNotificationProfileUtil::GrantPermission( 315 profile_, requesting_origin); 316 } else { 317 DesktopNotificationProfileUtil::DenyPermission(profile_, requesting_origin); 318 } 319} 320 321void DesktopNotificationService::OnNotificationPermissionRequested( 322 const NotificationPermissionCallback& callback, bool allowed) { 323 blink::WebNotificationPermission permission = allowed ? 324 blink::WebNotificationPermissionAllowed : 325 blink::WebNotificationPermissionDenied; 326 327 callback.Run(permission); 328} 329 330void DesktopNotificationService::FirePermissionLevelChangedEvent( 331 const NotifierId& notifier_id, bool enabled) { 332#if defined(ENABLE_EXTENSIONS) 333 DCHECK_EQ(NotifierId::APPLICATION, notifier_id.type); 334 extensions::api::notifications::PermissionLevel permission = 335 enabled ? extensions::api::notifications::PERMISSION_LEVEL_GRANTED 336 : extensions::api::notifications::PERMISSION_LEVEL_DENIED; 337 scoped_ptr<base::ListValue> args(new base::ListValue()); 338 args->Append(new base::StringValue( 339 extensions::api::notifications::ToString(permission))); 340 scoped_ptr<extensions::Event> event(new extensions::Event( 341 extensions::api::notifications::OnPermissionLevelChanged::kEventName, 342 args.Pass())); 343 extensions::EventRouter::Get(profile_) 344 ->DispatchEventToExtension(notifier_id.id, event.Pass()); 345 346 // Tell the IO thread that this extension's permission for notifications 347 // has changed. 348 extensions::InfoMap* extension_info_map = 349 extensions::ExtensionSystem::Get(profile_)->info_map(); 350 BrowserThread::PostTask( 351 BrowserThread::IO, FROM_HERE, 352 base::Bind(&extensions::InfoMap::SetNotificationsDisabled, 353 extension_info_map, notifier_id.id, !enabled)); 354#endif 355} 356