[email protected] | 489db084 | 2014-01-22 18:20:03 | [diff] [blame] | 1 | // Copyright 2014 The Chromium Authors. All rights reserved. |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | 489db084 | 2014-01-22 18:20:03 | [diff] [blame] | 5 | #ifndef EXTENSIONS_BROWSER_EXTENSION_PREF_VALUE_MAP_H_ |
| 6 | #define EXTENSIONS_BROWSER_EXTENSION_PREF_VALUE_MAP_H_ |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 7 | |
| 8 | #include <map> |
| 9 | #include <set> |
| 10 | #include <string> |
| 11 | |
[email protected] | ef9bba1 | 2012-04-06 16:26:09 | [diff] [blame] | 12 | #include "base/observer_list.h" |
[email protected] | b33f0b11 | 2014-03-13 17:05:30 | [diff] [blame] | 13 | #include "components/keyed_service/core/keyed_service.h" |
[email protected] | 6d8a0b09 | 2013-06-12 20:54:13 | [diff] [blame] | 14 | #include "extensions/browser/extension_prefs_scope.h" |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 15 | |
limasdf | 39e712d7 | 2015-11-19 16:00:50 | [diff] [blame] | 16 | class PrefValueMap; |
| 17 | |
| 18 | namespace base { |
| 19 | class Time; |
| 20 | class Value; |
| 21 | } |
| 22 | |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 23 | // Non-persistent data container that is shared by ExtensionPrefStores. All |
| 24 | // extension pref values (incognito and regular) are stored herein and |
| 25 | // provided to ExtensionPrefStores. |
| 26 | // |
| 27 | // The semantics of the ExtensionPrefValueMap are: |
[email protected] | 7d3a0e3 | 2012-06-14 22:37:29 | [diff] [blame] | 28 | // - A regular setting applies to regular browsing sessions as well as incognito |
| 29 | // browsing sessions. |
| 30 | // - An incognito setting applies only to incognito browsing sessions, not to |
| 31 | // regular ones. It takes precedence over a regular setting set by the same |
| 32 | // extension. |
| 33 | // - A regular-only setting applies only to regular browsing sessions, not to |
| 34 | // incognito ones. It takes precedence over a regular setting set by the same |
| 35 | // extension. |
| 36 | // - If two different extensions set a value for the same preference (and both |
| 37 | // values apply to the regular/incognito browsing session), the extension that |
| 38 | // was installed later takes precedence, regardless of whether the settings |
| 39 | // are regular, incognito or regular-only. |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 40 | // |
| 41 | // The following table illustrates the behavior: |
[email protected] | 7d3a0e3 | 2012-06-14 22:37:29 | [diff] [blame] | 42 | // A.reg | A.reg_only | A.inc | B.reg | B.reg_only | B.inc | E.reg | E.inc |
| 43 | // 1 | - | - | - | - | - | 1 | 1 |
| 44 | // 1 | 2 | - | - | - | - | 2 | 1 |
| 45 | // 1 | - | 3 | - | - | - | 1 | 3 |
| 46 | // 1 | 2 | 3 | - | - | - | 2 | 3 |
| 47 | // 1 | - | - | 4 | - | - | 4 | 4 |
| 48 | // 1 | 2 | 3 | 4 | - | - | 4 | 4 |
| 49 | // 1 | - | - | - | 5 | - | 5 | 1 |
| 50 | // 1 | - | 3 | 4 | 5 | - | 5 | 4 |
| 51 | // 1 | - | - | - | - | 6 | 1 | 6 |
| 52 | // 1 | 2 | - | 4 | - | 6 | 4 | 6 |
| 53 | // 1 | 2 | 3 | - | 5 | 6 | 5 | 6 |
| 54 | // |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 55 | // A = extension A, B = extension B, E = effective value |
| 56 | // .reg = regular value |
[email protected] | 7d3a0e3 | 2012-06-14 22:37:29 | [diff] [blame] | 57 | // .reg_only = regular-only value |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 58 | // .inc = incognito value |
| 59 | // Extension B has higher precedence than A. |
[email protected] | b33f0b11 | 2014-03-13 17:05:30 | [diff] [blame] | 60 | class ExtensionPrefValueMap : public KeyedService { |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 61 | public: |
| 62 | // Observer interface for monitoring ExtensionPrefValueMap. |
| 63 | class Observer { |
| 64 | public: |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 65 | // Called when the value for the given |key| set by one of the extensions |
| 66 | // changes. This does not necessarily mean that the effective value has |
| 67 | // changed. |
| 68 | virtual void OnPrefValueChanged(const std::string& key) = 0; |
| 69 | // Notification about the ExtensionPrefValueMap being fully initialized. |
| 70 | virtual void OnInitializationCompleted() = 0; |
| 71 | // Called when the ExtensionPrefValueMap is being destroyed. When called, |
| 72 | // observers must unsubscribe. |
| 73 | virtual void OnExtensionPrefValueMapDestruction() = 0; |
[email protected] | 512d03f | 2012-06-26 01:06:06 | [diff] [blame] | 74 | |
| 75 | protected: |
| 76 | virtual ~Observer() {} |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 77 | }; |
| 78 | |
| 79 | ExtensionPrefValueMap(); |
dcheng | 9168b2f | 2014-10-21 12:38:24 | [diff] [blame] | 80 | ~ExtensionPrefValueMap() override; |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 81 | |
[email protected] | b33f0b11 | 2014-03-13 17:05:30 | [diff] [blame] | 82 | // KeyedService implementation. |
dcheng | 9168b2f | 2014-10-21 12:38:24 | [diff] [blame] | 83 | void Shutdown() override; |
[email protected] | ef9bba1 | 2012-04-06 16:26:09 | [diff] [blame] | 84 | |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 85 | // Set an extension preference |value| for |key| of extension |ext_id|. |
| 86 | // Takes ownership of |value|. |
| 87 | // Note that regular extension pref values need to be reported to |
| 88 | // incognito and to regular ExtensionPrefStores. |
| 89 | // Precondition: the extension must be registered. |
| 90 | void SetExtensionPref(const std::string& ext_id, |
| 91 | const std::string& key, |
[email protected] | 4575961 | 2012-07-10 17:21:23 | [diff] [blame] | 92 | extensions::ExtensionPrefsScope scope, |
[email protected] | f3a1c64 | 2011-07-12 19:15:03 | [diff] [blame] | 93 | base::Value* value); |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 94 | |
| 95 | // Remove the extension preference value for |key| of extension |ext_id|. |
| 96 | // Precondition: the extension must be registered. |
| 97 | void RemoveExtensionPref(const std::string& ext_id, |
| 98 | const std::string& key, |
[email protected] | 4575961 | 2012-07-10 17:21:23 | [diff] [blame] | 99 | extensions::ExtensionPrefsScope scope); |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 100 | |
[email protected] | 9a28f13 | 2011-02-24 21:15:16 | [diff] [blame] | 101 | // Returns true if currently no extension with higher precedence controls the |
[email protected] | 6c16475 | 2014-03-12 00:29:15 | [diff] [blame] | 102 | // preference. If |incognito| is true and the extension does not have |
| 103 | // incognito permission, CanExtensionControlPref returns false. |
| 104 | // Note that this function does does not consider the existence of |
[email protected] | 9a28f13 | 2011-02-24 21:15:16 | [diff] [blame] | 105 | // policies. An extension is only really able to control a preference if |
| 106 | // PrefService::Preference::IsExtensionModifiable() returns true as well. |
| 107 | bool CanExtensionControlPref(const std::string& extension_id, |
| 108 | const std::string& pref_key, |
| 109 | bool incognito) const; |
| 110 | |
[email protected] | 3168574 | 2011-05-25 23:01:56 | [diff] [blame] | 111 | // Removes all "incognito session only" preference values. |
| 112 | void ClearAllIncognitoSessionOnlyPreferences(); |
| 113 | |
[email protected] | 9a28f13 | 2011-02-24 21:15:16 | [diff] [blame] | 114 | // Returns true if an extension identified by |extension_id| controls the |
| 115 | // preference. This means this extension has set a preference value and no |
[email protected] | 42c037e | 2012-06-26 22:23:32 | [diff] [blame] | 116 | // other extension with higher precedence overrides it. If |from_incognito| |
| 117 | // is not NULL, looks at incognito preferences first, and |from_incognito| is |
| 118 | // set to true if the effective pref value is coming from the incognito |
| 119 | // preferences, false if it is coming from the normal ones. |
[email protected] | 9a28f13 | 2011-02-24 21:15:16 | [diff] [blame] | 120 | // Note that the this function does does not consider the existence of |
| 121 | // policies. An extension is only really able to control a preference if |
| 122 | // PrefService::Preference::IsExtensionModifiable() returns true as well. |
| 123 | bool DoesExtensionControlPref(const std::string& extension_id, |
| 124 | const std::string& pref_key, |
[email protected] | 42c037e | 2012-06-26 22:23:32 | [diff] [blame] | 125 | bool* from_incognito) const; |
[email protected] | 9a28f13 | 2011-02-24 21:15:16 | [diff] [blame] | 126 | |
[email protected] | 6c16475 | 2014-03-12 00:29:15 | [diff] [blame] | 127 | // Returns the ID of the extension that currently controls this preference |
| 128 | // for a regular profile. Incognito settings are ignored. |
[email protected] | b5a507b2 | 2013-11-08 20:41:57 | [diff] [blame] | 129 | // Returns an empty string if this preference is not controlled by an |
| 130 | // extension. |
| 131 | std::string GetExtensionControllingPref(const std::string& pref_key) const; |
| 132 | |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 133 | // Tell the store it's now fully initialized. |
| 134 | void NotifyInitializationCompleted(); |
| 135 | |
| 136 | // Registers the time when an extension |ext_id| is installed. |
| 137 | void RegisterExtension(const std::string& ext_id, |
| 138 | const base::Time& install_time, |
[email protected] | 6c16475 | 2014-03-12 00:29:15 | [diff] [blame] | 139 | bool is_enabled, |
| 140 | bool is_incognito_enabled); |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 141 | |
| 142 | // Deletes all entries related to extension |ext_id|. |
| 143 | void UnregisterExtension(const std::string& ext_id); |
| 144 | |
| 145 | // Hides or makes the extension preference values of the specified extension |
| 146 | // visible. |
| 147 | void SetExtensionState(const std::string& ext_id, bool is_enabled); |
| 148 | |
[email protected] | 6c16475 | 2014-03-12 00:29:15 | [diff] [blame] | 149 | // Sets whether the extension has permission to access incognito state. |
| 150 | void SetExtensionIncognitoState(const std::string& ext_id, |
| 151 | bool is_incognito_enabled); |
| 152 | |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 153 | // Adds an observer and notifies it about the currently stored keys. |
| 154 | void AddObserver(Observer* observer); |
| 155 | |
| 156 | void RemoveObserver(Observer* observer); |
| 157 | |
[email protected] | f3a1c64 | 2011-07-12 19:15:03 | [diff] [blame] | 158 | const base::Value* GetEffectivePrefValue(const std::string& key, |
| 159 | bool incognito, |
| 160 | bool* from_incognito) const; |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 161 | |
| 162 | private: |
[email protected] | 0865c134 | 2011-01-28 20:29:37 | [diff] [blame] | 163 | struct ExtensionEntry; |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 164 | |
limasdf | 39e712d7 | 2015-11-19 16:00:50 | [diff] [blame] | 165 | typedef std::map<std::string, scoped_ptr<ExtensionEntry>> ExtensionEntryMap; |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 166 | |
[email protected] | 9783c16 | 2011-05-25 21:45:51 | [diff] [blame] | 167 | const PrefValueMap* GetExtensionPrefValueMap( |
| 168 | const std::string& ext_id, |
[email protected] | 4575961 | 2012-07-10 17:21:23 | [diff] [blame] | 169 | extensions::ExtensionPrefsScope scope) const; |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 170 | |
[email protected] | 9783c16 | 2011-05-25 21:45:51 | [diff] [blame] | 171 | PrefValueMap* GetExtensionPrefValueMap( |
| 172 | const std::string& ext_id, |
[email protected] | 4575961 | 2012-07-10 17:21:23 | [diff] [blame] | 173 | extensions::ExtensionPrefsScope scope); |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 174 | |
| 175 | // Returns all keys of pref values that are set by the extension of |entry|, |
| 176 | // regardless whether they are set for incognito or regular pref values. |
| 177 | void GetExtensionControlledKeys(const ExtensionEntry& entry, |
| 178 | std::set<std::string>* out) const; |
| 179 | |
[email protected] | c079356 | 2011-03-09 15:31:03 | [diff] [blame] | 180 | // Returns an iterator to the extension which controls the preference |key|. |
| 181 | // If |incognito| is true, looks at incognito preferences first. In that case, |
| 182 | // if |from_incognito| is not NULL, it is set to true if the effective pref |
| 183 | // value is coming from the incognito preferences, false if it is coming from |
| 184 | // the normal ones. |
[email protected] | 9a28f13 | 2011-02-24 21:15:16 | [diff] [blame] | 185 | ExtensionEntryMap::const_iterator GetEffectivePrefValueController( |
[email protected] | c079356 | 2011-03-09 15:31:03 | [diff] [blame] | 186 | const std::string& key, |
| 187 | bool incognito, |
| 188 | bool* from_incognito) const; |
[email protected] | 9a28f13 | 2011-02-24 21:15:16 | [diff] [blame] | 189 | |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 190 | void NotifyOfDestruction(); |
| 191 | void NotifyPrefValueChanged(const std::string& key); |
| 192 | void NotifyPrefValueChanged(const std::set<std::string>& keys); |
| 193 | |
| 194 | // Mapping of which extension set which preference value. The effective |
| 195 | // preferences values (i.e. the ones with the highest precedence) |
| 196 | // are stored in ExtensionPrefStores. |
| 197 | ExtensionEntryMap entries_; |
| 198 | |
[email protected] | ef9bba1 | 2012-04-06 16:26:09 | [diff] [blame] | 199 | // In normal Profile shutdown, Shutdown() notifies observers that we are |
| 200 | // being destroyed. In tests, it isn't called, so the notification must |
| 201 | // be done in the destructor. This bit tracks whether it has been done yet. |
| 202 | bool destroyed_; |
| 203 | |
brettw | 236d317 | 2015-06-03 16:31:43 | [diff] [blame] | 204 | base::ObserverList<Observer, true> observers_; |
[email protected] | 9a8c402 | 2011-01-25 14:25:33 | [diff] [blame] | 205 | |
| 206 | DISALLOW_COPY_AND_ASSIGN(ExtensionPrefValueMap); |
| 207 | }; |
| 208 | |
[email protected] | 489db084 | 2014-01-22 18:20:03 | [diff] [blame] | 209 | #endif // EXTENSIONS_BROWSER_EXTENSION_PREF_VALUE_MAP_H_ |