Home | History | Annotate | Download | only in preference
      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/event_router.h"
     14 #include "chrome/browser/extensions/extension_function.h"
     15 #include "content/public/browser/notification_observer.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.
    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:
    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 SyncExtensionFunction {
    179  protected:
    180   virtual ~PreferenceFunction();
    181 
    182   // Given an |extension_pref_key|, provides its |browser_pref_key| from the
    183   // static map in extension_preference.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