diff options
Diffstat (limited to 'extensions/browser/extension_pref_value_map.h')
-rw-r--r-- | extensions/browser/extension_pref_value_map.h | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/extensions/browser/extension_pref_value_map.h b/extensions/browser/extension_pref_value_map.h new file mode 100644 index 0000000..48f30d9 --- /dev/null +++ b/extensions/browser/extension_pref_value_map.h @@ -0,0 +1,198 @@ +// 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. + +#ifndef EXTENSIONS_BROWSER_EXTENSION_PREF_VALUE_MAP_H_ +#define EXTENSIONS_BROWSER_EXTENSION_PREF_VALUE_MAP_H_ + +#include <map> +#include <set> +#include <string> + +#include "base/observer_list.h" +#include "base/prefs/pref_value_map.h" +#include "base/time/time.h" +#include "base/values.h" +#include "components/browser_context_keyed_service/browser_context_keyed_service.h" +#include "extensions/browser/extension_prefs_scope.h" + +// Non-persistent data container that is shared by ExtensionPrefStores. All +// extension pref values (incognito and regular) are stored herein and +// provided to ExtensionPrefStores. +// +// The semantics of the ExtensionPrefValueMap are: +// - A regular setting applies to regular browsing sessions as well as incognito +// browsing sessions. +// - An incognito setting applies only to incognito browsing sessions, not to +// regular ones. It takes precedence over a regular setting set by the same +// extension. +// - A regular-only setting applies only to regular browsing sessions, not to +// incognito ones. It takes precedence over a regular setting set by the same +// extension. +// - If two different extensions set a value for the same preference (and both +// values apply to the regular/incognito browsing session), the extension that +// was installed later takes precedence, regardless of whether the settings +// are regular, incognito or regular-only. +// +// The following table illustrates the behavior: +// A.reg | A.reg_only | A.inc | B.reg | B.reg_only | B.inc | E.reg | E.inc +// 1 | - | - | - | - | - | 1 | 1 +// 1 | 2 | - | - | - | - | 2 | 1 +// 1 | - | 3 | - | - | - | 1 | 3 +// 1 | 2 | 3 | - | - | - | 2 | 3 +// 1 | - | - | 4 | - | - | 4 | 4 +// 1 | 2 | 3 | 4 | - | - | 4 | 4 +// 1 | - | - | - | 5 | - | 5 | 1 +// 1 | - | 3 | 4 | 5 | - | 5 | 4 +// 1 | - | - | - | - | 6 | 1 | 6 +// 1 | 2 | - | 4 | - | 6 | 4 | 6 +// 1 | 2 | 3 | - | 5 | 6 | 5 | 6 +// +// A = extension A, B = extension B, E = effective value +// .reg = regular value +// .reg_only = regular-only value +// .inc = incognito value +// Extension B has higher precedence than A. +class ExtensionPrefValueMap : public BrowserContextKeyedService { + public: + // Observer interface for monitoring ExtensionPrefValueMap. + class Observer { + public: + // Called when the value for the given |key| set by one of the extensions + // changes. This does not necessarily mean that the effective value has + // changed. + virtual void OnPrefValueChanged(const std::string& key) = 0; + // Notification about the ExtensionPrefValueMap being fully initialized. + virtual void OnInitializationCompleted() = 0; + // Called when the ExtensionPrefValueMap is being destroyed. When called, + // observers must unsubscribe. + virtual void OnExtensionPrefValueMapDestruction() = 0; + + protected: + virtual ~Observer() {} + }; + + ExtensionPrefValueMap(); + virtual ~ExtensionPrefValueMap(); + + // BrowserContextKeyedService implementation. + virtual void Shutdown() OVERRIDE; + + // Set an extension preference |value| for |key| of extension |ext_id|. + // Takes ownership of |value|. + // Note that regular extension pref values need to be reported to + // incognito and to regular ExtensionPrefStores. + // Precondition: the extension must be registered. + void SetExtensionPref(const std::string& ext_id, + const std::string& key, + extensions::ExtensionPrefsScope scope, + base::Value* value); + + // Remove the extension preference value for |key| of extension |ext_id|. + // Precondition: the extension must be registered. + void RemoveExtensionPref(const std::string& ext_id, + const std::string& key, + extensions::ExtensionPrefsScope scope); + + // Returns true if currently no extension with higher precedence controls the + // preference. + // Note that the this function does does not consider the existence of + // policies. An extension is only really able to control a preference if + // PrefService::Preference::IsExtensionModifiable() returns true as well. + bool CanExtensionControlPref(const std::string& extension_id, + const std::string& pref_key, + bool incognito) const; + + // Removes all "incognito session only" preference values. + void ClearAllIncognitoSessionOnlyPreferences(); + + // Returns true if an extension identified by |extension_id| controls the + // preference. This means this extension has set a preference value and no + // other extension with higher precedence overrides it. If |from_incognito| + // is not NULL, looks at incognito preferences first, and |from_incognito| is + // set to true if the effective pref value is coming from the incognito + // preferences, false if it is coming from the normal ones. + // Note that the this function does does not consider the existence of + // policies. An extension is only really able to control a preference if + // PrefService::Preference::IsExtensionModifiable() returns true as well. + bool DoesExtensionControlPref(const std::string& extension_id, + const std::string& pref_key, + bool* from_incognito) const; + + // Returns the ID of the extension that currently controls this preference. + // Returns an empty string if this preference is not controlled by an + // extension. + std::string GetExtensionControllingPref(const std::string& pref_key) const; + + // Tell the store it's now fully initialized. + void NotifyInitializationCompleted(); + + // Registers the time when an extension |ext_id| is installed. + void RegisterExtension(const std::string& ext_id, + const base::Time& install_time, + bool is_enabled); + + // Deletes all entries related to extension |ext_id|. + void UnregisterExtension(const std::string& ext_id); + + // Hides or makes the extension preference values of the specified extension + // visible. + void SetExtensionState(const std::string& ext_id, bool is_enabled); + + // Adds an observer and notifies it about the currently stored keys. + void AddObserver(Observer* observer); + + void RemoveObserver(Observer* observer); + + const base::Value* GetEffectivePrefValue(const std::string& key, + bool incognito, + bool* from_incognito) const; + + private: + struct ExtensionEntry; + + typedef std::map<std::string, ExtensionEntry*> ExtensionEntryMap; + + const PrefValueMap* GetExtensionPrefValueMap( + const std::string& ext_id, + extensions::ExtensionPrefsScope scope) const; + + PrefValueMap* GetExtensionPrefValueMap( + const std::string& ext_id, + extensions::ExtensionPrefsScope scope); + + // Returns all keys of pref values that are set by the extension of |entry|, + // regardless whether they are set for incognito or regular pref values. + void GetExtensionControlledKeys(const ExtensionEntry& entry, + std::set<std::string>* out) const; + + // Returns an iterator to the extension which controls the preference |key|. + // If |incognito| is true, looks at incognito preferences first. In that case, + // if |from_incognito| is not NULL, it is set to true if the effective pref + // value is coming from the incognito preferences, false if it is coming from + // the normal ones. + ExtensionEntryMap::const_iterator GetEffectivePrefValueController( + const std::string& key, + bool incognito, + bool* from_incognito) const; + + void NotifyOfDestruction(); + void NotifyPrefValueChanged(const std::string& key); + void NotifyPrefValueChanged(const std::set<std::string>& keys); + + // Mapping of which extension set which preference value. The effective + // preferences values (i.e. the ones with the highest precedence) + // are stored in ExtensionPrefStores. + ExtensionEntryMap entries_; + + // In normal Profile shutdown, Shutdown() notifies observers that we are + // being destroyed. In tests, it isn't called, so the notification must + // be done in the destructor. This bit tracks whether it has been done yet. + bool destroyed_; + + ObserverList<Observer, true> observers_; + + DISALLOW_COPY_AND_ASSIGN(ExtensionPrefValueMap); +}; + +#endif // EXTENSIONS_BROWSER_EXTENSION_PREF_VALUE_MAP_H_ |