1 // Copyright (c) 2011 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 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_PREF_VALUE_MAP_H_ 6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_PREF_VALUE_MAP_H_ 7 #pragma once 8 9 #include <map> 10 #include <set> 11 #include <string> 12 13 #include "base/time.h" 14 #include "chrome/browser/prefs/value_map_pref_store.h" 15 16 // Non-persistent data container that is shared by ExtensionPrefStores. All 17 // extension pref values (incognito and regular) are stored herein and 18 // provided to ExtensionPrefStores. 19 // 20 // The semantics of the ExtensionPrefValueMap are: 21 // - The precedence of extensions is determined by their installation time. 22 // The extension that has been installed later takes higher precedence. 23 // - If two extensions set a value for the same preference, the following 24 // rules determine which value becomes effective (visible). 25 // - The effective regular extension pref value is determined by the regular 26 // extension pref value of the extension with the highest precedence. 27 // - The effective incognito extension pref value is determined by the incognito 28 // extension pref value of the extension with the highest precedence, unless 29 // another extension with higher precedence overrides it with a regular 30 // extension pref value. 31 // 32 // The following table illustrates the behavior: 33 // A.reg | A.inc | B.reg | B.inc | E.reg | E.inc 34 // 1 | - | - | - | 1 | 1 35 // 1 | 2 | - | - | 1 | 2 36 // 1 | - | 3 | - | 3 | 3 37 // 1 | - | - | 4 | 1 | 4 38 // 1 | 2 | 3 | - | 3 | 3(!) 39 // 1 | 2 | - | 4 | 1 | 4 40 // 1 | 2 | 3 | 4 | 3 | 4 41 // A = extension A, B = extension B, E = effective value 42 // .reg = regular value 43 // .inc = incognito value 44 // Extension B has higher precedence than A. 45 class ExtensionPrefValueMap { 46 public: 47 // Observer interface for monitoring ExtensionPrefValueMap. 48 class Observer { 49 public: 50 virtual ~Observer() {} 51 52 // Called when the value for the given |key| set by one of the extensions 53 // changes. This does not necessarily mean that the effective value has 54 // changed. 55 virtual void OnPrefValueChanged(const std::string& key) = 0; 56 // Notification about the ExtensionPrefValueMap being fully initialized. 57 virtual void OnInitializationCompleted() = 0; 58 // Called when the ExtensionPrefValueMap is being destroyed. When called, 59 // observers must unsubscribe. 60 virtual void OnExtensionPrefValueMapDestruction() = 0; 61 }; 62 63 ExtensionPrefValueMap(); 64 virtual ~ExtensionPrefValueMap(); 65 66 // Set an extension preference |value| for |key| of extension |ext_id|. 67 // Takes ownership of |value|. 68 // Note that regular extension pref values need to be reported to 69 // incognito and to regular ExtensionPrefStores. 70 // Precondition: the extension must be registered. 71 void SetExtensionPref(const std::string& ext_id, 72 const std::string& key, 73 bool incognito, 74 Value* value); 75 76 // Remove the extension preference value for |key| of extension |ext_id|. 77 // Precondition: the extension must be registered. 78 void RemoveExtensionPref(const std::string& ext_id, 79 const std::string& key, 80 bool incognito); 81 82 // Returns true if currently no extension with higher precedence controls the 83 // preference. 84 // Note that the this function does does not consider the existence of 85 // policies. An extension is only really able to control a preference if 86 // PrefService::Preference::IsExtensionModifiable() returns true as well. 87 bool CanExtensionControlPref(const std::string& extension_id, 88 const std::string& pref_key, 89 bool incognito) const; 90 91 // Returns true if an extension identified by |extension_id| controls the 92 // preference. This means this extension has set a preference value and no 93 // other extension with higher precedence overrides it. 94 // Note that the this function does does not consider the existence of 95 // policies. An extension is only really able to control a preference if 96 // PrefService::Preference::IsExtensionModifiable() returns true as well. 97 bool DoesExtensionControlPref(const std::string& extension_id, 98 const std::string& pref_key, 99 bool incognito) const; 100 101 // Tell the store it's now fully initialized. 102 void NotifyInitializationCompleted(); 103 104 // Registers the time when an extension |ext_id| is installed. 105 void RegisterExtension(const std::string& ext_id, 106 const base::Time& install_time, 107 bool is_enabled); 108 109 // Deletes all entries related to extension |ext_id|. 110 void UnregisterExtension(const std::string& ext_id); 111 112 // Hides or makes the extension preference values of the specified extension 113 // visible. 114 void SetExtensionState(const std::string& ext_id, bool is_enabled); 115 116 // Adds an observer and notifies it about the currently stored keys. 117 void AddObserver(Observer* observer); 118 119 void RemoveObserver(Observer* observer); 120 121 const Value* GetEffectivePrefValue(const std::string& key, 122 bool incognito, 123 bool* from_incognito) const; 124 125 private: 126 struct ExtensionEntry; 127 128 typedef std::map<std::string, ExtensionEntry*> ExtensionEntryMap; 129 130 const PrefValueMap* GetExtensionPrefValueMap(const std::string& ext_id, 131 bool incognito) const; 132 133 PrefValueMap* GetExtensionPrefValueMap(const std::string& ext_id, 134 bool incognito); 135 136 // Returns all keys of pref values that are set by the extension of |entry|, 137 // regardless whether they are set for incognito or regular pref values. 138 void GetExtensionControlledKeys(const ExtensionEntry& entry, 139 std::set<std::string>* out) const; 140 141 // Returns an iterator to the extension which controls the preference |key|. 142 // If |incognito| is true, looks at incognito preferences first. In that case, 143 // if |from_incognito| is not NULL, it is set to true if the effective pref 144 // value is coming from the incognito preferences, false if it is coming from 145 // the normal ones. 146 ExtensionEntryMap::const_iterator GetEffectivePrefValueController( 147 const std::string& key, 148 bool incognito, 149 bool* from_incognito) const; 150 151 void NotifyOfDestruction(); 152 void NotifyPrefValueChanged(const std::string& key); 153 void NotifyPrefValueChanged(const std::set<std::string>& keys); 154 155 // Mapping of which extension set which preference value. The effective 156 // preferences values (i.e. the ones with the highest precedence) 157 // are stored in ExtensionPrefStores. 158 ExtensionEntryMap entries_; 159 160 ObserverList<Observer, true> observers_; 161 162 DISALLOW_COPY_AND_ASSIGN(ExtensionPrefValueMap); 163 }; 164 165 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_PREF_VALUE_MAP_H_ 166