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/web_applications/web_app.h" | 5 #include "chrome/browser/web_applications/web_app.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 | 81 |
82 base::FilePath GetShortcutDataDir(const web_app::ShortcutInfo& shortcut_info) { | 82 base::FilePath GetShortcutDataDir(const web_app::ShortcutInfo& shortcut_info) { |
83 return web_app::GetWebAppDataDirectory(shortcut_info.profile_path, | 83 return web_app::GetWebAppDataDirectory(shortcut_info.profile_path, |
84 shortcut_info.extension_id, | 84 shortcut_info.extension_id, |
85 shortcut_info.url); | 85 shortcut_info.url); |
86 } | 86 } |
87 | 87 |
88 void UpdateAllShortcutsForShortcutInfo( | 88 void UpdateAllShortcutsForShortcutInfo( |
89 const base::string16& old_app_title, | 89 const base::string16& old_app_title, |
90 const base::Closure& callback, | 90 const base::Closure& callback, |
91 std::unique_ptr<web_app::ShortcutInfo> shortcut_info, | 91 std::unique_ptr<web_app::ShortcutInfo> shortcut_info) { |
92 const extensions::FileHandlersInfo& file_handlers_info) { | |
93 base::FilePath shortcut_data_dir = GetShortcutDataDir(*shortcut_info); | 92 base::FilePath shortcut_data_dir = GetShortcutDataDir(*shortcut_info); |
94 base::Closure task = base::Bind( | 93 base::Closure task = base::Bind(&web_app::internals::UpdatePlatformShortcuts, |
95 &web_app::internals::UpdatePlatformShortcuts, shortcut_data_dir, | 94 shortcut_data_dir, old_app_title, |
96 old_app_title, base::Passed(&shortcut_info), file_handlers_info); | 95 base::Passed(&shortcut_info)); |
97 if (callback.is_null()) { | 96 if (callback.is_null()) { |
98 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, task); | 97 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, task); |
99 } else { | 98 } else { |
100 BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE, task, | 99 BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE, task, |
101 callback); | 100 callback); |
102 } | 101 } |
103 } | 102 } |
104 | 103 |
105 void OnImageLoaded(std::unique_ptr<web_app::ShortcutInfo> shortcut_info, | 104 void OnImageLoaded(std::unique_ptr<web_app::ShortcutInfo> shortcut_info, |
106 extensions::FileHandlersInfo file_handlers_info, | 105 web_app::ShortcutInfoCallback callback, |
107 web_app::InfoCallback callback, | |
108 const gfx::ImageFamily& image_family) { | 106 const gfx::ImageFamily& image_family) { |
109 // If the image failed to load (e.g. if the resource being loaded was empty) | 107 // If the image failed to load (e.g. if the resource being loaded was empty) |
110 // use the standard application icon. | 108 // use the standard application icon. |
111 if (image_family.empty()) { | 109 if (image_family.empty()) { |
112 gfx::Image default_icon = | 110 gfx::Image default_icon = |
113 ResourceBundle::GetSharedInstance().GetImageNamed(IDR_APP_DEFAULT_ICON); | 111 ResourceBundle::GetSharedInstance().GetImageNamed(IDR_APP_DEFAULT_ICON); |
114 int size = kDesiredSizes[kNumDesiredSizes - 1]; | 112 int size = kDesiredSizes[kNumDesiredSizes - 1]; |
115 SkBitmap bmp = skia::ImageOperations::Resize( | 113 SkBitmap bmp = skia::ImageOperations::Resize( |
116 *default_icon.ToSkBitmap(), skia::ImageOperations::RESIZE_BEST, | 114 *default_icon.ToSkBitmap(), skia::ImageOperations::RESIZE_BEST, |
117 size, size); | 115 size, size); |
118 gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bmp); | 116 gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bmp); |
119 // We are on the UI thread, and this image is needed from the FILE thread, | 117 // We are on the UI thread, and this image is needed from the FILE thread, |
120 // for creating shortcut icon files. | 118 // for creating shortcut icon files. |
121 image_skia.MakeThreadSafe(); | 119 image_skia.MakeThreadSafe(); |
122 shortcut_info->favicon.Add(gfx::Image(image_skia)); | 120 shortcut_info->favicon.Add(gfx::Image(image_skia)); |
123 } else { | 121 } else { |
124 shortcut_info->favicon = image_family; | 122 shortcut_info->favicon = image_family; |
125 } | 123 } |
126 | 124 |
127 callback.Run(std::move(shortcut_info), file_handlers_info); | 125 callback.Run(std::move(shortcut_info)); |
128 } | |
129 | |
130 void IgnoreFileHandlersInfo( | |
131 const web_app::ShortcutInfoCallback& shortcut_info_callback, | |
132 std::unique_ptr<web_app::ShortcutInfo> shortcut_info, | |
133 const extensions::FileHandlersInfo& file_handlers_info) { | |
134 shortcut_info_callback.Run(std::move(shortcut_info)); | |
135 } | 126 } |
136 | 127 |
137 void ScheduleCreatePlatformShortcut( | 128 void ScheduleCreatePlatformShortcut( |
138 web_app::ShortcutCreationReason reason, | 129 web_app::ShortcutCreationReason reason, |
139 const web_app::ShortcutLocations& locations, | 130 const web_app::ShortcutLocations& locations, |
140 std::unique_ptr<web_app::ShortcutInfo> shortcut_info, | 131 std::unique_ptr<web_app::ShortcutInfo> shortcut_info) { |
141 const extensions::FileHandlersInfo& file_handlers_info) { | |
142 base::FilePath shortcut_data_dir = GetShortcutDataDir(*shortcut_info); | 132 base::FilePath shortcut_data_dir = GetShortcutDataDir(*shortcut_info); |
143 BrowserThread::PostTask( | 133 BrowserThread::PostTask( |
144 BrowserThread::FILE, FROM_HERE, | 134 BrowserThread::FILE, FROM_HERE, |
145 base::Bind( | 135 base::Bind( |
146 base::IgnoreResult(&web_app::internals::CreatePlatformShortcuts), | 136 base::IgnoreResult(&web_app::internals::CreatePlatformShortcuts), |
147 shortcut_data_dir, base::Passed(&shortcut_info), file_handlers_info, | 137 shortcut_data_dir, base::Passed(&shortcut_info), locations, reason)); |
148 locations, reason)); | |
149 } | 138 } |
150 | 139 |
151 } // namespace | 140 } // namespace |
152 | 141 |
153 namespace web_app { | 142 namespace web_app { |
154 | 143 |
155 // The following string is used to build the directory name for | 144 // The following string is used to build the directory name for |
156 // shortcuts to chrome applications (the kind which are installed | 145 // shortcuts to chrome applications (the kind which are installed |
157 // from a CRX). Application shortcuts to URLs use the {host}_{path} | 146 // from a CRX). Application shortcuts to URLs use the {host}_{path} |
158 // for the name of this directory. Hosts can't include an underscore. | 147 // for the name of this directory. Hosts can't include an underscore. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 shortcut_info->title = base::UTF8ToUTF16(app->name()); | 220 shortcut_info->title = base::UTF8ToUTF16(app->name()); |
232 shortcut_info->description = base::UTF8ToUTF16(app->description()); | 221 shortcut_info->description = base::UTF8ToUTF16(app->description()); |
233 shortcut_info->extension_path = app->path(); | 222 shortcut_info->extension_path = app->path(); |
234 shortcut_info->profile_path = profile->GetPath(); | 223 shortcut_info->profile_path = profile->GetPath(); |
235 shortcut_info->profile_name = | 224 shortcut_info->profile_name = |
236 profile->GetPrefs()->GetString(prefs::kProfileName); | 225 profile->GetPrefs()->GetString(prefs::kProfileName); |
237 shortcut_info->version_for_display = app->GetVersionForDisplay(); | 226 shortcut_info->version_for_display = app->GetVersionForDisplay(); |
238 return shortcut_info; | 227 return shortcut_info; |
239 } | 228 } |
240 | 229 |
241 void GetInfoForApp(const extensions::Extension* extension, | 230 void GetShortcutInfoForApp(const extensions::Extension* extension, |
242 Profile* profile, | 231 Profile* profile, |
243 const InfoCallback& callback) { | 232 const ShortcutInfoCallback& callback) { |
244 std::unique_ptr<web_app::ShortcutInfo> shortcut_info( | 233 std::unique_ptr<web_app::ShortcutInfo> shortcut_info( |
245 web_app::ShortcutInfoForExtensionAndProfile(extension, profile)); | 234 web_app::ShortcutInfoForExtensionAndProfile(extension, profile)); |
246 const std::vector<extensions::FileHandlerInfo>* file_handlers = | |
247 extensions::FileHandlers::GetFileHandlers(extension); | |
248 extensions::FileHandlersInfo file_handlers_info = | |
249 file_handlers ? *file_handlers : extensions::FileHandlersInfo(); | |
250 | 235 |
251 std::vector<extensions::ImageLoader::ImageRepresentation> info_list; | 236 std::vector<extensions::ImageLoader::ImageRepresentation> info_list; |
252 for (size_t i = 0; i < kNumDesiredSizes; ++i) { | 237 for (size_t i = 0; i < kNumDesiredSizes; ++i) { |
253 int size = kDesiredSizes[i]; | 238 int size = kDesiredSizes[i]; |
254 extensions::ExtensionResource resource = | 239 extensions::ExtensionResource resource = |
255 extensions::IconsInfo::GetIconResource( | 240 extensions::IconsInfo::GetIconResource( |
256 extension, size, ExtensionIconSet::MATCH_EXACTLY); | 241 extension, size, ExtensionIconSet::MATCH_EXACTLY); |
257 if (!resource.empty()) { | 242 if (!resource.empty()) { |
258 info_list.push_back(extensions::ImageLoader::ImageRepresentation( | 243 info_list.push_back(extensions::ImageLoader::ImageRepresentation( |
259 resource, | 244 resource, |
(...skipping 22 matching lines...) Expand all Loading... |
282 extensions::ImageLoader::ImageRepresentation::ALWAYS_RESIZE, | 267 extensions::ImageLoader::ImageRepresentation::ALWAYS_RESIZE, |
283 gfx::Size(size, size), | 268 gfx::Size(size, size), |
284 ui::SCALE_FACTOR_100P)); | 269 ui::SCALE_FACTOR_100P)); |
285 } | 270 } |
286 | 271 |
287 // |info_list| may still be empty at this point, in which case | 272 // |info_list| may still be empty at this point, in which case |
288 // LoadImageFamilyAsync will call the OnImageLoaded callback with an empty | 273 // LoadImageFamilyAsync will call the OnImageLoaded callback with an empty |
289 // image and exit immediately. | 274 // image and exit immediately. |
290 extensions::ImageLoader::Get(profile)->LoadImageFamilyAsync( | 275 extensions::ImageLoader::Get(profile)->LoadImageFamilyAsync( |
291 extension, info_list, | 276 extension, info_list, |
292 base::Bind(&OnImageLoaded, base::Passed(&shortcut_info), | 277 base::Bind(&OnImageLoaded, base::Passed(&shortcut_info), callback)); |
293 file_handlers_info, callback)); | |
294 } | |
295 | |
296 void GetShortcutInfoForApp(const extensions::Extension* extension, | |
297 Profile* profile, | |
298 const ShortcutInfoCallback& callback) { | |
299 GetInfoForApp( | |
300 extension, profile, base::Bind(&IgnoreFileHandlersInfo, callback)); | |
301 } | 278 } |
302 | 279 |
303 bool ShouldCreateShortcutFor(web_app::ShortcutCreationReason reason, | 280 bool ShouldCreateShortcutFor(web_app::ShortcutCreationReason reason, |
304 Profile* profile, | 281 Profile* profile, |
305 const extensions::Extension* extension) { | 282 const extensions::Extension* extension) { |
306 // Shortcuts should never be created for component apps, or for apps that | 283 // Shortcuts should never be created for component apps, or for apps that |
307 // cannot be shown in the launcher. | 284 // cannot be shown in the launcher. |
308 if (extension->location() == extensions::Manifest::COMPONENT || | 285 if (extension->location() == extensions::Manifest::COMPONENT || |
309 !extensions::ui_util::CanDisplayInAppLauncher(extension, profile)) { | 286 !extensions::ui_util::CanDisplayInAppLauncher(extension, profile)) { |
310 return false; | 287 return false; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 return t; | 377 return t; |
401 } | 378 } |
402 | 379 |
403 std::string GetExtensionIdFromApplicationName(const std::string& app_name) { | 380 std::string GetExtensionIdFromApplicationName(const std::string& app_name) { |
404 std::string prefix(kCrxAppPrefix); | 381 std::string prefix(kCrxAppPrefix); |
405 if (app_name.substr(0, prefix.length()) != prefix) | 382 if (app_name.substr(0, prefix.length()) != prefix) |
406 return std::string(); | 383 return std::string(); |
407 return app_name.substr(prefix.length()); | 384 return app_name.substr(prefix.length()); |
408 } | 385 } |
409 | 386 |
410 void CreateShortcutsWithInfo( | 387 void CreateShortcutsWithInfo(ShortcutCreationReason reason, |
411 ShortcutCreationReason reason, | 388 const ShortcutLocations& locations, |
412 const ShortcutLocations& locations, | 389 std::unique_ptr<ShortcutInfo> shortcut_info) { |
413 std::unique_ptr<ShortcutInfo> shortcut_info, | |
414 const extensions::FileHandlersInfo& file_handlers_info) { | |
415 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 390 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
416 | 391 |
417 // If the shortcut is for an application shortcut with the new bookmark app | 392 // If the shortcut is for an application shortcut with the new bookmark app |
418 // flow disabled, there will be no corresponding extension. | 393 // flow disabled, there will be no corresponding extension. |
419 if (!shortcut_info->extension_id.empty()) { | 394 if (!shortcut_info->extension_id.empty()) { |
420 // It's possible for the extension to be deleted before we get here. | 395 // It's possible for the extension to be deleted before we get here. |
421 // For example, creating a hosted app from a website. Double check that | 396 // For example, creating a hosted app from a website. Double check that |
422 // it still exists. | 397 // it still exists. |
423 Profile* profile = g_browser_process->profile_manager()->GetProfileByPath( | 398 Profile* profile = g_browser_process->profile_manager()->GetProfileByPath( |
424 shortcut_info->profile_path); | 399 shortcut_info->profile_path); |
425 if (!profile) | 400 if (!profile) |
426 return; | 401 return; |
427 | 402 |
428 extensions::ExtensionRegistry* registry = | 403 extensions::ExtensionRegistry* registry = |
429 extensions::ExtensionRegistry::Get(profile); | 404 extensions::ExtensionRegistry::Get(profile); |
430 const extensions::Extension* extension = registry->GetExtensionById( | 405 const extensions::Extension* extension = registry->GetExtensionById( |
431 shortcut_info->extension_id, extensions::ExtensionRegistry::EVERYTHING); | 406 shortcut_info->extension_id, extensions::ExtensionRegistry::EVERYTHING); |
432 if (!extension) | 407 if (!extension) |
433 return; | 408 return; |
434 } | 409 } |
435 | 410 |
436 ScheduleCreatePlatformShortcut(reason, locations, std::move(shortcut_info), | 411 ScheduleCreatePlatformShortcut(reason, locations, std::move(shortcut_info)); |
437 file_handlers_info); | |
438 } | 412 } |
439 | 413 |
440 void CreateShortcuts(ShortcutCreationReason reason, | 414 void CreateShortcuts(ShortcutCreationReason reason, |
441 const ShortcutLocations& locations, | 415 const ShortcutLocations& locations, |
442 Profile* profile, | 416 Profile* profile, |
443 const extensions::Extension* app) { | 417 const extensions::Extension* app) { |
444 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 418 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
445 | 419 |
446 if (!ShouldCreateShortcutFor(reason, profile, app)) | 420 if (!ShouldCreateShortcutFor(reason, profile, app)) |
447 return; | 421 return; |
448 | 422 |
449 GetInfoForApp( | 423 GetShortcutInfoForApp( |
450 app, profile, base::Bind(&CreateShortcutsWithInfo, reason, locations)); | 424 app, profile, base::Bind(&CreateShortcutsWithInfo, reason, locations)); |
451 } | 425 } |
452 | 426 |
453 void DeleteAllShortcuts(Profile* profile, const extensions::Extension* app) { | 427 void DeleteAllShortcuts(Profile* profile, const extensions::Extension* app) { |
454 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 428 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
455 | 429 |
456 std::unique_ptr<ShortcutInfo> shortcut_info( | 430 std::unique_ptr<ShortcutInfo> shortcut_info( |
457 ShortcutInfoForExtensionAndProfile(app, profile)); | 431 ShortcutInfoForExtensionAndProfile(app, profile)); |
458 base::FilePath shortcut_data_dir = GetShortcutDataDir(*shortcut_info); | 432 base::FilePath shortcut_data_dir = GetShortcutDataDir(*shortcut_info); |
459 BrowserThread::PostTask( | 433 BrowserThread::PostTask( |
460 BrowserThread::FILE, FROM_HERE, | 434 BrowserThread::FILE, FROM_HERE, |
461 base::Bind(&web_app::internals::DeletePlatformShortcuts, | 435 base::Bind(&web_app::internals::DeletePlatformShortcuts, |
462 shortcut_data_dir, base::Passed(&shortcut_info))); | 436 shortcut_data_dir, base::Passed(&shortcut_info))); |
463 } | 437 } |
464 | 438 |
465 void UpdateAllShortcuts(const base::string16& old_app_title, | 439 void UpdateAllShortcuts(const base::string16& old_app_title, |
466 Profile* profile, | 440 Profile* profile, |
467 const extensions::Extension* app, | 441 const extensions::Extension* app, |
468 const base::Closure& callback) { | 442 const base::Closure& callback) { |
469 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 443 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
470 | 444 |
471 GetInfoForApp(app, profile, base::Bind(&UpdateAllShortcutsForShortcutInfo, | 445 GetShortcutInfoForApp( |
472 old_app_title, callback)); | 446 app, profile, |
| 447 base::Bind(&UpdateAllShortcutsForShortcutInfo, old_app_title, callback)); |
473 } | 448 } |
474 | 449 |
475 bool IsValidUrl(const GURL& url) { | 450 bool IsValidUrl(const GURL& url) { |
476 static const char* const kValidUrlSchemes[] = { | 451 static const char* const kValidUrlSchemes[] = { |
477 url::kFileScheme, | 452 url::kFileScheme, |
478 url::kFileSystemScheme, | 453 url::kFileSystemScheme, |
479 url::kFtpScheme, | 454 url::kFtpScheme, |
480 url::kHttpScheme, | 455 url::kHttpScheme, |
481 url::kHttpsScheme, | 456 url::kHttpsScheme, |
482 extensions::kExtensionScheme, | 457 extensions::kExtensionScheme, |
(...skipping 26 matching lines...) Expand all Loading... |
509 | 484 |
510 #if defined(OS_LINUX) | 485 #if defined(OS_LINUX) |
511 std::string GetWMClassFromAppName(std::string app_name) { | 486 std::string GetWMClassFromAppName(std::string app_name) { |
512 base::i18n::ReplaceIllegalCharactersInPath(&app_name, '_'); | 487 base::i18n::ReplaceIllegalCharactersInPath(&app_name, '_'); |
513 base::TrimString(app_name, "_", &app_name); | 488 base::TrimString(app_name, "_", &app_name); |
514 return app_name; | 489 return app_name; |
515 } | 490 } |
516 #endif | 491 #endif |
517 | 492 |
518 } // namespace web_app | 493 } // namespace web_app |
OLD | NEW |