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_win.h" | 5 #include "chrome/browser/web_applications/web_app_win.h" |
6 | 6 |
7 #include <shlobj.h> | 7 #include <shlobj.h> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
26 #include "ui/gfx/icon_util.h" | 26 #include "ui/gfx/icon_util.h" |
27 #include "ui/gfx/image/image.h" | 27 #include "ui/gfx/image/image.h" |
28 #include "ui/gfx/image/image_family.h" | 28 #include "ui/gfx/image/image_family.h" |
29 | 29 |
30 namespace { | 30 namespace { |
31 | 31 |
32 const base::FilePath::CharType kIconChecksumFileExt[] = | 32 const base::FilePath::CharType kIconChecksumFileExt[] = |
33 FILE_PATH_LITERAL(".ico.md5"); | 33 FILE_PATH_LITERAL(".ico.md5"); |
34 | 34 |
35 // Width and height of icons exported to .ico files. | |
36 | |
37 // Calculates checksum of an icon family using MD5. | 35 // Calculates checksum of an icon family using MD5. |
38 // The checksum is derived from all of the icons in the family. | 36 // The checksum is derived from all of the icons in the family. |
39 void GetImageCheckSum(const gfx::ImageFamily& image, base::MD5Digest* digest) { | 37 void GetImageCheckSum(const gfx::ImageFamily& image, base::MD5Digest* digest) { |
40 DCHECK(digest); | 38 DCHECK(digest); |
41 base::MD5Context md5_context; | 39 base::MD5Context md5_context; |
42 base::MD5Init(&md5_context); | 40 base::MD5Init(&md5_context); |
43 | 41 |
44 for (gfx::ImageFamily::const_iterator it = image.begin(); it != image.end(); | 42 for (gfx::ImageFamily::const_iterator it = image.begin(); it != image.end(); |
45 ++it) { | 43 ++it) { |
46 SkBitmap bitmap = it->AsBitmap(); | 44 SkBitmap bitmap = it->AsBitmap(); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 const std::vector<base::FilePath>& shortcut_paths, | 164 const std::vector<base::FilePath>& shortcut_paths, |
167 web_app::ShortcutCreationReason creation_reason, | 165 web_app::ShortcutCreationReason creation_reason, |
168 std::vector<base::FilePath>* out_filenames) { | 166 std::vector<base::FilePath>* out_filenames) { |
169 // Ensure web_app_path exists. | 167 // Ensure web_app_path exists. |
170 if (!base::PathExists(web_app_path) && | 168 if (!base::PathExists(web_app_path) && |
171 !base::CreateDirectory(web_app_path)) { | 169 !base::CreateDirectory(web_app_path)) { |
172 return false; | 170 return false; |
173 } | 171 } |
174 | 172 |
175 // Generates file name to use with persisted ico and shortcut file. | 173 // Generates file name to use with persisted ico and shortcut file. |
176 base::FilePath file_name = | 174 base::FilePath icon_file = |
177 web_app::internals::GetSanitizedFileName(shortcut_info.title); | 175 web_app::internals::GetIconFilePath(web_app_path, shortcut_info.title); |
178 | |
179 // Creates an ico file to use with shortcut. | |
180 base::FilePath icon_file = web_app_path.Append(file_name).AddExtension( | |
181 FILE_PATH_LITERAL(".ico")); | |
182 if (!web_app::internals::CheckAndSaveIcon(icon_file, shortcut_info.favicon)) { | 176 if (!web_app::internals::CheckAndSaveIcon(icon_file, shortcut_info.favicon)) { |
183 return false; | 177 return false; |
184 } | 178 } |
185 | 179 |
186 base::FilePath chrome_exe; | 180 base::FilePath chrome_exe; |
187 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 181 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { |
188 NOTREACHED(); | 182 NOTREACHED(); |
189 return false; | 183 return false; |
190 } | 184 } |
191 | 185 |
(...skipping 15 matching lines...) Expand all Loading... |
207 if (description.length() >= MAX_PATH) | 201 if (description.length() >= MAX_PATH) |
208 description.resize(MAX_PATH - 1); | 202 description.resize(MAX_PATH - 1); |
209 | 203 |
210 // Generates app id from web app url and profile path. | 204 // Generates app id from web app url and profile path. |
211 std::string app_name(web_app::GenerateApplicationNameFromInfo(shortcut_info)); | 205 std::string app_name(web_app::GenerateApplicationNameFromInfo(shortcut_info)); |
212 base::string16 app_id(ShellIntegration::GetAppModelIdForProfile( | 206 base::string16 app_id(ShellIntegration::GetAppModelIdForProfile( |
213 base::UTF8ToUTF16(app_name), shortcut_info.profile_path)); | 207 base::UTF8ToUTF16(app_name), shortcut_info.profile_path)); |
214 | 208 |
215 bool success = true; | 209 bool success = true; |
216 for (size_t i = 0; i < shortcut_paths.size(); ++i) { | 210 for (size_t i = 0; i < shortcut_paths.size(); ++i) { |
217 base::FilePath shortcut_file = shortcut_paths[i].Append(file_name). | 211 base::FilePath shortcut_file = |
218 AddExtension(installer::kLnkExt); | 212 shortcut_paths[i] |
| 213 .Append( |
| 214 web_app::internals::GetSanitizedFileName(shortcut_info.title)) |
| 215 .AddExtension(installer::kLnkExt); |
219 if (creation_reason == web_app::SHORTCUT_CREATION_AUTOMATED) { | 216 if (creation_reason == web_app::SHORTCUT_CREATION_AUTOMATED) { |
220 // Check whether there is an existing shortcut to this app. | 217 // Check whether there is an existing shortcut to this app. |
221 std::vector<base::FilePath> shortcut_files = | 218 std::vector<base::FilePath> shortcut_files = |
222 FindAppShortcutsByProfileAndTitle(shortcut_paths[i], | 219 FindAppShortcutsByProfileAndTitle(shortcut_paths[i], |
223 shortcut_info.profile_path, | 220 shortcut_info.profile_path, |
224 shortcut_info.title); | 221 shortcut_info.title); |
225 if (!shortcut_files.empty()) | 222 if (!shortcut_files.empty()) |
226 continue; | 223 continue; |
227 } | 224 } |
228 if (shortcut_paths[i] != web_app_path) { | 225 if (shortcut_paths[i] != web_app_path) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 } // namespace | 326 } // namespace |
330 | 327 |
331 namespace web_app { | 328 namespace web_app { |
332 | 329 |
333 base::FilePath CreateShortcutInWebAppDir( | 330 base::FilePath CreateShortcutInWebAppDir( |
334 const base::FilePath& web_app_dir, | 331 const base::FilePath& web_app_dir, |
335 const ShellIntegration::ShortcutInfo& shortcut_info) { | 332 const ShellIntegration::ShortcutInfo& shortcut_info) { |
336 std::vector<base::FilePath> paths; | 333 std::vector<base::FilePath> paths; |
337 paths.push_back(web_app_dir); | 334 paths.push_back(web_app_dir); |
338 std::vector<base::FilePath> out_filenames; | 335 std::vector<base::FilePath> out_filenames; |
339 CreateShortcutsInPaths(web_app_dir, shortcut_info, paths, | 336 base::FilePath web_app_dir_shortcut = |
340 SHORTCUT_CREATION_BY_USER, &out_filenames); | 337 web_app_dir.Append(internals::GetSanitizedFileName(shortcut_info.title)) |
341 DCHECK_EQ(out_filenames.size(), 1u); | 338 .AddExtension(installer::kLnkExt); |
342 return out_filenames[0]; | 339 if (!PathExists(web_app_dir_shortcut)) { |
| 340 CreateShortcutsInPaths(web_app_dir, |
| 341 shortcut_info, |
| 342 paths, |
| 343 SHORTCUT_CREATION_BY_USER, |
| 344 &out_filenames); |
| 345 DCHECK_EQ(out_filenames.size(), 1u); |
| 346 DCHECK_EQ(out_filenames[0].value(), web_app_dir_shortcut.value()); |
| 347 } else { |
| 348 internals::CheckAndSaveIcon( |
| 349 internals::GetIconFilePath(web_app_dir, shortcut_info.title), |
| 350 shortcut_info.favicon); |
| 351 } |
| 352 return web_app_dir_shortcut; |
343 } | 353 } |
344 | 354 |
345 namespace internals { | 355 namespace internals { |
346 | 356 |
347 // Saves |image| to |icon_file| if the file is outdated and refresh shell's | 357 // Saves |image| to |icon_file| if the file is outdated and refresh shell's |
348 // icon cache to ensure correct icon is displayed. Returns true if icon_file | 358 // icon cache to ensure correct icon is displayed. Returns true if icon_file |
349 // is up to date or successfully updated. | 359 // is up to date or successfully updated. |
350 bool CheckAndSaveIcon(const base::FilePath& icon_file, | 360 bool CheckAndSaveIcon(const base::FilePath& icon_file, |
351 const gfx::ImageFamily& image) { | 361 const gfx::ImageFamily& image) { |
352 if (ShouldUpdateIcon(icon_file, image)) { | 362 if (ShouldUpdateIcon(icon_file, image)) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 shortcut_paths.push_back(web_app_path); | 396 shortcut_paths.push_back(web_app_path); |
387 | 397 |
388 if (shortcut_paths.empty()) | 398 if (shortcut_paths.empty()) |
389 return false; | 399 return false; |
390 | 400 |
391 if (!CreateShortcutsInPaths(web_app_path, shortcut_info, shortcut_paths, | 401 if (!CreateShortcutsInPaths(web_app_path, shortcut_info, shortcut_paths, |
392 creation_reason, NULL)) | 402 creation_reason, NULL)) |
393 return false; | 403 return false; |
394 | 404 |
395 if (pin_to_taskbar) { | 405 if (pin_to_taskbar) { |
396 base::FilePath file_name = | 406 base::FilePath file_name = GetSanitizedFileName(shortcut_info.title); |
397 web_app::internals::GetSanitizedFileName(shortcut_info.title); | |
398 // Use the web app path shortcut for pinning to avoid having unique numbers | 407 // Use the web app path shortcut for pinning to avoid having unique numbers |
399 // in the application name. | 408 // in the application name. |
400 base::FilePath shortcut_to_pin = web_app_path.Append(file_name). | 409 base::FilePath shortcut_to_pin = web_app_path.Append(file_name). |
401 AddExtension(installer::kLnkExt); | 410 AddExtension(installer::kLnkExt); |
402 if (!base::win::TaskbarPinShortcutLink(shortcut_to_pin.value().c_str())) | 411 if (!base::win::TaskbarPinShortcutLink(shortcut_to_pin.value().c_str())) |
403 return false; | 412 return false; |
404 } | 413 } |
405 | 414 |
406 return true; | 415 return true; |
407 } | 416 } |
(...skipping 16 matching lines...) Expand all Loading... |
424 std::vector<base::FilePath> shortcut_paths; | 433 std::vector<base::FilePath> shortcut_paths; |
425 GetShortcutLocationsAndDeleteShortcuts( | 434 GetShortcutLocationsAndDeleteShortcuts( |
426 web_app_path, shortcut_info.profile_path, old_app_title, | 435 web_app_path, shortcut_info.profile_path, old_app_title, |
427 &was_pinned_to_taskbar, &shortcut_paths); | 436 &was_pinned_to_taskbar, &shortcut_paths); |
428 CreateShortcutsInPaths(web_app_path, shortcut_info, shortcut_paths, | 437 CreateShortcutsInPaths(web_app_path, shortcut_info, shortcut_paths, |
429 SHORTCUT_CREATION_BY_USER, NULL); | 438 SHORTCUT_CREATION_BY_USER, NULL); |
430 // If the shortcut was pinned to the taskbar, | 439 // If the shortcut was pinned to the taskbar, |
431 // GetShortcutLocationsAndDeleteShortcuts will have deleted it. In that | 440 // GetShortcutLocationsAndDeleteShortcuts will have deleted it. In that |
432 // case, re-pin it. | 441 // case, re-pin it. |
433 if (was_pinned_to_taskbar) { | 442 if (was_pinned_to_taskbar) { |
434 base::FilePath file_name = | 443 base::FilePath file_name = GetSanitizedFileName(shortcut_info.title); |
435 web_app::internals::GetSanitizedFileName(shortcut_info.title); | |
436 // Use the web app path shortcut for pinning to avoid having unique | 444 // Use the web app path shortcut for pinning to avoid having unique |
437 // numbers in the application name. | 445 // numbers in the application name. |
438 base::FilePath shortcut_to_pin = web_app_path.Append(file_name). | 446 base::FilePath shortcut_to_pin = web_app_path.Append(file_name). |
439 AddExtension(installer::kLnkExt); | 447 AddExtension(installer::kLnkExt); |
440 base::win::TaskbarPinShortcutLink(shortcut_to_pin.value().c_str()); | 448 base::win::TaskbarPinShortcutLink(shortcut_to_pin.value().c_str()); |
441 } | 449 } |
442 } | 450 } |
443 | 451 |
444 // Update the icon if necessary. | 452 // Update the icon if necessary. |
445 base::FilePath icon_file = web_app_path.Append(file_name).AddExtension( | 453 base::FilePath icon_file = GetIconFilePath(web_app_path, shortcut_info.title); |
446 FILE_PATH_LITERAL(".ico")); | 454 CheckAndSaveIcon(icon_file, shortcut_info.favicon); |
447 web_app::internals::CheckAndSaveIcon(icon_file, shortcut_info.favicon); | |
448 } | 455 } |
449 | 456 |
450 void DeletePlatformShortcuts( | 457 void DeletePlatformShortcuts( |
451 const base::FilePath& web_app_path, | 458 const base::FilePath& web_app_path, |
452 const ShellIntegration::ShortcutInfo& shortcut_info) { | 459 const ShellIntegration::ShortcutInfo& shortcut_info) { |
453 GetShortcutLocationsAndDeleteShortcuts( | 460 GetShortcutLocationsAndDeleteShortcuts( |
454 web_app_path, shortcut_info.profile_path, shortcut_info.title, NULL, | 461 web_app_path, shortcut_info.profile_path, shortcut_info.title, NULL, |
455 NULL); | 462 NULL); |
456 | 463 |
457 // If there are no more shortcuts in the Chrome Apps subdirectory, remove it. | 464 // If there are no more shortcuts in the Chrome Apps subdirectory, remove it. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 &path)) { | 533 &path)) { |
527 NOTREACHED(); | 534 NOTREACHED(); |
528 continue; | 535 continue; |
529 } | 536 } |
530 shortcut_paths.push_back(path); | 537 shortcut_paths.push_back(path); |
531 } | 538 } |
532 } | 539 } |
533 return shortcut_paths; | 540 return shortcut_paths; |
534 } | 541 } |
535 | 542 |
| 543 base::FilePath GetIconFilePath(const base::FilePath& web_app_path, |
| 544 const base::string16& title) { |
| 545 return web_app_path.Append(GetSanitizedFileName(title)) |
| 546 .AddExtension(FILE_PATH_LITERAL(".ico")); |
| 547 } |
| 548 |
536 } // namespace internals | 549 } // namespace internals |
537 | 550 |
538 } // namespace web_app | 551 } // namespace web_app |
OLD | NEW |