1 // Copyright (c) 2012 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_API_PREFERENCE_PREFERENCE_API_H__ 6 #define CHROME_BROWSER_EXTENSIONS_API_PREFERENCE_PREFERENCE_API_H__ 7 8 #include <string> 9 10 #include "base/prefs/pref_change_registrar.h" 11 #include "chrome/browser/extensions/api/content_settings/content_settings_store.h" 12 #include "chrome/browser/extensions/api/profile_keyed_api_factory.h" 13 #include "chrome/browser/extensions/chrome_extension_function.h" 14 #include "content/public/browser/notification_observer.h" 15 #include "extensions/browser/event_router.h" 16 #include "extensions/browser/extension_prefs_scope.h" 17 18 class ExtensionPrefValueMap; 19 class PrefService; 20 21 namespace base { 22 class Value; 23 } 24 25 namespace extensions { 26 class ExtensionPrefs; 27 28 class PreferenceEventRouter { 29 public: 30 explicit PreferenceEventRouter(Profile* profile); 31 virtual ~PreferenceEventRouter(); 32 33 private: 34 void OnPrefChanged(PrefService* pref_service, 35 const std::string& pref_key); 36 37 PrefChangeRegistrar registrar_; 38 PrefChangeRegistrar incognito_registrar_; 39 40 // Weak, owns us (transitively via ExtensionService). 41 Profile* profile_; 42 43 DISALLOW_COPY_AND_ASSIGN(PreferenceEventRouter); 44 }; 45 46 // The class containing the implementation for extension-controlled preference 47 // manipulation. This implementation is separate from PreferenceAPI, since 48 // we need to be able to use these methods in testing, where we use 49 // TestExtensionPrefs and don't construct a profile. 50 // 51 // See also PreferenceAPI and TestPreferenceAPI. 52 class PreferenceAPIBase { 53 public: 54 // Functions for manipulating preference values that are controlled by the 55 // extension. In other words, these are not pref values *about* the extension, 56 // but rather about something global the extension wants to override. 57 58 // Set a new extension-controlled preference value. 59 // Takes ownership of |value|. 60 void SetExtensionControlledPref(const std::string& extension_id, 61 const std::string& pref_key, 62 ExtensionPrefsScope scope, 63 base::Value* value); 64 65 // Remove an extension-controlled preference value. 66 void RemoveExtensionControlledPref(const std::string& extension_id, 67 const std::string& pref_key, 68 ExtensionPrefsScope scope); 69 70 // Returns true if currently no extension with higher precedence controls the 71 // preference. 72 bool CanExtensionControlPref(const std::string& extension_id, 73 const std::string& pref_key, 74 bool incognito); 75 76 // Returns true if extension |extension_id| currently controls the 77 // preference. If |from_incognito| is not NULL, looks at incognito preferences 78 // first, and |from_incognito| is set to true if the effective pref value is 79 // coming from the incognito preferences, false if it is coming from the 80 // normal ones. 81 bool DoesExtensionControlPref(const std::string& extension_id, 82 const std::string& pref_key, 83 bool* from_incognito); 84 85 protected: 86 // Virtual for testing. 87 virtual ExtensionPrefs* extension_prefs() = 0; 88 virtual ExtensionPrefValueMap* extension_pref_value_map() = 0; 89 }; 90 91 class PreferenceAPI : public PreferenceAPIBase, 92 public ProfileKeyedAPI, 93 public EventRouter::Observer, 94 public ContentSettingsStore::Observer { 95 public: 96 explicit PreferenceAPI(Profile* profile); 97 virtual ~PreferenceAPI(); 98 99 // BrowserContextKeyedService implementation. 100 virtual void Shutdown() OVERRIDE; 101 102 // ProfileKeyedAPI implementation. 103 static ProfileKeyedAPIFactory<PreferenceAPI>* GetFactoryInstance(); 104 105 // Convenience method to get the PreferenceAPI for a profile. 106 static PreferenceAPI* Get(Profile* profile); 107 108 // EventRouter::Observer implementation. 109 virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE; 110 111 // Loads the preferences controlled by the specified extension from their 112 // dictionary and sets them in the |value_map|. 113 static void LoadExtensionControlledPrefs(ExtensionPrefs* prefs, 114 ExtensionPrefValueMap* value_map, 115 const std::string& extension_id, 116 ExtensionPrefsScope scope); 117 118 // Store extension controlled preference values in the |value_map|, 119 // which then informs the subscribers (ExtensionPrefStores) about the winning 120 // values. 121 static void InitExtensionControlledPrefs(ExtensionPrefs* prefs, 122 ExtensionPrefValueMap* value_map); 123 124 private: 125 friend class ProfileKeyedAPIFactory<PreferenceAPI>; 126 127 // ContentSettingsStore::Observer implementation. 128 virtual void OnContentSettingChanged(const std::string& extension_id, 129 bool incognito) OVERRIDE; 130 131 // Clears incognito session-only content settings for all extensions. 132 void ClearIncognitoSessionOnlyContentSettings(); 133 134 // PreferenceAPIBase implementation. 135 virtual ExtensionPrefs* extension_prefs() OVERRIDE; 136 virtual ExtensionPrefValueMap* extension_pref_value_map() OVERRIDE; 137 138 Profile* profile_; 139 140 // ProfileKeyedAPI implementation. service_name()141 static const char* service_name() { 142 return "PreferenceAPI"; 143 } 144 static const bool kServiceIsNULLWhileTesting = true; 145 static const bool kServiceRedirectedInIncognito = true; 146 147 // Created lazily upon OnListenerAdded. 148 scoped_ptr<PreferenceEventRouter> preference_event_router_; 149 150 DISALLOW_COPY_AND_ASSIGN(PreferenceAPI); 151 }; 152 153 class PrefTransformerInterface { 154 public: ~PrefTransformerInterface()155 virtual ~PrefTransformerInterface() {} 156 157 // Converts the representation of a preference as seen by the extension 158 // into a representation that is used in the pref stores of the browser. 159 // Returns the pref store representation in case of success or sets 160 // |error| and returns NULL otherwise. |bad_message| is passed to simulate 161 // the behavior of EXTENSION_FUNCTION_VALIDATE. It is never NULL. 162 // The ownership of the returned value is passed to the caller. 163 virtual base::Value* ExtensionToBrowserPref( 164 const base::Value* extension_pref, 165 std::string* error, 166 bool* bad_message) = 0; 167 168 // Converts the representation of the preference as stored in the browser 169 // into a representation that is used by the extension. 170 // Returns the extension representation in case of success or NULL otherwise. 171 // The ownership of the returned value is passed to the caller. 172 virtual base::Value* BrowserToExtensionPref( 173 const base::Value* browser_pref) = 0; 174 }; 175 176 // A base class to provide functionality common to the other *PreferenceFunction 177 // classes. 178 class PreferenceFunction : public ChromeSyncExtensionFunction { 179 protected: 180 virtual ~PreferenceFunction(); 181 182 // Given an |extension_pref_key|, provides its |browser_pref_key| from the 183 // static map in preference_api.cc. Returns true if the corresponding 184 // browser pref exists and the extension has the API permission needed to 185 // modify that pref. Sets |error_| if the extension doesn't have the needed 186 // permission. 187 bool ValidateBrowserPref(const std::string& extension_pref_key, 188 std::string* browser_pref_key); 189 }; 190 191 class GetPreferenceFunction : public PreferenceFunction { 192 public: 193 DECLARE_EXTENSION_FUNCTION("types.ChromeSetting.get", TYPES_CHROMESETTING_GET) 194 195 protected: 196 virtual ~GetPreferenceFunction(); 197 198 // ExtensionFunction: 199 virtual bool RunImpl() OVERRIDE; 200 }; 201 202 class SetPreferenceFunction : public PreferenceFunction { 203 public: 204 DECLARE_EXTENSION_FUNCTION("types.ChromeSetting.set", TYPES_CHROMESETTING_SET) 205 206 protected: 207 virtual ~SetPreferenceFunction(); 208 209 // ExtensionFunction: 210 virtual bool RunImpl() OVERRIDE; 211 }; 212 213 class ClearPreferenceFunction : public PreferenceFunction { 214 public: 215 DECLARE_EXTENSION_FUNCTION("types.ChromeSetting.clear", 216 TYPES_CHROMESETTING_CLEAR) 217 218 protected: 219 virtual ~ClearPreferenceFunction(); 220 221 // ExtensionFunction: 222 virtual bool RunImpl() OVERRIDE; 223 }; 224 225 } // namespace extensions 226 227 #endif // CHROME_BROWSER_EXTENSIONS_API_PREFERENCE_PREFERENCE_API_H__ 228