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 24 matching lines...) Expand all Loading... | |
35 #include "ui/gfx/image/image_skia.h" | 35 #include "ui/gfx/image/image_skia.h" |
36 | 36 |
37 #if defined(OS_WIN) | 37 #if defined(OS_WIN) |
38 #include "ui/gfx/icon_util.h" | 38 #include "ui/gfx/icon_util.h" |
39 #endif | 39 #endif |
40 | 40 |
41 using content::BrowserThread; | 41 using content::BrowserThread; |
42 | 42 |
43 namespace { | 43 namespace { |
44 | 44 |
45 typedef base::Callback<void(const web_app::ShortcutInfo&, | |
46 const extensions::FileHandlersInfo&)> InfoCallback; | |
47 | |
48 #if defined(OS_MACOSX) | 45 #if defined(OS_MACOSX) |
49 const int kDesiredSizes[] = {16, 32, 128, 256, 512}; | 46 const int kDesiredSizes[] = {16, 32, 128, 256, 512}; |
50 const size_t kNumDesiredSizes = arraysize(kDesiredSizes); | 47 const size_t kNumDesiredSizes = arraysize(kDesiredSizes); |
51 #elif defined(OS_LINUX) | 48 #elif defined(OS_LINUX) |
52 // Linux supports icons of any size. FreeDesktop Icon Theme Specification states | 49 // Linux supports icons of any size. FreeDesktop Icon Theme Specification states |
53 // that "Minimally you should install a 48x48 icon in the hicolor theme." | 50 // that "Minimally you should install a 48x48 icon in the hicolor theme." |
54 const int kDesiredSizes[] = {16, 32, 48, 128, 256, 512}; | 51 const int kDesiredSizes[] = {16, 32, 48, 128, 256, 512}; |
55 const size_t kNumDesiredSizes = arraysize(kDesiredSizes); | 52 const size_t kNumDesiredSizes = arraysize(kDesiredSizes); |
56 #elif defined(OS_WIN) | 53 #elif defined(OS_WIN) |
57 const int* kDesiredSizes = IconUtil::kIconDimensions; | 54 const int* kDesiredSizes = IconUtil::kIconDimensions; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
127 const extensions::FileHandlersInfo& file_handlers_info) { | 124 const extensions::FileHandlersInfo& file_handlers_info) { |
128 BrowserThread::PostTask( | 125 BrowserThread::PostTask( |
129 BrowserThread::FILE, | 126 BrowserThread::FILE, |
130 FROM_HERE, | 127 FROM_HERE, |
131 base::Bind(&UpdateShortcutsOnFileThread, | 128 base::Bind(&UpdateShortcutsOnFileThread, |
132 old_app_title, shortcut_info, file_handlers_info)); | 129 old_app_title, shortcut_info, file_handlers_info)); |
133 } | 130 } |
134 | 131 |
135 void OnImageLoaded(web_app::ShortcutInfo shortcut_info, | 132 void OnImageLoaded(web_app::ShortcutInfo shortcut_info, |
136 extensions::FileHandlersInfo file_handlers_info, | 133 extensions::FileHandlersInfo file_handlers_info, |
137 InfoCallback callback, | 134 web_app::InfoCallback callback, |
138 const gfx::ImageFamily& image_family) { | 135 const gfx::ImageFamily& image_family) { |
139 // If the image failed to load (e.g. if the resource being loaded was empty) | 136 // If the image failed to load (e.g. if the resource being loaded was empty) |
140 // use the standard application icon. | 137 // use the standard application icon. |
141 if (image_family.empty()) { | 138 if (image_family.empty()) { |
142 gfx::Image default_icon = | 139 gfx::Image default_icon = |
143 ResourceBundle::GetSharedInstance().GetImageNamed(IDR_APP_DEFAULT_ICON); | 140 ResourceBundle::GetSharedInstance().GetImageNamed(IDR_APP_DEFAULT_ICON); |
144 int size = kDesiredSizes[kNumDesiredSizes - 1]; | 141 int size = kDesiredSizes[kNumDesiredSizes - 1]; |
145 SkBitmap bmp = skia::ImageOperations::Resize( | 142 SkBitmap bmp = skia::ImageOperations::Resize( |
146 *default_icon.ToSkBitmap(), skia::ImageOperations::RESIZE_BEST, | 143 *default_icon.ToSkBitmap(), skia::ImageOperations::RESIZE_BEST, |
147 size, size); | 144 size, size); |
148 gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bmp); | 145 gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bmp); |
149 // We are on the UI thread, and this image is needed from the FILE thread, | 146 // We are on the UI thread, and this image is needed from the FILE thread, |
150 // for creating shortcut icon files. | 147 // for creating shortcut icon files. |
151 image_skia.MakeThreadSafe(); | 148 image_skia.MakeThreadSafe(); |
152 shortcut_info.favicon.Add(gfx::Image(image_skia)); | 149 shortcut_info.favicon.Add(gfx::Image(image_skia)); |
153 } else { | 150 } else { |
154 shortcut_info.favicon = image_family; | 151 shortcut_info.favicon = image_family; |
155 } | 152 } |
156 | 153 |
157 callback.Run(shortcut_info, file_handlers_info); | 154 callback.Run(shortcut_info, file_handlers_info); |
158 } | 155 } |
159 | 156 |
157 void IgnoreFileHandlersInfo( | |
158 const web_app::ShortcutInfoCallback& shortcut_info_callback, | |
159 const web_app::ShortcutInfo& shortcut_info, | |
160 const extensions::FileHandlersInfo& file_handlers_info) { | |
161 shortcut_info_callback.Run(shortcut_info); | |
162 } | |
163 | |
164 } // namespace | |
165 | |
166 namespace web_app { | |
167 | |
168 // The following string is used to build the directory name for | |
169 // shortcuts to chrome applications (the kind which are installed | |
170 // from a CRX). Application shortcuts to URLs use the {host}_{path} | |
171 // for the name of this directory. Hosts can't include an underscore. | |
172 // By starting this string with an underscore, we ensure that there | |
173 // are no naming conflicts. | |
174 static const char* kCrxAppPrefix = "_crx_"; | |
tapted
2014/05/06 07:13:24
nit: (since it's showing up in the diff) should th
jackhou1
2014/05/06 08:38:17
Done.
| |
175 | |
176 namespace internals { | |
177 | |
160 void GetInfoForApp(const extensions::Extension* extension, | 178 void GetInfoForApp(const extensions::Extension* extension, |
161 Profile* profile, | 179 Profile* profile, |
162 const InfoCallback& callback) { | 180 const InfoCallback& callback) { |
163 web_app::ShortcutInfo shortcut_info = | 181 web_app::ShortcutInfo shortcut_info = |
164 web_app::ShortcutInfoForExtensionAndProfile(extension, profile); | 182 web_app::ShortcutInfoForExtensionAndProfile(extension, profile); |
165 extensions::FileHandlersInfo file_handlers_info; | 183 extensions::FileHandlersInfo file_handlers_info; |
166 const std::vector<extensions::FileHandlerInfo>* file_handlers = | 184 const std::vector<extensions::FileHandlerInfo>* file_handlers = |
167 extensions::FileHandlers::GetFileHandlers(extension); | 185 extensions::FileHandlers::GetFileHandlers(extension); |
168 if (file_handlers) | 186 if (file_handlers) |
169 file_handlers_info.handlers = *file_handlers; | 187 file_handlers_info.handlers = *file_handlers; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
206 | 224 |
207 // |info_list| may still be empty at this point, in which case | 225 // |info_list| may still be empty at this point, in which case |
208 // LoadImageFamilyAsync will call the OnImageLoaded callback with an empty | 226 // LoadImageFamilyAsync will call the OnImageLoaded callback with an empty |
209 // image and exit immediately. | 227 // image and exit immediately. |
210 extensions::ImageLoader::Get(profile)->LoadImageFamilyAsync( | 228 extensions::ImageLoader::Get(profile)->LoadImageFamilyAsync( |
211 extension, | 229 extension, |
212 info_list, | 230 info_list, |
213 base::Bind(&OnImageLoaded, shortcut_info, file_handlers_info, callback)); | 231 base::Bind(&OnImageLoaded, shortcut_info, file_handlers_info, callback)); |
214 } | 232 } |
215 | 233 |
216 void IgnoreFileHandlersInfo( | |
217 const web_app::ShortcutInfoCallback& shortcut_info_callback, | |
218 const web_app::ShortcutInfo& shortcut_info, | |
219 const extensions::FileHandlersInfo& file_handlers_info) { | |
220 shortcut_info_callback.Run(shortcut_info); | |
221 } | |
222 | |
223 } // namespace | |
224 | |
225 namespace web_app { | |
226 | |
227 // The following string is used to build the directory name for | |
228 // shortcuts to chrome applications (the kind which are installed | |
229 // from a CRX). Application shortcuts to URLs use the {host}_{path} | |
230 // for the name of this directory. Hosts can't include an underscore. | |
231 // By starting this string with an underscore, we ensure that there | |
232 // are no naming conflicts. | |
233 static const char* kCrxAppPrefix = "_crx_"; | |
234 | |
235 namespace internals { | |
236 | |
237 base::FilePath GetSanitizedFileName(const base::string16& name) { | 234 base::FilePath GetSanitizedFileName(const base::string16& name) { |
238 #if defined(OS_WIN) | 235 #if defined(OS_WIN) |
239 base::string16 file_name = name; | 236 base::string16 file_name = name; |
240 #else | 237 #else |
241 std::string file_name = base::UTF16ToUTF8(name); | 238 std::string file_name = base::UTF16ToUTF8(name); |
242 #endif | 239 #endif |
243 file_util::ReplaceIllegalCharactersInPath(&file_name, '_'); | 240 file_util::ReplaceIllegalCharactersInPath(&file_name, '_'); |
244 return base::FilePath(file_name); | 241 return base::FilePath(file_name); |
245 } | 242 } |
246 | 243 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
312 shortcut_info.profile_path = profile->GetPath(); | 309 shortcut_info.profile_path = profile->GetPath(); |
313 shortcut_info.profile_name = | 310 shortcut_info.profile_name = |
314 profile->GetPrefs()->GetString(prefs::kProfileName); | 311 profile->GetPrefs()->GetString(prefs::kProfileName); |
315 return shortcut_info; | 312 return shortcut_info; |
316 } | 313 } |
317 | 314 |
318 void UpdateShortcutInfoAndIconForApp( | 315 void UpdateShortcutInfoAndIconForApp( |
319 const extensions::Extension* extension, | 316 const extensions::Extension* extension, |
320 Profile* profile, | 317 Profile* profile, |
321 const web_app::ShortcutInfoCallback& callback) { | 318 const web_app::ShortcutInfoCallback& callback) { |
322 GetInfoForApp(extension, | 319 internals::GetInfoForApp(extension, |
323 profile, | 320 profile, |
324 base::Bind(&IgnoreFileHandlersInfo, callback)); | 321 base::Bind(&IgnoreFileHandlersInfo, callback)); |
325 } | 322 } |
326 | 323 |
327 base::FilePath GetWebAppDataDirectory(const base::FilePath& profile_path, | 324 base::FilePath GetWebAppDataDirectory(const base::FilePath& profile_path, |
328 const std::string& extension_id, | 325 const std::string& extension_id, |
329 const GURL& url) { | 326 const GURL& url) { |
330 DCHECK(!profile_path.empty()); | 327 DCHECK(!profile_path.empty()); |
331 base::FilePath app_data_dir(profile_path.Append(chrome::kWebAppDirname)); | 328 base::FilePath app_data_dir(profile_path.Append(chrome::kWebAppDirname)); |
332 | 329 |
333 if (!extension_id.empty()) { | 330 if (!extension_id.empty()) { |
334 return app_data_dir.AppendASCII( | 331 return app_data_dir.AppendASCII( |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
405 reason, locations, shortcut_info)); | 402 reason, locations, shortcut_info)); |
406 } | 403 } |
407 | 404 |
408 void CreateShortcuts( | 405 void CreateShortcuts( |
409 ShortcutCreationReason reason, | 406 ShortcutCreationReason reason, |
410 const web_app::ShortcutLocations& locations, | 407 const web_app::ShortcutLocations& locations, |
411 Profile* profile, | 408 Profile* profile, |
412 const extensions::Extension* app) { | 409 const extensions::Extension* app) { |
413 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
414 | 411 |
415 GetInfoForApp(app, | 412 internals::GetInfoForApp( |
416 profile, | 413 app, |
417 base::Bind(&CreateShortcutsWithInfo, reason, locations)); | 414 profile, |
415 base::Bind(&CreateShortcutsWithInfo, reason, locations)); | |
418 } | 416 } |
419 | 417 |
420 void DeleteAllShortcuts(Profile* profile, const extensions::Extension* app) { | 418 void DeleteAllShortcuts(Profile* profile, const extensions::Extension* app) { |
421 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 419 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
422 | 420 |
423 BrowserThread::PostTask( | 421 BrowserThread::PostTask( |
424 BrowserThread::FILE, | 422 BrowserThread::FILE, |
425 FROM_HERE, | 423 FROM_HERE, |
426 base::Bind(&DeleteShortcutsOnFileThread, | 424 base::Bind(&DeleteShortcutsOnFileThread, |
427 web_app::ShortcutInfoForExtensionAndProfile(app, profile))); | 425 web_app::ShortcutInfoForExtensionAndProfile(app, profile))); |
428 } | 426 } |
429 | 427 |
430 void UpdateAllShortcuts(const base::string16& old_app_title, | 428 void UpdateAllShortcuts(const base::string16& old_app_title, |
431 Profile* profile, | 429 Profile* profile, |
432 const extensions::Extension* app) { | 430 const extensions::Extension* app) { |
433 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 431 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
434 | 432 |
435 GetInfoForApp(app, | 433 internals::GetInfoForApp( |
436 profile, | 434 app, |
437 base::Bind(&UpdateAllShortcutsForShortcutInfo, old_app_title)); | 435 profile, |
436 base::Bind(&UpdateAllShortcutsForShortcutInfo, old_app_title)); | |
438 } | 437 } |
439 | 438 |
440 bool IsValidUrl(const GURL& url) { | 439 bool IsValidUrl(const GURL& url) { |
441 static const char* const kValidUrlSchemes[] = { | 440 static const char* const kValidUrlSchemes[] = { |
442 content::kFileScheme, | 441 content::kFileScheme, |
443 content::kFileSystemScheme, | 442 content::kFileSystemScheme, |
444 content::kFtpScheme, | 443 content::kFtpScheme, |
445 content::kHttpScheme, | 444 content::kHttpScheme, |
446 content::kHttpsScheme, | 445 content::kHttpsScheme, |
447 extensions::kExtensionScheme, | 446 extensions::kExtensionScheme, |
(...skipping 26 matching lines...) Expand all Loading... | |
474 | 473 |
475 #if defined(OS_LINUX) | 474 #if defined(OS_LINUX) |
476 std::string GetWMClassFromAppName(std::string app_name) { | 475 std::string GetWMClassFromAppName(std::string app_name) { |
477 file_util::ReplaceIllegalCharactersInPath(&app_name, '_'); | 476 file_util::ReplaceIllegalCharactersInPath(&app_name, '_'); |
478 base::TrimString(app_name, "_", &app_name); | 477 base::TrimString(app_name, "_", &app_name); |
479 return app_name; | 478 return app_name; |
480 } | 479 } |
481 #endif | 480 #endif |
482 | 481 |
483 } // namespace web_app | 482 } // namespace web_app |
OLD | NEW |