OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_web_ui.h" | 5 #include "chrome/browser/extensions/extension_web_ui.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 29 matching lines...) Expand all Loading... | |
40 #include "ui/gfx/codec/png_codec.h" | 40 #include "ui/gfx/codec/png_codec.h" |
41 #include "ui/gfx/favicon_size.h" | 41 #include "ui/gfx/favicon_size.h" |
42 #include "ui/gfx/image/image_skia.h" | 42 #include "ui/gfx/image/image_skia.h" |
43 | 43 |
44 using content::WebContents; | 44 using content::WebContents; |
45 using extensions::Extension; | 45 using extensions::Extension; |
46 using extensions::URLOverrides; | 46 using extensions::URLOverrides; |
47 | 47 |
48 namespace { | 48 namespace { |
49 | 49 |
50 // De-dupes the items in |list|. Assumes the values are strings. | 50 // The key to the override value for a page. |
51 void CleanUpDuplicates(base::ListValue* list) { | 51 const char kEntry[] = "entry"; |
52 std::set<std::string> seen_values; | 52 // The key to whether or not the override is active (i.e., can be used). |
53 // Overrides may be inactive e.g. when an extension is disabled. | |
54 const char kActive[] = "active"; | |
53 | 55 |
54 // Loop backwards as we may be removing items. | 56 // Iterates over |list| and: |
55 for (size_t i = list->GetSize() - 1; (i + 1) > 0; --i) { | 57 // - Converts any entries of the form <entry> to |
56 std::string value; | 58 // { 'entry': <entry>, 'active': true }. |
57 if (!list->GetString(i, &value)) { | 59 // - Removes any duplicate entries. |
60 // We do the conversion because we previously stored these values as strings | |
61 // rather than objects. | |
62 // TODO(devlin): Remove the conversion once everyone's updated. | |
63 void InitializeOverridesList(base::ListValue* list) { | |
Devlin
2015/12/22 23:31:23
Transforming prefs. Yuck. But I can't think of a
| |
64 base::ListValue migrated; | |
65 std::set<std::string> seen_entries; | |
66 for (base::Value* val : *list) { | |
67 scoped_ptr<base::DictionaryValue> new_dict(new base::DictionaryValue()); | |
68 std::string entry_name; | |
69 base::DictionaryValue* existing_dict = nullptr; | |
70 if (val->GetAsDictionary(&existing_dict)) { | |
71 CHECK(existing_dict->GetString(kEntry, &entry_name)); | |
72 new_dict->Swap(existing_dict); | |
73 } else if (val->GetAsString(&entry_name)) { | |
74 new_dict->SetString(kEntry, entry_name); | |
75 new_dict->SetBoolean(kActive, true); | |
76 } else { | |
58 NOTREACHED(); | 77 NOTREACHED(); |
59 continue; | 78 continue; |
60 } | 79 } |
61 | 80 |
62 if (seen_values.find(value) == seen_values.end()) | 81 if (seen_entries.count(entry_name) == 0) { |
63 seen_values.insert(value); | 82 seen_entries.insert(entry_name); |
64 else | 83 migrated.Append(std::move(new_dict)); |
65 list->Remove(i, NULL); | 84 } |
66 } | 85 } |
86 | |
87 list->Swap(&migrated); | |
88 } | |
89 | |
90 // Adds |override| to |list|, or, if there's already an entry for the override, | |
91 // marks it as active. | |
92 void AddOverridesToList(base::ListValue* list, | |
93 const std::string& override) { | |
94 for (base::Value* val : *list) { | |
95 base::DictionaryValue* dict = nullptr; | |
96 std::string entry; | |
97 if (!val->GetAsDictionary(&dict) || !dict->GetString(kEntry, &entry)) { | |
98 NOTREACHED(); | |
99 continue; | |
100 } | |
101 if (entry == override) { | |
102 dict->SetBoolean(kActive, true); | |
103 return; // All done! | |
104 } | |
105 } | |
106 | |
107 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | |
108 dict->SetString(kEntry, override); | |
109 dict->SetBoolean(kActive, true); | |
110 // Add the entry to the front of the list. | |
111 list->Insert(0, dict.release()); | |
112 } | |
113 | |
114 // Validates that each entry in |list| contains a valid url and points to an | |
115 // extension contained in |all_extensions| (and, if not, removes it). | |
116 void ValidateOverridesList(base::ListValue* list, | |
117 const extensions::ExtensionSet& all_extensions) { | |
118 base::ListValue migrated; | |
119 for (base::Value* val : *list) { | |
120 base::DictionaryValue* dict = nullptr; | |
121 std::string entry; | |
122 if (!val->GetAsDictionary(&dict) || !dict->GetString(kEntry, &entry)) { | |
123 NOTREACHED(); | |
124 continue; | |
125 } | |
126 scoped_ptr<base::DictionaryValue> new_dict(new base::DictionaryValue()); | |
127 new_dict->Swap(dict); | |
128 GURL override_url(entry); | |
129 if (!override_url.is_valid()) | |
130 continue; | |
131 | |
132 if (!all_extensions.GetByID(override_url.host())) | |
133 continue; | |
134 | |
135 migrated.Append(std::move(new_dict)); | |
136 } | |
137 | |
138 list->Swap(&migrated); | |
67 } | 139 } |
68 | 140 |
69 // Reloads the page in |web_contents| if it uses the same profile as |profile| | 141 // Reloads the page in |web_contents| if it uses the same profile as |profile| |
70 // and if the current URL is a chrome URL. | 142 // and if the current URL is a chrome URL. |
71 void UnregisterAndReplaceOverrideForWebContents(const std::string& page, | 143 void UnregisterAndReplaceOverrideForWebContents(const std::string& page, |
72 Profile* profile, | 144 Profile* profile, |
73 WebContents* web_contents) { | 145 WebContents* web_contents) { |
74 if (Profile::FromBrowserContext(web_contents->GetBrowserContext()) != profile) | 146 if (Profile::FromBrowserContext(web_contents->GetBrowserContext()) != profile) |
75 return; | 147 return; |
76 | 148 |
77 GURL url = web_contents->GetURL(); | 149 GURL url = web_contents->GetURL(); |
78 if (!url.SchemeIs(content::kChromeUIScheme) || url.host_piece() != page) | 150 if (!url.SchemeIs(content::kChromeUIScheme) || url.host_piece() != page) |
79 return; | 151 return; |
80 | 152 |
81 // Don't use Reload() since |url| isn't the same as the internal URL that | 153 // Don't use Reload() since |url| isn't the same as the internal URL that |
82 // NavigationController has. | 154 // NavigationController has. |
83 web_contents->GetController().LoadURL( | 155 web_contents->GetController().LoadURL( |
84 url, content::Referrer::SanitizeForRequest( | 156 url, content::Referrer::SanitizeForRequest( |
85 url, content::Referrer(url, blink::WebReferrerPolicyDefault)), | 157 url, content::Referrer(url, blink::WebReferrerPolicyDefault)), |
86 ui::PAGE_TRANSITION_RELOAD, std::string()); | 158 ui::PAGE_TRANSITION_RELOAD, std::string()); |
87 } | 159 } |
88 | 160 |
161 enum UpdateBehavior { | |
162 UPDATE_DEACTIVATE, // Mark 'active' as false. | |
163 UPDATE_REMOVE, // Remove the entry from the list. | |
164 }; | |
165 | |
166 // Updates the entry (if any) for |override_url| in |overrides_list| according | |
167 // to |behavior|. Returns true if anything changed. | |
168 bool UpdateOverridesList(base::ListValue* overrides_list, | |
169 const std::string& override_url, | |
170 UpdateBehavior behavior) { | |
171 base::ListValue::iterator iter = | |
172 std::find_if(overrides_list->begin(), overrides_list->end(), | |
173 [&override_url](const base::Value* value) { | |
174 std::string entry; | |
175 const base::DictionaryValue* dict = nullptr; | |
176 return value->GetAsDictionary(&dict) && | |
177 dict->GetString(kEntry, &entry) && | |
178 entry == override_url; | |
179 }); | |
180 if (iter != overrides_list->end()) { | |
181 switch (behavior) { | |
182 case UPDATE_DEACTIVATE: { | |
183 base::DictionaryValue* dict = nullptr; | |
184 CHECK((*iter)->GetAsDictionary(&dict)); | |
Finnur
2015/12/23 13:08:03
I know this isn't a DCHECK, but including producti
Devlin
2015/12/30 03:10:40
Done.
| |
185 dict->SetBoolean(kActive, false); | |
186 break; | |
187 } | |
188 case UPDATE_REMOVE: | |
189 overrides_list->Erase(iter, nullptr); | |
190 break; | |
191 } | |
192 return true; | |
193 } | |
194 return false; | |
195 } | |
196 | |
197 // Updates each list referenced in |overrides| according to |behavior|. | |
198 void UpdateOverridesLists(Profile* profile, | |
199 const URLOverrides::URLOverrideMap& overrides, | |
200 UpdateBehavior behavior) { | |
201 if (overrides.empty()) | |
202 return; | |
203 PrefService* prefs = profile->GetPrefs(); | |
204 DictionaryPrefUpdate update(prefs, ExtensionWebUI::kExtensionURLOverrides); | |
205 base::DictionaryValue* all_overrides = update.Get(); | |
206 for (const auto& page_override_pair : overrides) { | |
207 base::ListValue* page_overrides = nullptr; | |
208 // If it's being unregistered, it should already be in the list. | |
209 if (!all_overrides->GetList(page_override_pair.first, &page_overrides)) { | |
210 NOTREACHED(); | |
211 continue; | |
212 } | |
213 if (UpdateOverridesList(page_overrides, page_override_pair.second.spec(), | |
214 behavior)) { | |
215 // This is the active override, so we need to find all existing | |
216 // tabs for this override and get them to reload the original URL. | |
217 base::Callback<void(WebContents*)> callback = | |
218 base::Bind(&UnregisterAndReplaceOverrideForWebContents, | |
219 page_override_pair.first, profile); | |
220 extensions::ExtensionTabUtil::ForEachTab(callback); | |
221 } | |
222 } | |
223 } | |
224 | |
89 // Run favicon callbck with image result. If no favicon was available then | 225 // Run favicon callbck with image result. If no favicon was available then |
90 // |image| will be empty. | 226 // |image| will be empty. |
91 void RunFaviconCallbackAsync( | 227 void RunFaviconCallbackAsync( |
92 const favicon_base::FaviconResultsCallback& callback, | 228 const favicon_base::FaviconResultsCallback& callback, |
93 const gfx::Image& image) { | 229 const gfx::Image& image) { |
94 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results = | 230 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results = |
95 new std::vector<favicon_base::FaviconRawBitmapResult>(); | 231 new std::vector<favicon_base::FaviconRawBitmapResult>(); |
96 | 232 |
97 const std::vector<gfx::ImageSkiaRep>& image_reps = | 233 const std::vector<gfx::ImageSkiaRep>& image_reps = |
98 image.AsImageSkia().image_reps(); | 234 image.AsImageSkia().image_reps(); |
(...skipping 21 matching lines...) Expand all Loading... | |
120 FROM_HERE, | 256 FROM_HERE, |
121 base::Bind(&favicon::FaviconService::FaviconResultsCallbackRunner, | 257 base::Bind(&favicon::FaviconService::FaviconResultsCallbackRunner, |
122 callback, base::Owned(favicon_bitmap_results))); | 258 callback, base::Owned(favicon_bitmap_results))); |
123 } | 259 } |
124 | 260 |
125 bool ValidateOverrideURL(const base::Value* override_url_value, | 261 bool ValidateOverrideURL(const base::Value* override_url_value, |
126 const GURL& source_url, | 262 const GURL& source_url, |
127 const extensions::ExtensionSet& extensions, | 263 const extensions::ExtensionSet& extensions, |
128 GURL* override_url, | 264 GURL* override_url, |
129 const Extension** extension) { | 265 const Extension** extension) { |
266 const base::DictionaryValue* dict = nullptr; | |
130 std::string override; | 267 std::string override; |
131 if (!override_url_value || !override_url_value->GetAsString(&override)) { | 268 bool is_active = false; |
269 if (!override_url_value || !override_url_value->GetAsDictionary(&dict) || | |
270 !dict->GetBoolean(kActive, &is_active) || !is_active || | |
271 !dict->GetString(kEntry, &override)) { | |
132 return false; | 272 return false; |
133 } | 273 } |
134 if (!source_url.query().empty()) | 274 if (!source_url.query().empty()) |
135 override += "?" + source_url.query(); | 275 override += "?" + source_url.query(); |
136 if (!source_url.ref().empty()) | 276 if (!source_url.ref().empty()) |
137 override += "#" + source_url.ref(); | 277 override += "#" + source_url.ref(); |
138 *override_url = GURL(override); | 278 *override_url = GURL(override); |
139 if (!override_url->is_valid()) { | 279 if (!override_url->is_valid()) { |
140 return false; | 280 return false; |
141 } | 281 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
217 // Iterate over the URL list looking for a suitable override. If a | 357 // Iterate over the URL list looking for a suitable override. If a |
218 // valid non-component override is encountered it is chosen immediately. | 358 // valid non-component override is encountered it is chosen immediately. |
219 for (size_t i = 0; i < url_list->GetSize(); ++i) { | 359 for (size_t i = 0; i < url_list->GetSize(); ++i) { |
220 const base::Value* val = NULL; | 360 const base::Value* val = NULL; |
221 url_list->Get(i, &val); | 361 url_list->Get(i, &val); |
222 | 362 |
223 GURL override_url; | 363 GURL override_url; |
224 const Extension* extension; | 364 const Extension* extension; |
225 if (!ValidateOverrideURL( | 365 if (!ValidateOverrideURL( |
226 val, *url, extensions, &override_url, &extension)) { | 366 val, *url, extensions, &override_url, &extension)) { |
227 LOG(WARNING) << "Invalid chrome URL override"; | 367 // Invalid overrides are cleaned up on startup. |
228 UnregisterChromeURLOverride(url_host, profile, val); | |
229 // The above Unregister call will remove this item from url_list. | |
230 --i; | |
231 continue; | 368 continue; |
232 } | 369 } |
233 | 370 |
234 // We can't handle chrome-extension URLs in incognito mode unless the | 371 // We can't handle chrome-extension URLs in incognito mode unless the |
235 // extension uses split mode. | 372 // extension uses split mode. |
236 bool incognito_override_allowed = | 373 bool incognito_override_allowed = |
237 extensions::IncognitoInfo::IsSplitMode(extension) && | 374 extensions::IncognitoInfo::IsSplitMode(extension) && |
238 extensions::util::IsIncognitoEnabled(extension->id(), profile); | 375 extensions::util::IsIncognitoEnabled(extension->id(), profile); |
239 if (profile->IsOffTheRecord() && !incognito_override_allowed) { | 376 if (profile->IsOffTheRecord() && !incognito_override_allowed) { |
240 continue; | 377 continue; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
292 *url = original_url; | 429 *url = original_url; |
293 return true; | 430 return true; |
294 } | 431 } |
295 } | 432 } |
296 } | 433 } |
297 | 434 |
298 return false; | 435 return false; |
299 } | 436 } |
300 | 437 |
301 // static | 438 // static |
302 void ExtensionWebUI::RegisterChromeURLOverrides( | 439 void ExtensionWebUI::InitializeChromeURLOverrides(Profile* profile) { |
303 Profile* profile, const URLOverrides::URLOverrideMap& overrides) { | 440 PrefService* prefs = profile->GetPrefs(); |
304 if (overrides.empty()) | 441 DictionaryPrefUpdate update(prefs, kExtensionURLOverrides); |
305 return; | 442 base::DictionaryValue* all_overrides = update.Get(); |
443 | |
444 // DictionaryValue::Iterator cannot be used to modify the list. Generate the | |
445 // set of keys instead. | |
446 std::vector<std::string> keys; | |
447 for (base::DictionaryValue::Iterator iter(*all_overrides); | |
448 !iter.IsAtEnd(); iter.Advance()) { | |
449 keys.push_back(iter.key()); | |
450 } | |
451 for (const std::string& key : keys) { | |
452 base::ListValue* list = nullptr; | |
453 CHECK(all_overrides->GetList(key, &list)); | |
454 InitializeOverridesList(list); | |
455 } | |
456 } | |
457 | |
458 // static | |
459 void ExtensionWebUI::ValidateChromeURLOverrides(Profile* profile) { | |
460 scoped_ptr<extensions::ExtensionSet> all_extensions = | |
461 extensions::ExtensionRegistry::Get(profile)-> | |
462 GenerateInstalledExtensionsSet(); | |
306 | 463 |
307 PrefService* prefs = profile->GetPrefs(); | 464 PrefService* prefs = profile->GetPrefs(); |
308 DictionaryPrefUpdate update(prefs, kExtensionURLOverrides); | 465 DictionaryPrefUpdate update(prefs, kExtensionURLOverrides); |
309 base::DictionaryValue* all_overrides = update.Get(); | 466 base::DictionaryValue* all_overrides = update.Get(); |
310 | 467 |
311 // For each override provided by the extension, add it to the front of | 468 // DictionaryValue::Iterator cannot be used to modify the list. Generate the |
312 // the override list if it's not already in the list. | 469 // set of keys instead. |
313 URLOverrides::URLOverrideMap::const_iterator iter = overrides.begin(); | 470 std::vector<std::string> keys; |
314 for (; iter != overrides.end(); ++iter) { | 471 for (base::DictionaryValue::Iterator iter(*all_overrides); |
315 const std::string& key = iter->first; | 472 !iter.IsAtEnd(); iter.Advance()) { |
316 base::ListValue* page_overrides = NULL; | 473 keys.push_back(iter.key()); |
317 if (!all_overrides->GetList(key, &page_overrides)) { | 474 } |
318 page_overrides = new base::ListValue(); | 475 for (const std::string& key : keys) { |
319 all_overrides->Set(key, page_overrides); | 476 base::ListValue* list = nullptr; |
320 } else { | 477 CHECK(all_overrides->GetList(key, &list)); |
321 CleanUpDuplicates(page_overrides); | 478 ValidateOverridesList(list, *all_extensions); |
322 | |
323 // Verify that the override isn't already in the list. | |
324 base::ListValue::iterator i = page_overrides->begin(); | |
325 for (; i != page_overrides->end(); ++i) { | |
326 std::string override_val; | |
327 if (!(*i)->GetAsString(&override_val)) { | |
328 NOTREACHED(); | |
329 continue; | |
330 } | |
331 if (override_val == iter->second.spec()) | |
332 break; | |
333 } | |
334 // This value is already in the list, leave it alone. | |
335 if (i != page_overrides->end()) | |
336 continue; | |
337 } | |
338 // Insert the override at the front of the list. Last registered override | |
339 // wins. | |
340 page_overrides->Insert(0, new base::StringValue(iter->second.spec())); | |
341 } | 479 } |
342 } | 480 } |
343 | 481 |
344 // static | 482 // static |
345 void ExtensionWebUI::UnregisterAndReplaceOverride(const std::string& page, | 483 void ExtensionWebUI::RegisterOrActivateChromeURLOverrides( |
346 Profile* profile, | 484 Profile* profile, |
347 base::ListValue* list, | 485 const URLOverrides::URLOverrideMap& overrides) { |
348 const base::Value* override) { | |
349 size_t index = 0; | |
350 bool found = list->Remove(*override, &index); | |
351 if (found && index == 0) { | |
352 // This is the active override, so we need to find all existing | |
353 // tabs for this override and get them to reload the original URL. | |
354 base::Callback<void(WebContents*)> callback = | |
355 base::Bind(&UnregisterAndReplaceOverrideForWebContents, page, profile); | |
356 extensions::ExtensionTabUtil::ForEachTab(callback); | |
357 } | |
358 } | |
359 | |
360 // static | |
361 void ExtensionWebUI::UnregisterChromeURLOverride(const std::string& page, | |
362 Profile* profile, | |
363 const base::Value* override) { | |
364 if (!override) | |
365 return; | |
366 PrefService* prefs = profile->GetPrefs(); | |
367 DictionaryPrefUpdate update(prefs, kExtensionURLOverrides); | |
368 base::DictionaryValue* all_overrides = update.Get(); | |
369 base::ListValue* page_overrides = NULL; | |
370 if (!all_overrides->GetList(page, &page_overrides)) { | |
371 // If it's being unregistered, it should already be in the list. | |
372 NOTREACHED(); | |
373 return; | |
374 } else { | |
375 UnregisterAndReplaceOverride(page, profile, page_overrides, override); | |
376 } | |
377 } | |
378 | |
379 // static | |
380 void ExtensionWebUI::UnregisterChromeURLOverrides( | |
381 Profile* profile, const URLOverrides::URLOverrideMap& overrides) { | |
382 if (overrides.empty()) | 486 if (overrides.empty()) |
383 return; | 487 return; |
384 PrefService* prefs = profile->GetPrefs(); | 488 PrefService* prefs = profile->GetPrefs(); |
385 DictionaryPrefUpdate update(prefs, kExtensionURLOverrides); | 489 DictionaryPrefUpdate update(prefs, kExtensionURLOverrides); |
386 base::DictionaryValue* all_overrides = update.Get(); | 490 base::DictionaryValue* all_overrides = update.Get(); |
387 URLOverrides::URLOverrideMap::const_iterator iter = overrides.begin(); | 491 for (const auto& page_override_pair : overrides) { |
388 for (; iter != overrides.end(); ++iter) { | 492 base::ListValue* page_overrides = nullptr; |
389 const std::string& page = iter->first; | 493 if (!all_overrides->GetList(page_override_pair.first, &page_overrides)) { |
390 base::ListValue* page_overrides = NULL; | 494 page_overrides = new base::ListValue(); |
391 if (!all_overrides->GetList(page, &page_overrides)) { | 495 all_overrides->Set(page_override_pair.first, page_overrides); |
392 // If it's being unregistered, it should already be in the list. | |
393 NOTREACHED(); | |
394 continue; | |
395 } else { | |
396 base::StringValue override(iter->second.spec()); | |
397 UnregisterAndReplaceOverride(iter->first, profile, | |
398 page_overrides, &override); | |
399 } | 496 } |
497 AddOverridesToList(page_overrides, page_override_pair.second.spec()); | |
400 } | 498 } |
401 } | 499 } |
402 | 500 |
403 // static | 501 // static |
502 void ExtensionWebUI::DeactivateChromeURLOverrides( | |
503 Profile* profile, | |
504 const URLOverrides::URLOverrideMap& overrides) { | |
505 UpdateOverridesLists(profile, overrides, UPDATE_DEACTIVATE); | |
506 } | |
507 | |
508 // static | |
509 void ExtensionWebUI::UnregisterChromeURLOverrides( | |
510 Profile* profile, | |
511 const URLOverrides::URLOverrideMap& overrides) { | |
512 UpdateOverridesLists(profile, overrides, UPDATE_REMOVE); | |
513 } | |
514 | |
515 // static | |
404 void ExtensionWebUI::GetFaviconForURL( | 516 void ExtensionWebUI::GetFaviconForURL( |
405 Profile* profile, | 517 Profile* profile, |
406 const GURL& page_url, | 518 const GURL& page_url, |
407 const favicon_base::FaviconResultsCallback& callback) { | 519 const favicon_base::FaviconResultsCallback& callback) { |
408 const Extension* extension = extensions::ExtensionRegistry::Get( | 520 const Extension* extension = extensions::ExtensionRegistry::Get( |
409 profile)->enabled_extensions().GetByID(page_url.host()); | 521 profile)->enabled_extensions().GetByID(page_url.host()); |
410 if (!extension) { | 522 if (!extension) { |
411 RunFaviconCallbackAsync(callback, gfx::Image()); | 523 RunFaviconCallbackAsync(callback, gfx::Image()); |
412 return; | 524 return; |
413 } | 525 } |
(...skipping 18 matching lines...) Expand all Loading... | |
432 extensions::ImageLoader::ImageRepresentation::ALWAYS_RESIZE, | 544 extensions::ImageLoader::ImageRepresentation::ALWAYS_RESIZE, |
433 gfx::Size(pixel_size, pixel_size), | 545 gfx::Size(pixel_size, pixel_size), |
434 resource_scale_factor)); | 546 resource_scale_factor)); |
435 } | 547 } |
436 | 548 |
437 // LoadImagesAsync actually can run callback synchronously. We want to force | 549 // LoadImagesAsync actually can run callback synchronously. We want to force |
438 // async. | 550 // async. |
439 extensions::ImageLoader::Get(profile)->LoadImagesAsync( | 551 extensions::ImageLoader::Get(profile)->LoadImagesAsync( |
440 extension, info_list, base::Bind(&RunFaviconCallbackAsync, callback)); | 552 extension, info_list, base::Bind(&RunFaviconCallbackAsync, callback)); |
441 } | 553 } |
OLD | NEW |