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