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

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

Issue 26511002: Revert 227477 "Refactored loading of applications / extensions i..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 2 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"
(...skipping 21 matching lines...) Expand all
32 #include "ui/base/resource/resource_bundle.h" 32 #include "ui/base/resource/resource_bundle.h"
33 #include "ui/gfx/codec/png_codec.h" 33 #include "ui/gfx/codec/png_codec.h"
34 #include "ui/gfx/color_utils.h" 34 #include "ui/gfx/color_utils.h"
35 #include "ui/gfx/favicon_size.h" 35 #include "ui/gfx/favicon_size.h"
36 #include "ui/gfx/size.h" 36 #include "ui/gfx/size.h"
37 #include "ui/gfx/skbitmap_operations.h" 37 #include "ui/gfx/skbitmap_operations.h"
38 #include "url/gurl.h" 38 #include "url/gurl.h"
39 39
40 namespace extensions { 40 namespace extensions {
41 41
42 namespace {
43
44 scoped_refptr<base::RefCountedMemory> BitmapToMemory(const SkBitmap* image) {
45 base::RefCountedBytes* image_bytes = new base::RefCountedBytes;
46 gfx::PNGCodec::EncodeBGRASkBitmap(*image, false, &image_bytes->data());
47 return image_bytes;
48 }
49
50 SkBitmap DesaturateImage(const SkBitmap* image) {
51 color_utils::HSL shift = {-1, 0, 0.6};
52 return SkBitmapOperations::CreateHSLShiftedBitmap(*image, shift);
53 }
54
55 SkBitmap* ToBitmap(const unsigned char* data, size_t size) {
56 SkBitmap* decoded = new SkBitmap();
57 bool success = gfx::PNGCodec::Decode(data, size, decoded);
58 DCHECK(success);
59 return decoded;
60 }
61
62 } // namespace
63
42 ExtensionIconSource::ExtensionIconSource(Profile* profile) : profile_(profile) { 64 ExtensionIconSource::ExtensionIconSource(Profile* profile) : profile_(profile) {
43 } 65 }
44 66
45 struct ExtensionIconSource::ExtensionIconRequest { 67 struct ExtensionIconSource::ExtensionIconRequest {
46 content::URLDataSource::GotDataCallback callback; 68 content::URLDataSource::GotDataCallback callback;
47 scoped_refptr<const Extension> extension; 69 scoped_refptr<const Extension> extension;
48 bool grayscale; 70 bool grayscale;
49 int size; 71 int size;
50 ExtensionIconSet::MatchType match; 72 ExtensionIconSet::MatchType match;
51 }; 73 };
(...skipping 12 matching lines...) Expand all
64 GURL icon_url(base::StringPrintf("%s%s/%d/%d%s", 86 GURL icon_url(base::StringPrintf("%s%s/%d/%d%s",
65 chrome::kChromeUIExtensionIconURL, 87 chrome::kChromeUIExtensionIconURL,
66 extension->id().c_str(), 88 extension->id().c_str(),
67 icon_size, 89 icon_size,
68 match, 90 match,
69 grayscale ? "?grayscale=true" : "")); 91 grayscale ? "?grayscale=true" : ""));
70 CHECK(icon_url.is_valid()); 92 CHECK(icon_url.is_valid());
71 return icon_url; 93 return icon_url;
72 } 94 }
73 95
96 // static
97 SkBitmap* ExtensionIconSource::LoadImageByResourceId(int resource_id) {
98 std::string contents = ResourceBundle::GetSharedInstance()
99 .GetRawDataResourceForScale(resource_id,
100 ui::SCALE_FACTOR_100P).as_string();
101
102 // Convert and return it.
103 const unsigned char* data =
104 reinterpret_cast<const unsigned char*>(contents.data());
105 return ToBitmap(data, contents.length());
106 }
107
74 std::string ExtensionIconSource::GetSource() const { 108 std::string ExtensionIconSource::GetSource() const {
75 return chrome::kChromeUIExtensionIconHost; 109 return chrome::kChromeUIExtensionIconHost;
76 } 110 }
77 111
78 std::string ExtensionIconSource::GetMimeType(const std::string&) const { 112 std::string ExtensionIconSource::GetMimeType(const std::string&) const {
79 // We need to explicitly return a mime type, otherwise if the user tries to 113 // We need to explicitly return a mime type, otherwise if the user tries to
80 // drag the image they get no extension. 114 // drag the image they get no extension.
81 return "image/png"; 115 return "image/png";
82 } 116 }
83 117
84 void ExtensionIconSource::StartDataRequest( 118 void ExtensionIconSource::StartDataRequest(
85 const std::string& path, 119 const std::string& path,
86 int render_process_id, 120 int render_process_id,
87 int render_view_id, 121 int render_view_id,
88 const content::URLDataSource::GotDataCallback& callback) { 122 const content::URLDataSource::GotDataCallback& callback) {
89 // This is where everything gets started. First, parse the request and make 123 // This is where everything gets started. First, parse the request and make
90 // the request data available for later. 124 // the request data available for later.
91 static int next_id = 0; 125 static int next_id = 0;
92 if (!ParseData(path, ++next_id, callback)) { 126 if (!ParseData(path, ++next_id, callback)) {
93 // If the request data cannot be parsed, we will request anyway a default 127 // If the request data cannot be parsed, request parameters will not be
94 // icon (not resized or desaturated). 128 // added to |request_map_|.
95 SetData(next_id, callback, NULL, false, -1, ExtensionIconSet::MATCH_BIGGER); 129 // Send back the default application icon (not resized or desaturated) as
130 // the default response.
131 callback.Run(BitmapToMemory(GetDefaultAppImage()).get());
132 return;
96 } 133 }
97 134
98 LoadExtensionImage(next_id); 135 ExtensionIconRequest* request = GetData(next_id);
136 ExtensionResource icon = IconsInfo::GetIconResource(
137 request->extension, request->size, request->match);
138
139 if (icon.relative_path().empty()) {
140 LoadIconFailed(next_id);
141 } else {
142 LoadExtensionImage(icon, next_id);
143 }
99 } 144 }
100 145
101 ExtensionIconSource::~ExtensionIconSource() { 146 ExtensionIconSource::~ExtensionIconSource() {
102 // Clean up all the temporary data we're holding for requests. 147 // Clean up all the temporary data we're holding for requests.
103 STLDeleteValues(&request_map_); 148 STLDeleteValues(&request_map_);
104 } 149 }
105 150
106 void ExtensionIconSource::LoadExtensionImage(int request_id) { 151 const SkBitmap* ExtensionIconSource::GetDefaultAppImage() {
107 ExtensionIconRequest* request = GetData(request_id); 152 if (!default_app_data_.get())
108 ImageLoader::Get(profile_)->LoadExtensionIconAsync( 153 default_app_data_.reset(LoadImageByResourceId(IDR_APP_DEFAULT_ICON));
109 request->extension, 154
110 request->size, 155 return default_app_data_.get();
111 request->match,
112 request->grayscale,
113 base::Bind(&ExtensionIconSource::OnIconLoaded, AsWeakPtr(), request_id));
114 } 156 }
115 157
116 void ExtensionIconSource::OnIconLoaded(int request_id, const gfx::Image& image) 158 const SkBitmap* ExtensionIconSource::GetDefaultExtensionImage() {
117 { 159 if (!default_extension_data_.get()) {
160 default_extension_data_.reset(
161 LoadImageByResourceId(IDR_EXTENSION_DEFAULT_ICON));
162 }
163
164 return default_extension_data_.get();
165 }
166
167 void ExtensionIconSource::FinalizeImage(const SkBitmap* image,
168 int request_id) {
169 SkBitmap bitmap;
118 ExtensionIconRequest* request = GetData(request_id); 170 ExtensionIconRequest* request = GetData(request_id);
119 request->callback.Run(ImageLoader::BitmapToMemory(image.ToSkBitmap()).get()); 171 if (request->grayscale)
172 bitmap = DesaturateImage(image);
173 else
174 bitmap = *image;
175
176 request->callback.Run(BitmapToMemory(&bitmap).get());
120 ClearData(request_id); 177 ClearData(request_id);
121 } 178 }
122 179
180 void ExtensionIconSource::LoadDefaultImage(int request_id) {
181 ExtensionIconRequest* request = GetData(request_id);
182 const SkBitmap* default_image = NULL;
183
184 if (request->extension->is_app())
185 default_image = GetDefaultAppImage();
186 else
187 default_image = GetDefaultExtensionImage();
188
189 SkBitmap resized_image(skia::ImageOperations::Resize(
190 *default_image, skia::ImageOperations::RESIZE_LANCZOS3,
191 request->size, request->size));
192
193 // There are cases where Resize returns an empty bitmap, for example if you
194 // ask for an image too large. In this case it is better to return the default
195 // image than returning nothing at all.
196 if (resized_image.empty())
197 resized_image = *default_image;
198
199 FinalizeImage(&resized_image, request_id);
200 }
201
202 void ExtensionIconSource::LoadExtensionImage(const ExtensionResource& icon,
203 int request_id) {
204 ExtensionIconRequest* request = GetData(request_id);
205 ImageLoader::Get(profile_)->LoadImageAsync(
206 request->extension, icon,
207 gfx::Size(request->size, request->size),
208 base::Bind(&ExtensionIconSource::OnImageLoaded, AsWeakPtr(), request_id));
209 }
210
211 void ExtensionIconSource::LoadFaviconImage(int request_id) {
212 FaviconService* favicon_service =
213 FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS);
214 // Fall back to the default icons if the service isn't available.
215 if (favicon_service == NULL) {
216 LoadDefaultImage(request_id);
217 return;
218 }
219
220 GURL favicon_url =
221 AppLaunchInfo::GetFullLaunchURL(GetData(request_id)->extension);
222 favicon_service->GetRawFaviconForURL(
223 FaviconService::FaviconForURLParams(
224 profile_, favicon_url, chrome::FAVICON, gfx::kFaviconSize),
225 ui::SCALE_FACTOR_100P,
226 base::Bind(&ExtensionIconSource::OnFaviconDataAvailable,
227 base::Unretained(this), request_id),
228 &cancelable_task_tracker_);
229 }
230
231 void ExtensionIconSource::OnFaviconDataAvailable(
232 int request_id,
233 const chrome::FaviconBitmapResult& bitmap_result) {
234 ExtensionIconRequest* request = GetData(request_id);
235
236 // Fallback to the default icon if there wasn't a favicon.
237 if (!bitmap_result.is_valid()) {
238 LoadDefaultImage(request_id);
239 return;
240 }
241
242 if (!request->grayscale) {
243 // If we don't need a grayscale image, then we can bypass FinalizeImage
244 // to avoid unnecessary conversions.
245 request->callback.Run(bitmap_result.bitmap_data.get());
246 ClearData(request_id);
247 } else {
248 FinalizeImage(ToBitmap(bitmap_result.bitmap_data->front(),
249 bitmap_result.bitmap_data->size()), request_id);
250 }
251 }
252
253 void ExtensionIconSource::OnImageLoaded(int request_id,
254 const gfx::Image& image) {
255 if (image.IsEmpty())
256 LoadIconFailed(request_id);
257 else
258 FinalizeImage(image.ToSkBitmap(), request_id);
259 }
260
261 void ExtensionIconSource::LoadIconFailed(int request_id) {
262 ExtensionIconRequest* request = GetData(request_id);
263 ExtensionResource icon = IconsInfo::GetIconResource(
264 request->extension, request->size, request->match);
265
266 if (request->size == extension_misc::EXTENSION_ICON_BITTY)
267 LoadFaviconImage(request_id);
268 else
269 LoadDefaultImage(request_id);
270 }
271
123 bool ExtensionIconSource::ParseData( 272 bool ExtensionIconSource::ParseData(
124 const std::string& path, 273 const std::string& path,
125 int request_id, 274 int request_id,
126 const content::URLDataSource::GotDataCallback& callback) { 275 const content::URLDataSource::GotDataCallback& callback) {
127 // Extract the parameters from the path by lower casing and splitting. 276 // Extract the parameters from the path by lower casing and splitting.
128 std::string path_lower = StringToLowerASCII(path); 277 std::string path_lower = StringToLowerASCII(path);
129 std::vector<std::string> path_parts; 278 std::vector<std::string> path_parts;
130 279
131 base::SplitString(path_lower, '/', &path_parts); 280 base::SplitString(path_lower, '/', &path_parts);
132 if (path_lower.empty() || path_parts.size() < 3) 281 if (path_lower.empty() || path_parts.size() < 3)
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 std::map<int, ExtensionIconRequest*>::iterator i = 339 std::map<int, ExtensionIconRequest*>::iterator i =
191 request_map_.find(request_id); 340 request_map_.find(request_id);
192 if (i == request_map_.end()) 341 if (i == request_map_.end())
193 return; 342 return;
194 343
195 delete i->second; 344 delete i->second;
196 request_map_.erase(i); 345 request_map_.erase(i);
197 } 346 }
198 347
199 } // namespace extensions 348 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698