Introduce ProfilerMetricsProvider
[chromium-blink-merge.git] / chrome / browser / content_settings / content_settings_policy_provider.cc
blob13198e50137bbaacecc0a940411429d89ff47dc8
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
3 // found in the LICENSE file.
5 #include "chrome/browser/content_settings/content_settings_policy_provider.h"
7 #include <string>
8 #include <vector>
10 #include "base/json/json_reader.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/values.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/content_settings/content_settings_rule.h"
15 #include "chrome/browser/content_settings/content_settings_utils.h"
16 #include "chrome/common/content_settings_pattern.h"
17 #include "chrome/common/pref_names.h"
18 #include "components/pref_registry/pref_registry_syncable.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/notification_details.h"
21 #include "content/public/browser/notification_source.h"
23 using content::BrowserThread;
25 namespace {
27 // The preferences used to manage ContentSettingsTypes.
28 const char* kPrefToManageType[] = {
29 prefs::kManagedDefaultCookiesSetting,
30 prefs::kManagedDefaultImagesSetting,
31 prefs::kManagedDefaultJavaScriptSetting,
32 prefs::kManagedDefaultPluginsSetting,
33 prefs::kManagedDefaultPopupsSetting,
34 prefs::kManagedDefaultGeolocationSetting,
35 prefs::kManagedDefaultNotificationsSetting,
36 NULL, // No policy for default value of content type auto-select-certificate
37 NULL, // No policy for default value of fullscreen requests
38 NULL, // No policy for default value of mouse lock requests
39 NULL, // No policy for default value of mixed script blocking
40 prefs::kManagedDefaultMediaStreamSetting,
41 NULL, // No policy for default value of media stream mic
42 NULL, // No policy for default value of media stream camera
43 NULL, // No policy for default value of protocol handlers
44 NULL, // No policy for default value of PPAPI broker
45 NULL, // No policy for default value of multiple automatic downloads
46 NULL, // No policy for default value of MIDI system exclusive requests
47 #if defined(OS_WIN)
48 NULL, // No policy for default value of "switch to desktop"
49 #elif defined(OS_ANDROID) || defined(OS_CHROMEOS)
50 NULL, // No policy for default value of protected media identifier
51 #endif
52 #if defined(OS_ANDROID)
53 NULL, // No policy for default value of app banners
54 #endif
56 COMPILE_ASSERT(arraysize(kPrefToManageType) == CONTENT_SETTINGS_NUM_TYPES,
57 managed_content_settings_pref_names_array_size_incorrect);
59 struct PrefsForManagedContentSettingsMapEntry {
60 const char* pref_name;
61 ContentSettingsType content_type;
62 ContentSetting setting;
65 const PrefsForManagedContentSettingsMapEntry
66 kPrefsForManagedContentSettingsMap[] = {
68 prefs::kManagedCookiesAllowedForUrls,
69 CONTENT_SETTINGS_TYPE_COOKIES,
70 CONTENT_SETTING_ALLOW
71 }, {
72 prefs::kManagedCookiesSessionOnlyForUrls,
73 CONTENT_SETTINGS_TYPE_COOKIES,
74 CONTENT_SETTING_SESSION_ONLY
75 }, {
76 prefs::kManagedCookiesBlockedForUrls,
77 CONTENT_SETTINGS_TYPE_COOKIES,
78 CONTENT_SETTING_BLOCK
79 }, {
80 prefs::kManagedImagesAllowedForUrls,
81 CONTENT_SETTINGS_TYPE_IMAGES,
82 CONTENT_SETTING_ALLOW
83 }, {
84 prefs::kManagedImagesBlockedForUrls,
85 CONTENT_SETTINGS_TYPE_IMAGES,
86 CONTENT_SETTING_BLOCK
87 }, {
88 prefs::kManagedJavaScriptAllowedForUrls,
89 CONTENT_SETTINGS_TYPE_JAVASCRIPT,
90 CONTENT_SETTING_ALLOW
91 }, {
92 prefs::kManagedJavaScriptBlockedForUrls,
93 CONTENT_SETTINGS_TYPE_JAVASCRIPT,
94 CONTENT_SETTING_BLOCK
95 }, {
96 prefs::kManagedPluginsAllowedForUrls,
97 CONTENT_SETTINGS_TYPE_PLUGINS,
98 CONTENT_SETTING_ALLOW
99 }, {
100 prefs::kManagedPluginsBlockedForUrls,
101 CONTENT_SETTINGS_TYPE_PLUGINS,
102 CONTENT_SETTING_BLOCK
103 }, {
104 prefs::kManagedPopupsAllowedForUrls,
105 CONTENT_SETTINGS_TYPE_POPUPS,
106 CONTENT_SETTING_ALLOW
107 }, {
108 prefs::kManagedPopupsBlockedForUrls,
109 CONTENT_SETTINGS_TYPE_POPUPS,
110 CONTENT_SETTING_BLOCK
111 }, {
112 prefs::kManagedNotificationsAllowedForUrls,
113 CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
114 CONTENT_SETTING_ALLOW
115 }, {
116 prefs::kManagedNotificationsBlockedForUrls,
117 CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
118 CONTENT_SETTING_BLOCK
122 } // namespace
124 namespace content_settings {
126 // static
127 void PolicyProvider::RegisterProfilePrefs(
128 user_prefs::PrefRegistrySyncable* registry) {
129 registry->RegisterListPref(prefs::kManagedAutoSelectCertificateForUrls,
130 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
131 registry->RegisterListPref(prefs::kManagedCookiesAllowedForUrls,
132 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
133 registry->RegisterListPref(prefs::kManagedCookiesBlockedForUrls,
134 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
135 registry->RegisterListPref(prefs::kManagedCookiesSessionOnlyForUrls,
136 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
137 registry->RegisterListPref(prefs::kManagedImagesAllowedForUrls,
138 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
139 registry->RegisterListPref(prefs::kManagedImagesBlockedForUrls,
140 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
141 registry->RegisterListPref(prefs::kManagedJavaScriptAllowedForUrls,
142 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
143 registry->RegisterListPref(prefs::kManagedJavaScriptBlockedForUrls,
144 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
145 registry->RegisterListPref(prefs::kManagedPluginsAllowedForUrls,
146 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
147 registry->RegisterListPref(prefs::kManagedPluginsBlockedForUrls,
148 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
149 registry->RegisterListPref(prefs::kManagedPopupsAllowedForUrls,
150 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
151 registry->RegisterListPref(prefs::kManagedPopupsBlockedForUrls,
152 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
153 registry->RegisterListPref(prefs::kManagedNotificationsAllowedForUrls,
154 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
155 registry->RegisterListPref(prefs::kManagedNotificationsBlockedForUrls,
156 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
157 // Preferences for default content setting policies. If a policy is not set of
158 // the corresponding preferences below is set to CONTENT_SETTING_DEFAULT.
159 registry->RegisterIntegerPref(
160 prefs::kManagedDefaultCookiesSetting,
161 CONTENT_SETTING_DEFAULT,
162 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
163 registry->RegisterIntegerPref(
164 prefs::kManagedDefaultImagesSetting,
165 CONTENT_SETTING_DEFAULT,
166 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
167 registry->RegisterIntegerPref(
168 prefs::kManagedDefaultJavaScriptSetting,
169 CONTENT_SETTING_DEFAULT,
170 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
171 registry->RegisterIntegerPref(
172 prefs::kManagedDefaultPluginsSetting,
173 CONTENT_SETTING_DEFAULT,
174 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
175 registry->RegisterIntegerPref(
176 prefs::kManagedDefaultPopupsSetting,
177 CONTENT_SETTING_DEFAULT,
178 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
179 registry->RegisterIntegerPref(
180 prefs::kManagedDefaultGeolocationSetting,
181 CONTENT_SETTING_DEFAULT,
182 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
183 registry->RegisterIntegerPref(
184 prefs::kManagedDefaultNotificationsSetting,
185 CONTENT_SETTING_DEFAULT,
186 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
187 registry->RegisterIntegerPref(
188 prefs::kManagedDefaultMediaStreamSetting,
189 CONTENT_SETTING_DEFAULT,
190 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
193 PolicyProvider::PolicyProvider(PrefService* prefs) : prefs_(prefs) {
194 ReadManagedDefaultSettings();
195 ReadManagedContentSettings(false);
197 pref_change_registrar_.Init(prefs_);
198 PrefChangeRegistrar::NamedChangeCallback callback =
199 base::Bind(&PolicyProvider::OnPreferenceChanged, base::Unretained(this));
200 pref_change_registrar_.Add(
201 prefs::kManagedAutoSelectCertificateForUrls, callback);
202 pref_change_registrar_.Add(prefs::kManagedCookiesBlockedForUrls, callback);
203 pref_change_registrar_.Add(prefs::kManagedCookiesAllowedForUrls, callback);
204 pref_change_registrar_.Add(
205 prefs::kManagedCookiesSessionOnlyForUrls, callback);
206 pref_change_registrar_.Add(prefs::kManagedImagesBlockedForUrls, callback);
207 pref_change_registrar_.Add(prefs::kManagedImagesAllowedForUrls, callback);
208 pref_change_registrar_.Add(prefs::kManagedJavaScriptBlockedForUrls, callback);
209 pref_change_registrar_.Add(prefs::kManagedJavaScriptAllowedForUrls, callback);
210 pref_change_registrar_.Add(prefs::kManagedPluginsBlockedForUrls, callback);
211 pref_change_registrar_.Add(prefs::kManagedPluginsAllowedForUrls, callback);
212 pref_change_registrar_.Add(prefs::kManagedPopupsBlockedForUrls, callback);
213 pref_change_registrar_.Add(prefs::kManagedPopupsAllowedForUrls, callback);
214 pref_change_registrar_.Add(
215 prefs::kManagedNotificationsAllowedForUrls, callback);
216 pref_change_registrar_.Add(
217 prefs::kManagedNotificationsBlockedForUrls, callback);
218 // The following preferences are only used to indicate if a
219 // default content setting is managed and to hold the managed default setting
220 // value. If the value for any of the following perferences is set then the
221 // corresponding default content setting is managed. These preferences exist
222 // in parallel to the preference default content settings. If a
223 // default content settings type is managed any user defined excpetions
224 // (patterns) for this type are ignored.
225 pref_change_registrar_.Add(prefs::kManagedDefaultCookiesSetting, callback);
226 pref_change_registrar_.Add(prefs::kManagedDefaultImagesSetting, callback);
227 pref_change_registrar_.Add(prefs::kManagedDefaultJavaScriptSetting, callback);
228 pref_change_registrar_.Add(prefs::kManagedDefaultPluginsSetting, callback);
229 pref_change_registrar_.Add(prefs::kManagedDefaultPopupsSetting, callback);
230 pref_change_registrar_.Add(
231 prefs::kManagedDefaultGeolocationSetting, callback);
232 pref_change_registrar_.Add(
233 prefs::kManagedDefaultNotificationsSetting, callback);
234 pref_change_registrar_.Add(
235 prefs::kManagedDefaultMediaStreamSetting, callback);
238 PolicyProvider::~PolicyProvider() {
239 DCHECK(!prefs_);
242 RuleIterator* PolicyProvider::GetRuleIterator(
243 ContentSettingsType content_type,
244 const ResourceIdentifier& resource_identifier,
245 bool incognito) const {
246 return value_map_.GetRuleIterator(content_type, resource_identifier, &lock_);
249 void PolicyProvider::GetContentSettingsFromPreferences(
250 OriginIdentifierValueMap* value_map) {
251 for (size_t i = 0; i < arraysize(kPrefsForManagedContentSettingsMap); ++i) {
252 const char* pref_name = kPrefsForManagedContentSettingsMap[i].pref_name;
253 // Skip unset policies.
254 if (!prefs_->HasPrefPath(pref_name)) {
255 VLOG(2) << "Skipping unset preference: " << pref_name;
256 continue;
259 const PrefService::Preference* pref = prefs_->FindPreference(pref_name);
260 DCHECK(pref);
261 DCHECK(pref->IsManaged());
263 const base::ListValue* pattern_str_list = NULL;
264 if (!pref->GetValue()->GetAsList(&pattern_str_list)) {
265 NOTREACHED();
266 return;
269 for (size_t j = 0; j < pattern_str_list->GetSize(); ++j) {
270 std::string original_pattern_str;
271 if (!pattern_str_list->GetString(j, &original_pattern_str)) {
272 NOTREACHED();
273 continue;
276 PatternPair pattern_pair = ParsePatternString(original_pattern_str);
277 // Ignore invalid patterns.
278 if (!pattern_pair.first.IsValid()) {
279 VLOG(1) << "Ignoring invalid content settings pattern: " <<
280 original_pattern_str;
281 continue;
284 ContentSettingsType content_type =
285 kPrefsForManagedContentSettingsMap[i].content_type;
286 DCHECK_NE(content_type, CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE);
287 // If only one pattern was defined auto expand it to a pattern pair.
288 ContentSettingsPattern secondary_pattern =
289 !pattern_pair.second.IsValid() ? ContentSettingsPattern::Wildcard()
290 : pattern_pair.second;
291 value_map->SetValue(
292 pattern_pair.first,
293 secondary_pattern,
294 content_type,
295 NO_RESOURCE_IDENTIFIER,
296 base::Value::CreateIntegerValue(
297 kPrefsForManagedContentSettingsMap[i].setting));
302 void PolicyProvider::GetAutoSelectCertificateSettingsFromPreferences(
303 OriginIdentifierValueMap* value_map) {
304 const char* pref_name = prefs::kManagedAutoSelectCertificateForUrls;
306 if (!prefs_->HasPrefPath(pref_name)) {
307 VLOG(2) << "Skipping unset preference: " << pref_name;
308 return;
311 const PrefService::Preference* pref = prefs_->FindPreference(pref_name);
312 DCHECK(pref);
313 DCHECK(pref->IsManaged());
315 const base::ListValue* pattern_filter_str_list = NULL;
316 if (!pref->GetValue()->GetAsList(&pattern_filter_str_list)) {
317 NOTREACHED();
318 return;
321 // Parse the list of pattern filter strings. A pattern filter string has
322 // the following JSON format:
324 // {
325 // "pattern": <content settings pattern string>,
326 // "filter" : <certificate filter in JSON format>
327 // }
329 // e.g.
330 // {
331 // "pattern": "[*.]example.com",
332 // "filter": {
333 // "ISSUER": {
334 // "CN": "some name"
335 // }
336 // }
337 // }
338 for (size_t j = 0; j < pattern_filter_str_list->GetSize(); ++j) {
339 std::string pattern_filter_json;
340 if (!pattern_filter_str_list->GetString(j, &pattern_filter_json)) {
341 NOTREACHED();
342 continue;
345 scoped_ptr<base::Value> value(base::JSONReader::Read(pattern_filter_json,
346 base::JSON_ALLOW_TRAILING_COMMAS));
347 if (!value || !value->IsType(base::Value::TYPE_DICTIONARY)) {
348 VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:"
349 " Invalid JSON object: " << pattern_filter_json;
350 continue;
353 scoped_ptr<base::DictionaryValue> pattern_filter_pair(
354 static_cast<base::DictionaryValue*>(value.release()));
355 std::string pattern_str;
356 bool pattern_read = pattern_filter_pair->GetString("pattern", &pattern_str);
357 scoped_ptr<base::Value> cert_filter;
358 bool filter_read = pattern_filter_pair->Remove("filter", &cert_filter);
359 if (!pattern_read || !filter_read ||
360 !cert_filter->IsType(base::Value::TYPE_DICTIONARY)) {
361 VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:"
362 " Missing pattern or filter.";
363 continue;
366 ContentSettingsPattern pattern =
367 ContentSettingsPattern::FromString(pattern_str);
368 // Ignore invalid patterns.
369 if (!pattern.IsValid()) {
370 VLOG(1) << "Ignoring invalid certificate auto select setting:"
371 " Invalid content settings pattern: " << pattern;
372 continue;
375 value_map->SetValue(pattern,
376 ContentSettingsPattern::Wildcard(),
377 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
378 std::string(),
379 cert_filter.release());
383 void PolicyProvider::ReadManagedDefaultSettings() {
384 for (size_t type = 0; type < arraysize(kPrefToManageType); ++type) {
385 if (kPrefToManageType[type] == NULL) {
386 continue;
388 UpdateManagedDefaultSetting(ContentSettingsType(type));
392 void PolicyProvider::UpdateManagedDefaultSetting(
393 ContentSettingsType content_type) {
394 // If a pref to manage a default-content-setting was not set (NOTICE:
395 // "HasPrefPath" returns false if no value was set for a registered pref) then
396 // the default value of the preference is used. The default value of a
397 // preference to manage a default-content-settings is CONTENT_SETTING_DEFAULT.
398 // This indicates that no managed value is set. If a pref was set, than it
399 // MUST be managed.
400 DCHECK(!prefs_->HasPrefPath(kPrefToManageType[content_type]) ||
401 prefs_->IsManagedPreference(kPrefToManageType[content_type]));
402 base::AutoLock auto_lock(lock_);
404 int setting = prefs_->GetInteger(kPrefToManageType[content_type]);
405 if (setting == CONTENT_SETTING_DEFAULT) {
406 value_map_.DeleteValue(
407 ContentSettingsPattern::Wildcard(),
408 ContentSettingsPattern::Wildcard(),
409 content_type,
410 std::string());
411 } else {
412 value_map_.SetValue(
413 ContentSettingsPattern::Wildcard(),
414 ContentSettingsPattern::Wildcard(),
415 content_type,
416 std::string(),
417 base::Value::CreateIntegerValue(setting));
422 void PolicyProvider::ReadManagedContentSettings(bool overwrite) {
423 base::AutoLock auto_lock(lock_);
424 if (overwrite)
425 value_map_.clear();
426 GetContentSettingsFromPreferences(&value_map_);
427 GetAutoSelectCertificateSettingsFromPreferences(&value_map_);
430 // Since the PolicyProvider is a read only content settings provider, all
431 // methodes of the ProviderInterface that set or delete any settings do nothing.
432 bool PolicyProvider::SetWebsiteSetting(
433 const ContentSettingsPattern& primary_pattern,
434 const ContentSettingsPattern& secondary_pattern,
435 ContentSettingsType content_type,
436 const ResourceIdentifier& resource_identifier,
437 base::Value* value) {
438 return false;
441 void PolicyProvider::ClearAllContentSettingsRules(
442 ContentSettingsType content_type) {
445 void PolicyProvider::ShutdownOnUIThread() {
446 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
447 RemoveAllObservers();
448 if (!prefs_)
449 return;
450 pref_change_registrar_.RemoveAll();
451 prefs_ = NULL;
454 void PolicyProvider::OnPreferenceChanged(const std::string& name) {
455 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
457 if (name == prefs::kManagedDefaultCookiesSetting) {
458 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES);
459 } else if (name == prefs::kManagedDefaultImagesSetting) {
460 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_IMAGES);
461 } else if (name == prefs::kManagedDefaultJavaScriptSetting) {
462 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
463 } else if (name == prefs::kManagedDefaultPluginsSetting) {
464 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_PLUGINS);
465 } else if (name == prefs::kManagedDefaultPopupsSetting) {
466 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_POPUPS);
467 } else if (name == prefs::kManagedDefaultGeolocationSetting) {
468 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION);
469 } else if (name == prefs::kManagedDefaultNotificationsSetting) {
470 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
471 } else if (name == prefs::kManagedDefaultMediaStreamSetting) {
472 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM);
473 } else if (name == prefs::kManagedAutoSelectCertificateForUrls ||
474 name == prefs::kManagedCookiesAllowedForUrls ||
475 name == prefs::kManagedCookiesBlockedForUrls ||
476 name == prefs::kManagedCookiesSessionOnlyForUrls ||
477 name == prefs::kManagedImagesAllowedForUrls ||
478 name == prefs::kManagedImagesBlockedForUrls ||
479 name == prefs::kManagedJavaScriptAllowedForUrls ||
480 name == prefs::kManagedJavaScriptBlockedForUrls ||
481 name == prefs::kManagedPluginsAllowedForUrls ||
482 name == prefs::kManagedPluginsBlockedForUrls ||
483 name == prefs::kManagedPopupsAllowedForUrls ||
484 name == prefs::kManagedPopupsBlockedForUrls ||
485 name == prefs::kManagedNotificationsAllowedForUrls ||
486 name == prefs::kManagedNotificationsBlockedForUrls) {
487 ReadManagedContentSettings(true);
488 ReadManagedDefaultSettings();
491 NotifyObservers(ContentSettingsPattern(),
492 ContentSettingsPattern(),
493 CONTENT_SETTINGS_TYPE_DEFAULT,
494 std::string());
497 } // namespace content_settings