extension_pref_value_map.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1// Copyright (c) 2011 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/extensions/extension_pref_value_map.h"
6
7#include "base/stl_util-inl.h"
8#include "base/values.h"
9#include "chrome/browser/prefs/pref_value_map.h"
10
11struct ExtensionPrefValueMap::ExtensionEntry {
12  // Installation time of the extension.
13  base::Time install_time;
14  // Whether extension is enabled in the profile.
15  bool enabled;
16  // Regular preferences.
17  PrefValueMap reg_preferences;
18  // Incognito preferences, empty for regular ExtensionPrefStore.
19  PrefValueMap inc_preferences;
20};
21
22ExtensionPrefValueMap::ExtensionPrefValueMap() {
23}
24
25ExtensionPrefValueMap::~ExtensionPrefValueMap() {
26  NotifyOfDestruction();
27  STLDeleteValues(&entries_);
28  entries_.clear();
29}
30
31void ExtensionPrefValueMap::SetExtensionPref(const std::string& ext_id,
32                                             const std::string& key,
33                                             bool incognito,
34                                             Value* value) {
35  PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, incognito);
36
37  if (prefs->SetValue(key, value))
38    NotifyPrefValueChanged(key);
39}
40
41void ExtensionPrefValueMap::RemoveExtensionPref(const std::string& ext_id,
42                                                const std::string& key,
43                                                bool incognito) {
44  PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, incognito);
45  if (prefs->RemoveValue(key))
46    NotifyPrefValueChanged(key);
47}
48
49void ExtensionPrefValueMap::RegisterExtension(const std::string& ext_id,
50                                              const base::Time& install_time,
51                                              bool is_enabled) {
52  if (entries_.find(ext_id) != entries_.end())
53    UnregisterExtension(ext_id);
54  entries_[ext_id] = new ExtensionEntry;
55  entries_[ext_id]->install_time = install_time;
56  entries_[ext_id]->enabled = is_enabled;
57}
58
59void ExtensionPrefValueMap::UnregisterExtension(const std::string& ext_id) {
60  ExtensionEntryMap::iterator i = entries_.find(ext_id);
61  if (i == entries_.end())
62    return;
63  std::set<std::string> keys;  // keys set by this extension
64  GetExtensionControlledKeys(*(i->second), &keys);
65
66  delete i->second;
67  entries_.erase(i);
68
69  NotifyPrefValueChanged(keys);
70}
71
72void ExtensionPrefValueMap::SetExtensionState(const std::string& ext_id,
73                                              bool is_enabled) {
74  ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
75  CHECK(i != entries_.end());
76  if (i->second->enabled == is_enabled)
77    return;
78  std::set<std::string> keys;  // keys set by this extension
79  GetExtensionControlledKeys(*(i->second), &keys);
80  i->second->enabled = is_enabled;
81  NotifyPrefValueChanged(keys);
82}
83
84PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
85    const std::string& ext_id,
86    bool incognito) {
87  ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
88  CHECK(i != entries_.end());
89  return incognito ? &(i->second->inc_preferences)
90                   : &(i->second->reg_preferences);
91}
92
93const PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
94    const std::string& ext_id,
95    bool incognito) const {
96  ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
97  CHECK(i != entries_.end());
98  return incognito ? &(i->second->inc_preferences)
99                   : &(i->second->reg_preferences);
100}
101
102void ExtensionPrefValueMap::GetExtensionControlledKeys(
103    const ExtensionEntry& entry,
104    std::set<std::string>* out) const {
105  PrefValueMap::const_iterator i;
106
107  const PrefValueMap& reg_prefs = entry.reg_preferences;
108  for (i = reg_prefs.begin(); i != reg_prefs.end(); ++i)
109    out->insert(i->first);
110
111  const PrefValueMap& inc_prefs = entry.inc_preferences;
112  for (i = inc_prefs.begin(); i != inc_prefs.end(); ++i)
113    out->insert(i->first);
114}
115
116const Value* ExtensionPrefValueMap::GetEffectivePrefValue(
117    const std::string& key,
118    bool incognito) const {
119  Value *winner = NULL;
120  base::Time winners_install_time;
121
122  ExtensionEntryMap::const_iterator i;
123  for (i = entries_.begin(); i != entries_.end(); ++i) {
124    const std::string& ext_id = i->first;
125    const base::Time& install_time = i->second->install_time;
126    const bool enabled = i->second->enabled;
127
128    if (!enabled)
129      continue;
130    if (install_time < winners_install_time)
131      continue;
132
133    Value* value = NULL;
134    const PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, false);
135    if (prefs->GetValue(key, &value)) {
136      winner = value;
137      winners_install_time = install_time;
138    }
139
140    if (!incognito)
141      continue;
142
143    prefs = GetExtensionPrefValueMap(ext_id, true);
144    if (prefs->GetValue(key, &value)) {
145      winner = value;
146      winners_install_time = install_time;
147    }
148  }
149  return winner;
150}
151
152void ExtensionPrefValueMap::AddObserver(
153    ExtensionPrefValueMap::Observer* observer) {
154  observers_.AddObserver(observer);
155
156  // Collect all currently used keys and notify the new observer.
157  std::set<std::string> keys;
158  ExtensionEntryMap::const_iterator i;
159  for (i = entries_.begin(); i != entries_.end(); ++i)
160    GetExtensionControlledKeys(*(i->second), &keys);
161
162  std::set<std::string>::const_iterator j;
163  for (j = keys.begin(); j != keys.end(); ++j)
164    observer->OnPrefValueChanged(*j);
165}
166
167void ExtensionPrefValueMap::RemoveObserver(
168    ExtensionPrefValueMap::Observer* observer) {
169  observers_.RemoveObserver(observer);
170}
171
172void ExtensionPrefValueMap::NotifyInitializationCompleted() {
173  FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
174                    OnInitializationCompleted());
175}
176
177void ExtensionPrefValueMap::NotifyPrefValueChanged(
178    const std::set<std::string>& keys) {
179  std::set<std::string>::const_iterator i;
180  for (i = keys.begin(); i != keys.end(); ++i)
181    NotifyPrefValueChanged(*i);
182}
183
184void ExtensionPrefValueMap::NotifyPrefValueChanged(const std::string& key) {
185  FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
186                    OnPrefValueChanged(key));
187}
188
189void ExtensionPrefValueMap::NotifyOfDestruction() {
190  FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
191                    OnExtensionPrefValueMapDestruction());
192}
193