1// Copyright 2014 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.
4
5#include "chrome/browser/content_settings/content_settings_override_provider.h"
6
7#include <string>
8
9#include "base/auto_reset.h"
10#include "base/prefs/pref_service.h"
11#include "base/prefs/scoped_user_pref_update.h"
12#include "base/values.h"
13#include "chrome/browser/content_settings/content_settings_utils.h"
14#include "chrome/common/pref_names.h"
15#include "components/content_settings/core/browser/content_settings_rule.h"
16#include "components/content_settings/core/common/content_settings.h"
17#include "components/content_settings/core/common/content_settings_pattern.h"
18#include "components/pref_registry/pref_registry_syncable.h"
19#include "content/public/browser/browser_thread.h"
20
21using content::BrowserThread;
22
23namespace content_settings {
24
25namespace {
26
27class OverrideRuleIterator : public RuleIterator {
28 public:
29  explicit OverrideRuleIterator(bool is_allowed) : is_done_(is_allowed) {}
30
31  virtual bool HasNext() const OVERRIDE { return !is_done_; }
32
33  virtual Rule Next() OVERRIDE {
34    DCHECK(!is_done_);
35    is_done_ = true;
36    return Rule(ContentSettingsPattern::Wildcard(),
37                ContentSettingsPattern::Wildcard(),
38                new base::FundamentalValue(CONTENT_SETTING_BLOCK));
39  }
40
41 private:
42  bool is_done_;
43};
44
45}  // namespace
46
47// static
48void OverrideProvider::RegisterProfilePrefs(
49    user_prefs::PrefRegistrySyncable* registry) {
50  registry->RegisterDictionaryPref(
51      prefs::kOverrideContentSettings,
52      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
53}
54
55OverrideProvider::OverrideProvider(PrefService* prefs, bool incognito)
56    : prefs_(prefs), is_incognito_(incognito) {
57  DCHECK(prefs_);
58
59  // Read global overrides.
60  ReadOverrideSettings();
61}
62
63OverrideProvider::~OverrideProvider() {
64}
65
66RuleIterator* OverrideProvider::GetRuleIterator(
67    ContentSettingsType content_type,
68    const ResourceIdentifier& resource_identifier,
69    bool incognito) const {
70  base::AutoLock lock(lock_);
71  if (resource_identifier.empty()) {
72    return new OverrideRuleIterator(allowed_settings_[content_type]);
73  }
74  return new EmptyRuleIterator();
75}
76
77void OverrideProvider::ClearAllContentSettingsRules(
78    ContentSettingsType content_type) {
79}
80
81bool OverrideProvider::SetWebsiteSetting(
82    const ContentSettingsPattern& primary_pattern,
83    const ContentSettingsPattern& secondary_pattern,
84    ContentSettingsType content_type,
85    const ResourceIdentifier& resource_identifier,
86    base::Value* in_value) {
87  return false;
88}
89
90void OverrideProvider::ShutdownOnUIThread() {
91  DCHECK(prefs_);
92  prefs_ = NULL;
93}
94
95void OverrideProvider::SetOverrideSetting(ContentSettingsType content_type,
96                                          bool enabled) {
97  DCHECK_CURRENTLY_ON(BrowserThread::UI);
98  DCHECK(prefs_);
99
100  // Disallow incognito to change the state.
101  DCHECK(!is_incognito_);
102
103  base::AutoLock lock(lock_);
104  DictionaryPrefUpdate update(prefs_, prefs::kOverrideContentSettings);
105  base::DictionaryValue* default_settings_dictionary = update.Get();
106  if (enabled) {
107    allowed_settings_[content_type] = true;
108    default_settings_dictionary->RemoveWithoutPathExpansion(
109        GetTypeName(content_type), NULL);
110  } else {
111    allowed_settings_[content_type] = false;
112    default_settings_dictionary->SetWithoutPathExpansion(
113        GetTypeName(content_type), new base::FundamentalValue(true));
114  }
115}
116
117bool OverrideProvider::IsEnabled(ContentSettingsType content_type) const {
118  base::AutoLock lock(lock_);
119  return allowed_settings_[content_type];
120}
121
122void OverrideProvider::ReadOverrideSettings() {
123  DCHECK_CURRENTLY_ON(BrowserThread::UI);
124  const base::DictionaryValue* blocked_settings_dictionary =
125      prefs_->GetDictionary(prefs::kOverrideContentSettings);
126
127  for (int type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) {
128    ContentSettingsType content_setting = ContentSettingsType(type);
129    allowed_settings_[content_setting] =
130        !blocked_settings_dictionary->HasKey(GetTypeName(content_setting));
131  }
132}
133
134}  // namespace content_settings
135