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 "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/i18n/file_util_icu.h" | 10 #include "base/i18n/file_util_icu.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 #include "url/url_constants.h" | 37 #include "url/url_constants.h" |
38 | 38 |
39 #if defined(OS_WIN) | 39 #if defined(OS_WIN) |
40 #include "ui/gfx/icon_util.h" | 40 #include "ui/gfx/icon_util.h" |
41 #endif | 41 #endif |
42 | 42 |
43 using content::BrowserThread; | 43 using content::BrowserThread; |
44 | 44 |
45 namespace { | 45 namespace { |
46 | 46 |
47 typedef base::Callback<void(const web_app::ShortcutInfo&, | |
48 const extensions::FileHandlersInfo&)> InfoCallback; | |
49 | |
50 #if defined(OS_MACOSX) | 47 #if defined(OS_MACOSX) |
51 const int kDesiredSizes[] = {16, 32, 128, 256, 512}; | 48 const int kDesiredSizes[] = {16, 32, 128, 256, 512}; |
52 const size_t kNumDesiredSizes = arraysize(kDesiredSizes); | 49 const size_t kNumDesiredSizes = arraysize(kDesiredSizes); |
53 #elif defined(OS_LINUX) | 50 #elif defined(OS_LINUX) |
54 // Linux supports icons of any size. FreeDesktop Icon Theme Specification states | 51 // Linux supports icons of any size. FreeDesktop Icon Theme Specification states |
55 // that "Minimally you should install a 48x48 icon in the hicolor theme." | 52 // that "Minimally you should install a 48x48 icon in the hicolor theme." |
56 const int kDesiredSizes[] = {16, 32, 48, 128, 256, 512}; | 53 const int kDesiredSizes[] = {16, 32, 48, 128, 256, 512}; |
57 const size_t kNumDesiredSizes = arraysize(kDesiredSizes); | 54 const size_t kNumDesiredSizes = arraysize(kDesiredSizes); |
58 #elif defined(OS_WIN) | 55 #elif defined(OS_WIN) |
59 const int* kDesiredSizes = IconUtil::kIconDimensions; | 56 const int* kDesiredSizes = IconUtil::kIconDimensions; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 BrowserThread::PostTask( | 97 BrowserThread::PostTask( |
101 BrowserThread::FILE, | 98 BrowserThread::FILE, |
102 FROM_HERE, | 99 FROM_HERE, |
103 base::Bind(&web_app::internals::UpdatePlatformShortcuts, | 100 base::Bind(&web_app::internals::UpdatePlatformShortcuts, |
104 GetShortcutDataDir(shortcut_info), | 101 GetShortcutDataDir(shortcut_info), |
105 old_app_title, shortcut_info, file_handlers_info)); | 102 old_app_title, shortcut_info, file_handlers_info)); |
106 } | 103 } |
107 | 104 |
108 void OnImageLoaded(web_app::ShortcutInfo shortcut_info, | 105 void OnImageLoaded(web_app::ShortcutInfo shortcut_info, |
109 extensions::FileHandlersInfo file_handlers_info, | 106 extensions::FileHandlersInfo file_handlers_info, |
110 InfoCallback callback, | 107 web_app::InfoCallback callback, |
111 const gfx::ImageFamily& image_family) { | 108 const gfx::ImageFamily& image_family) { |
112 // If the image failed to load (e.g. if the resource being loaded was empty) | 109 // If the image failed to load (e.g. if the resource being loaded was empty) |
113 // use the standard application icon. | 110 // use the standard application icon. |
114 if (image_family.empty()) { | 111 if (image_family.empty()) { |
115 gfx::Image default_icon = | 112 gfx::Image default_icon = |
116 ResourceBundle::GetSharedInstance().GetImageNamed(IDR_APP_DEFAULT_ICON); | 113 ResourceBundle::GetSharedInstance().GetImageNamed(IDR_APP_DEFAULT_ICON); |
117 int size = kDesiredSizes[kNumDesiredSizes - 1]; | 114 int size = kDesiredSizes[kNumDesiredSizes - 1]; |
118 SkBitmap bmp = skia::ImageOperations::Resize( | 115 SkBitmap bmp = skia::ImageOperations::Resize( |
119 *default_icon.ToSkBitmap(), skia::ImageOperations::RESIZE_BEST, | 116 *default_icon.ToSkBitmap(), skia::ImageOperations::RESIZE_BEST, |
120 size, size); | 117 size, size); |
121 gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bmp); | 118 gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bmp); |
122 // We are on the UI thread, and this image is needed from the FILE thread, | 119 // We are on the UI thread, and this image is needed from the FILE thread, |
123 // for creating shortcut icon files. | 120 // for creating shortcut icon files. |
124 image_skia.MakeThreadSafe(); | 121 image_skia.MakeThreadSafe(); |
125 shortcut_info.favicon.Add(gfx::Image(image_skia)); | 122 shortcut_info.favicon.Add(gfx::Image(image_skia)); |
126 } else { | 123 } else { |
127 shortcut_info.favicon = image_family; | 124 shortcut_info.favicon = image_family; |
128 } | 125 } |
129 | 126 |
130 callback.Run(shortcut_info, file_handlers_info); | 127 callback.Run(shortcut_info, file_handlers_info); |
131 } | 128 } |
132 | 129 |
| 130 void IgnoreFileHandlersInfo( |
| 131 const web_app::ShortcutInfoCallback& shortcut_info_callback, |
| 132 const web_app::ShortcutInfo& shortcut_info, |
| 133 const extensions::FileHandlersInfo& file_handlers_info) { |
| 134 shortcut_info_callback.Run(shortcut_info); |
| 135 } |
| 136 |
| 137 } // namespace |
| 138 |
| 139 namespace web_app { |
| 140 |
| 141 // The following string is used to build the directory name for |
| 142 // shortcuts to chrome applications (the kind which are installed |
| 143 // from a CRX). Application shortcuts to URLs use the {host}_{path} |
| 144 // for the name of this directory. Hosts can't include an underscore. |
| 145 // By starting this string with an underscore, we ensure that there |
| 146 // are no naming conflicts. |
| 147 static const char kCrxAppPrefix[] = "_crx_"; |
| 148 |
| 149 namespace internals { |
| 150 |
133 void GetInfoForApp(const extensions::Extension* extension, | 151 void GetInfoForApp(const extensions::Extension* extension, |
134 Profile* profile, | 152 Profile* profile, |
135 const InfoCallback& callback) { | 153 const InfoCallback& callback) { |
136 web_app::ShortcutInfo shortcut_info = | 154 web_app::ShortcutInfo shortcut_info = |
137 web_app::ShortcutInfoForExtensionAndProfile(extension, profile); | 155 web_app::ShortcutInfoForExtensionAndProfile(extension, profile); |
138 const std::vector<extensions::FileHandlerInfo>* file_handlers = | 156 const std::vector<extensions::FileHandlerInfo>* file_handlers = |
139 extensions::FileHandlers::GetFileHandlers(extension); | 157 extensions::FileHandlers::GetFileHandlers(extension); |
140 extensions::FileHandlersInfo file_handlers_info = | 158 extensions::FileHandlersInfo file_handlers_info = |
141 file_handlers ? *file_handlers : extensions::FileHandlersInfo(); | 159 file_handlers ? *file_handlers : extensions::FileHandlersInfo(); |
142 | 160 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 | 196 |
179 // |info_list| may still be empty at this point, in which case | 197 // |info_list| may still be empty at this point, in which case |
180 // LoadImageFamilyAsync will call the OnImageLoaded callback with an empty | 198 // LoadImageFamilyAsync will call the OnImageLoaded callback with an empty |
181 // image and exit immediately. | 199 // image and exit immediately. |
182 extensions::ImageLoader::Get(profile)->LoadImageFamilyAsync( | 200 extensions::ImageLoader::Get(profile)->LoadImageFamilyAsync( |
183 extension, | 201 extension, |
184 info_list, | 202 info_list, |
185 base::Bind(&OnImageLoaded, shortcut_info, file_handlers_info, callback)); | 203 base::Bind(&OnImageLoaded, shortcut_info, file_handlers_info, callback)); |
186 } | 204 } |
187 | 205 |
188 void IgnoreFileHandlersInfo( | |
189 const web_app::ShortcutInfoCallback& shortcut_info_callback, | |
190 const web_app::ShortcutInfo& shortcut_info, | |
191 const extensions::FileHandlersInfo& file_handlers_info) { | |
192 shortcut_info_callback.Run(shortcut_info); | |
193 } | |
194 | |
195 } // namespace | |
196 | |
197 namespace web_app { | |
198 | |
199 // The following string is used to build the directory name for | |
200 // shortcuts to chrome applications (the kind which are installed | |
201 // from a CRX). Application shortcuts to URLs use the {host}_{path} | |
202 // for the name of this directory. Hosts can't include an underscore. | |
203 // By starting this string with an underscore, we ensure that there | |
204 // are no naming conflicts. | |
205 static const char* kCrxAppPrefix = "_crx_"; | |
206 | |
207 namespace internals { | |
208 | |
209 base::FilePath GetSanitizedFileName(const base::string16& name) { | 206 base::FilePath GetSanitizedFileName(const base::string16& name) { |
210 #if defined(OS_WIN) | 207 #if defined(OS_WIN) |
211 base::string16 file_name = name; | 208 base::string16 file_name = name; |
212 #else | 209 #else |
213 std::string file_name = base::UTF16ToUTF8(name); | 210 std::string file_name = base::UTF16ToUTF8(name); |
214 #endif | 211 #endif |
215 file_util::ReplaceIllegalCharactersInPath(&file_name, '_'); | 212 file_util::ReplaceIllegalCharactersInPath(&file_name, '_'); |
216 return base::FilePath(file_name); | 213 return base::FilePath(file_name); |
217 } | 214 } |
218 | 215 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 shortcut_info.extension_path = app->path(); | 276 shortcut_info.extension_path = app->path(); |
280 shortcut_info.profile_path = profile->GetPath(); | 277 shortcut_info.profile_path = profile->GetPath(); |
281 shortcut_info.profile_name = | 278 shortcut_info.profile_name = |
282 profile->GetPrefs()->GetString(prefs::kProfileName); | 279 profile->GetPrefs()->GetString(prefs::kProfileName); |
283 return shortcut_info; | 280 return shortcut_info; |
284 } | 281 } |
285 | 282 |
286 void UpdateShortcutInfoAndIconForApp(const extensions::Extension* extension, | 283 void UpdateShortcutInfoAndIconForApp(const extensions::Extension* extension, |
287 Profile* profile, | 284 Profile* profile, |
288 const ShortcutInfoCallback& callback) { | 285 const ShortcutInfoCallback& callback) { |
289 GetInfoForApp(extension, | 286 web_app::internals::GetInfoForApp( |
290 profile, | 287 extension, profile, base::Bind(&IgnoreFileHandlersInfo, callback)); |
291 base::Bind(&IgnoreFileHandlersInfo, callback)); | |
292 } | 288 } |
293 | 289 |
294 bool ShouldCreateShortcutFor(Profile* profile, | 290 bool ShouldCreateShortcutFor(Profile* profile, |
295 const extensions::Extension* extension) { | 291 const extensions::Extension* extension) { |
296 return extension->is_platform_app() && | 292 return extension->is_platform_app() && |
297 extension->location() != extensions::Manifest::COMPONENT && | 293 extension->location() != extensions::Manifest::COMPONENT && |
298 extensions::ui_util::CanDisplayInAppLauncher(extension, profile); | 294 extensions::ui_util::CanDisplayInAppLauncher(extension, profile); |
299 } | 295 } |
300 | 296 |
301 base::FilePath GetWebAppDataDirectory(const base::FilePath& profile_path, | 297 base::FilePath GetWebAppDataDirectory(const base::FilePath& profile_path, |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 | 372 |
377 void CreateShortcuts(ShortcutCreationReason reason, | 373 void CreateShortcuts(ShortcutCreationReason reason, |
378 const ShortcutLocations& locations, | 374 const ShortcutLocations& locations, |
379 Profile* profile, | 375 Profile* profile, |
380 const extensions::Extension* app) { | 376 const extensions::Extension* app) { |
381 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 377 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
382 | 378 |
383 if (!ShouldCreateShortcutFor(profile, app)) | 379 if (!ShouldCreateShortcutFor(profile, app)) |
384 return; | 380 return; |
385 | 381 |
386 GetInfoForApp(app, | 382 internals::GetInfoForApp( |
387 profile, | 383 app, profile, base::Bind(&CreateShortcutsWithInfo, reason, locations)); |
388 base::Bind(&CreateShortcutsWithInfo, reason, locations)); | |
389 } | 384 } |
390 | 385 |
391 void DeleteAllShortcuts(Profile* profile, const extensions::Extension* app) { | 386 void DeleteAllShortcuts(Profile* profile, const extensions::Extension* app) { |
392 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 387 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
393 | 388 |
394 ShortcutInfo shortcut_info = | 389 ShortcutInfo shortcut_info = |
395 ShortcutInfoForExtensionAndProfile(app, profile); | 390 ShortcutInfoForExtensionAndProfile(app, profile); |
396 BrowserThread::PostTask( | 391 BrowserThread::PostTask( |
397 BrowserThread::FILE, | 392 BrowserThread::FILE, |
398 FROM_HERE, | 393 FROM_HERE, |
399 base::Bind(&web_app::internals::DeletePlatformShortcuts, | 394 base::Bind(&web_app::internals::DeletePlatformShortcuts, |
400 GetShortcutDataDir(shortcut_info), shortcut_info)); | 395 GetShortcutDataDir(shortcut_info), shortcut_info)); |
401 } | 396 } |
402 | 397 |
403 void UpdateAllShortcuts(const base::string16& old_app_title, | 398 void UpdateAllShortcuts(const base::string16& old_app_title, |
404 Profile* profile, | 399 Profile* profile, |
405 const extensions::Extension* app) { | 400 const extensions::Extension* app) { |
406 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 401 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
407 | 402 |
408 GetInfoForApp(app, | 403 internals::GetInfoForApp( |
409 profile, | 404 app, |
410 base::Bind(&UpdateAllShortcutsForShortcutInfo, old_app_title)); | 405 profile, |
| 406 base::Bind(&UpdateAllShortcutsForShortcutInfo, old_app_title)); |
411 } | 407 } |
412 | 408 |
413 bool IsValidUrl(const GURL& url) { | 409 bool IsValidUrl(const GURL& url) { |
414 static const char* const kValidUrlSchemes[] = { | 410 static const char* const kValidUrlSchemes[] = { |
415 url::kFileScheme, | 411 url::kFileScheme, |
416 url::kFileSystemScheme, | 412 url::kFileSystemScheme, |
417 url::kFtpScheme, | 413 url::kFtpScheme, |
418 url::kHttpScheme, | 414 url::kHttpScheme, |
419 url::kHttpsScheme, | 415 url::kHttpsScheme, |
420 extensions::kExtensionScheme, | 416 extensions::kExtensionScheme, |
(...skipping 26 matching lines...) Expand all Loading... |
447 | 443 |
448 #if defined(OS_LINUX) | 444 #if defined(OS_LINUX) |
449 std::string GetWMClassFromAppName(std::string app_name) { | 445 std::string GetWMClassFromAppName(std::string app_name) { |
450 file_util::ReplaceIllegalCharactersInPath(&app_name, '_'); | 446 file_util::ReplaceIllegalCharactersInPath(&app_name, '_'); |
451 base::TrimString(app_name, "_", &app_name); | 447 base::TrimString(app_name, "_", &app_name); |
452 return app_name; | 448 return app_name; |
453 } | 449 } |
454 #endif | 450 #endif |
455 | 451 |
456 } // namespace web_app | 452 } // namespace web_app |
OLD | NEW |