| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "chrome/browser/extensions/extension_pref_value_map.h" | |
| 6 | |
| 7 #include "base/prefs/pref_value_map.h" | |
| 8 #include "base/stl_util.h" | |
| 9 #include "base/values.h" | |
| 10 | |
| 11 using extensions::ExtensionPrefsScope; | |
| 12 | |
| 13 struct ExtensionPrefValueMap::ExtensionEntry { | |
| 14 // Installation time of the extension. | |
| 15 base::Time install_time; | |
| 16 // Whether extension is enabled in the profile. | |
| 17 bool enabled; | |
| 18 // Extension controlled preferences for the regular profile. | |
| 19 PrefValueMap regular_profile_preferences; | |
| 20 // Extension controlled preferences that should *only* apply to the regular | |
| 21 // profile. | |
| 22 PrefValueMap regular_only_profile_preferences; | |
| 23 // Persistent extension controlled preferences for the incognito profile, | |
| 24 // empty for regular profile ExtensionPrefStore. | |
| 25 PrefValueMap incognito_profile_preferences_persistent; | |
| 26 // Session only extension controlled preferences for the incognito profile. | |
| 27 // These preferences are deleted when the incognito profile is destroyed. | |
| 28 PrefValueMap incognito_profile_preferences_session_only; | |
| 29 }; | |
| 30 | |
| 31 ExtensionPrefValueMap::ExtensionPrefValueMap() : destroyed_(false) { | |
| 32 } | |
| 33 | |
| 34 ExtensionPrefValueMap::~ExtensionPrefValueMap() { | |
| 35 if (!destroyed_) { | |
| 36 NotifyOfDestruction(); | |
| 37 destroyed_ = true; | |
| 38 } | |
| 39 STLDeleteValues(&entries_); | |
| 40 entries_.clear(); | |
| 41 } | |
| 42 | |
| 43 void ExtensionPrefValueMap::Shutdown() { | |
| 44 NotifyOfDestruction(); | |
| 45 destroyed_ = true; | |
| 46 } | |
| 47 | |
| 48 void ExtensionPrefValueMap::SetExtensionPref(const std::string& ext_id, | |
| 49 const std::string& key, | |
| 50 ExtensionPrefsScope scope, | |
| 51 base::Value* value) { | |
| 52 PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope); | |
| 53 | |
| 54 if (prefs->SetValue(key, value)) | |
| 55 NotifyPrefValueChanged(key); | |
| 56 } | |
| 57 | |
| 58 void ExtensionPrefValueMap::RemoveExtensionPref( | |
| 59 const std::string& ext_id, | |
| 60 const std::string& key, | |
| 61 ExtensionPrefsScope scope) { | |
| 62 PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope); | |
| 63 if (prefs->RemoveValue(key)) | |
| 64 NotifyPrefValueChanged(key); | |
| 65 } | |
| 66 | |
| 67 bool ExtensionPrefValueMap::CanExtensionControlPref( | |
| 68 const std::string& extension_id, | |
| 69 const std::string& pref_key, | |
| 70 bool incognito) const { | |
| 71 ExtensionEntryMap::const_iterator ext = entries_.find(extension_id); | |
| 72 if (ext == entries_.end()) { | |
| 73 NOTREACHED(); | |
| 74 return false; | |
| 75 } | |
| 76 | |
| 77 ExtensionEntryMap::const_iterator winner = | |
| 78 GetEffectivePrefValueController(pref_key, incognito, NULL); | |
| 79 if (winner == entries_.end()) | |
| 80 return true; | |
| 81 | |
| 82 return winner->second->install_time <= ext->second->install_time; | |
| 83 } | |
| 84 | |
| 85 void ExtensionPrefValueMap::ClearAllIncognitoSessionOnlyPreferences() { | |
| 86 typedef std::set<std::string> KeySet; | |
| 87 KeySet deleted_keys; | |
| 88 | |
| 89 ExtensionEntryMap::iterator i; | |
| 90 for (i = entries_.begin(); i != entries_.end(); ++i) { | |
| 91 PrefValueMap& inc_prefs = | |
| 92 i->second->incognito_profile_preferences_session_only; | |
| 93 PrefValueMap::iterator j; | |
| 94 for (j = inc_prefs.begin(); j != inc_prefs.end(); ++j) | |
| 95 deleted_keys.insert(j->first); | |
| 96 inc_prefs.Clear(); | |
| 97 } | |
| 98 | |
| 99 KeySet::iterator k; | |
| 100 for (k = deleted_keys.begin(); k != deleted_keys.end(); ++k) | |
| 101 NotifyPrefValueChanged(*k); | |
| 102 } | |
| 103 | |
| 104 bool ExtensionPrefValueMap::DoesExtensionControlPref( | |
| 105 const std::string& extension_id, | |
| 106 const std::string& pref_key, | |
| 107 bool* from_incognito) const { | |
| 108 bool incognito = (from_incognito != NULL); | |
| 109 ExtensionEntryMap::const_iterator winner = | |
| 110 GetEffectivePrefValueController(pref_key, incognito, from_incognito); | |
| 111 if (winner == entries_.end()) | |
| 112 return false; | |
| 113 return winner->first == extension_id; | |
| 114 } | |
| 115 | |
| 116 void ExtensionPrefValueMap::RegisterExtension(const std::string& ext_id, | |
| 117 const base::Time& install_time, | |
| 118 bool is_enabled) { | |
| 119 if (entries_.find(ext_id) == entries_.end()) { | |
| 120 entries_[ext_id] = new ExtensionEntry; | |
| 121 | |
| 122 // Only update the install time if the extension is newly installed. | |
| 123 entries_[ext_id]->install_time = install_time; | |
| 124 } | |
| 125 | |
| 126 entries_[ext_id]->enabled = is_enabled; | |
| 127 } | |
| 128 | |
| 129 void ExtensionPrefValueMap::UnregisterExtension(const std::string& ext_id) { | |
| 130 ExtensionEntryMap::iterator i = entries_.find(ext_id); | |
| 131 if (i == entries_.end()) | |
| 132 return; | |
| 133 std::set<std::string> keys; // keys set by this extension | |
| 134 GetExtensionControlledKeys(*(i->second), &keys); | |
| 135 | |
| 136 delete i->second; | |
| 137 entries_.erase(i); | |
| 138 | |
| 139 NotifyPrefValueChanged(keys); | |
| 140 } | |
| 141 | |
| 142 void ExtensionPrefValueMap::SetExtensionState(const std::string& ext_id, | |
| 143 bool is_enabled) { | |
| 144 ExtensionEntryMap::const_iterator i = entries_.find(ext_id); | |
| 145 // This may happen when sync sets the extension state for an | |
| 146 // extension that is not installed. | |
| 147 if (i == entries_.end()) | |
| 148 return; | |
| 149 if (i->second->enabled == is_enabled) | |
| 150 return; | |
| 151 std::set<std::string> keys; // keys set by this extension | |
| 152 GetExtensionControlledKeys(*(i->second), &keys); | |
| 153 i->second->enabled = is_enabled; | |
| 154 NotifyPrefValueChanged(keys); | |
| 155 } | |
| 156 | |
| 157 PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap( | |
| 158 const std::string& ext_id, | |
| 159 ExtensionPrefsScope scope) { | |
| 160 ExtensionEntryMap::const_iterator i = entries_.find(ext_id); | |
| 161 CHECK(i != entries_.end()); | |
| 162 switch (scope) { | |
| 163 case extensions::kExtensionPrefsScopeRegular: | |
| 164 return &(i->second->regular_profile_preferences); | |
| 165 case extensions::kExtensionPrefsScopeRegularOnly: | |
| 166 return &(i->second->regular_only_profile_preferences); | |
| 167 case extensions::kExtensionPrefsScopeIncognitoPersistent: | |
| 168 return &(i->second->incognito_profile_preferences_persistent); | |
| 169 case extensions::kExtensionPrefsScopeIncognitoSessionOnly: | |
| 170 return &(i->second->incognito_profile_preferences_session_only); | |
| 171 } | |
| 172 NOTREACHED(); | |
| 173 return NULL; | |
| 174 } | |
| 175 | |
| 176 const PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap( | |
| 177 const std::string& ext_id, | |
| 178 ExtensionPrefsScope scope) const { | |
| 179 ExtensionEntryMap::const_iterator i = entries_.find(ext_id); | |
| 180 CHECK(i != entries_.end()); | |
| 181 switch (scope) { | |
| 182 case extensions::kExtensionPrefsScopeRegular: | |
| 183 return &(i->second->regular_profile_preferences); | |
| 184 case extensions::kExtensionPrefsScopeRegularOnly: | |
| 185 return &(i->second->regular_only_profile_preferences); | |
| 186 case extensions::kExtensionPrefsScopeIncognitoPersistent: | |
| 187 return &(i->second->incognito_profile_preferences_persistent); | |
| 188 case extensions::kExtensionPrefsScopeIncognitoSessionOnly: | |
| 189 return &(i->second->incognito_profile_preferences_session_only); | |
| 190 } | |
| 191 NOTREACHED(); | |
| 192 return NULL; | |
| 193 } | |
| 194 | |
| 195 void ExtensionPrefValueMap::GetExtensionControlledKeys( | |
| 196 const ExtensionEntry& entry, | |
| 197 std::set<std::string>* out) const { | |
| 198 PrefValueMap::const_iterator i; | |
| 199 | |
| 200 const PrefValueMap& regular_prefs = entry.regular_profile_preferences; | |
| 201 for (i = regular_prefs.begin(); i != regular_prefs.end(); ++i) | |
| 202 out->insert(i->first); | |
| 203 | |
| 204 const PrefValueMap& regular_only_prefs = | |
| 205 entry.regular_only_profile_preferences; | |
| 206 for (i = regular_only_prefs.begin(); i != regular_only_prefs.end(); ++i) | |
| 207 out->insert(i->first); | |
| 208 | |
| 209 const PrefValueMap& inc_prefs_pers = | |
| 210 entry.incognito_profile_preferences_persistent; | |
| 211 for (i = inc_prefs_pers.begin(); i != inc_prefs_pers.end(); ++i) | |
| 212 out->insert(i->first); | |
| 213 | |
| 214 const PrefValueMap& inc_prefs_session = | |
| 215 entry.incognito_profile_preferences_session_only; | |
| 216 for (i = inc_prefs_session.begin(); i != inc_prefs_session.end(); ++i) | |
| 217 out->insert(i->first); | |
| 218 } | |
| 219 | |
| 220 const base::Value* ExtensionPrefValueMap::GetEffectivePrefValue( | |
| 221 const std::string& key, | |
| 222 bool incognito, | |
| 223 bool* from_incognito) const { | |
| 224 ExtensionEntryMap::const_iterator winner = | |
| 225 GetEffectivePrefValueController(key, incognito, from_incognito); | |
| 226 if (winner == entries_.end()) | |
| 227 return NULL; | |
| 228 | |
| 229 const base::Value* value = NULL; | |
| 230 const std::string& ext_id = winner->first; | |
| 231 | |
| 232 // First search for incognito session only preferences. | |
| 233 if (incognito) { | |
| 234 const PrefValueMap* prefs = GetExtensionPrefValueMap( | |
| 235 ext_id, extensions::kExtensionPrefsScopeIncognitoSessionOnly); | |
| 236 prefs->GetValue(key, &value); | |
| 237 if (value) | |
| 238 return value; | |
| 239 | |
| 240 // If no incognito session only preference exists, fall back to persistent | |
| 241 // incognito preference. | |
| 242 prefs = GetExtensionPrefValueMap( | |
| 243 ext_id, | |
| 244 extensions::kExtensionPrefsScopeIncognitoPersistent); | |
| 245 prefs->GetValue(key, &value); | |
| 246 if (value) | |
| 247 return value; | |
| 248 } else { | |
| 249 // Regular-only preference. | |
| 250 const PrefValueMap* prefs = GetExtensionPrefValueMap( | |
| 251 ext_id, extensions::kExtensionPrefsScopeRegularOnly); | |
| 252 prefs->GetValue(key, &value); | |
| 253 if (value) | |
| 254 return value; | |
| 255 } | |
| 256 | |
| 257 // Regular preference. | |
| 258 const PrefValueMap* prefs = GetExtensionPrefValueMap( | |
| 259 ext_id, extensions::kExtensionPrefsScopeRegular); | |
| 260 prefs->GetValue(key, &value); | |
| 261 return value; | |
| 262 } | |
| 263 | |
| 264 ExtensionPrefValueMap::ExtensionEntryMap::const_iterator | |
| 265 ExtensionPrefValueMap::GetEffectivePrefValueController( | |
| 266 const std::string& key, | |
| 267 bool incognito, | |
| 268 bool* from_incognito) const { | |
| 269 ExtensionEntryMap::const_iterator winner = entries_.end(); | |
| 270 base::Time winners_install_time; | |
| 271 | |
| 272 ExtensionEntryMap::const_iterator i; | |
| 273 for (i = entries_.begin(); i != entries_.end(); ++i) { | |
| 274 const std::string& ext_id = i->first; | |
| 275 const base::Time& install_time = i->second->install_time; | |
| 276 const bool enabled = i->second->enabled; | |
| 277 | |
| 278 if (!enabled) | |
| 279 continue; | |
| 280 if (install_time < winners_install_time) | |
| 281 continue; | |
| 282 | |
| 283 const base::Value* value = NULL; | |
| 284 const PrefValueMap* prefs = GetExtensionPrefValueMap( | |
| 285 ext_id, extensions::kExtensionPrefsScopeRegular); | |
| 286 if (prefs->GetValue(key, &value)) { | |
| 287 winner = i; | |
| 288 winners_install_time = install_time; | |
| 289 if (from_incognito) | |
| 290 *from_incognito = false; | |
| 291 } | |
| 292 | |
| 293 if (!incognito) { | |
| 294 const PrefValueMap* prefs = GetExtensionPrefValueMap( | |
| 295 ext_id, extensions::kExtensionPrefsScopeRegularOnly); | |
| 296 if (prefs->GetValue(key, &value)) { | |
| 297 winner = i; | |
| 298 winners_install_time = install_time; | |
| 299 if (from_incognito) | |
| 300 *from_incognito = false; | |
| 301 } | |
| 302 // Ignore the following prefs, because they're incognito-only. | |
| 303 continue; | |
| 304 } | |
| 305 | |
| 306 prefs = GetExtensionPrefValueMap( | |
| 307 ext_id, extensions::kExtensionPrefsScopeIncognitoPersistent); | |
| 308 if (prefs->GetValue(key, &value)) { | |
| 309 winner = i; | |
| 310 winners_install_time = install_time; | |
| 311 if (from_incognito) | |
| 312 *from_incognito = true; | |
| 313 } | |
| 314 | |
| 315 prefs = GetExtensionPrefValueMap( | |
| 316 ext_id, extensions::kExtensionPrefsScopeIncognitoSessionOnly); | |
| 317 if (prefs->GetValue(key, &value)) { | |
| 318 winner = i; | |
| 319 winners_install_time = install_time; | |
| 320 if (from_incognito) | |
| 321 *from_incognito = true; | |
| 322 } | |
| 323 } | |
| 324 return winner; | |
| 325 } | |
| 326 | |
| 327 void ExtensionPrefValueMap::AddObserver( | |
| 328 ExtensionPrefValueMap::Observer* observer) { | |
| 329 observers_.AddObserver(observer); | |
| 330 | |
| 331 // Collect all currently used keys and notify the new observer. | |
| 332 std::set<std::string> keys; | |
| 333 ExtensionEntryMap::const_iterator i; | |
| 334 for (i = entries_.begin(); i != entries_.end(); ++i) | |
| 335 GetExtensionControlledKeys(*(i->second), &keys); | |
| 336 | |
| 337 std::set<std::string>::const_iterator j; | |
| 338 for (j = keys.begin(); j != keys.end(); ++j) | |
| 339 observer->OnPrefValueChanged(*j); | |
| 340 } | |
| 341 | |
| 342 void ExtensionPrefValueMap::RemoveObserver( | |
| 343 ExtensionPrefValueMap::Observer* observer) { | |
| 344 observers_.RemoveObserver(observer); | |
| 345 } | |
| 346 | |
| 347 std::string ExtensionPrefValueMap::GetExtensionControllingPref( | |
| 348 const std::string& pref_key) const { | |
| 349 ExtensionEntryMap::const_iterator winner = | |
| 350 GetEffectivePrefValueController(pref_key, false, NULL); | |
| 351 if (winner == entries_.end()) | |
| 352 return std::string(); | |
| 353 return winner->first; | |
| 354 } | |
| 355 | |
| 356 void ExtensionPrefValueMap::NotifyInitializationCompleted() { | |
| 357 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_, | |
| 358 OnInitializationCompleted()); | |
| 359 } | |
| 360 | |
| 361 void ExtensionPrefValueMap::NotifyPrefValueChanged( | |
| 362 const std::set<std::string>& keys) { | |
| 363 std::set<std::string>::const_iterator i; | |
| 364 for (i = keys.begin(); i != keys.end(); ++i) | |
| 365 NotifyPrefValueChanged(*i); | |
| 366 } | |
| 367 | |
| 368 void ExtensionPrefValueMap::NotifyPrefValueChanged(const std::string& key) { | |
| 369 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_, | |
| 370 OnPrefValueChanged(key)); | |
| 371 } | |
| 372 | |
| 373 void ExtensionPrefValueMap::NotifyOfDestruction() { | |
| 374 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_, | |
| 375 OnExtensionPrefValueMapDestruction()); | |
| 376 } | |
| OLD | NEW |