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