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 11 struct 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 22 ExtensionPrefValueMap::ExtensionPrefValueMap() { 23 } 24 25 ExtensionPrefValueMap::~ExtensionPrefValueMap() { 26 NotifyOfDestruction(); 27 STLDeleteValues(&entries_); 28 entries_.clear(); 29 } 30 31 void 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 41 void 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 49 bool ExtensionPrefValueMap::CanExtensionControlPref( 50 const std::string& extension_id, 51 const std::string& pref_key, 52 bool incognito) const { 53 ExtensionEntryMap::const_iterator ext = entries_.find(extension_id); 54 if (ext == entries_.end()) { 55 NOTREACHED(); 56 return false; 57 } 58 59 ExtensionEntryMap::const_iterator winner = 60 GetEffectivePrefValueController(pref_key, incognito, NULL); 61 if (winner == entries_.end()) 62 return true; 63 64 return winner->second->install_time <= ext->second->install_time; 65 } 66 67 bool ExtensionPrefValueMap::DoesExtensionControlPref( 68 const std::string& extension_id, 69 const std::string& pref_key, 70 bool incognito) const { 71 ExtensionEntryMap::const_iterator winner = 72 GetEffectivePrefValueController(pref_key, incognito, NULL); 73 if (winner == entries_.end()) 74 return false; 75 return winner->first == extension_id; 76 } 77 78 void ExtensionPrefValueMap::RegisterExtension(const std::string& ext_id, 79 const base::Time& install_time, 80 bool is_enabled) { 81 if (entries_.find(ext_id) != entries_.end()) 82 UnregisterExtension(ext_id); 83 entries_[ext_id] = new ExtensionEntry; 84 entries_[ext_id]->install_time = install_time; 85 entries_[ext_id]->enabled = is_enabled; 86 } 87 88 void ExtensionPrefValueMap::UnregisterExtension(const std::string& ext_id) { 89 ExtensionEntryMap::iterator i = entries_.find(ext_id); 90 if (i == entries_.end()) 91 return; 92 std::set<std::string> keys; // keys set by this extension 93 GetExtensionControlledKeys(*(i->second), &keys); 94 95 delete i->second; 96 entries_.erase(i); 97 98 NotifyPrefValueChanged(keys); 99 } 100 101 void ExtensionPrefValueMap::SetExtensionState(const std::string& ext_id, 102 bool is_enabled) { 103 ExtensionEntryMap::const_iterator i = entries_.find(ext_id); 104 CHECK(i != entries_.end()); 105 if (i->second->enabled == is_enabled) 106 return; 107 std::set<std::string> keys; // keys set by this extension 108 GetExtensionControlledKeys(*(i->second), &keys); 109 i->second->enabled = is_enabled; 110 NotifyPrefValueChanged(keys); 111 } 112 113 PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap( 114 const std::string& ext_id, 115 bool incognito) { 116 ExtensionEntryMap::const_iterator i = entries_.find(ext_id); 117 CHECK(i != entries_.end()); 118 return incognito ? &(i->second->inc_preferences) 119 : &(i->second->reg_preferences); 120 } 121 122 const PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap( 123 const std::string& ext_id, 124 bool incognito) const { 125 ExtensionEntryMap::const_iterator i = entries_.find(ext_id); 126 CHECK(i != entries_.end()); 127 return incognito ? &(i->second->inc_preferences) 128 : &(i->second->reg_preferences); 129 } 130 131 void ExtensionPrefValueMap::GetExtensionControlledKeys( 132 const ExtensionEntry& entry, 133 std::set<std::string>* out) const { 134 PrefValueMap::const_iterator i; 135 136 const PrefValueMap& reg_prefs = entry.reg_preferences; 137 for (i = reg_prefs.begin(); i != reg_prefs.end(); ++i) 138 out->insert(i->first); 139 140 const PrefValueMap& inc_prefs = entry.inc_preferences; 141 for (i = inc_prefs.begin(); i != inc_prefs.end(); ++i) 142 out->insert(i->first); 143 } 144 145 const Value* ExtensionPrefValueMap::GetEffectivePrefValue( 146 const std::string& key, 147 bool incognito, 148 bool* from_incognito) const { 149 ExtensionEntryMap::const_iterator winner = 150 GetEffectivePrefValueController(key, incognito, from_incognito); 151 if (winner == entries_.end()) 152 return NULL; 153 154 const Value* value = NULL; 155 const std::string& ext_id = winner->first; 156 if (incognito) 157 GetExtensionPrefValueMap(ext_id, true)->GetValue(key, &value); 158 if (!value) 159 GetExtensionPrefValueMap(ext_id, false)->GetValue(key, &value); 160 return value; 161 } 162 163 ExtensionPrefValueMap::ExtensionEntryMap::const_iterator 164 ExtensionPrefValueMap::GetEffectivePrefValueController( 165 const std::string& key, 166 bool incognito, 167 bool* from_incognito) const { 168 ExtensionEntryMap::const_iterator winner = entries_.end(); 169 base::Time winners_install_time; 170 171 ExtensionEntryMap::const_iterator i; 172 for (i = entries_.begin(); i != entries_.end(); ++i) { 173 const std::string& ext_id = i->first; 174 const base::Time& install_time = i->second->install_time; 175 const bool enabled = i->second->enabled; 176 177 if (!enabled) 178 continue; 179 if (install_time < winners_install_time) 180 continue; 181 182 const Value* value = NULL; 183 const PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, false); 184 if (prefs->GetValue(key, &value)) { 185 winner = i; 186 winners_install_time = install_time; 187 if (from_incognito) 188 *from_incognito = false; 189 } 190 191 if (!incognito) 192 continue; 193 194 prefs = GetExtensionPrefValueMap(ext_id, true); 195 if (prefs->GetValue(key, &value)) { 196 winner = i; 197 winners_install_time = install_time; 198 if (from_incognito) 199 *from_incognito = true; 200 } 201 } 202 return winner; 203 } 204 205 void ExtensionPrefValueMap::AddObserver( 206 ExtensionPrefValueMap::Observer* observer) { 207 observers_.AddObserver(observer); 208 209 // Collect all currently used keys and notify the new observer. 210 std::set<std::string> keys; 211 ExtensionEntryMap::const_iterator i; 212 for (i = entries_.begin(); i != entries_.end(); ++i) 213 GetExtensionControlledKeys(*(i->second), &keys); 214 215 std::set<std::string>::const_iterator j; 216 for (j = keys.begin(); j != keys.end(); ++j) 217 observer->OnPrefValueChanged(*j); 218 } 219 220 void ExtensionPrefValueMap::RemoveObserver( 221 ExtensionPrefValueMap::Observer* observer) { 222 observers_.RemoveObserver(observer); 223 } 224 225 void ExtensionPrefValueMap::NotifyInitializationCompleted() { 226 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_, 227 OnInitializationCompleted()); 228 } 229 230 void ExtensionPrefValueMap::NotifyPrefValueChanged( 231 const std::set<std::string>& keys) { 232 std::set<std::string>::const_iterator i; 233 for (i = keys.begin(); i != keys.end(); ++i) 234 NotifyPrefValueChanged(*i); 235 } 236 237 void ExtensionPrefValueMap::NotifyPrefValueChanged(const std::string& key) { 238 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_, 239 OnPrefValueChanged(key)); 240 } 241 242 void ExtensionPrefValueMap::NotifyOfDestruction() { 243 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_, 244 OnExtensionPrefValueMapDestruction()); 245 } 246