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/ui/web_applications/web_app_ui.h" | 5 #include "chrome/browser/ui/web_applications/web_app_ui.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/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 std::vector<ui::ScaleFactor> scale_factors; | 187 std::vector<ui::ScaleFactor> scale_factors; |
188 scale_factors.push_back(ui::SCALE_FACTOR_100P); | 188 scale_factors.push_back(ui::SCALE_FACTOR_100P); |
189 | 189 |
190 size_t closest_index = | 190 size_t closest_index = |
191 FaviconUtil::SelectBestFaviconFromBitmaps(bitmaps, | 191 FaviconUtil::SelectBestFaviconFromBitmaps(bitmaps, |
192 scale_factors, | 192 scale_factors, |
193 requested_size); | 193 requested_size); |
194 | 194 |
195 if (!bitmaps.empty() && !bitmaps[closest_index].isNull()) { | 195 if (!bitmaps.empty() && !bitmaps[closest_index].isNull()) { |
196 // Update icon with download image and update shortcut. | 196 // Update icon with download image and update shortcut. |
197 shortcut_info_.favicon = | 197 shortcut_info_.favicon.Add( |
198 gfx::Image::CreateFrom1xBitmap(bitmaps[closest_index]); | 198 gfx::ImageSkia::CreateFrom1xBitmap(bitmaps[closest_index])); |
199 extensions::TabHelper* extensions_tab_helper = | 199 extensions::TabHelper* extensions_tab_helper = |
200 extensions::TabHelper::FromWebContents(web_contents_); | 200 extensions::TabHelper::FromWebContents(web_contents_); |
201 extensions_tab_helper->SetAppIcon(bitmaps[closest_index]); | 201 extensions_tab_helper->SetAppIcon(bitmaps[closest_index]); |
202 UpdateShortcuts(); | 202 UpdateShortcuts(); |
203 } else { | 203 } else { |
204 // Try the next icon otherwise. | 204 // Try the next icon otherwise. |
205 DownloadIcon(); | 205 DownloadIcon(); |
206 } | 206 } |
207 } | 207 } |
208 | 208 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 // Ensure web_app_path exists. web_app_path could be missing for a legacy | 262 // Ensure web_app_path exists. web_app_path could be missing for a legacy |
263 // shortcut created by Gears. | 263 // shortcut created by Gears. |
264 if (!file_util::PathExists(web_app_path) && | 264 if (!file_util::PathExists(web_app_path) && |
265 !file_util::CreateDirectory(web_app_path)) { | 265 !file_util::CreateDirectory(web_app_path)) { |
266 NOTREACHED(); | 266 NOTREACHED(); |
267 return; | 267 return; |
268 } | 268 } |
269 | 269 |
270 base::FilePath icon_file = web_app_path.Append(file_name_).ReplaceExtension( | 270 base::FilePath icon_file = web_app_path.Append(file_name_).ReplaceExtension( |
271 FILE_PATH_LITERAL(".ico")); | 271 FILE_PATH_LITERAL(".ico")); |
272 web_app::internals::CheckAndSaveIcon(icon_file, | 272 web_app::internals::CheckAndSaveIcon(icon_file, shortcut_info_.favicon); |
273 *shortcut_info_.favicon.ToSkBitmap()); | |
274 | 273 |
275 // Update existing shortcuts' description, icon and app id. | 274 // Update existing shortcuts' description, icon and app id. |
276 CheckExistingShortcuts(); | 275 CheckExistingShortcuts(); |
277 if (!shortcut_files_.empty()) { | 276 if (!shortcut_files_.empty()) { |
278 // Generates app id from web app url and profile path. | 277 // Generates app id from web app url and profile path. |
279 string16 app_id = ShellIntegration::GetAppModelIdForProfile( | 278 string16 app_id = ShellIntegration::GetAppModelIdForProfile( |
280 UTF8ToWide(web_app::GenerateApplicationNameFromURL(shortcut_info_.url)), | 279 UTF8ToWide(web_app::GenerateApplicationNameFromURL(shortcut_info_.url)), |
281 profile_path_); | 280 profile_path_); |
282 | 281 |
283 // Sanitize description | 282 // Sanitize description |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 const gfx::Image& image) { | 323 const gfx::Image& image) { |
325 // If the image failed to load (e.g. if the resource being loaded was empty) | 324 // If the image failed to load (e.g. if the resource being loaded was empty) |
326 // use the standard application icon. | 325 // use the standard application icon. |
327 if (image.IsEmpty()) { | 326 if (image.IsEmpty()) { |
328 gfx::Image default_icon = | 327 gfx::Image default_icon = |
329 ResourceBundle::GetSharedInstance().GetImageNamed(IDR_APP_DEFAULT_ICON); | 328 ResourceBundle::GetSharedInstance().GetImageNamed(IDR_APP_DEFAULT_ICON); |
330 int size = kDesiredSizes[arraysize(kDesiredSizes) - 1]; | 329 int size = kDesiredSizes[arraysize(kDesiredSizes) - 1]; |
331 SkBitmap bmp = skia::ImageOperations::Resize( | 330 SkBitmap bmp = skia::ImageOperations::Resize( |
332 *default_icon.ToSkBitmap(), skia::ImageOperations::RESIZE_BEST, | 331 *default_icon.ToSkBitmap(), skia::ImageOperations::RESIZE_BEST, |
333 size, size); | 332 size, size); |
334 shortcut_info.favicon = gfx::Image::CreateFrom1xBitmap(bmp); | 333 shortcut_info.favicon.Add(gfx::ImageSkia::CreateFrom1xBitmap(bmp)); |
335 } else { | 334 } else { |
336 shortcut_info.favicon = image; | 335 // As described in UpdateShortcutInfoAndIconForApp, image contains all of |
| 336 // the icons, hackily put into a single ImageSkia. Separate them out into |
| 337 // individual ImageSkias and insert them into the icon family. |
| 338 const gfx::ImageSkia& multires_image_skia = *(image.ToImageSkia()); |
| 339 std::vector<gfx::ImageSkiaRep> image_reps = |
| 340 multires_image_skia.image_reps(); |
| 341 for (std::vector<gfx::ImageSkiaRep>::const_iterator it = image_reps.begin(); |
| 342 it != image_reps.end(); ++it) { |
| 343 const gfx::ImageSkiaRep& image = *it; |
| 344 gfx::ImageSkia image_skia(image); |
| 345 image_skia.MakeThreadSafe(); |
| 346 shortcut_info.favicon.Add(image_skia); |
| 347 } |
337 } | 348 } |
338 | 349 |
339 callback.Run(shortcut_info); | 350 callback.Run(shortcut_info); |
340 } | 351 } |
341 | 352 |
342 } // namespace | 353 } // namespace |
343 | 354 |
344 namespace web_app { | 355 namespace web_app { |
345 | 356 |
346 ShellIntegration::ShortcutInfo ShortcutInfoForExtensionAndProfile( | 357 ShellIntegration::ShortcutInfo ShortcutInfoForExtensionAndProfile( |
(...skipping 13 matching lines...) Expand all Loading... |
360 extensions::TabHelper::FromWebContents(web_contents); | 371 extensions::TabHelper::FromWebContents(web_contents); |
361 const WebApplicationInfo& app_info = extensions_tab_helper->web_app_info(); | 372 const WebApplicationInfo& app_info = extensions_tab_helper->web_app_info(); |
362 | 373 |
363 info->url = app_info.app_url.is_empty() ? web_contents->GetURL() : | 374 info->url = app_info.app_url.is_empty() ? web_contents->GetURL() : |
364 app_info.app_url; | 375 app_info.app_url; |
365 info->title = app_info.title.empty() ? | 376 info->title = app_info.title.empty() ? |
366 (web_contents->GetTitle().empty() ? UTF8ToUTF16(info->url.spec()) : | 377 (web_contents->GetTitle().empty() ? UTF8ToUTF16(info->url.spec()) : |
367 web_contents->GetTitle()) : | 378 web_contents->GetTitle()) : |
368 app_info.title; | 379 app_info.title; |
369 info->description = app_info.description; | 380 info->description = app_info.description; |
370 info->favicon = gfx::Image(favicon_tab_helper->GetFavicon()); | 381 info->favicon.Add(favicon_tab_helper->GetFavicon()); |
371 | 382 |
372 Profile* profile = | 383 Profile* profile = |
373 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 384 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
374 info->profile_path = profile->GetPath(); | 385 info->profile_path = profile->GetPath(); |
375 } | 386 } |
376 | 387 |
377 void UpdateShortcutForTabContents(WebContents* web_contents) { | 388 void UpdateShortcutForTabContents(WebContents* web_contents) { |
378 #if defined(OS_WIN) | 389 #if defined(OS_WIN) |
379 // UpdateShortcutWorker will delete itself when it's done. | 390 // UpdateShortcutWorker will delete itself when it's done. |
380 UpdateShortcutWorker* worker = new UpdateShortcutWorker(web_contents); | 391 UpdateShortcutWorker* worker = new UpdateShortcutWorker(web_contents); |
(...skipping 13 matching lines...) Expand all Loading... |
394 shortcut_info->profile_path = profile->GetPath(); | 405 shortcut_info->profile_path = profile->GetPath(); |
395 } | 406 } |
396 | 407 |
397 void UpdateShortcutInfoAndIconForApp( | 408 void UpdateShortcutInfoAndIconForApp( |
398 const extensions::Extension& extension, | 409 const extensions::Extension& extension, |
399 Profile* profile, | 410 Profile* profile, |
400 const web_app::ShortcutInfoCallback& callback) { | 411 const web_app::ShortcutInfoCallback& callback) { |
401 ShellIntegration::ShortcutInfo shortcut_info = | 412 ShellIntegration::ShortcutInfo shortcut_info = |
402 ShortcutInfoForExtensionAndProfile(&extension, profile); | 413 ShortcutInfoForExtensionAndProfile(&extension, profile); |
403 | 414 |
| 415 // We want to load each icon into a separate ImageSkia to insert into an |
| 416 // IconFamily, but LoadImagesAsync currently only builds a single ImageSkia. |
| 417 // Hack around this by loading all images into the ImageSkia as 100% |
| 418 // representations, and later (in OnImageLoaded), pulling them out and |
| 419 // individually inserting them into an IconFamily. |
404 std::vector<extensions::ImageLoader::ImageRepresentation> info_list; | 420 std::vector<extensions::ImageLoader::ImageRepresentation> info_list; |
405 for (size_t i = 0; i < arraysize(kDesiredSizes); ++i) { | 421 for (size_t i = 0; i < arraysize(kDesiredSizes); ++i) { |
406 int size = kDesiredSizes[i]; | 422 int size = kDesiredSizes[i]; |
407 ExtensionResource resource = extensions::IconsInfo::GetIconResource( | 423 ExtensionResource resource = extensions::IconsInfo::GetIconResource( |
408 &extension, size, ExtensionIconSet::MATCH_EXACTLY); | 424 &extension, size, ExtensionIconSet::MATCH_EXACTLY); |
409 if (!resource.empty()) { | 425 if (!resource.empty()) { |
410 info_list.push_back(extensions::ImageLoader::ImageRepresentation( | 426 info_list.push_back(extensions::ImageLoader::ImageRepresentation( |
411 resource, | 427 resource, |
412 extensions::ImageLoader::ImageRepresentation::RESIZE_WHEN_LARGER, | 428 extensions::ImageLoader::ImageRepresentation::RESIZE_WHEN_LARGER, |
413 gfx::Size(size, size), | 429 gfx::Size(size, size), |
(...skipping 22 matching lines...) Expand all Loading... |
436 } | 452 } |
437 | 453 |
438 // |info_list| may still be empty at this point, in which case LoadImage | 454 // |info_list| may still be empty at this point, in which case LoadImage |
439 // will call the OnImageLoaded callback with an empty image and exit | 455 // will call the OnImageLoaded callback with an empty image and exit |
440 // immediately. | 456 // immediately. |
441 extensions::ImageLoader::Get(profile)->LoadImagesAsync(&extension, info_list, | 457 extensions::ImageLoader::Get(profile)->LoadImagesAsync(&extension, info_list, |
442 base::Bind(&OnImageLoaded, shortcut_info, callback)); | 458 base::Bind(&OnImageLoaded, shortcut_info, callback)); |
443 } | 459 } |
444 | 460 |
445 } // namespace web_app | 461 } // namespace web_app |
OLD | NEW |