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