15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_pref_value_map.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/prefs/pref_value_map.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::ExtensionPrefsScope;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ExtensionPrefValueMap::ExtensionEntry {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Installation time of the extension.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time install_time;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether extension is enabled in the profile.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool enabled;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Extension controlled preferences for the regular profile.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefValueMap regular_profile_preferences;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Extension controlled preferences that should *only* apply to the regular
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // profile.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefValueMap regular_only_profile_preferences;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Persistent extension controlled preferences for the incognito profile,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // empty for regular profile ExtensionPrefStore.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefValueMap incognito_profile_preferences_persistent;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Session only extension controlled preferences for the incognito profile.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These preferences are deleted when the incognito profile is destroyed.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefValueMap incognito_profile_preferences_session_only;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionPrefValueMap::ExtensionPrefValueMap() : destroyed_(false) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionPrefValueMap::~ExtensionPrefValueMap() {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!destroyed_) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyOfDestruction();
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    destroyed_ = true;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteValues(&entries_);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entries_.clear();
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionPrefValueMap::Shutdown() {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyOfDestruction();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  destroyed_ = true;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionPrefValueMap::SetExtensionPref(const std::string& ext_id,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             const std::string& key,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             ExtensionPrefsScope scope,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             Value* value) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (prefs->SetValue(key, value))
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyPrefValueChanged(key);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionPrefValueMap::RemoveExtensionPref(
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& ext_id,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionPrefsScope scope) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (prefs->RemoveValue(key))
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyPrefValueChanged(key);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionPrefValueMap::CanExtensionControlPref(
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& pref_key,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool incognito) const {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionEntryMap::const_iterator ext = entries_.find(extension_id);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ext == entries_.end()) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionEntryMap::const_iterator winner =
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetEffectivePrefValueController(pref_key, incognito, NULL);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (winner == entries_.end())
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return winner->second->install_time <= ext->second->install_time;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionPrefValueMap::ClearAllIncognitoSessionOnlyPreferences() {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::set<std::string> KeySet;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeySet deleted_keys;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionEntryMap::iterator i;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (i = entries_.begin(); i != entries_.end(); ++i) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefValueMap& inc_prefs =
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        i->second->incognito_profile_preferences_session_only;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefValueMap::iterator j;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (j = inc_prefs.begin(); j != inc_prefs.end(); ++j)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      deleted_keys.insert(j->first);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inc_prefs.Clear();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeySet::iterator k;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (k = deleted_keys.begin(); k != deleted_keys.end(); ++k)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyPrefValueChanged(*k);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionPrefValueMap::DoesExtensionControlPref(
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& pref_key,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* from_incognito) const {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool incognito = (from_incognito != NULL);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionEntryMap::const_iterator winner =
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetEffectivePrefValueController(pref_key, incognito, from_incognito);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (winner == entries_.end())
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return winner->first == extension_id;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionPrefValueMap::RegisterExtension(const std::string& ext_id,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              const base::Time& install_time,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              bool is_enabled) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (entries_.find(ext_id) != entries_.end())
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UnregisterExtension(ext_id);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entries_[ext_id] = new ExtensionEntry;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entries_[ext_id]->install_time = install_time;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entries_[ext_id]->enabled = is_enabled;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionPrefValueMap::UnregisterExtension(const std::string& ext_id) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionEntryMap::iterator i = entries_.find(ext_id);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (i == entries_.end())
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<std::string> keys;  // keys set by this extension
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetExtensionControlledKeys(*(i->second), &keys);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete i->second;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entries_.erase(i);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyPrefValueChanged(keys);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionPrefValueMap::SetExtensionState(const std::string& ext_id,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              bool is_enabled) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This may happen when sync sets the extension state for an
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // extension that is not installed.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (i == entries_.end())
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (i->second->enabled == is_enabled)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<std::string> keys;  // keys set by this extension
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetExtensionControlledKeys(*(i->second), &keys);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  i->second->enabled = is_enabled;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyPrefValueChanged(keys);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& ext_id,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionPrefsScope scope) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(i != entries_.end());
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (scope) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case extensions::kExtensionPrefsScopeRegular:
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &(i->second->regular_profile_preferences);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case extensions::kExtensionPrefsScopeRegularOnly:
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &(i->second->regular_only_profile_preferences);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case extensions::kExtensionPrefsScopeIncognitoPersistent:
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &(i->second->incognito_profile_preferences_persistent);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case extensions::kExtensionPrefsScopeIncognitoSessionOnly:
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &(i->second->incognito_profile_preferences_session_only);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& ext_id,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionPrefsScope scope) const {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(i != entries_.end());
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (scope) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case extensions::kExtensionPrefsScopeRegular:
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &(i->second->regular_profile_preferences);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case extensions::kExtensionPrefsScopeRegularOnly:
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &(i->second->regular_only_profile_preferences);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case extensions::kExtensionPrefsScopeIncognitoPersistent:
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &(i->second->incognito_profile_preferences_persistent);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case extensions::kExtensionPrefsScopeIncognitoSessionOnly:
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &(i->second->incognito_profile_preferences_session_only);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionPrefValueMap::GetExtensionControlledKeys(
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ExtensionEntry& entry,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::set<std::string>* out) const {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefValueMap::const_iterator i;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PrefValueMap& regular_prefs = entry.regular_profile_preferences;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (i = regular_prefs.begin(); i != regular_prefs.end(); ++i)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out->insert(i->first);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PrefValueMap& regular_only_prefs =
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry.regular_only_profile_preferences;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (i = regular_only_prefs.begin(); i != regular_only_prefs.end(); ++i)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out->insert(i->first);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PrefValueMap& inc_prefs_pers =
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry.incognito_profile_preferences_persistent;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (i = inc_prefs_pers.begin(); i != inc_prefs_pers.end(); ++i)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out->insert(i->first);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PrefValueMap& inc_prefs_session =
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry.incognito_profile_preferences_session_only;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (i = inc_prefs_session.begin(); i != inc_prefs_session.end(); ++i)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out->insert(i->first);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Value* ExtensionPrefValueMap::GetEffectivePrefValue(
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool incognito,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* from_incognito) const {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionEntryMap::const_iterator winner =
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetEffectivePrefValueController(key, incognito, from_incognito);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (winner == entries_.end())
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Value* value = NULL;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& ext_id = winner->first;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First search for incognito session only preferences.
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (incognito) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PrefValueMap* prefs = GetExtensionPrefValueMap(
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ext_id, extensions::kExtensionPrefsScopeIncognitoSessionOnly);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    prefs->GetValue(key, &value);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return value;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If no incognito session only preference exists, fall back to persistent
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // incognito preference.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    prefs = GetExtensionPrefValueMap(
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ext_id,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        extensions::kExtensionPrefsScopeIncognitoPersistent);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    prefs->GetValue(key, &value);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return value;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Regular-only preference.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PrefValueMap* prefs = GetExtensionPrefValueMap(
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ext_id, extensions::kExtensionPrefsScopeRegularOnly);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    prefs->GetValue(key, &value);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return value;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Regular preference.
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PrefValueMap* prefs = GetExtensionPrefValueMap(
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ext_id, extensions::kExtensionPrefsScopeRegular);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs->GetValue(key, &value);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionPrefValueMap::ExtensionEntryMap::const_iterator
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionPrefValueMap::GetEffectivePrefValueController(
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool incognito,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* from_incognito) const {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionEntryMap::const_iterator winner = entries_.end();
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time winners_install_time;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionEntryMap::const_iterator i;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (i = entries_.begin(); i != entries_.end(); ++i) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& ext_id = i->first;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Time& install_time = i->second->install_time;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const bool enabled = i->second->enabled;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!enabled)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (install_time < winners_install_time)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Value* value = NULL;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PrefValueMap* prefs = GetExtensionPrefValueMap(
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ext_id, extensions::kExtensionPrefsScopeRegular);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (prefs->GetValue(key, &value)) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      winner = i;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      winners_install_time = install_time;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (from_incognito)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *from_incognito = false;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!incognito) {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const PrefValueMap* prefs = GetExtensionPrefValueMap(
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ext_id, extensions::kExtensionPrefsScopeRegularOnly);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (prefs->GetValue(key, &value)) {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        winner = i;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        winners_install_time = install_time;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (from_incognito)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          *from_incognito = false;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Ignore the following prefs, because they're incognito-only.
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    prefs = GetExtensionPrefValueMap(
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ext_id, extensions::kExtensionPrefsScopeIncognitoPersistent);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (prefs->GetValue(key, &value)) {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      winner = i;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      winners_install_time = install_time;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (from_incognito)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *from_incognito = true;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    prefs = GetExtensionPrefValueMap(
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ext_id, extensions::kExtensionPrefsScopeIncognitoSessionOnly);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (prefs->GetValue(key, &value)) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      winner = i;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      winners_install_time = install_time;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (from_incognito)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *from_incognito = true;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return winner;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionPrefValueMap::AddObserver(
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionPrefValueMap::Observer* observer) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observers_.AddObserver(observer);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Collect all currently used keys and notify the new observer.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<std::string> keys;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionEntryMap::const_iterator i;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (i = entries_.begin(); i != entries_.end(); ++i)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetExtensionControlledKeys(*(i->second), &keys);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<std::string>::const_iterator j;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (j = keys.begin(); j != keys.end(); ++j)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer->OnPrefValueChanged(*j);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionPrefValueMap::RemoveObserver(
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionPrefValueMap::Observer* observer) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observers_.RemoveObserver(observer);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionPrefValueMap::NotifyInitializationCompleted() {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnInitializationCompleted());
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionPrefValueMap::NotifyPrefValueChanged(
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::set<std::string>& keys) {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<std::string>::const_iterator i;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (i = keys.begin(); i != keys.end(); ++i)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyPrefValueChanged(*i);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionPrefValueMap::NotifyPrefValueChanged(const std::string& key) {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnPrefValueChanged(key));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionPrefValueMap::NotifyOfDestruction() {
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnExtensionPrefValueMapDestruction());
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
365