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 #include <stddef.h> | 8 #include <stddef.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 for (std::vector<base::FilePath>::const_iterator j = shortcut_files.begin(); | 329 for (std::vector<base::FilePath>::const_iterator j = shortcut_files.begin(); |
330 j != shortcut_files.end(); ++j) { | 330 j != shortcut_files.end(); ++j) { |
331 // Any shortcut could have been pinned, either by chrome or the user, so | 331 // Any shortcut could have been pinned, either by chrome or the user, so |
332 // they are all unpinned. | 332 // they are all unpinned. |
333 base::win::UnpinShortcutFromTaskbar(*j); | 333 base::win::UnpinShortcutFromTaskbar(*j); |
334 base::DeleteFile(*j, false); | 334 base::DeleteFile(*j, false); |
335 } | 335 } |
336 } | 336 } |
337 } | 337 } |
338 | 338 |
339 void CreateIconAndSetRelaunchDetails( | 339 void CreateIconAndSetRelaunchDetails(const base::FilePath& web_app_path, |
340 const base::FilePath& web_app_path, | 340 const base::FilePath& icon_file, |
341 const base::FilePath& icon_file, | 341 const web_app::ShortcutInfo& shortcut_info, |
342 std::unique_ptr<web_app::ShortcutInfo> shortcut_info, | 342 HWND hwnd) { |
343 HWND hwnd) { | |
344 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); | 343 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
345 | 344 |
346 base::CommandLine command_line = | 345 base::CommandLine command_line = |
347 shell_integration::CommandLineArgsForLauncher( | 346 shell_integration::CommandLineArgsForLauncher(shortcut_info.url, |
348 shortcut_info->url, shortcut_info->extension_id, | 347 shortcut_info.extension_id, |
349 shortcut_info->profile_path); | 348 shortcut_info.profile_path); |
350 | 349 |
351 base::FilePath chrome_exe; | 350 base::FilePath chrome_exe; |
352 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 351 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { |
353 NOTREACHED(); | 352 NOTREACHED(); |
354 return; | 353 return; |
355 } | 354 } |
356 command_line.SetProgram(chrome_exe); | 355 command_line.SetProgram(chrome_exe); |
357 ui::win::SetRelaunchDetailsForWindow(command_line.GetCommandLineString(), | 356 ui::win::SetRelaunchDetailsForWindow(command_line.GetCommandLineString(), |
358 shortcut_info->title, hwnd); | 357 shortcut_info.title, hwnd); |
359 | 358 |
360 if (!base::PathExists(web_app_path) && !base::CreateDirectory(web_app_path)) | 359 if (!base::PathExists(web_app_path) && !base::CreateDirectory(web_app_path)) |
361 return; | 360 return; |
362 | 361 |
363 ui::win::SetAppIconForWindow(icon_file, 0, hwnd); | 362 ui::win::SetAppIconForWindow(icon_file, 0, hwnd); |
364 web_app::internals::CheckAndSaveIcon(icon_file, shortcut_info->favicon, true); | 363 web_app::internals::CheckAndSaveIcon(icon_file, shortcut_info.favicon, true); |
365 } | 364 } |
366 | 365 |
367 void OnShortcutInfoLoadedForSetRelaunchDetails( | 366 void OnShortcutInfoLoadedForSetRelaunchDetails( |
368 HWND hwnd, | 367 HWND hwnd, |
369 std::unique_ptr<web_app::ShortcutInfo> shortcut_info) { | 368 std::unique_ptr<web_app::ShortcutInfo> shortcut_info) { |
370 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 369 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
371 | 370 |
372 // Set window's icon to the one we're about to create/update in the web app | 371 // Set window's icon to the one we're about to create/update in the web app |
373 // path. The icon cache will refresh on icon creation. | 372 // path. The icon cache will refresh on icon creation. |
374 base::FilePath web_app_path = web_app::GetWebAppDataDirectory( | 373 base::FilePath web_app_path = web_app::GetWebAppDataDirectory( |
375 shortcut_info->profile_path, shortcut_info->extension_id, | 374 shortcut_info->profile_path, shortcut_info->extension_id, |
376 shortcut_info->url); | 375 shortcut_info->url); |
377 base::FilePath icon_file = | 376 base::FilePath icon_file = |
378 web_app::internals::GetIconFilePath(web_app_path, shortcut_info->title); | 377 web_app::internals::GetIconFilePath(web_app_path, shortcut_info->title); |
379 content::BrowserThread::PostBlockingPoolTask( | 378 const web_app::ShortcutInfo& shortcut_info_ref = *shortcut_info; |
380 FROM_HERE, base::Bind(&CreateIconAndSetRelaunchDetails, web_app_path, | 379 content::BrowserThread::PostBlockingPoolTaskAndReply( |
381 icon_file, base::Passed(&shortcut_info), hwnd)); | 380 FROM_HERE, |
| 381 base::Bind(&CreateIconAndSetRelaunchDetails, web_app_path, icon_file, |
| 382 base::ConstRef(shortcut_info_ref), hwnd), |
| 383 base::Bind(&web_app::internals::DeleteShortcutInfoOnUIThread, |
| 384 base::Passed(&shortcut_info), base::Closure())); |
382 } | 385 } |
383 | 386 |
384 } // namespace | 387 } // namespace |
385 | 388 |
386 namespace web_app { | 389 namespace web_app { |
387 | 390 |
388 base::FilePath CreateShortcutInWebAppDir( | 391 base::FilePath CreateShortcutInWebAppDir( |
389 const base::FilePath& web_app_dir, | 392 const base::FilePath& web_app_dir, |
390 std::unique_ptr<ShortcutInfo> shortcut_info) { | 393 std::unique_ptr<ShortcutInfo> shortcut_info) { |
391 std::vector<base::FilePath> paths; | 394 std::vector<base::FilePath> paths; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 if (refresh_shell_icon_cache) { | 438 if (refresh_shell_icon_cache) { |
436 // Refresh shell's icon cache. This call is quite disruptive as user would | 439 // Refresh shell's icon cache. This call is quite disruptive as user would |
437 // see explorer rebuilding the icon cache. It would be great that we find | 440 // see explorer rebuilding the icon cache. It would be great that we find |
438 // a better way to achieve this. | 441 // a better way to achieve this. |
439 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT, NULL, | 442 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT, NULL, |
440 NULL); | 443 NULL); |
441 } | 444 } |
442 return true; | 445 return true; |
443 } | 446 } |
444 | 447 |
445 bool CreatePlatformShortcuts( | 448 bool CreatePlatformShortcuts(const base::FilePath& web_app_path, |
446 const base::FilePath& web_app_path, | 449 const ShortcutInfo& shortcut_info, |
447 std::unique_ptr<ShortcutInfo> shortcut_info, | 450 const ShortcutLocations& creation_locations, |
448 const ShortcutLocations& creation_locations, | 451 ShortcutCreationReason creation_reason) { |
449 ShortcutCreationReason creation_reason) { | |
450 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); | 452 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); |
451 | 453 |
452 // Nothing to do on Windows for hidden apps. | 454 // Nothing to do on Windows for hidden apps. |
453 if (creation_locations.applications_menu_location == APP_MENU_LOCATION_HIDDEN) | 455 if (creation_locations.applications_menu_location == APP_MENU_LOCATION_HIDDEN) |
454 return true; | 456 return true; |
455 | 457 |
456 // Shortcut paths under which to create shortcuts. | 458 // Shortcut paths under which to create shortcuts. |
457 std::vector<base::FilePath> shortcut_paths = | 459 std::vector<base::FilePath> shortcut_paths = |
458 GetShortcutPaths(creation_locations); | 460 GetShortcutPaths(creation_locations); |
459 | 461 |
460 bool pin_to_taskbar = creation_locations.in_quick_launch_bar && | 462 bool pin_to_taskbar = creation_locations.in_quick_launch_bar && |
461 base::win::CanPinShortcutToTaskbar(); | 463 base::win::CanPinShortcutToTaskbar(); |
462 | 464 |
463 // Create/update the shortcut in the web app path for the "Pin To Taskbar" | 465 // Create/update the shortcut in the web app path for the "Pin To Taskbar" |
464 // option in Win7. We use the web app path shortcut because we will overwrite | 466 // option in Win7. We use the web app path shortcut because we will overwrite |
465 // it rather than appending unique numbers if the shortcut already exists. | 467 // it rather than appending unique numbers if the shortcut already exists. |
466 // This prevents pinned apps from having unique numbers in their names. | 468 // This prevents pinned apps from having unique numbers in their names. |
467 if (pin_to_taskbar) | 469 if (pin_to_taskbar) |
468 shortcut_paths.push_back(web_app_path); | 470 shortcut_paths.push_back(web_app_path); |
469 | 471 |
470 if (shortcut_paths.empty()) | 472 if (shortcut_paths.empty()) |
471 return false; | 473 return false; |
472 | 474 |
473 if (!CreateShortcutsInPaths(web_app_path, *shortcut_info, shortcut_paths, | 475 if (!CreateShortcutsInPaths(web_app_path, shortcut_info, shortcut_paths, |
474 creation_reason, NULL)) | 476 creation_reason, NULL)) |
475 return false; | 477 return false; |
476 | 478 |
477 if (pin_to_taskbar) { | 479 if (pin_to_taskbar) { |
478 base::FilePath file_name = GetSanitizedFileName(shortcut_info->title); | 480 base::FilePath file_name = GetSanitizedFileName(shortcut_info.title); |
479 // Use the web app path shortcut for pinning to avoid having unique numbers | 481 // Use the web app path shortcut for pinning to avoid having unique numbers |
480 // in the application name. | 482 // in the application name. |
481 base::FilePath shortcut_to_pin = web_app_path.Append(file_name). | 483 base::FilePath shortcut_to_pin = web_app_path.Append(file_name). |
482 AddExtension(installer::kLnkExt); | 484 AddExtension(installer::kLnkExt); |
483 if (!base::win::PinShortcutToTaskbar(shortcut_to_pin)) | 485 if (!base::win::PinShortcutToTaskbar(shortcut_to_pin)) |
484 return false; | 486 return false; |
485 } | 487 } |
486 | 488 |
487 return true; | 489 return true; |
488 } | 490 } |
489 | 491 |
490 void UpdatePlatformShortcuts(const base::FilePath& web_app_path, | 492 void UpdatePlatformShortcuts(const base::FilePath& web_app_path, |
491 const base::string16& old_app_title, | 493 const base::string16& old_app_title, |
492 std::unique_ptr<ShortcutInfo> shortcut_info) { | 494 const ShortcutInfo& shortcut_info) { |
493 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); | 495 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); |
494 | 496 |
495 // Generates file name to use with persisted ico and shortcut file. | 497 // Generates file name to use with persisted ico and shortcut file. |
496 base::FilePath file_name = | 498 base::FilePath file_name = |
497 web_app::internals::GetSanitizedFileName(shortcut_info->title); | 499 web_app::internals::GetSanitizedFileName(shortcut_info.title); |
498 | 500 |
499 if (old_app_title != shortcut_info->title) { | 501 if (old_app_title != shortcut_info.title) { |
500 // The app's title has changed. Delete all existing app shortcuts and | 502 // The app's title has changed. Delete all existing app shortcuts and |
501 // recreate them in any locations they already existed (but do not add them | 503 // recreate them in any locations they already existed (but do not add them |
502 // to locations where they do not currently exist). | 504 // to locations where they do not currently exist). |
503 bool was_pinned_to_taskbar; | 505 bool was_pinned_to_taskbar; |
504 std::vector<base::FilePath> shortcut_paths; | 506 std::vector<base::FilePath> shortcut_paths; |
505 GetShortcutLocationsAndDeleteShortcuts( | 507 GetShortcutLocationsAndDeleteShortcuts( |
506 web_app_path, shortcut_info->profile_path, old_app_title, | 508 web_app_path, shortcut_info.profile_path, old_app_title, |
507 &was_pinned_to_taskbar, &shortcut_paths); | 509 &was_pinned_to_taskbar, &shortcut_paths); |
508 CreateShortcutsInPaths(web_app_path, *shortcut_info, shortcut_paths, | 510 CreateShortcutsInPaths(web_app_path, shortcut_info, shortcut_paths, |
509 SHORTCUT_CREATION_BY_USER, NULL); | 511 SHORTCUT_CREATION_BY_USER, NULL); |
510 // If the shortcut was pinned to the taskbar, | 512 // If the shortcut was pinned to the taskbar, |
511 // GetShortcutLocationsAndDeleteShortcuts will have deleted it. In that | 513 // GetShortcutLocationsAndDeleteShortcuts will have deleted it. In that |
512 // case, re-pin it. | 514 // case, re-pin it. |
513 if (was_pinned_to_taskbar && base::win::CanPinShortcutToTaskbar()) { | 515 if (was_pinned_to_taskbar && base::win::CanPinShortcutToTaskbar()) { |
514 base::FilePath file_name = GetSanitizedFileName(shortcut_info->title); | 516 base::FilePath file_name = GetSanitizedFileName(shortcut_info.title); |
515 // Use the web app path shortcut for pinning to avoid having unique | 517 // Use the web app path shortcut for pinning to avoid having unique |
516 // numbers in the application name. | 518 // numbers in the application name. |
517 base::FilePath shortcut_to_pin = web_app_path.Append(file_name). | 519 base::FilePath shortcut_to_pin = web_app_path.Append(file_name). |
518 AddExtension(installer::kLnkExt); | 520 AddExtension(installer::kLnkExt); |
519 base::win::PinShortcutToTaskbar(shortcut_to_pin); | 521 base::win::PinShortcutToTaskbar(shortcut_to_pin); |
520 } | 522 } |
521 } | 523 } |
522 | 524 |
523 // Update the icon if necessary. | 525 // Update the icon if necessary. |
524 base::FilePath icon_file = | 526 base::FilePath icon_file = GetIconFilePath(web_app_path, shortcut_info.title); |
525 GetIconFilePath(web_app_path, shortcut_info->title); | 527 CheckAndSaveIcon(icon_file, shortcut_info.favicon, true); |
526 CheckAndSaveIcon(icon_file, shortcut_info->favicon, true); | |
527 } | 528 } |
528 | 529 |
529 void DeletePlatformShortcuts(const base::FilePath& web_app_path, | 530 void DeletePlatformShortcuts(const base::FilePath& web_app_path, |
530 std::unique_ptr<ShortcutInfo> shortcut_info) { | 531 const ShortcutInfo& shortcut_info) { |
531 GetShortcutLocationsAndDeleteShortcuts(web_app_path, | 532 GetShortcutLocationsAndDeleteShortcuts(web_app_path, |
532 shortcut_info->profile_path, | 533 shortcut_info.profile_path, |
533 shortcut_info->title, NULL, NULL); | 534 shortcut_info.title, NULL, NULL); |
534 | 535 |
535 // If there are no more shortcuts in the Chrome Apps subdirectory, remove it. | 536 // If there are no more shortcuts in the Chrome Apps subdirectory, remove it. |
536 base::FilePath chrome_apps_dir; | 537 base::FilePath chrome_apps_dir; |
537 if (ShellUtil::GetShortcutPath( | 538 if (ShellUtil::GetShortcutPath( |
538 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR, | 539 ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR, |
539 BrowserDistribution::GetDistribution(), | 540 BrowserDistribution::GetDistribution(), |
540 ShellUtil::CURRENT_USER, | 541 ShellUtil::CURRENT_USER, |
541 &chrome_apps_dir)) { | 542 &chrome_apps_dir)) { |
542 if (base::IsDirectoryEmpty(chrome_apps_dir)) | 543 if (base::IsDirectoryEmpty(chrome_apps_dir)) |
543 base::DeleteFile(chrome_apps_dir, false); | 544 base::DeleteFile(chrome_apps_dir, false); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 | 619 |
619 } // namespace internals | 620 } // namespace internals |
620 | 621 |
621 void UpdateShortcutForTabContents(content::WebContents* web_contents) { | 622 void UpdateShortcutForTabContents(content::WebContents* web_contents) { |
622 // UpdateShortcutWorker will delete itself when it's done. | 623 // UpdateShortcutWorker will delete itself when it's done. |
623 UpdateShortcutWorker* worker = new UpdateShortcutWorker(web_contents); | 624 UpdateShortcutWorker* worker = new UpdateShortcutWorker(web_contents); |
624 worker->Run(); | 625 worker->Run(); |
625 } | 626 } |
626 | 627 |
627 } // namespace web_app | 628 } // namespace web_app |
OLD | NEW |