OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/notifications/desktop_notification_service.h" | 5 #include "chrome/browser/notifications/desktop_notification_service.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
10 #include "base/prefs/scoped_user_pref_update.h" | 10 #include "base/prefs/scoped_user_pref_update.h" |
11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
12 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
13 #include "chrome/browser/notifications/desktop_notification_profile_util.h" | 13 #include "chrome/browser/notifications/desktop_notification_profile_util.h" |
14 #include "chrome/browser/notifications/notification.h" | 14 #include "chrome/browser/notifications/notification.h" |
15 #include "chrome/browser/notifications/notification_object_proxy.h" | 15 #include "chrome/browser/notifications/notification_object_proxy.h" |
16 #include "chrome/browser/notifications/notification_ui_manager.h" | 16 #include "chrome/browser/notifications/notification_ui_manager.h" |
17 #include "chrome/browser/permissions/permission_request_id.h" | |
18 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
19 #include "chrome/browser/ui/browser.h" | 18 #include "chrome/browser/ui/browser.h" |
20 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
21 #include "components/pref_registry/pref_registry_syncable.h" | 20 #include "components/pref_registry/pref_registry_syncable.h" |
22 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
23 #include "ui/base/webui/web_ui_util.h" | 22 #include "ui/base/webui/web_ui_util.h" |
24 #include "ui/message_center/notifier_settings.h" | 23 #include "ui/message_center/notifier_settings.h" |
25 | 24 |
26 #if defined(ENABLE_EXTENSIONS) | 25 #if defined(ENABLE_EXTENSIONS) |
27 #include "chrome/browser/extensions/api/notifications/notifications_api.h" | 26 #include "chrome/browser/extensions/api/notifications/notifications_api.h" |
(...skipping 15 matching lines...) Expand all Loading... |
43 // DesktopNotificationService ------------------------------------------------- | 42 // DesktopNotificationService ------------------------------------------------- |
44 | 43 |
45 // static | 44 // static |
46 void DesktopNotificationService::RegisterProfilePrefs( | 45 void DesktopNotificationService::RegisterProfilePrefs( |
47 user_prefs::PrefRegistrySyncable* registry) { | 46 user_prefs::PrefRegistrySyncable* registry) { |
48 registry->RegisterListPref(prefs::kMessageCenterDisabledExtensionIds); | 47 registry->RegisterListPref(prefs::kMessageCenterDisabledExtensionIds); |
49 registry->RegisterListPref(prefs::kMessageCenterDisabledSystemComponentIds); | 48 registry->RegisterListPref(prefs::kMessageCenterDisabledSystemComponentIds); |
50 } | 49 } |
51 | 50 |
52 DesktopNotificationService::DesktopNotificationService(Profile* profile) | 51 DesktopNotificationService::DesktopNotificationService(Profile* profile) |
53 : PermissionContextBase(profile, CONTENT_SETTINGS_TYPE_NOTIFICATIONS), | 52 : profile_(profile) |
54 profile_(profile) | |
55 #if defined(ENABLE_EXTENSIONS) | 53 #if defined(ENABLE_EXTENSIONS) |
56 , | 54 , |
57 extension_registry_observer_(this) | 55 extension_registry_observer_(this) |
58 #endif | 56 #endif |
59 { | 57 { |
60 OnStringListPrefChanged( | 58 OnStringListPrefChanged( |
61 prefs::kMessageCenterDisabledExtensionIds, &disabled_extension_ids_); | 59 prefs::kMessageCenterDisabledExtensionIds, &disabled_extension_ids_); |
62 OnStringListPrefChanged( | 60 OnStringListPrefChanged( |
63 prefs::kMessageCenterDisabledSystemComponentIds, | 61 prefs::kMessageCenterDisabledSystemComponentIds, |
64 &disabled_system_component_ids_); | 62 &disabled_system_component_ids_); |
(...skipping 15 matching lines...) Expand all Loading... |
80 base::Unretained(&disabled_system_component_ids_))); | 78 base::Unretained(&disabled_system_component_ids_))); |
81 #if defined(ENABLE_EXTENSIONS) | 79 #if defined(ENABLE_EXTENSIONS) |
82 extension_registry_observer_.Add( | 80 extension_registry_observer_.Add( |
83 extensions::ExtensionRegistry::Get(profile_)); | 81 extensions::ExtensionRegistry::Get(profile_)); |
84 #endif | 82 #endif |
85 } | 83 } |
86 | 84 |
87 DesktopNotificationService::~DesktopNotificationService() { | 85 DesktopNotificationService::~DesktopNotificationService() { |
88 } | 86 } |
89 | 87 |
90 void DesktopNotificationService::RequestNotificationPermission( | |
91 content::WebContents* web_contents, | |
92 const PermissionRequestID& request_id, | |
93 const GURL& requesting_origin, | |
94 bool user_gesture, | |
95 const BrowserPermissionCallback& result_callback) { | |
96 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
97 | |
98 #if defined(ENABLE_EXTENSIONS) | |
99 extensions::InfoMap* extension_info_map = | |
100 extensions::ExtensionSystem::Get(profile_)->info_map(); | |
101 const extensions::Extension* extension = NULL; | |
102 if (extension_info_map) { | |
103 extensions::ExtensionSet extensions; | |
104 extension_info_map->GetExtensionsWithAPIPermissionForSecurityOrigin( | |
105 requesting_origin, | |
106 request_id.render_process_id(), | |
107 extensions::APIPermission::kNotifications, | |
108 &extensions); | |
109 for (extensions::ExtensionSet::const_iterator iter = extensions.begin(); | |
110 iter != extensions.end(); ++iter) { | |
111 if (IsNotifierEnabled(NotifierId( | |
112 NotifierId::APPLICATION, (*iter)->id()))) { | |
113 extension = iter->get(); | |
114 break; | |
115 } | |
116 } | |
117 } | |
118 if (IsExtensionWithPermissionOrSuggestInConsole( | |
119 extensions::APIPermission::kNotifications, extension, | |
120 web_contents->GetMainFrame())) { | |
121 result_callback.Run(CONTENT_SETTING_ALLOW); | |
122 return; | |
123 } | |
124 #endif | |
125 | |
126 // Track whether the requesting and embedding origins are different when | |
127 // permission to display Web Notifications is being requested. | |
128 UMA_HISTOGRAM_BOOLEAN("Notifications.DifferentRequestingEmbeddingOrigins", | |
129 requesting_origin.GetOrigin() != | |
130 web_contents->GetLastCommittedURL().GetOrigin()); | |
131 | |
132 RequestPermission(web_contents, | |
133 request_id, | |
134 requesting_origin, | |
135 user_gesture, | |
136 result_callback); | |
137 } | |
138 | |
139 bool DesktopNotificationService::IsNotifierEnabled( | 88 bool DesktopNotificationService::IsNotifierEnabled( |
140 const NotifierId& notifier_id) const { | 89 const NotifierId& notifier_id) const { |
141 switch (notifier_id.type) { | 90 switch (notifier_id.type) { |
142 case NotifierId::APPLICATION: | 91 case NotifierId::APPLICATION: |
143 return disabled_extension_ids_.find(notifier_id.id) == | 92 return disabled_extension_ids_.find(notifier_id.id) == |
144 disabled_extension_ids_.end(); | 93 disabled_extension_ids_.end(); |
145 case NotifierId::WEB_PAGE: | 94 case NotifierId::WEB_PAGE: |
146 return DesktopNotificationProfileUtil::GetContentSetting( | 95 return DesktopNotificationProfileUtil::GetContentSetting( |
147 profile_, notifier_id.url) == CONTENT_SETTING_ALLOW; | 96 profile_, notifier_id.url) == CONTENT_SETTING_ALLOW; |
148 case NotifierId::SYSTEM_COMPONENT: | 97 case NotifierId::SYSTEM_COMPONENT: |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 return; | 174 return; |
226 | 175 |
227 // The settings for ephemeral apps will be persisted across cache evictions. | 176 // The settings for ephemeral apps will be persisted across cache evictions. |
228 if (extensions::util::IsEphemeralApp(extension->id(), profile_)) | 177 if (extensions::util::IsEphemeralApp(extension->id(), profile_)) |
229 return; | 178 return; |
230 | 179 |
231 SetNotifierEnabled(notifier_id, true); | 180 SetNotifierEnabled(notifier_id, true); |
232 } | 181 } |
233 #endif | 182 #endif |
234 | 183 |
235 // Unlike other permission types, granting a notification for a given origin | |
236 // will not take into account the |embedder_origin|, it will only be based | |
237 // on the requesting iframe origin. | |
238 // TODO(mukai) Consider why notifications behave differently than | |
239 // other permissions. crbug.com/416894 | |
240 void DesktopNotificationService::UpdateContentSetting( | |
241 const GURL& requesting_origin, | |
242 const GURL& embedder_origin, | |
243 ContentSetting content_setting) { | |
244 DCHECK(content_setting == CONTENT_SETTING_ALLOW || | |
245 content_setting == CONTENT_SETTING_BLOCK); | |
246 | |
247 if (content_setting == CONTENT_SETTING_ALLOW) { | |
248 DesktopNotificationProfileUtil::GrantPermission( | |
249 profile_, requesting_origin); | |
250 } else { | |
251 DesktopNotificationProfileUtil::DenyPermission(profile_, requesting_origin); | |
252 } | |
253 } | |
254 | |
255 bool DesktopNotificationService::IsRestrictedToSecureOrigins() const { | |
256 return false; | |
257 } | |
258 | |
259 void DesktopNotificationService::FirePermissionLevelChangedEvent( | 184 void DesktopNotificationService::FirePermissionLevelChangedEvent( |
260 const NotifierId& notifier_id, bool enabled) { | 185 const NotifierId& notifier_id, bool enabled) { |
261 #if defined(ENABLE_EXTENSIONS) | 186 #if defined(ENABLE_EXTENSIONS) |
262 DCHECK_EQ(NotifierId::APPLICATION, notifier_id.type); | 187 DCHECK_EQ(NotifierId::APPLICATION, notifier_id.type); |
263 extensions::api::notifications::PermissionLevel permission = | 188 extensions::api::notifications::PermissionLevel permission = |
264 enabled ? extensions::api::notifications::PERMISSION_LEVEL_GRANTED | 189 enabled ? extensions::api::notifications::PERMISSION_LEVEL_GRANTED |
265 : extensions::api::notifications::PERMISSION_LEVEL_DENIED; | 190 : extensions::api::notifications::PERMISSION_LEVEL_DENIED; |
266 scoped_ptr<base::ListValue> args(new base::ListValue()); | 191 scoped_ptr<base::ListValue> args(new base::ListValue()); |
267 args->Append(new base::StringValue( | 192 args->Append(new base::StringValue( |
268 extensions::api::notifications::ToString(permission))); | 193 extensions::api::notifications::ToString(permission))); |
269 scoped_ptr<extensions::Event> event(new extensions::Event( | 194 scoped_ptr<extensions::Event> event(new extensions::Event( |
270 extensions::events::UNKNOWN, | 195 extensions::events::UNKNOWN, |
271 extensions::api::notifications::OnPermissionLevelChanged::kEventName, | 196 extensions::api::notifications::OnPermissionLevelChanged::kEventName, |
272 args.Pass())); | 197 args.Pass())); |
273 extensions::EventRouter::Get(profile_) | 198 extensions::EventRouter::Get(profile_) |
274 ->DispatchEventToExtension(notifier_id.id, event.Pass()); | 199 ->DispatchEventToExtension(notifier_id.id, event.Pass()); |
275 | 200 |
276 // Tell the IO thread that this extension's permission for notifications | 201 // Tell the IO thread that this extension's permission for notifications |
277 // has changed. | 202 // has changed. |
278 extensions::InfoMap* extension_info_map = | 203 extensions::InfoMap* extension_info_map = |
279 extensions::ExtensionSystem::Get(profile_)->info_map(); | 204 extensions::ExtensionSystem::Get(profile_)->info_map(); |
280 BrowserThread::PostTask( | 205 BrowserThread::PostTask( |
281 BrowserThread::IO, FROM_HERE, | 206 BrowserThread::IO, FROM_HERE, |
282 base::Bind(&extensions::InfoMap::SetNotificationsDisabled, | 207 base::Bind(&extensions::InfoMap::SetNotificationsDisabled, |
283 extension_info_map, notifier_id.id, !enabled)); | 208 extension_info_map, notifier_id.id, !enabled)); |
284 #endif | 209 #endif |
285 } | 210 } |
OLD | NEW |