Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(394)

Side by Side Diff: chrome/browser/extensions/extension_font_settings_api.cc

Issue 10830180: Moving font_settings extensions API to api/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Moving "namespace extensions" up Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 // Font Settings Extension API implementation.
6
7 #include "chrome/browser/extensions/extension_font_settings_api.h"
8
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/json/json_writer.h"
12 #include "base/stringprintf.h"
13 #include "base/string_util.h"
14 #include "base/values.h"
15 #include "chrome/browser/extensions/extension_preference_helpers.h"
16 #include "chrome/browser/extensions/extension_service.h"
17 #include "chrome/browser/prefs/pref_service.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/common/chrome_notification_types.h"
20 #include "chrome/common/extensions/api/font_settings.h"
21 #include "chrome/common/extensions/extension_error_utils.h"
22 #include "chrome/common/pref_names.h"
23 #include "content/public/browser/font_list_async.h"
24 #include "content/public/browser/notification_details.h"
25 #include "content/public/browser/notification_source.h"
26
27 #if defined(OS_WIN)
28 #include "ui/gfx/font.h"
29 #include "ui/gfx/platform_font_win.h"
30 #endif
31
32 using extensions::APIPermission;
33
34 namespace fonts = extensions::api::font_settings;
35
36 namespace {
37
38 const char kFontIdKey[] = "fontId";
39 const char kGenericFamilyKey[] = "genericFamily";
40 const char kLevelOfControlKey[] = "levelOfControl";
41 const char kDisplayNameKey[] = "displayName";
42 const char kPixelSizeKey[] = "pixelSize";
43 const char kScriptKey[] = "script";
44
45 const char kSetFromIncognitoError[] =
46 "Can't modify regular settings from an incognito context.";
47
48 const char kOnDefaultFixedFontSizeChanged[] =
49 "fontSettings.onDefaultFixedFontSizeChanged";
50 const char kOnDefaultFontSizeChanged[] =
51 "fontSettings.onDefaultFontSizeChanged";
52 const char kOnFontChanged[] = "fontSettings.onFontChanged";
53 const char kOnMinimumFontSizeChanged[] =
54 "fontSettings.onMinimumFontSizeChanged";
55
56 // Format for font name preference paths.
57 const char kWebKitFontPrefFormat[] = "webkit.webprefs.fonts.%s.%s";
58 const char kWebKitFontPrefPrefix[] = "webkit.webprefs.fonts.";
59
60 // Gets the font name preference path for |generic_family| and |script|. If
61 // |script| is NULL, uses prefs::kWebKitCommonScript.
62 std::string GetFontNamePrefPath(const std::string& generic_family,
63 const std::string* script) {
64 return StringPrintf(kWebKitFontPrefFormat,
65 generic_family.c_str(),
66 script ? script->c_str() : prefs::kWebKitCommonScript);
67 }
68
69 // Extracts the generic family and script from font name pref path |pref_path|.
70 bool ParseFontNamePrefPath(std::string pref_path,
71 std::string* generic_family,
72 std::string* script) {
73 if (!StartsWithASCII(pref_path, kWebKitFontPrefPrefix, true))
74 return false;
75
76 size_t start = strlen(kWebKitFontPrefPrefix);
77 size_t pos = pref_path.find('.', start);
78 if (pos == std::string::npos || pos + 1 == pref_path.length())
79 return false;
80 *generic_family = pref_path.substr(start, pos - start);
81 *script = pref_path.substr(pos + 1);
82 return true;
83 }
84
85 // Returns the localized name of a font so that it can be matched within the
86 // list of system fonts. On Windows, the list of system fonts has names only
87 // for the system locale, but the pref value may be in the English name.
88 std::string MaybeGetLocalizedFontName(const std::string& font_name) {
89 #if defined(OS_WIN)
90 if (!font_name.empty()) {
91 gfx::Font font(font_name, 12); // dummy font size
92 return static_cast<gfx::PlatformFontWin*>(font.platform_font())->
93 GetLocalizedFontName();
94 }
95 #endif
96 return font_name;
97 }
98
99 // Registers |obs| to observe per-script font prefs under the path |map_name|.
100 void RegisterFontFamilyMapObserver(PrefChangeRegistrar* registrar,
101 const char* map_name,
102 content::NotificationObserver* obs) {
103 for (size_t i = 0; i < prefs::kWebKitScriptsForFontFamilyMapsLength; ++i) {
104 const char* script = prefs::kWebKitScriptsForFontFamilyMaps[i];
105 std::string pref_name = base::StringPrintf("%s.%s", map_name, script);
106 registrar->Add(pref_name.c_str(), obs);
107 }
108 }
109
110 } // namespace
111
112 ExtensionFontSettingsEventRouter::ExtensionFontSettingsEventRouter(
113 Profile* profile) : profile_(profile) {}
114
115 ExtensionFontSettingsEventRouter::~ExtensionFontSettingsEventRouter() {}
116
117 void ExtensionFontSettingsEventRouter::Init() {
118 registrar_.Init(profile_->GetPrefs());
119
120 AddPrefToObserve(prefs::kWebKitDefaultFixedFontSize,
121 kOnDefaultFixedFontSizeChanged,
122 kPixelSizeKey);
123 AddPrefToObserve(prefs::kWebKitDefaultFontSize,
124 kOnDefaultFontSizeChanged,
125 kPixelSizeKey);
126 AddPrefToObserve(prefs::kWebKitMinimumFontSize,
127 kOnMinimumFontSizeChanged,
128 kPixelSizeKey);
129
130 RegisterFontFamilyMapObserver(&registrar_,
131 prefs::kWebKitStandardFontFamilyMap, this);
132 RegisterFontFamilyMapObserver(&registrar_,
133 prefs::kWebKitSerifFontFamilyMap, this);
134 RegisterFontFamilyMapObserver(&registrar_,
135 prefs::kWebKitSansSerifFontFamilyMap, this);
136 RegisterFontFamilyMapObserver(&registrar_,
137 prefs::kWebKitFixedFontFamilyMap, this);
138 RegisterFontFamilyMapObserver(&registrar_,
139 prefs::kWebKitCursiveFontFamilyMap, this);
140 RegisterFontFamilyMapObserver(&registrar_,
141 prefs::kWebKitFantasyFontFamilyMap, this);
142 }
143
144 void ExtensionFontSettingsEventRouter::AddPrefToObserve(const char* pref_name,
145 const char* event_name,
146 const char* key) {
147 registrar_.Add(pref_name, this);
148 pref_event_map_[pref_name] = std::make_pair(event_name, key);
149 }
150
151 void ExtensionFontSettingsEventRouter::Observe(
152 int type,
153 const content::NotificationSource& source,
154 const content::NotificationDetails& details) {
155 if (type != chrome::NOTIFICATION_PREF_CHANGED) {
156 NOTREACHED();
157 return;
158 }
159
160 PrefService* pref_service = content::Source<PrefService>(source).ptr();
161 bool incognito = (pref_service != profile_->GetPrefs());
162 // We're only observing pref changes on the regular profile.
163 DCHECK(!incognito);
164 const std::string* pref_name =
165 content::Details<const std::string>(details).ptr();
166
167 PrefEventMap::iterator iter = pref_event_map_.find(*pref_name);
168 if (iter != pref_event_map_.end()) {
169 const std::string& event_name = iter->second.first;
170 const std::string& key = iter->second.second;
171 OnFontPrefChanged(pref_service, *pref_name, event_name, key, incognito);
172 return;
173 }
174
175 std::string generic_family;
176 std::string script;
177 if (ParseFontNamePrefPath(*pref_name, &generic_family, &script)) {
178 OnFontNamePrefChanged(pref_service, *pref_name, generic_family, script,
179 incognito);
180 return;
181 }
182
183 NOTREACHED();
184 }
185
186 void ExtensionFontSettingsEventRouter::OnFontNamePrefChanged(
187 PrefService* pref_service,
188 const std::string& pref_name,
189 const std::string& generic_family,
190 const std::string& script,
191 bool incognito) {
192 const PrefService::Preference* pref = pref_service->FindPreference(
193 pref_name.c_str());
194 CHECK(pref);
195
196 std::string font_name;
197 if (!pref->GetValue()->GetAsString(&font_name)) {
198 NOTREACHED();
199 return;
200 }
201 font_name = MaybeGetLocalizedFontName(font_name);
202
203 ListValue args;
204 DictionaryValue* dict = new DictionaryValue();
205 args.Append(dict);
206 dict->SetString(kFontIdKey, font_name);
207 dict->SetString(kGenericFamilyKey, generic_family);
208 dict->SetString(kScriptKey, script);
209
210 extension_preference_helpers::DispatchEventToExtensions(
211 profile_,
212 kOnFontChanged,
213 &args,
214 APIPermission::kFontSettings,
215 incognito,
216 pref_name);
217 }
218
219 void ExtensionFontSettingsEventRouter::OnFontPrefChanged(
220 PrefService* pref_service,
221 const std::string& pref_name,
222 const std::string& event_name,
223 const std::string& key,
224 bool incognito) {
225 const PrefService::Preference* pref = pref_service->FindPreference(
226 pref_name.c_str());
227 CHECK(pref);
228
229 ListValue args;
230 DictionaryValue* dict = new DictionaryValue();
231 args.Append(dict);
232 dict->Set(key, pref->GetValue()->DeepCopy());
233
234 extension_preference_helpers::DispatchEventToExtensions(
235 profile_,
236 event_name,
237 &args,
238 APIPermission::kFontSettings,
239 incognito,
240 pref_name);
241 }
242
243 bool ClearFontFunction::RunImpl() {
244 if (profile_->IsOffTheRecord()) {
245 error_ = kSetFromIncognitoError;
246 return false;
247 }
248
249 scoped_ptr<fonts::ClearFont::Params> params(
250 fonts::ClearFont::Params::Create(*args_));
251 EXTENSION_FUNCTION_VALIDATE(params.get());
252
253 std::string pref_path = GetFontNamePrefPath(params->details.generic_family,
254 params->details.script.get());
255
256 // Ensure |pref_path| really is for a registered per-script font pref.
257 EXTENSION_FUNCTION_VALIDATE(
258 profile_->GetPrefs()->FindPreference(pref_path.c_str()));
259
260 extensions::ExtensionPrefs* prefs =
261 profile_->GetExtensionService()->extension_prefs();
262 prefs->RemoveExtensionControlledPref(extension_id(),
263 pref_path.c_str(),
264 extensions::kExtensionPrefsScopeRegular);
265 return true;
266 }
267
268 bool GetFontFunction::RunImpl() {
269 scoped_ptr<fonts::GetFont::Params> params(
270 fonts::GetFont::Params::Create(*args_));
271 EXTENSION_FUNCTION_VALIDATE(params.get());
272
273 std::string pref_path = GetFontNamePrefPath(params->details.generic_family,
274 params->details.script.get());
275 PrefService* prefs = profile_->GetPrefs();
276 const PrefService::Preference* pref =
277 prefs->FindPreference(pref_path.c_str());
278
279 std::string font_name;
280 EXTENSION_FUNCTION_VALIDATE(
281 pref && pref->GetValue()->GetAsString(&font_name));
282 font_name = MaybeGetLocalizedFontName(font_name);
283
284 // We don't support incognito-specific font prefs, so don't consider them when
285 // getting level of control.
286 const bool kIncognito = false;
287 std::string level_of_control =
288 extension_preference_helpers::GetLevelOfControl(profile_,
289 extension_id(),
290 pref_path,
291 kIncognito);
292
293 DictionaryValue* result = new DictionaryValue();
294 result->SetString(kFontIdKey, font_name);
295 result->SetString(kLevelOfControlKey, level_of_control);
296 SetResult(result);
297 return true;
298 }
299
300 bool SetFontFunction::RunImpl() {
301 if (profile_->IsOffTheRecord()) {
302 error_ = kSetFromIncognitoError;
303 return false;
304 }
305
306 scoped_ptr<fonts::SetFont::Params> params(
307 fonts::SetFont::Params::Create(*args_));
308 EXTENSION_FUNCTION_VALIDATE(params.get());
309
310 std::string pref_path = GetFontNamePrefPath(params->details.generic_family,
311 params->details.script.get());
312 // Ensure |pref_path| really is for a registered font pref.
313 EXTENSION_FUNCTION_VALIDATE(
314 profile_->GetPrefs()->FindPreference(pref_path.c_str()));
315
316 extensions::ExtensionPrefs* prefs =
317 profile_->GetExtensionService()->extension_prefs();
318 prefs->SetExtensionControlledPref(
319 extension_id(),
320 pref_path.c_str(),
321 extensions::kExtensionPrefsScopeRegular,
322 Value::CreateStringValue(params->details.font_id));
323 return true;
324 }
325
326 bool GetFontListFunction::RunImpl() {
327 content::GetFontListAsync(
328 Bind(&GetFontListFunction::FontListHasLoaded, this));
329 return true;
330 }
331
332 void GetFontListFunction::FontListHasLoaded(scoped_ptr<ListValue> list) {
333 bool success = CopyFontsToResult(list.get());
334 SendResponse(success);
335 }
336
337 bool GetFontListFunction::CopyFontsToResult(ListValue* fonts) {
338 scoped_ptr<ListValue> result(new ListValue());
339 for (ListValue::iterator it = fonts->begin(); it != fonts->end(); ++it) {
340 ListValue* font_list_value;
341 if (!(*it)->GetAsList(&font_list_value)) {
342 NOTREACHED();
343 return false;
344 }
345
346 std::string name;
347 if (!font_list_value->GetString(0, &name)) {
348 NOTREACHED();
349 return false;
350 }
351
352 std::string localized_name;
353 if (!font_list_value->GetString(1, &localized_name)) {
354 NOTREACHED();
355 return false;
356 }
357
358 DictionaryValue* font_name = new DictionaryValue();
359 font_name->Set(kFontIdKey, Value::CreateStringValue(name));
360 font_name->Set(kDisplayNameKey, Value::CreateStringValue(localized_name));
361 result->Append(font_name);
362 }
363
364 SetResult(result.release());
365 return true;
366 }
367
368 bool ClearFontPrefExtensionFunction::RunImpl() {
369 if (profile_->IsOffTheRecord()) {
370 error_ = kSetFromIncognitoError;
371 return false;
372 }
373
374 extensions::ExtensionPrefs* prefs =
375 profile_->GetExtensionService()->extension_prefs();
376 prefs->RemoveExtensionControlledPref(extension_id(),
377 GetPrefName(),
378 extensions::kExtensionPrefsScopeRegular);
379 return true;
380 }
381
382 bool GetFontPrefExtensionFunction::RunImpl() {
383 PrefService* prefs = profile_->GetPrefs();
384 const PrefService::Preference* pref = prefs->FindPreference(GetPrefName());
385 EXTENSION_FUNCTION_VALIDATE(pref);
386
387 // We don't support incognito-specific font prefs, so don't consider them when
388 // getting level of control.
389 const bool kIncognito = false;
390
391 std::string level_of_control =
392 extension_preference_helpers::GetLevelOfControl(profile_,
393 extension_id(),
394 GetPrefName(),
395 kIncognito);
396
397 DictionaryValue* result = new DictionaryValue();
398 result->Set(GetKey(), pref->GetValue()->DeepCopy());
399 result->SetString(kLevelOfControlKey, level_of_control);
400 SetResult(result);
401 return true;
402 }
403
404 bool SetFontPrefExtensionFunction::RunImpl() {
405 if (profile_->IsOffTheRecord()) {
406 error_ = kSetFromIncognitoError;
407 return false;
408 }
409
410 DictionaryValue* details = NULL;
411 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details));
412
413 Value* value;
414 EXTENSION_FUNCTION_VALIDATE(details->Get(GetKey(), &value));
415
416 extensions::ExtensionPrefs* prefs =
417 profile_->GetExtensionService()->extension_prefs();
418 prefs->SetExtensionControlledPref(extension_id(),
419 GetPrefName(),
420 extensions::kExtensionPrefsScopeRegular,
421 value->DeepCopy());
422 return true;
423 }
424
425 const char* ClearDefaultFontSizeFunction::GetPrefName() {
426 return prefs::kWebKitDefaultFontSize;
427 }
428
429 const char* GetDefaultFontSizeFunction::GetPrefName() {
430 return prefs::kWebKitDefaultFontSize;
431 }
432
433 const char* GetDefaultFontSizeFunction::GetKey() {
434 return kPixelSizeKey;
435 }
436
437 const char* SetDefaultFontSizeFunction::GetPrefName() {
438 return prefs::kWebKitDefaultFontSize;
439 }
440
441 const char* SetDefaultFontSizeFunction::GetKey() {
442 return kPixelSizeKey;
443 }
444
445 const char* ClearDefaultFixedFontSizeFunction::GetPrefName() {
446 return prefs::kWebKitDefaultFixedFontSize;
447 }
448
449 const char* GetDefaultFixedFontSizeFunction::GetPrefName() {
450 return prefs::kWebKitDefaultFixedFontSize;
451 }
452
453 const char* GetDefaultFixedFontSizeFunction::GetKey() {
454 return kPixelSizeKey;
455 }
456
457 const char* SetDefaultFixedFontSizeFunction::GetPrefName() {
458 return prefs::kWebKitDefaultFixedFontSize;
459 }
460
461 const char* SetDefaultFixedFontSizeFunction::GetKey() {
462 return kPixelSizeKey;
463 }
464
465 const char* ClearMinimumFontSizeFunction::GetPrefName() {
466 return prefs::kWebKitMinimumFontSize;
467 }
468
469 const char* GetMinimumFontSizeFunction::GetPrefName() {
470 return prefs::kWebKitMinimumFontSize;
471 }
472
473 const char* GetMinimumFontSizeFunction::GetKey() {
474 return kPixelSizeKey;
475 }
476
477 const char* SetMinimumFontSizeFunction::GetPrefName() {
478 return prefs::kWebKitMinimumFontSize;
479 }
480
481 const char* SetMinimumFontSizeFunction::GetKey() {
482 return kPixelSizeKey;
483 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_font_settings_api.h ('k') | chrome/browser/extensions/extension_font_settings_apitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698