OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/bookmark_app_helper.h" | 5 #include "chrome/browser/extensions/bookmark_app_helper.h" |
6 | 6 |
7 #include <cctype> | 7 #include <cctype> |
8 | 8 |
9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
11 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" | |
12 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher_delegate.h" | |
11 #include "chrome/browser/chrome_notification_types.h" | 13 #include "chrome/browser/chrome_notification_types.h" |
12 #include "chrome/browser/extensions/crx_installer.h" | 14 #include "chrome/browser/extensions/crx_installer.h" |
13 #include "chrome/browser/extensions/extension_service.h" | 15 #include "chrome/browser/extensions/extension_service.h" |
14 #include "chrome/browser/extensions/favicon_downloader.h" | 16 #include "chrome/browser/extensions/favicon_downloader.h" |
15 #include "chrome/browser/extensions/launch_util.h" | 17 #include "chrome/browser/extensions/launch_util.h" |
16 #include "chrome/browser/extensions/tab_helper.h" | 18 #include "chrome/browser/extensions/tab_helper.h" |
17 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
18 #include "chrome/browser/ui/app_list/app_list_service.h" | 20 #include "chrome/browser/ui/app_list/app_list_service.h" |
19 #include "chrome/browser/ui/app_list/app_list_util.h" | 21 #include "chrome/browser/ui/app_list/app_list_util.h" |
20 #include "chrome/browser/ui/browser_finder.h" | 22 #include "chrome/browser/ui/browser_finder.h" |
21 #include "chrome/browser/ui/browser_window.h" | 23 #include "chrome/browser/ui/browser_window.h" |
22 #include "chrome/browser/ui/host_desktop.h" | 24 #include "chrome/browser/ui/host_desktop.h" |
23 #include "chrome/browser/web_applications/web_app.h" | 25 #include "chrome/browser/web_applications/web_app.h" |
24 #include "chrome/common/extensions/extension_constants.h" | 26 #include "chrome/common/extensions/extension_constants.h" |
25 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" | 27 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" |
26 #include "chrome/common/url_constants.h" | 28 #include "chrome/common/url_constants.h" |
27 #include "content/public/browser/notification_service.h" | 29 #include "content/public/browser/notification_service.h" |
28 #include "content/public/browser/notification_source.h" | 30 #include "content/public/browser/notification_source.h" |
29 #include "content/public/browser/web_contents.h" | 31 #include "content/public/browser/web_contents.h" |
30 #include "extensions/browser/extension_system.h" | 32 #include "extensions/browser/extension_system.h" |
31 #include "extensions/browser/image_loader.h" | 33 #include "extensions/browser/image_loader.h" |
32 #include "extensions/browser/notification_types.h" | 34 #include "extensions/browser/notification_types.h" |
33 #include "extensions/browser/pref_names.h" | 35 #include "extensions/browser/pref_names.h" |
34 #include "extensions/common/constants.h" | 36 #include "extensions/common/constants.h" |
35 #include "extensions/common/extension.h" | 37 #include "extensions/common/extension.h" |
36 #include "extensions/common/manifest_handlers/icons_handler.h" | 38 #include "extensions/common/manifest_handlers/icons_handler.h" |
37 #include "extensions/common/url_pattern.h" | 39 #include "extensions/common/url_pattern.h" |
38 #include "grit/platform_locale_settings.h" | 40 #include "grit/platform_locale_settings.h" |
41 #include "net/base/load_flags.h" | |
39 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 42 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
43 #include "net/url_request/url_request.h" | |
40 #include "skia/ext/image_operations.h" | 44 #include "skia/ext/image_operations.h" |
41 #include "skia/ext/platform_canvas.h" | 45 #include "skia/ext/platform_canvas.h" |
42 #include "third_party/skia/include/core/SkBitmap.h" | 46 #include "third_party/skia/include/core/SkBitmap.h" |
43 #include "ui/base/l10n/l10n_util.h" | 47 #include "ui/base/l10n/l10n_util.h" |
44 #include "ui/gfx/canvas.h" | 48 #include "ui/gfx/canvas.h" |
45 #include "ui/gfx/color_analysis.h" | 49 #include "ui/gfx/color_analysis.h" |
46 #include "ui/gfx/color_utils.h" | 50 #include "ui/gfx/color_utils.h" |
47 #include "ui/gfx/font.h" | 51 #include "ui/gfx/font.h" |
48 #include "ui/gfx/font_list.h" | 52 #include "ui/gfx/font_list.h" |
49 #include "ui/gfx/geometry/rect.h" | 53 #include "ui/gfx/geometry/rect.h" |
50 #include "ui/gfx/image/canvas_image_source.h" | 54 #include "ui/gfx/image/canvas_image_source.h" |
51 #include "ui/gfx/image/image.h" | 55 #include "ui/gfx/image/image.h" |
52 #include "ui/gfx/image/image_family.h" | 56 #include "ui/gfx/image/image_family.h" |
53 | 57 |
54 #if defined(OS_MACOSX) | 58 #if defined(OS_MACOSX) |
55 #include "base/command_line.h" | 59 #include "base/command_line.h" |
56 #include "chrome/browser/web_applications/web_app_mac.h" | 60 #include "chrome/browser/web_applications/web_app_mac.h" |
57 #include "chrome/common/chrome_switches.h" | 61 #include "chrome/common/chrome_switches.h" |
58 #endif | 62 #endif |
59 | 63 |
60 #if defined(USE_ASH) | 64 #if defined(USE_ASH) |
61 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" | 65 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" |
62 #endif | 66 #endif |
63 | 67 |
64 namespace { | 68 namespace { |
65 | 69 |
70 using extensions::BookmarkAppHelper; | |
71 | |
66 // Overlays a shortcut icon over the bottom left corner of a given image. | 72 // Overlays a shortcut icon over the bottom left corner of a given image. |
67 class GeneratedIconImageSource : public gfx::CanvasImageSource { | 73 class GeneratedIconImageSource : public gfx::CanvasImageSource { |
68 public: | 74 public: |
69 explicit GeneratedIconImageSource(char letter, SkColor color, int output_size) | 75 explicit GeneratedIconImageSource(char letter, SkColor color, int output_size) |
70 : gfx::CanvasImageSource(gfx::Size(output_size, output_size), false), | 76 : gfx::CanvasImageSource(gfx::Size(output_size, output_size), false), |
71 letter_(letter), | 77 letter_(letter), |
72 color_(color), | 78 color_(color), |
73 output_size_(output_size) {} | 79 output_size_(output_size) {} |
74 ~GeneratedIconImageSource() override {} | 80 ~GeneratedIconImageSource() override {} |
75 | 81 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
139 // Generate container icons from smaller icons. | 145 // Generate container icons from smaller icons. |
140 const int kIconSizesToGenerate[] = { | 146 const int kIconSizesToGenerate[] = { |
141 extension_misc::EXTENSION_ICON_SMALL, | 147 extension_misc::EXTENSION_ICON_SMALL, |
142 extension_misc::EXTENSION_ICON_MEDIUM, | 148 extension_misc::EXTENSION_ICON_MEDIUM, |
143 extension_misc::EXTENSION_ICON_LARGE, | 149 extension_misc::EXTENSION_ICON_LARGE, |
144 }; | 150 }; |
145 return std::set<int>(kIconSizesToGenerate, | 151 return std::set<int>(kIconSizesToGenerate, |
146 kIconSizesToGenerate + arraysize(kIconSizesToGenerate)); | 152 kIconSizesToGenerate + arraysize(kIconSizesToGenerate)); |
147 } | 153 } |
148 | 154 |
149 void GenerateIcons(std::set<int> generate_sizes, | 155 void GenerateIcons( |
150 const GURL& app_url, | 156 std::set<int> generate_sizes, |
151 SkColor generated_icon_color, | 157 const GURL& app_url, |
152 std::map<int, SkBitmap>* bitmap_map) { | 158 SkColor generated_icon_color, |
159 std::map<int, BookmarkAppHelper::BitmapAndSource>* bitmap_map) { | |
153 // The letter that will be painted on the generated icon. | 160 // The letter that will be painted on the generated icon. |
154 char icon_letter = ' '; | 161 char icon_letter = ' '; |
155 std::string domain_and_registry( | 162 std::string domain_and_registry( |
156 net::registry_controlled_domains::GetDomainAndRegistry( | 163 net::registry_controlled_domains::GetDomainAndRegistry( |
157 app_url, | 164 app_url, |
158 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)); | 165 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)); |
159 if (!domain_and_registry.empty()) { | 166 if (!domain_and_registry.empty()) { |
160 icon_letter = domain_and_registry[0]; | 167 icon_letter = domain_and_registry[0]; |
161 } else if (!app_url.host().empty()) { | 168 } else if (!app_url.host().empty()) { |
162 icon_letter = app_url.host()[0]; | 169 icon_letter = app_url.host()[0]; |
163 } | 170 } |
164 | 171 |
165 // If no color has been specified, use a dark gray so it will stand out on the | 172 // If no color has been specified, use a dark gray so it will stand out on the |
166 // black shelf. | 173 // black shelf. |
167 if (generated_icon_color == SK_ColorTRANSPARENT) | 174 if (generated_icon_color == SK_ColorTRANSPARENT) |
168 generated_icon_color = SK_ColorDKGRAY; | 175 generated_icon_color = SK_ColorDKGRAY; |
169 | 176 |
170 for (std::set<int>::const_iterator it = generate_sizes.begin(); | 177 for (std::set<int>::const_iterator it = generate_sizes.begin(); |
171 it != generate_sizes.end(); ++it) { | 178 it != generate_sizes.end(); ++it) { |
172 extensions::BookmarkAppHelper::GenerateIcon( | 179 extensions::BookmarkAppHelper::GenerateIcon( |
173 bitmap_map, *it, generated_icon_color, icon_letter); | 180 bitmap_map, *it, generated_icon_color, icon_letter); |
174 // Also generate the 2x resource for this size. | 181 // Also generate the 2x resource for this size. |
175 extensions::BookmarkAppHelper::GenerateIcon( | 182 extensions::BookmarkAppHelper::GenerateIcon( |
176 bitmap_map, *it * 2, generated_icon_color, icon_letter); | 183 bitmap_map, *it * 2, generated_icon_color, icon_letter); |
177 } | 184 } |
178 } | 185 } |
179 | 186 |
180 void ReplaceWebAppIcons(std::map<int, SkBitmap> bitmap_map, | 187 void ReplaceWebAppIcons( |
181 WebApplicationInfo* web_app_info) { | 188 std::map<int, BookmarkAppHelper::BitmapAndSource> bitmap_map, |
189 WebApplicationInfo* web_app_info) { | |
182 web_app_info->icons.clear(); | 190 web_app_info->icons.clear(); |
183 | 191 |
184 // Populate the icon data into the WebApplicationInfo we are using to | 192 // Populate the icon data into the WebApplicationInfo we are using to |
185 // install the bookmark app. | 193 // install the bookmark app. |
186 for (std::map<int, SkBitmap>::const_iterator bitmap_map_it = | 194 for (const auto& pair : bitmap_map) { |
187 bitmap_map.begin(); | |
188 bitmap_map_it != bitmap_map.end(); ++bitmap_map_it) { | |
189 WebApplicationInfo::IconInfo icon_info; | 195 WebApplicationInfo::IconInfo icon_info; |
190 icon_info.data = bitmap_map_it->second; | 196 icon_info.data = pair.second.bitmap; |
197 icon_info.url = pair.second.source_url; | |
191 icon_info.width = icon_info.data.width(); | 198 icon_info.width = icon_info.data.width(); |
192 icon_info.height = icon_info.data.height(); | 199 icon_info.height = icon_info.data.height(); |
193 web_app_info->icons.push_back(icon_info); | 200 web_app_info->icons.push_back(icon_info); |
194 } | 201 } |
195 } | 202 } |
196 | 203 |
204 void UpdateWebAppInfoIcons( | |
calamity
2015/04/24 05:05:40
This function is mostly about generating icons if
benwells
2015/04/27 09:54:54
It does a bit more than that, it resizes as well.
| |
205 std::vector<BookmarkAppHelper::BitmapAndSource> downloaded_icons, | |
206 WebApplicationInfo* web_app_info) { | |
207 // Add the downloaded icons. Extensions only allow certain icon sizes. First | |
208 // populate icons that match the allowed sizes exactly and then downscale | |
209 // remaining icons to the closest allowed size that doesn't yet have an icon. | |
210 std::set<int> allowed_sizes(extension_misc::kExtensionIconSizes, | |
211 extension_misc::kExtensionIconSizes + | |
212 extension_misc::kNumExtensionIconSizes); | |
213 | |
214 // If there are icons that don't match the accepted icon sizes, find the | |
215 // closest bigger icon to the accepted sizes and resize the icon to it. An | |
216 // icon will be resized and used for at most one size. | |
217 std::map<int, BookmarkAppHelper::BitmapAndSource> resized_bitmaps( | |
218 extensions::BookmarkAppHelper::ConstrainBitmapsToSizes(downloaded_icons, | |
219 allowed_sizes)); | |
220 | |
221 // Determine the color that will be used for the icon's background. For this | |
222 // the dominant color of the first icon found is used. | |
223 if (resized_bitmaps.size()) { | |
224 color_utils::GridSampler sampler; | |
225 web_app_info->generated_icon_color = | |
226 color_utils::CalculateKMeanColorOfBitmap( | |
227 resized_bitmaps.begin()->second.bitmap); | |
228 } | |
229 | |
230 std::set<int> generate_sizes; | |
231 for (int size : SizesToGenerate()) { | |
232 if (resized_bitmaps.find(size) == resized_bitmaps.end()) | |
233 generate_sizes.insert(size); | |
234 } | |
235 GenerateIcons(generate_sizes, web_app_info->app_url, | |
236 web_app_info->generated_icon_color, &resized_bitmaps); | |
237 | |
238 ReplaceWebAppIcons(resized_bitmaps, web_app_info); | |
239 } | |
240 | |
241 // Class to handle installing a bookmark app. Handles downloading and decoding | |
242 // the icons. | |
243 class BookmarkAppInstaller : public base::RefCounted<BookmarkAppInstaller>, | |
244 public chrome::BitmapFetcherDelegate { | |
245 public: | |
246 BookmarkAppInstaller(ExtensionService* service, | |
247 const WebApplicationInfo& web_app_info) | |
248 : service_(service), web_app_info_(web_app_info) {} | |
249 | |
250 void Run() { | |
251 for (const auto& icon : web_app_info_.icons) { | |
252 if (icon.url.is_valid()) | |
253 urls_to_download_.push_back(icon.url); | |
calamity
2015/04/24 05:05:40
Are these URLs deduped anywhere? Since you can get
benwells
2015/04/27 09:54:54
Yeah, I thought about this. The bitmapfetcher only
calamity
2015/04/28 06:56:35
Acknowledged. I'm happy to just leave it as is for
| |
254 } | |
255 | |
256 if (urls_to_download_.size()) { | |
257 DownloadNextImage(); | |
258 | |
259 // Matched in OnFetchComplete. | |
260 AddRef(); | |
261 return; | |
262 } | |
263 | |
264 FinishInstallation(); | |
265 } | |
266 | |
267 private: | |
268 friend class base::RefCounted<BookmarkAppInstaller>; | |
269 ~BookmarkAppInstaller() override {} | |
270 | |
271 // BitmapFetcherDelegate: | |
272 void OnFetchComplete(const GURL& url, const SkBitmap* bitmap) override { | |
273 if (bitmap && !bitmap->empty() && bitmap->width() == bitmap->height()) { | |
274 BookmarkAppHelper::BitmapAndSource bitmap_and_source; | |
275 bitmap_and_source.source_url = url; | |
276 bitmap_and_source.bitmap = *bitmap; | |
277 downloaded_bitmaps_.push_back(bitmap_and_source); | |
278 } | |
279 | |
280 if (urls_to_download_.size()) { | |
281 DownloadNextImage(); | |
282 return; | |
283 } | |
284 | |
285 FinishInstallation(); | |
286 Release(); | |
287 } | |
288 | |
289 void DownloadNextImage() { | |
290 DCHECK(urls_to_download_.size()); | |
291 | |
292 bitmap_fetcher_.reset( | |
293 new chrome::BitmapFetcher(urls_to_download_.back(), this)); | |
294 urls_to_download_.pop_back(); | |
295 bitmap_fetcher_->Start( | |
296 service_->profile()->GetRequestContext(), std::string(), | |
297 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, | |
298 net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES); | |
299 } | |
300 | |
301 void FinishInstallation() { | |
302 UpdateWebAppInfoIcons(downloaded_bitmaps_, &web_app_info_); | |
303 scoped_refptr<extensions::CrxInstaller> installer( | |
304 extensions::CrxInstaller::CreateSilent(service_)); | |
305 installer->set_error_on_unsupported_requirements(true); | |
306 installer->InstallWebApp(web_app_info_); | |
307 } | |
308 | |
309 ExtensionService* service_; | |
310 WebApplicationInfo web_app_info_; | |
311 | |
312 scoped_ptr<chrome::BitmapFetcher> bitmap_fetcher_; | |
313 std::vector<GURL> urls_to_download_; | |
314 std::vector<BookmarkAppHelper::BitmapAndSource> downloaded_bitmaps_; | |
315 }; | |
316 | |
197 } // namespace | 317 } // namespace |
198 | 318 |
199 namespace extensions { | 319 namespace extensions { |
200 | 320 |
201 // static | 321 // static |
202 void BookmarkAppHelper::UpdateWebAppInfoFromManifest( | 322 void BookmarkAppHelper::UpdateWebAppInfoFromManifest( |
203 const content::Manifest& manifest, | 323 const content::Manifest& manifest, |
204 WebApplicationInfo* web_app_info) { | 324 WebApplicationInfo* web_app_info) { |
205 if (!manifest.short_name.is_null()) | 325 if (!manifest.short_name.is_null()) |
206 web_app_info->title = manifest.short_name.string(); | 326 web_app_info->title = manifest.short_name.string(); |
(...skipping 13 matching lines...) Expand all Loading... | |
220 for (const auto& icon : manifest.icons) { | 340 for (const auto& icon : manifest.icons) { |
221 // TODO(benwells): Take the declared icon density and sizes into account. | 341 // TODO(benwells): Take the declared icon density and sizes into account. |
222 WebApplicationInfo::IconInfo info; | 342 WebApplicationInfo::IconInfo info; |
223 info.url = icon.src; | 343 info.url = icon.src; |
224 web_app_info->icons.push_back(info); | 344 web_app_info->icons.push_back(info); |
225 } | 345 } |
226 } | 346 } |
227 } | 347 } |
228 | 348 |
229 // static | 349 // static |
230 void BookmarkAppHelper::GenerateIcon(std::map<int, SkBitmap>* bitmaps, | 350 std::map<int, BookmarkAppHelper::BitmapAndSource> |
231 int output_size, | 351 BookmarkAppHelper::ConstrainBitmapsToSizes( |
calamity
2015/04/24 05:05:40
This reverts a deletion of this code right? I thin
benwells
2015/04/27 09:54:54
Yep, done. Here is the original CL if you're inter
| |
232 SkColor color, | 352 const std::vector<BookmarkAppHelper::BitmapAndSource>& bitmaps, |
233 char letter) { | 353 const std::set<int>& sizes) { |
354 std::map<int, BitmapAndSource> output_bitmaps; | |
355 std::map<int, BitmapAndSource> ordered_bitmaps; | |
356 for (std::vector<BitmapAndSource>::const_iterator it = bitmaps.begin(); | |
357 it != bitmaps.end(); ++it) { | |
358 DCHECK(it->bitmap.width() == it->bitmap.height()); | |
359 ordered_bitmaps[it->bitmap.width()] = *it; | |
360 } | |
361 | |
362 std::set<int>::const_iterator sizes_it = sizes.begin(); | |
363 std::map<int, BitmapAndSource>::const_iterator bitmaps_it = | |
364 ordered_bitmaps.begin(); | |
365 while (sizes_it != sizes.end() && bitmaps_it != ordered_bitmaps.end()) { | |
366 int size = *sizes_it; | |
367 // Find the closest not-smaller bitmap. | |
368 bitmaps_it = ordered_bitmaps.lower_bound(size); | |
369 ++sizes_it; | |
370 // Ensure the bitmap is valid and smaller than the next allowed size. | |
371 if (bitmaps_it != ordered_bitmaps.end() && | |
372 (sizes_it == sizes.end() || | |
373 bitmaps_it->second.bitmap.width() < *sizes_it)) { | |
374 output_bitmaps[size] = bitmaps_it->second; | |
375 // Resize the bitmap if it does not exactly match the desired size. | |
376 if (output_bitmaps[size].bitmap.width() != size) { | |
377 output_bitmaps[size].bitmap = skia::ImageOperations::Resize( | |
378 output_bitmaps[size].bitmap, skia::ImageOperations::RESIZE_LANCZOS3, | |
379 size, size); | |
380 } | |
381 } | |
382 } | |
383 return output_bitmaps; | |
384 } | |
385 | |
386 // static | |
387 void BookmarkAppHelper::GenerateIcon( | |
388 std::map<int, BookmarkAppHelper::BitmapAndSource>* bitmaps, | |
389 int output_size, | |
390 SkColor color, | |
391 char letter) { | |
234 // Do nothing if there is already an icon of |output_size|. | 392 // Do nothing if there is already an icon of |output_size|. |
235 if (bitmaps->count(output_size)) | 393 if (bitmaps->count(output_size)) |
236 return; | 394 return; |
237 | 395 |
238 gfx::ImageSkia icon_image( | 396 gfx::ImageSkia icon_image( |
239 new GeneratedIconImageSource(letter, color, output_size), | 397 new GeneratedIconImageSource(letter, color, output_size), |
240 gfx::Size(output_size, output_size)); | 398 gfx::Size(output_size, output_size)); |
241 icon_image.bitmap()->deepCopyTo(&(*bitmaps)[output_size]); | 399 icon_image.bitmap()->deepCopyTo(&(*bitmaps)[output_size].bitmap); |
400 } | |
401 | |
402 BookmarkAppHelper::BitmapAndSource::BitmapAndSource() { | |
403 } | |
404 | |
405 BookmarkAppHelper::BitmapAndSource::~BitmapAndSource() { | |
242 } | 406 } |
243 | 407 |
244 BookmarkAppHelper::BookmarkAppHelper(Profile* profile, | 408 BookmarkAppHelper::BookmarkAppHelper(Profile* profile, |
245 WebApplicationInfo web_app_info, | 409 WebApplicationInfo web_app_info, |
246 content::WebContents* contents) | 410 content::WebContents* contents) |
247 : profile_(profile), | 411 : profile_(profile), |
248 contents_(contents), | 412 contents_(contents), |
249 web_app_info_(web_app_info), | 413 web_app_info_(web_app_info), |
250 crx_installer_(extensions::CrxInstaller::CreateSilent( | 414 crx_installer_(extensions::CrxInstaller::CreateSilent( |
251 ExtensionSystem::Get(profile)->extension_service())) { | 415 ExtensionSystem::Get(profile)->extension_service())) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
306 bool success, | 470 bool success, |
307 const std::map<GURL, std::vector<SkBitmap> >& bitmaps) { | 471 const std::map<GURL, std::vector<SkBitmap> >& bitmaps) { |
308 // The tab has navigated away during the icon download. Cancel the bookmark | 472 // The tab has navigated away during the icon download. Cancel the bookmark |
309 // app creation. | 473 // app creation. |
310 if (!success) { | 474 if (!success) { |
311 favicon_downloader_.reset(); | 475 favicon_downloader_.reset(); |
312 callback_.Run(nullptr, web_app_info_); | 476 callback_.Run(nullptr, web_app_info_); |
313 return; | 477 return; |
314 } | 478 } |
315 | 479 |
316 std::vector<SkBitmap> downloaded_icons; | 480 std::vector<BitmapAndSource> downloaded_icons; |
317 for (FaviconDownloader::FaviconMap::const_iterator map_it = bitmaps.begin(); | 481 for (FaviconDownloader::FaviconMap::const_iterator map_it = bitmaps.begin(); |
318 map_it != bitmaps.end(); | 482 map_it != bitmaps.end(); |
319 ++map_it) { | 483 ++map_it) { |
320 for (std::vector<SkBitmap>::const_iterator bitmap_it = | 484 for (std::vector<SkBitmap>::const_iterator bitmap_it = |
321 map_it->second.begin(); | 485 map_it->second.begin(); |
322 bitmap_it != map_it->second.end(); | 486 bitmap_it != map_it->second.end(); |
323 ++bitmap_it) { | 487 ++bitmap_it) { |
324 if (bitmap_it->empty() || bitmap_it->width() != bitmap_it->height()) | 488 if (bitmap_it->empty() || bitmap_it->width() != bitmap_it->height()) |
325 continue; | 489 continue; |
326 | 490 |
327 downloaded_icons.push_back(*bitmap_it); | 491 BitmapAndSource bitmap_and_source; |
492 bitmap_and_source.source_url = map_it->first; | |
493 bitmap_and_source.bitmap = *bitmap_it; | |
494 downloaded_icons.push_back(bitmap_and_source); | |
328 } | 495 } |
329 } | 496 } |
330 | 497 |
331 // Add all existing icons from WebApplicationInfo. | 498 // Add all existing icons from WebApplicationInfo. |
332 for (std::vector<WebApplicationInfo::IconInfo>::const_iterator it = | 499 for (std::vector<WebApplicationInfo::IconInfo>::const_iterator it = |
333 web_app_info_.icons.begin(); | 500 web_app_info_.icons.begin(); |
334 it != web_app_info_.icons.end(); | 501 it != web_app_info_.icons.end(); |
335 ++it) { | 502 ++it) { |
336 const SkBitmap& icon = it->data; | 503 const SkBitmap& icon = it->data; |
337 if (!icon.drawsNothing() && icon.width() == icon.height()) | 504 if (!icon.drawsNothing() && icon.width() == icon.height()) { |
338 downloaded_icons.push_back(icon); | 505 BitmapAndSource bitmap_and_source; |
506 bitmap_and_source.bitmap = icon; | |
calamity
2015/04/24 05:05:40
bitmap_and_source.source_url = it->url?
or is the
benwells
2015/04/27 09:54:54
I didn't think they would have a URL in this case.
| |
507 downloaded_icons.push_back(bitmap_and_source); | |
508 } | |
339 } | 509 } |
340 | 510 |
341 // Add the downloaded icons. Extensions only allow certain icon sizes. First | |
342 // populate icons that match the allowed sizes exactly and then downscale | |
343 // remaining icons to the closest allowed size that doesn't yet have an icon. | |
344 std::set<int> allowed_sizes(extension_misc::kExtensionIconSizes, | |
345 extension_misc::kExtensionIconSizes + | |
346 extension_misc::kNumExtensionIconSizes); | |
347 | |
348 web_app_info_.generated_icon_color = SK_ColorTRANSPARENT; | 511 web_app_info_.generated_icon_color = SK_ColorTRANSPARENT; |
349 // Determine the color that will be used for the icon's background. For this | 512 UpdateWebAppInfoIcons(downloaded_icons, &web_app_info_); |
350 // the dominant color of the first icon found is used. | |
351 if (downloaded_icons.size()) { | |
352 color_utils::GridSampler sampler; | |
353 web_app_info_.generated_icon_color = | |
354 color_utils::CalculateKMeanColorOfBitmap(downloaded_icons[0]); | |
355 } | |
356 | |
357 std::set<int> generate_sizes = SizesToGenerate(); | |
358 | |
359 std::map<int, SkBitmap> generated_icons; | |
360 // Icons are always generated, replacing the icons that were downloaded. This | |
361 // is done so that the icons are consistent across machines. | |
362 // TODO(benwells): Use blob sync once it is available to sync the downloaded | |
363 // icons, and then only generate when there are required sizes missing. | |
364 GenerateIcons(generate_sizes, web_app_info_.app_url, | |
365 web_app_info_.generated_icon_color, &generated_icons); | |
366 | |
367 ReplaceWebAppIcons(generated_icons, &web_app_info_); | |
368 favicon_downloader_.reset(); | 513 favicon_downloader_.reset(); |
369 | 514 |
370 if (!contents_) { | 515 if (!contents_) { |
371 // The web contents can be null in tests. | 516 // The web contents can be null in tests. |
372 OnBubbleCompleted(true, web_app_info_); | 517 OnBubbleCompleted(true, web_app_info_); |
373 return; | 518 return; |
374 } | 519 } |
375 | 520 |
376 Browser* browser = chrome::FindBrowserWithWebContents(contents_); | 521 Browser* browser = chrome::FindBrowserWithWebContents(contents_); |
377 if (!browser) { | 522 if (!browser) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
473 callback_.Run(nullptr, web_app_info_); | 618 callback_.Run(nullptr, web_app_info_); |
474 break; | 619 break; |
475 default: | 620 default: |
476 NOTREACHED(); | 621 NOTREACHED(); |
477 break; | 622 break; |
478 } | 623 } |
479 } | 624 } |
480 | 625 |
481 void CreateOrUpdateBookmarkApp(ExtensionService* service, | 626 void CreateOrUpdateBookmarkApp(ExtensionService* service, |
482 WebApplicationInfo* web_app_info) { | 627 WebApplicationInfo* web_app_info) { |
483 scoped_refptr<extensions::CrxInstaller> installer( | 628 scoped_refptr<BookmarkAppInstaller> installer( |
484 extensions::CrxInstaller::CreateSilent(service)); | 629 new BookmarkAppInstaller(service, *web_app_info)); |
485 installer->set_error_on_unsupported_requirements(true); | 630 installer->Run(); |
486 if (web_app_info->icons.empty()) { | |
487 std::map<int, SkBitmap> bitmap_map; | |
488 GenerateIcons(SizesToGenerate(), web_app_info->app_url, | |
489 web_app_info->generated_icon_color, &bitmap_map); | |
490 ReplaceWebAppIcons(bitmap_map, web_app_info); | |
491 } | |
492 | |
493 installer->InstallWebApp(*web_app_info); | |
494 } | 631 } |
495 | 632 |
496 void GetWebApplicationInfoFromApp( | 633 void GetWebApplicationInfoFromApp( |
497 content::BrowserContext* browser_context, | 634 content::BrowserContext* browser_context, |
498 const extensions::Extension* extension, | 635 const extensions::Extension* extension, |
499 const base::Callback<void(const WebApplicationInfo&)> callback) { | 636 const base::Callback<void(const WebApplicationInfo&)> callback) { |
500 if (!extension->from_bookmark()) { | 637 if (!extension->from_bookmark()) { |
501 callback.Run(WebApplicationInfo()); | 638 callback.Run(WebApplicationInfo()); |
502 return; | 639 return; |
503 } | 640 } |
(...skipping 22 matching lines...) Expand all Loading... | |
526 extension, info_list, base::Bind(&OnIconsLoaded, web_app_info, callback)); | 663 extension, info_list, base::Bind(&OnIconsLoaded, web_app_info, callback)); |
527 } | 664 } |
528 | 665 |
529 bool IsValidBookmarkAppUrl(const GURL& url) { | 666 bool IsValidBookmarkAppUrl(const GURL& url) { |
530 URLPattern origin_only_pattern(Extension::kValidWebExtentSchemes); | 667 URLPattern origin_only_pattern(Extension::kValidWebExtentSchemes); |
531 origin_only_pattern.SetMatchAllURLs(true); | 668 origin_only_pattern.SetMatchAllURLs(true); |
532 return url.is_valid() && origin_only_pattern.MatchesURL(url); | 669 return url.is_valid() && origin_only_pattern.MatchesURL(url); |
533 } | 670 } |
534 | 671 |
535 } // namespace extensions | 672 } // namespace extensions |
OLD | NEW |