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

Side by Side Diff: chrome/browser/ui/webui/extensions/extension_icon_source.cc

Issue 11881055: Simplify WebUI data sources. Currently WebUI data sources implement a URLDataSourceDelegate interfa… (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: fix issue in about_ui exposed by cros tests Created 7 years, 11 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
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/ui/webui/extensions/extension_icon_source.h" 5 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/memory/ref_counted_memory.h" 9 #include "base/memory/ref_counted_memory.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "base/string_number_conversions.h" 11 #include "base/string_number_conversions.h"
12 #include "base/string_split.h" 12 #include "base/string_split.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "base/stringprintf.h" 14 #include "base/stringprintf.h"
15 #include "base/threading/thread.h" 15 #include "base/threading/thread.h"
16 #include "chrome/browser/extensions/extension_prefs.h" 16 #include "chrome/browser/extensions/extension_prefs.h"
17 #include "chrome/browser/extensions/extension_service.h" 17 #include "chrome/browser/extensions/extension_service.h"
18 #include "chrome/browser/extensions/extension_system.h" 18 #include "chrome/browser/extensions/extension_system.h"
19 #include "chrome/browser/extensions/image_loader.h" 19 #include "chrome/browser/extensions/image_loader.h"
20 #include "chrome/browser/favicon/favicon_service_factory.h" 20 #include "chrome/browser/favicon/favicon_service_factory.h"
21 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
23 #include "chrome/common/extensions/extension.h" 22 #include "chrome/common/extensions/extension.h"
24 #include "chrome/common/extensions/extension_constants.h" 23 #include "chrome/common/extensions/extension_constants.h"
25 #include "chrome/common/extensions/extension_resource.h" 24 #include "chrome/common/extensions/extension_resource.h"
26 #include "chrome/common/url_constants.h" 25 #include "chrome/common/url_constants.h"
27 #include "googleurl/src/gurl.h" 26 #include "googleurl/src/gurl.h"
28 #include "grit/component_extension_resources_map.h" 27 #include "grit/component_extension_resources_map.h"
29 #include "grit/theme_resources.h" 28 #include "grit/theme_resources.h"
30 #include "skia/ext/image_operations.h" 29 #include "skia/ext/image_operations.h"
31 #include "ui/base/layout.h" 30 #include "ui/base/layout.h"
32 #include "ui/base/resource/resource_bundle.h" 31 #include "ui/base/resource/resource_bundle.h"
(...skipping 23 matching lines...) Expand all
56 return decoded; 55 return decoded;
57 } 56 }
58 57
59 } // namespace 58 } // namespace
60 59
61 ExtensionIconSource::ExtensionIconSource(Profile* profile) 60 ExtensionIconSource::ExtensionIconSource(Profile* profile)
62 : profile_(profile) { 61 : profile_(profile) {
63 } 62 }
64 63
65 struct ExtensionIconSource::ExtensionIconRequest { 64 struct ExtensionIconSource::ExtensionIconRequest {
66 int request_id; 65 content::URLDataSource::GotDataCallback callback;
67 const extensions::Extension* extension; 66 const extensions::Extension* extension;
68 bool grayscale; 67 bool grayscale;
69 int size; 68 int size;
70 ExtensionIconSet::MatchType match; 69 ExtensionIconSet::MatchType match;
71 }; 70 };
72 71
73 // static 72 // static
74 GURL ExtensionIconSource::GetIconURL(const extensions::Extension* extension, 73 GURL ExtensionIconSource::GetIconURL(const extensions::Extension* extension,
75 int icon_size, 74 int icon_size,
76 ExtensionIconSet::MatchType match, 75 ExtensionIconSet::MatchType match,
(...skipping 29 matching lines...) Expand all
106 std::string ExtensionIconSource::GetSource() { 105 std::string ExtensionIconSource::GetSource() {
107 return chrome::kChromeUIExtensionIconHost; 106 return chrome::kChromeUIExtensionIconHost;
108 } 107 }
109 108
110 std::string ExtensionIconSource::GetMimeType(const std::string&) const { 109 std::string ExtensionIconSource::GetMimeType(const std::string&) const {
111 // We need to explicitly return a mime type, otherwise if the user tries to 110 // We need to explicitly return a mime type, otherwise if the user tries to
112 // drag the image they get no extension. 111 // drag the image they get no extension.
113 return "image/png"; 112 return "image/png";
114 } 113 }
115 114
116 void ExtensionIconSource::StartDataRequest(const std::string& path, 115 void ExtensionIconSource::StartDataRequest(
117 bool is_incognito, 116 const std::string& path,
118 int request_id) { 117 bool is_incognito,
118 const content::URLDataSource::GotDataCallback& callback) {
119 // This is where everything gets started. First, parse the request and make 119 // This is where everything gets started. First, parse the request and make
120 // the request data available for later. 120 // the request data available for later.
121 if (!ParseData(path, request_id)) { 121 static int next_id = 0;
122 SendDefaultResponse(request_id); 122 if (!ParseData(path, ++next_id, callback)) {
123 SendDefaultResponse(next_id);
123 return; 124 return;
124 } 125 }
125 126
126 ExtensionIconRequest* request = GetData(request_id); 127 ExtensionIconRequest* request = GetData(next_id);
127 ExtensionResource icon = 128 ExtensionResource icon =
128 request->extension->GetIconResource(request->size, request->match); 129 request->extension->GetIconResource(request->size, request->match);
129 130
130 if (icon.relative_path().empty()) { 131 if (icon.relative_path().empty()) {
131 LoadIconFailed(request_id); 132 LoadIconFailed(next_id);
132 } else { 133 } else {
133 LoadExtensionImage(icon, request_id); 134 LoadExtensionImage(icon, next_id);
134 } 135 }
135 } 136 }
136 137
137 ExtensionIconSource::~ExtensionIconSource() { 138 ExtensionIconSource::~ExtensionIconSource() {
138 // Clean up all the temporary data we're holding for requests. 139 // Clean up all the temporary data we're holding for requests.
139 STLDeleteValues(&request_map_); 140 STLDeleteValues(&request_map_);
140 } 141 }
141 142
142 const SkBitmap* ExtensionIconSource::GetDefaultAppImage() { 143 const SkBitmap* ExtensionIconSource::GetDefaultAppImage() {
143 if (!default_app_data_.get()) 144 if (!default_app_data_.get())
144 default_app_data_.reset(LoadImageByResourceId(IDR_APP_DEFAULT_ICON)); 145 default_app_data_.reset(LoadImageByResourceId(IDR_APP_DEFAULT_ICON));
145 146
146 return default_app_data_.get(); 147 return default_app_data_.get();
147 } 148 }
148 149
149 const SkBitmap* ExtensionIconSource::GetDefaultExtensionImage() { 150 const SkBitmap* ExtensionIconSource::GetDefaultExtensionImage() {
150 if (!default_extension_data_.get()) { 151 if (!default_extension_data_.get()) {
151 default_extension_data_.reset( 152 default_extension_data_.reset(
152 LoadImageByResourceId(IDR_EXTENSION_DEFAULT_ICON)); 153 LoadImageByResourceId(IDR_EXTENSION_DEFAULT_ICON));
153 } 154 }
154 155
155 return default_extension_data_.get(); 156 return default_extension_data_.get();
156 } 157 }
157 158
158 void ExtensionIconSource::FinalizeImage(const SkBitmap* image, 159 void ExtensionIconSource::FinalizeImage(const SkBitmap* image,
159 int request_id) { 160 int request_id) {
160 SkBitmap bitmap; 161 SkBitmap bitmap;
161 if (GetData(request_id)->grayscale) 162 ExtensionIconRequest* request = GetData(request_id);
163 if (request->grayscale)
162 bitmap = DesaturateImage(image); 164 bitmap = DesaturateImage(image);
163 else 165 else
164 bitmap = *image; 166 bitmap = *image;
165 167
168 request->callback.Run(BitmapToMemory(&bitmap));
166 ClearData(request_id); 169 ClearData(request_id);
167 url_data_source()->SendResponse(request_id, BitmapToMemory(&bitmap));
168 } 170 }
169 171
170 void ExtensionIconSource::LoadDefaultImage(int request_id) { 172 void ExtensionIconSource::LoadDefaultImage(int request_id) {
171 ExtensionIconRequest* request = GetData(request_id); 173 ExtensionIconRequest* request = GetData(request_id);
172 const SkBitmap* default_image = NULL; 174 const SkBitmap* default_image = NULL;
173 175
174 if (request->extension->is_app()) 176 if (request->extension->is_app())
175 default_image = GetDefaultAppImage(); 177 default_image = GetDefaultAppImage();
176 else 178 else
177 default_image = GetDefaultExtensionImage(); 179 default_image = GetDefaultExtensionImage();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 226
225 // Fallback to the default icon if there wasn't a favicon. 227 // Fallback to the default icon if there wasn't a favicon.
226 if (!bitmap_result.is_valid()) { 228 if (!bitmap_result.is_valid()) {
227 LoadDefaultImage(request_id); 229 LoadDefaultImage(request_id);
228 return; 230 return;
229 } 231 }
230 232
231 if (!request->grayscale) { 233 if (!request->grayscale) {
232 // If we don't need a grayscale image, then we can bypass FinalizeImage 234 // If we don't need a grayscale image, then we can bypass FinalizeImage
233 // to avoid unnecessary conversions. 235 // to avoid unnecessary conversions.
236 request->callback.Run(bitmap_result.bitmap_data);
234 ClearData(request_id); 237 ClearData(request_id);
235 url_data_source()->SendResponse(request_id, bitmap_result.bitmap_data);
236 } else { 238 } else {
237 FinalizeImage(ToBitmap(bitmap_result.bitmap_data->front(), 239 FinalizeImage(ToBitmap(bitmap_result.bitmap_data->front(),
238 bitmap_result.bitmap_data->size()), request_id); 240 bitmap_result.bitmap_data->size()), request_id);
239 } 241 }
240 } 242 }
241 243
242 void ExtensionIconSource::OnImageLoaded(int request_id, 244 void ExtensionIconSource::OnImageLoaded(int request_id,
243 const gfx::Image& image) { 245 const gfx::Image& image) {
244 if (image.IsEmpty()) 246 if (image.IsEmpty())
245 LoadIconFailed(request_id); 247 LoadIconFailed(request_id);
246 else 248 else
247 FinalizeImage(image.ToSkBitmap(), request_id); 249 FinalizeImage(image.ToSkBitmap(), request_id);
248 } 250 }
249 251
250 void ExtensionIconSource::LoadIconFailed(int request_id) { 252 void ExtensionIconSource::LoadIconFailed(int request_id) {
251 ExtensionIconRequest* request = GetData(request_id); 253 ExtensionIconRequest* request = GetData(request_id);
252 ExtensionResource icon = 254 ExtensionResource icon =
253 request->extension->GetIconResource(request->size, request->match); 255 request->extension->GetIconResource(request->size, request->match);
254 256
255 if (request->size == extension_misc::EXTENSION_ICON_BITTY) 257 if (request->size == extension_misc::EXTENSION_ICON_BITTY)
256 LoadFaviconImage(request_id); 258 LoadFaviconImage(request_id);
257 else 259 else
258 LoadDefaultImage(request_id); 260 LoadDefaultImage(request_id);
259 } 261 }
260 262
261 bool ExtensionIconSource::ParseData(const std::string& path, 263 bool ExtensionIconSource::ParseData(
262 int request_id) { 264 const std::string& path,
265 int request_id,
266 const content::URLDataSource::GotDataCallback& callback) {
263 // Extract the parameters from the path by lower casing and splitting. 267 // Extract the parameters from the path by lower casing and splitting.
264 std::string path_lower = StringToLowerASCII(path); 268 std::string path_lower = StringToLowerASCII(path);
265 std::vector<std::string> path_parts; 269 std::vector<std::string> path_parts;
266 270
267 base::SplitString(path_lower, '/', &path_parts); 271 base::SplitString(path_lower, '/', &path_parts);
268 if (path_lower.empty() || path_parts.size() < 3) 272 if (path_lower.empty() || path_parts.size() < 3)
269 return false; 273 return false;
270 274
271 std::string size_param = path_parts.at(1); 275 std::string size_param = path_parts.at(1);
272 std::string match_param = path_parts.at(2); 276 std::string match_param = path_parts.at(2);
(...skipping 17 matching lines...) Expand all
290 294
291 std::string extension_id = path_parts.at(0); 295 std::string extension_id = path_parts.at(0);
292 const extensions::Extension* extension = 296 const extensions::Extension* extension =
293 extensions::ExtensionSystem::Get(profile_)->extension_service()-> 297 extensions::ExtensionSystem::Get(profile_)->extension_service()->
294 GetInstalledExtension(extension_id); 298 GetInstalledExtension(extension_id);
295 if (!extension) 299 if (!extension)
296 return false; 300 return false;
297 301
298 bool grayscale = path_lower.find("grayscale=true") != std::string::npos; 302 bool grayscale = path_lower.find("grayscale=true") != std::string::npos;
299 303
300 SetData(request_id, extension, grayscale, size, match_type); 304 SetData(request_id, callback, extension, grayscale, size, match_type);
301 305
302 return true; 306 return true;
303 } 307 }
304 308
305 void ExtensionIconSource::SendDefaultResponse(int request_id) { 309 void ExtensionIconSource::SendDefaultResponse(int request_id) {
306 // We send back the default application icon (not resized or desaturated) 310 // We send back the default application icon (not resized or desaturated)
307 // as the default response, like when there is no data. 311 // as the default response, like when there is no data.
312 ExtensionIconRequest* request = GetData(request_id);
313 request->callback.Run(BitmapToMemory(GetDefaultAppImage()));
308 ClearData(request_id); 314 ClearData(request_id);
309 url_data_source()->SendResponse(
310 request_id, BitmapToMemory(GetDefaultAppImage()));
311 } 315 }
312 316
313 void ExtensionIconSource::SetData(int request_id, 317 void ExtensionIconSource::SetData(
314 const extensions::Extension* extension, 318 int request_id,
315 bool grayscale, 319 const content::URLDataSource::GotDataCallback& callback,
316 int size, 320 const extensions::Extension* extension,
317 ExtensionIconSet::MatchType match) { 321 bool grayscale,
322 int size,
323 ExtensionIconSet::MatchType match) {
318 ExtensionIconRequest* request = new ExtensionIconRequest(); 324 ExtensionIconRequest* request = new ExtensionIconRequest();
319 request->request_id = request_id; 325 request->callback = callback;
320 request->extension = extension; 326 request->extension = extension;
321 request->grayscale = grayscale; 327 request->grayscale = grayscale;
322 request->size = size; 328 request->size = size;
323 request->match = match; 329 request->match = match;
324 request_map_[request_id] = request; 330 request_map_[request_id] = request;
325 } 331 }
326 332
327 ExtensionIconSource::ExtensionIconRequest* ExtensionIconSource::GetData( 333 ExtensionIconSource::ExtensionIconRequest* ExtensionIconSource::GetData(
328 int request_id) { 334 int request_id) {
329 return request_map_[request_id]; 335 return request_map_[request_id];
330 } 336 }
331 337
332 void ExtensionIconSource::ClearData(int request_id) { 338 void ExtensionIconSource::ClearData(int request_id) {
333 std::map<int, ExtensionIconRequest*>::iterator i = 339 std::map<int, ExtensionIconRequest*>::iterator i =
334 request_map_.find(request_id); 340 request_map_.find(request_id);
335 if (i == request_map_.end()) 341 if (i == request_map_.end())
336 return; 342 return;
337 343
338 delete i->second; 344 delete i->second;
339 request_map_.erase(i); 345 request_map_.erase(i);
340 } 346 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698