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
221
222
223
224
225
226
227
|
// 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/prefs/pref_change_registrar.h"
#include "chrome/browser/extensions/api/content_settings/content_settings_store.h"
#include "chrome/browser/extensions/api/profile_keyed_api_factory.h"
#include "chrome/browser/extensions/chrome_extension_function.h"
#include "chrome/browser/extensions/event_router.h"
#include "content/public/browser/notification_observer.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;
};
class PreferenceAPI : public PreferenceAPIBase,
public ProfileKeyedAPI,
public EventRouter::Observer,
public ContentSettingsStore::Observer {
public:
explicit PreferenceAPI(Profile* profile);
virtual ~PreferenceAPI();
// BrowserContextKeyedService implementation.
virtual void Shutdown() OVERRIDE;
// ProfileKeyedAPI implementation.
static ProfileKeyedAPIFactory<PreferenceAPI>* GetFactoryInstance();
// Convenience method to get the PreferenceAPI for a profile.
static PreferenceAPI* Get(Profile* profile);
// EventRouter::Observer implementation.
virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE;
// Loads the preferences controlled by the specified extension from their
// dictionary and sets them in the |value_map|.
static void LoadExtensionControlledPrefs(ExtensionPrefs* prefs,
ExtensionPrefValueMap* value_map,
const std::string& extension_id,
ExtensionPrefsScope scope);
// Store extension controlled preference values in the |value_map|,
// which then informs the subscribers (ExtensionPrefStores) about the winning
// values.
static void InitExtensionControlledPrefs(ExtensionPrefs* prefs,
ExtensionPrefValueMap* value_map);
private:
friend class ProfileKeyedAPIFactory<PreferenceAPI>;
// ContentSettingsStore::Observer implementation.
virtual void OnContentSettingChanged(const std::string& extension_id,
bool incognito) OVERRIDE;
// Clears incognito session-only content settings for all extensions.
void ClearIncognitoSessionOnlyContentSettings();
// PreferenceAPIBase implementation.
virtual ExtensionPrefs* extension_prefs() OVERRIDE;
virtual ExtensionPrefValueMap* extension_pref_value_map() OVERRIDE;
Profile* profile_;
// ProfileKeyedAPI 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:
virtual ~PreferenceFunction();
// 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,
std::string* browser_pref_key);
};
class GetPreferenceFunction : public PreferenceFunction {
public:
DECLARE_EXTENSION_FUNCTION("types.ChromeSetting.get", TYPES_CHROMESETTING_GET)
protected:
virtual ~GetPreferenceFunction();
// ExtensionFunction:
virtual bool RunImpl() OVERRIDE;
};
class SetPreferenceFunction : public PreferenceFunction {
public:
DECLARE_EXTENSION_FUNCTION("types.ChromeSetting.set", TYPES_CHROMESETTING_SET)
protected:
virtual ~SetPreferenceFunction();
// ExtensionFunction:
virtual bool RunImpl() OVERRIDE;
};
class ClearPreferenceFunction : public PreferenceFunction {
public:
DECLARE_EXTENSION_FUNCTION("types.ChromeSetting.clear",
TYPES_CHROMESETTING_CLEAR)
protected:
virtual ~ClearPreferenceFunction();
// ExtensionFunction:
virtual bool RunImpl() OVERRIDE;
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_PREFERENCE_PREFERENCE_API_H__
|