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" |
11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "chrome/browser/bookmarks/bookmark_manager_extension_api.h" | 13 #include "chrome/browser/bookmarks/bookmark_manager_extension_api.h" |
14 #include "chrome/browser/extensions/extension_service.h" | 14 #include "chrome/browser/extensions/extension_service.h" |
15 #include "chrome/browser/extensions/extension_tab_util.h" | 15 #include "chrome/browser/extensions/extension_tab_util.h" |
16 #include "chrome/browser/extensions/image_loading_tracker.h" | 16 #include "chrome/browser/extensions/image_loader.h" |
17 #include "chrome/browser/prefs/pref_service.h" | 17 #include "chrome/browser/prefs/pref_service.h" |
18 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 18 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
19 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
20 #include "chrome/browser/ui/browser.h" | 20 #include "chrome/browser/ui/browser.h" |
21 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 21 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
22 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" | 22 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" |
23 #include "chrome/common/chrome_switches.h" | 23 #include "chrome/common/chrome_switches.h" |
24 #include "chrome/common/extensions/extension.h" | 24 #include "chrome/common/extensions/extension.h" |
25 #include "chrome/common/extensions/extension_constants.h" | 25 #include "chrome/common/extensions/extension_constants.h" |
26 #include "chrome/common/extensions/extension_icon_set.h" | 26 #include "chrome/common/extensions/extension_icon_set.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 if (!url.SchemeIs(chrome::kChromeUIScheme) || url.host() != page) | 71 if (!url.SchemeIs(chrome::kChromeUIScheme) || url.host() != page) |
72 return; | 72 return; |
73 | 73 |
74 // Don't use Reload() since |url| isn't the same as the internal URL that | 74 // Don't use Reload() since |url| isn't the same as the internal URL that |
75 // NavigationController has. | 75 // NavigationController has. |
76 web_contents->GetController().LoadURL( | 76 web_contents->GetController().LoadURL( |
77 url, content::Referrer(url, WebKit::WebReferrerPolicyDefault), | 77 url, content::Referrer(url, WebKit::WebReferrerPolicyDefault), |
78 content::PAGE_TRANSITION_RELOAD, std::string()); | 78 content::PAGE_TRANSITION_RELOAD, std::string()); |
79 } | 79 } |
80 | 80 |
81 // Helper class that is used to track the loading of the favicon of an | 81 // Forwards the result of the request. If no favicon was available then |
82 // extension. | 82 // |image| will be empty. Once the result has been forwarded the instance is |
83 class ExtensionWebUIImageLoadingTracker : public ImageLoadingTracker::Observer { | 83 // deleted. |
84 public: | 84 void ForwardFaviconResult(FaviconService::GetFaviconRequest* request, |
85 ExtensionWebUIImageLoadingTracker(Profile* profile, | 85 const gfx::Image& image) { |
86 FaviconService::GetFaviconRequest* request, | 86 std::vector<history::FaviconBitmapResult> favicon_bitmap_results; |
87 const GURL& page_url) | 87 const std::vector<gfx::ImageSkiaRep>& image_reps = |
88 : ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)), | 88 image.AsImageSkia().image_reps(); |
89 request_(request), | 89 for (size_t i = 0; i < image_reps.size(); ++i) { |
90 extension_(NULL) { | 90 const gfx::ImageSkiaRep& image_rep = image_reps[i]; |
91 // Even when the extensions service is enabled by default, it's still | 91 scoped_refptr<base::RefCountedBytes> bitmap_data( |
92 // disabled in incognito mode. | 92 new base::RefCountedBytes()); |
93 ExtensionService* service = profile->GetExtensionService(); | 93 if (gfx::PNGCodec::EncodeBGRASkBitmap(image_rep.sk_bitmap(), |
94 if (service) | 94 false, |
95 extension_ = service->extensions()->GetByID(page_url.host()); | 95 &bitmap_data->data())) { |
96 } | 96 history::FaviconBitmapResult bitmap_result; |
| 97 bitmap_result.bitmap_data = bitmap_data; |
| 98 bitmap_result.pixel_size = gfx::Size(image_rep.pixel_width(), |
| 99 image_rep.pixel_height()); |
| 100 // Leave |bitmap_result|'s icon URL as the default of GURL(). |
| 101 bitmap_result.icon_type = history::FAVICON; |
97 | 102 |
98 void Init() { | 103 favicon_bitmap_results.push_back(bitmap_result); |
99 if (extension_) { | |
100 // Fetch resources for all supported scale factors for which there are | |
101 // resources. Load image reps for all supported scale factors immediately | |
102 // instead of in an as needed fashion to be consistent with how favicons | |
103 // are requested for chrome:// and page URLs. | |
104 const std::vector<ui::ScaleFactor>& scale_factors = | |
105 ui::GetSupportedScaleFactors(); | |
106 std::vector<ImageLoadingTracker::ImageRepresentation> info_list; | |
107 for (size_t i = 0; i < scale_factors.size(); ++i) { | |
108 float scale = ui::GetScaleFactorScale(scale_factors[i]); | |
109 int pixel_size = static_cast<int>(gfx::kFaviconSize * scale); | |
110 ExtensionResource icon_resource = | |
111 extension_->GetIconResource(pixel_size, | |
112 ExtensionIconSet::MATCH_BIGGER); | |
113 | |
114 info_list.push_back( | |
115 ImageLoadingTracker::ImageRepresentation( | |
116 icon_resource, | |
117 ImageLoadingTracker::ImageRepresentation::ALWAYS_RESIZE, | |
118 gfx::Size(pixel_size, pixel_size), | |
119 scale_factors[i])); | |
120 } | |
121 | |
122 tracker_.LoadImages(extension_, info_list, | |
123 ImageLoadingTracker::DONT_CACHE); | |
124 } else { | 104 } else { |
125 ForwardResult(gfx::Image()); | 105 NOTREACHED() << "Could not encode extension favicon"; |
126 } | 106 } |
127 } | 107 } |
128 | 108 |
129 virtual void OnImageLoaded(const gfx::Image& image, | 109 // Populate IconURLSizesMap such that all the icon URLs in |
130 const std::string& extension_id, | 110 // |favicon_bitmap_results| are present in |icon_url_sizes|. |
131 int index) OVERRIDE { | 111 // Populate the favicon sizes with the relevant pixel sizes in the |
132 ForwardResult(image); | 112 // extension's icon set. |
| 113 history::IconURLSizesMap icon_url_sizes; |
| 114 for (size_t i = 0; i < favicon_bitmap_results.size(); ++i) { |
| 115 const history::FaviconBitmapResult& bitmap_result = |
| 116 favicon_bitmap_results[i]; |
| 117 const GURL& icon_url = bitmap_result.icon_url; |
| 118 icon_url_sizes[icon_url].push_back(bitmap_result.pixel_size); |
133 } | 119 } |
134 | 120 |
135 private: | 121 request->ForwardResultAsync(request->handle(), favicon_bitmap_results, |
136 ~ExtensionWebUIImageLoadingTracker() {} | 122 icon_url_sizes); |
137 | 123 } |
138 // Forwards the result of the request. If no favicon was available then | |
139 // |image| will be empty. Once the result has been forwarded the instance is | |
140 // deleted. | |
141 void ForwardResult(const gfx::Image& image) { | |
142 std::vector<history::FaviconBitmapResult> favicon_bitmap_results; | |
143 const std::vector<gfx::ImageSkiaRep>& image_reps = | |
144 image.AsImageSkia().image_reps(); | |
145 for (size_t i = 0; i < image_reps.size(); ++i) { | |
146 const gfx::ImageSkiaRep& image_rep = image_reps[i]; | |
147 scoped_refptr<base::RefCountedBytes> bitmap_data( | |
148 new base::RefCountedBytes()); | |
149 if (gfx::PNGCodec::EncodeBGRASkBitmap(image_rep.sk_bitmap(), | |
150 false, | |
151 &bitmap_data->data())) { | |
152 history::FaviconBitmapResult bitmap_result; | |
153 bitmap_result.bitmap_data = bitmap_data; | |
154 bitmap_result.pixel_size = gfx::Size(image_rep.pixel_width(), | |
155 image_rep.pixel_height()); | |
156 // Leave |bitmap_result|'s icon URL as the default of GURL(). | |
157 bitmap_result.icon_type = history::FAVICON; | |
158 | |
159 favicon_bitmap_results.push_back(bitmap_result); | |
160 } else { | |
161 NOTREACHED() << "Could not encode extension favicon"; | |
162 } | |
163 } | |
164 | |
165 // Populate IconURLSizesMap such that all the icon URLs in | |
166 // |favicon_bitmap_results| are present in |icon_url_sizes|. | |
167 // Populate the favicon sizes with the relevant pixel sizes in the | |
168 // extension's icon set. | |
169 history::IconURLSizesMap icon_url_sizes; | |
170 for (size_t i = 0; i < favicon_bitmap_results.size(); ++i) { | |
171 const history::FaviconBitmapResult& bitmap_result = | |
172 favicon_bitmap_results[i]; | |
173 const GURL& icon_url = bitmap_result.icon_url; | |
174 icon_url_sizes[icon_url].push_back(bitmap_result.pixel_size); | |
175 } | |
176 | |
177 request_->ForwardResultAsync(request_->handle(), favicon_bitmap_results, | |
178 icon_url_sizes); | |
179 delete this; | |
180 } | |
181 | |
182 ImageLoadingTracker tracker_; | |
183 scoped_refptr<FaviconService::GetFaviconRequest> request_; | |
184 const Extension* extension_; | |
185 | |
186 DISALLOW_COPY_AND_ASSIGN(ExtensionWebUIImageLoadingTracker); | |
187 }; | |
188 | 124 |
189 } // namespace | 125 } // namespace |
190 | 126 |
191 const char ExtensionWebUI::kExtensionURLOverrides[] = | 127 const char ExtensionWebUI::kExtensionURLOverrides[] = |
192 "extensions.chrome_url_overrides"; | 128 "extensions.chrome_url_overrides"; |
193 | 129 |
194 ExtensionWebUI::ExtensionWebUI(content::WebUI* web_ui, const GURL& url) | 130 ExtensionWebUI::ExtensionWebUI(content::WebUI* web_ui, const GURL& url) |
195 : WebUIController(web_ui), | 131 : WebUIController(web_ui), |
196 url_(url) { | 132 url_(url) { |
197 Profile* profile = Profile::FromWebUI(web_ui); | 133 Profile* profile = Profile::FromWebUI(web_ui); |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 StringValue override(iter->second.spec()); | 393 StringValue override(iter->second.spec()); |
458 UnregisterAndReplaceOverride(iter->first, profile, | 394 UnregisterAndReplaceOverride(iter->first, profile, |
459 page_overrides, &override); | 395 page_overrides, &override); |
460 } | 396 } |
461 } | 397 } |
462 } | 398 } |
463 | 399 |
464 // static | 400 // static |
465 void ExtensionWebUI::GetFaviconForURL(Profile* profile, | 401 void ExtensionWebUI::GetFaviconForURL(Profile* profile, |
466 FaviconService::GetFaviconRequest* request, const GURL& page_url) { | 402 FaviconService::GetFaviconRequest* request, const GURL& page_url) { |
467 // tracker deletes itself when done. | 403 // Even when the extensions service is enabled by default, it's still |
468 ExtensionWebUIImageLoadingTracker* tracker = | 404 // disabled in incognito mode. |
469 new ExtensionWebUIImageLoadingTracker(profile, request, page_url); | 405 ExtensionService* service = profile->GetExtensionService(); |
470 tracker->Init(); | 406 if (!service) { |
| 407 ForwardFaviconResult(request, gfx::Image()); |
| 408 return; |
| 409 } |
| 410 const Extension* extension = service->extensions()->GetByID(page_url.host()); |
| 411 if (!extension) { |
| 412 ForwardFaviconResult(request, gfx::Image()); |
| 413 return; |
| 414 } |
| 415 |
| 416 // Fetch resources for all supported scale factors for which there are |
| 417 // resources. Load image reps for all supported scale factors immediately |
| 418 // instead of in an as needed fashion to be consistent with how favicons |
| 419 // are requested for chrome:// and page URLs. |
| 420 const std::vector<ui::ScaleFactor>& scale_factors = |
| 421 ui::GetSupportedScaleFactors(); |
| 422 std::vector<extensions::ImageLoader::ImageRepresentation> info_list; |
| 423 for (size_t i = 0; i < scale_factors.size(); ++i) { |
| 424 float scale = ui::GetScaleFactorScale(scale_factors[i]); |
| 425 int pixel_size = static_cast<int>(gfx::kFaviconSize * scale); |
| 426 ExtensionResource icon_resource = |
| 427 extension->GetIconResource(pixel_size, |
| 428 ExtensionIconSet::MATCH_BIGGER); |
| 429 |
| 430 info_list.push_back( |
| 431 extensions::ImageLoader::ImageRepresentation( |
| 432 icon_resource, |
| 433 extensions::ImageLoader::ImageRepresentation::ALWAYS_RESIZE, |
| 434 gfx::Size(pixel_size, pixel_size), |
| 435 scale_factors[i])); |
| 436 } |
| 437 |
| 438 extensions::ImageLoader::Get(profile)->LoadImagesAsync( |
| 439 extension, info_list, |
| 440 base::Bind(&ForwardFaviconResult, |
| 441 scoped_refptr<FaviconService::GetFaviconRequest>(request))); |
471 } | 442 } |
OLD | NEW |