123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "extensions/browser/extension_pref_value_map.h"
- #include <utility>
- #include "base/memory/ptr_util.h"
- #include "base/observer_list.h"
- #include "base/time/time.h"
- #include "base/values.h"
- #include "components/prefs/pref_value_map.h"
- using extensions::ExtensionPrefsScope;
- struct ExtensionPrefValueMap::ExtensionEntry {
- // Installation time of the extension.
- base::Time install_time;
- // Whether extension is enabled in the profile.
- bool enabled;
- // Whether the extension has access to the incognito profile.
- bool incognito_enabled;
- // Extension controlled preferences for the regular profile.
- PrefValueMap regular_profile_preferences;
- // Extension controlled preferences that should *only* apply to the regular
- // profile.
- PrefValueMap regular_only_profile_preferences;
- // Persistent extension controlled preferences for the incognito profile,
- // empty for regular profile ExtensionPrefStore.
- PrefValueMap incognito_profile_preferences_persistent;
- // Session only extension controlled preferences for the incognito profile.
- // These preferences are deleted when the incognito profile is destroyed.
- PrefValueMap incognito_profile_preferences_session_only;
- };
- ExtensionPrefValueMap::ExtensionPrefValueMap() : destroyed_(false) {
- }
- ExtensionPrefValueMap::~ExtensionPrefValueMap() {
- if (!destroyed_) {
- NotifyOfDestruction();
- destroyed_ = true;
- }
- }
- void ExtensionPrefValueMap::Shutdown() {
- NotifyOfDestruction();
- destroyed_ = true;
- }
- void ExtensionPrefValueMap::SetExtensionPref(const std::string& ext_id,
- const std::string& key,
- ExtensionPrefsScope scope,
- base::Value value) {
- PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope);
- if (prefs->SetValue(key, std::move(value)))
- NotifyPrefValueChanged(key);
- }
- void ExtensionPrefValueMap::RemoveExtensionPref(
- const std::string& ext_id,
- const std::string& key,
- ExtensionPrefsScope scope) {
- PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope);
- if (prefs->RemoveValue(key))
- NotifyPrefValueChanged(key);
- }
- bool ExtensionPrefValueMap::CanExtensionControlPref(
- const std::string& extension_id,
- const std::string& pref_key,
- bool incognito) const {
- auto ext = entries_.find(extension_id);
- if (ext == entries_.end()) {
- NOTREACHED() << "Extension " << extension_id
- << " is not registered but accesses pref " << pref_key
- << " (incognito: " << incognito << ")."
- << " http://crbug.com/454513";
- return false;
- }
- if (incognito && !ext->second->incognito_enabled)
- return false;
- auto winner = GetEffectivePrefValueController(pref_key, incognito, NULL);
- if (winner == entries_.end())
- return true;
- return winner->second->install_time <= ext->second->install_time;
- }
- void ExtensionPrefValueMap::ClearAllIncognitoSessionOnlyPreferences() {
- typedef std::set<std::string> KeySet;
- KeySet deleted_keys;
- for (const auto& entry : entries_) {
- PrefValueMap& inc_prefs =
- entry.second->incognito_profile_preferences_session_only;
- for (const auto& pref : inc_prefs)
- deleted_keys.insert(pref.first);
- inc_prefs.Clear();
- }
- for (const auto& key : deleted_keys)
- NotifyPrefValueChanged(key);
- }
- bool ExtensionPrefValueMap::DoesExtensionControlPref(
- const std::string& extension_id,
- const std::string& pref_key,
- bool* from_incognito) const {
- bool incognito = (from_incognito != NULL);
- auto winner =
- GetEffectivePrefValueController(pref_key, incognito, from_incognito);
- if (winner == entries_.end())
- return false;
- return winner->first == extension_id;
- }
- void ExtensionPrefValueMap::RegisterExtension(const std::string& ext_id,
- const base::Time& install_time,
- bool is_enabled,
- bool is_incognito_enabled) {
- if (entries_.find(ext_id) == entries_.end()) {
- entries_[ext_id] = base::WrapUnique(new ExtensionEntry);
- // Only update the install time if the extension is newly installed.
- entries_[ext_id]->install_time = install_time;
- }
- entries_[ext_id]->enabled = is_enabled;
- entries_[ext_id]->incognito_enabled = is_incognito_enabled;
- }
- void ExtensionPrefValueMap::UnregisterExtension(const std::string& ext_id) {
- auto i = entries_.find(ext_id);
- if (i == entries_.end())
- return;
- std::set<std::string> keys; // keys set by this extension
- GetExtensionControlledKeys(*(i->second.get()), &keys);
- entries_.erase(i);
- NotifyPrefValueChanged(keys);
- }
- void ExtensionPrefValueMap::SetExtensionState(const std::string& ext_id,
- bool is_enabled) {
- ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
- // This may happen when sync sets the extension state for an
- // extension that is not installed.
- if (i == entries_.end())
- return;
- if (i->second->enabled == is_enabled)
- return;
- std::set<std::string> keys; // keys set by this extension
- GetExtensionControlledKeys(*(i->second), &keys);
- i->second->enabled = is_enabled;
- NotifyPrefValueChanged(keys);
- }
- void ExtensionPrefValueMap::SetExtensionIncognitoState(
- const std::string& ext_id,
- bool is_incognito_enabled) {
- ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
- // This may happen when sync sets the extension state for an
- // extension that is not installed.
- if (i == entries_.end())
- return;
- if (i->second->incognito_enabled == is_incognito_enabled)
- return;
- std::set<std::string> keys; // keys set by this extension
- GetExtensionControlledKeys(*(i->second), &keys);
- i->second->incognito_enabled = is_incognito_enabled;
- NotifyPrefValueChanged(keys);
- }
- PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
- const std::string& ext_id,
- ExtensionPrefsScope scope) {
- ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
- CHECK(i != entries_.end());
- switch (scope) {
- case extensions::kExtensionPrefsScopeRegular:
- return &(i->second->regular_profile_preferences);
- case extensions::kExtensionPrefsScopeRegularOnly:
- return &(i->second->regular_only_profile_preferences);
- case extensions::kExtensionPrefsScopeIncognitoPersistent:
- return &(i->second->incognito_profile_preferences_persistent);
- case extensions::kExtensionPrefsScopeIncognitoSessionOnly:
- return &(i->second->incognito_profile_preferences_session_only);
- }
- NOTREACHED();
- return NULL;
- }
- const PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
- const std::string& ext_id,
- ExtensionPrefsScope scope) const {
- auto i = entries_.find(ext_id);
- CHECK(i != entries_.end());
- switch (scope) {
- case extensions::kExtensionPrefsScopeRegular:
- return &(i->second->regular_profile_preferences);
- case extensions::kExtensionPrefsScopeRegularOnly:
- return &(i->second->regular_only_profile_preferences);
- case extensions::kExtensionPrefsScopeIncognitoPersistent:
- return &(i->second->incognito_profile_preferences_persistent);
- case extensions::kExtensionPrefsScopeIncognitoSessionOnly:
- return &(i->second->incognito_profile_preferences_session_only);
- }
- NOTREACHED();
- return NULL;
- }
- void ExtensionPrefValueMap::GetExtensionControlledKeys(
- const ExtensionEntry& entry,
- std::set<std::string>* out) const {
- PrefValueMap::const_iterator i;
- const PrefValueMap& regular_prefs = entry.regular_profile_preferences;
- for (i = regular_prefs.begin(); i != regular_prefs.end(); ++i)
- out->insert(i->first);
- const PrefValueMap& regular_only_prefs =
- entry.regular_only_profile_preferences;
- for (i = regular_only_prefs.begin(); i != regular_only_prefs.end(); ++i)
- out->insert(i->first);
- const PrefValueMap& inc_prefs_pers =
- entry.incognito_profile_preferences_persistent;
- for (i = inc_prefs_pers.begin(); i != inc_prefs_pers.end(); ++i)
- out->insert(i->first);
- const PrefValueMap& inc_prefs_session =
- entry.incognito_profile_preferences_session_only;
- for (i = inc_prefs_session.begin(); i != inc_prefs_session.end(); ++i)
- out->insert(i->first);
- }
- const base::Value* ExtensionPrefValueMap::GetEffectivePrefValue(
- const std::string& key,
- bool incognito,
- bool* from_incognito) const {
- auto winner = GetEffectivePrefValueController(key, incognito, from_incognito);
- if (winner == entries_.end())
- return NULL;
- const base::Value* value = NULL;
- const std::string& ext_id = winner->first;
- // First search for incognito session only preferences.
- if (incognito) {
- DCHECK(winner->second->incognito_enabled);
- const PrefValueMap* prefs = GetExtensionPrefValueMap(
- ext_id, extensions::kExtensionPrefsScopeIncognitoSessionOnly);
- prefs->GetValue(key, &value);
- if (value)
- return value;
- // If no incognito session only preference exists, fall back to persistent
- // incognito preference.
- prefs = GetExtensionPrefValueMap(
- ext_id,
- extensions::kExtensionPrefsScopeIncognitoPersistent);
- prefs->GetValue(key, &value);
- if (value)
- return value;
- } else {
- // Regular-only preference.
- const PrefValueMap* prefs = GetExtensionPrefValueMap(
- ext_id, extensions::kExtensionPrefsScopeRegularOnly);
- prefs->GetValue(key, &value);
- if (value)
- return value;
- }
- // Regular preference.
- const PrefValueMap* prefs = GetExtensionPrefValueMap(
- ext_id, extensions::kExtensionPrefsScopeRegular);
- prefs->GetValue(key, &value);
- return value;
- }
- ExtensionPrefValueMap::ExtensionEntryMap::const_iterator
- ExtensionPrefValueMap::GetEffectivePrefValueController(
- const std::string& key,
- bool incognito,
- bool* from_incognito) const {
- auto winner = entries_.cend();
- base::Time winners_install_time;
- for (auto i = entries_.cbegin(); i != entries_.cend(); ++i) {
- const std::string& ext_id = i->first;
- const base::Time& install_time = i->second->install_time;
- const bool enabled = i->second->enabled;
- const bool incognito_enabled = i->second->incognito_enabled;
- if (!enabled)
- continue;
- if (install_time < winners_install_time)
- continue;
- if (incognito && !incognito_enabled)
- continue;
- const base::Value* value = NULL;
- const PrefValueMap* prefs = GetExtensionPrefValueMap(
- ext_id, extensions::kExtensionPrefsScopeRegular);
- if (prefs->GetValue(key, &value)) {
- winner = i;
- winners_install_time = install_time;
- if (from_incognito)
- *from_incognito = false;
- }
- if (!incognito) {
- prefs = GetExtensionPrefValueMap(
- ext_id, extensions::kExtensionPrefsScopeRegularOnly);
- if (prefs->GetValue(key, &value)) {
- winner = i;
- winners_install_time = install_time;
- if (from_incognito)
- *from_incognito = false;
- }
- // Ignore the following prefs, because they're incognito-only.
- continue;
- }
- prefs = GetExtensionPrefValueMap(
- ext_id, extensions::kExtensionPrefsScopeIncognitoPersistent);
- if (prefs->GetValue(key, &value)) {
- winner = i;
- winners_install_time = install_time;
- if (from_incognito)
- *from_incognito = true;
- }
- prefs = GetExtensionPrefValueMap(
- ext_id, extensions::kExtensionPrefsScopeIncognitoSessionOnly);
- if (prefs->GetValue(key, &value)) {
- winner = i;
- winners_install_time = install_time;
- if (from_incognito)
- *from_incognito = true;
- }
- }
- return winner;
- }
- void ExtensionPrefValueMap::AddObserver(
- ExtensionPrefValueMap::Observer* observer) {
- observers_.AddObserver(observer);
- // Collect all currently used keys and notify the new observer.
- std::set<std::string> keys;
- ExtensionEntryMap::const_iterator i;
- for (i = entries_.begin(); i != entries_.end(); ++i)
- GetExtensionControlledKeys(*(i->second), &keys);
- std::set<std::string>::const_iterator j;
- for (j = keys.begin(); j != keys.end(); ++j)
- observer->OnPrefValueChanged(*j);
- }
- void ExtensionPrefValueMap::RemoveObserver(
- ExtensionPrefValueMap::Observer* observer) {
- observers_.RemoveObserver(observer);
- }
- std::string ExtensionPrefValueMap::GetExtensionControllingPref(
- const std::string& pref_key) const {
- auto winner = GetEffectivePrefValueController(pref_key, false, NULL);
- if (winner == entries_.end())
- return std::string();
- return winner->first;
- }
- void ExtensionPrefValueMap::NotifyInitializationCompleted() {
- for (auto& observer : observers_)
- observer.OnInitializationCompleted();
- }
- void ExtensionPrefValueMap::NotifyPrefValueChanged(
- const std::set<std::string>& keys) {
- for (const auto& key : keys)
- NotifyPrefValueChanged(key);
- }
- void ExtensionPrefValueMap::NotifyPrefValueChanged(const std::string& key) {
- for (auto& observer : observers_)
- observer.OnPrefValueChanged(key);
- }
- void ExtensionPrefValueMap::NotifyOfDestruction() {
- for (auto& observer : observers_)
- observer.OnExtensionPrefValueMapDestruction();
- }
|