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/shell_integration_linux.h" | 5 #include "chrome/browser/shell_integration_linux.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 | 8 |
9 #if defined(USE_GLIB) | 9 #if defined(USE_GLIB) |
10 #include <glib.h> | 10 #include <glib.h> |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "base/command_line.h" | 22 #include "base/command_line.h" |
23 #include "base/environment.h" | 23 #include "base/environment.h" |
24 #include "base/files/file_enumerator.h" | 24 #include "base/files/file_enumerator.h" |
25 #include "base/files/file_path.h" | 25 #include "base/files/file_path.h" |
26 #include "base/files/file_util.h" | 26 #include "base/files/file_util.h" |
27 #include "base/files/scoped_temp_dir.h" | 27 #include "base/files/scoped_temp_dir.h" |
28 #include "base/i18n/file_util_icu.h" | 28 #include "base/i18n/file_util_icu.h" |
29 #include "base/memory/ref_counted_memory.h" | 29 #include "base/memory/ref_counted_memory.h" |
30 #include "base/memory/scoped_ptr.h" | 30 #include "base/memory/scoped_ptr.h" |
31 #include "base/message_loop/message_loop.h" | 31 #include "base/message_loop/message_loop.h" |
| 32 #include "base/nix/xdg_util.h" |
32 #include "base/path_service.h" | 33 #include "base/path_service.h" |
33 #include "base/posix/eintr_wrapper.h" | 34 #include "base/posix/eintr_wrapper.h" |
34 #include "base/process/kill.h" | 35 #include "base/process/kill.h" |
35 #include "base/process/launch.h" | 36 #include "base/process/launch.h" |
36 #include "base/strings/string_number_conversions.h" | 37 #include "base/strings/string_number_conversions.h" |
37 #include "base/strings/string_tokenizer.h" | 38 #include "base/strings/string_tokenizer.h" |
38 #include "base/strings/string_util.h" | 39 #include "base/strings/string_util.h" |
39 #include "base/strings/utf_string_conversions.h" | 40 #include "base/strings/utf_string_conversions.h" |
40 #include "base/threading/thread.h" | 41 #include "base/threading/thread.h" |
41 #include "base/threading/thread_restrictions.h" | 42 #include "base/threading/thread_restrictions.h" |
(...skipping 29 matching lines...) Expand all Loading... |
71 *exit_code = EXIT_FAILURE; | 72 *exit_code = EXIT_FAILURE; |
72 int devnull = open("/dev/null", O_RDONLY); | 73 int devnull = open("/dev/null", O_RDONLY); |
73 if (devnull < 0) | 74 if (devnull < 0) |
74 return false; | 75 return false; |
75 base::FileHandleMappingVector no_stdin; | 76 base::FileHandleMappingVector no_stdin; |
76 no_stdin.push_back(std::make_pair(devnull, STDIN_FILENO)); | 77 no_stdin.push_back(std::make_pair(devnull, STDIN_FILENO)); |
77 | 78 |
78 base::LaunchOptions options; | 79 base::LaunchOptions options; |
79 options.fds_to_remap = &no_stdin; | 80 options.fds_to_remap = &no_stdin; |
80 base::Process process = base::LaunchProcess(argv, options); | 81 base::Process process = base::LaunchProcess(argv, options); |
81 if (!process.IsValid()) { | 82 close(devnull); |
82 close(devnull); | 83 if (!process.IsValid()) |
83 return false; | 84 return false; |
84 } | |
85 close(devnull); | |
86 | |
87 return process.WaitForExit(exit_code); | 85 return process.WaitForExit(exit_code); |
88 } | 86 } |
89 | 87 |
90 std::string CreateShortcutIcon(const gfx::ImageFamily& icon_images, | 88 std::string CreateShortcutIcon(const gfx::ImageFamily& icon_images, |
91 const base::FilePath& shortcut_filename) { | 89 const base::FilePath& shortcut_filename) { |
92 if (icon_images.empty()) | 90 if (icon_images.empty()) |
93 return std::string(); | 91 return std::string(); |
94 | 92 |
95 // TODO(phajdan.jr): Report errors from this function, possibly as infobars. | 93 // TODO(phajdan.jr): Report errors from this function, possibly as infobars. |
96 base::ScopedTempDir temp_dir; | 94 base::ScopedTempDir temp_dir; |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 | 471 |
474 g_key_file_free(key_file); | 472 g_key_file_free(key_file); |
475 return nodisplay; | 473 return nodisplay; |
476 #else | 474 #else |
477 NOTIMPLEMENTED(); | 475 NOTIMPLEMENTED(); |
478 return false; | 476 return false; |
479 #endif | 477 #endif |
480 } | 478 } |
481 | 479 |
482 // Gets the path to the Chrome executable or wrapper script. | 480 // Gets the path to the Chrome executable or wrapper script. |
483 // Returns an empty path if the executable path could not be found. | 481 // Returns an empty path if the executable path could not be found, which should |
| 482 // never happen. |
484 base::FilePath GetChromeExePath() { | 483 base::FilePath GetChromeExePath() { |
485 // Try to get the name of the wrapper script that launched Chrome. | 484 // Try to get the name of the wrapper script that launched Chrome. |
486 scoped_ptr<base::Environment> environment(base::Environment::Create()); | 485 scoped_ptr<base::Environment> environment(base::Environment::Create()); |
487 std::string wrapper_script; | 486 std::string wrapper_script; |
488 if (environment->GetVar("CHROME_WRAPPER", &wrapper_script)) { | 487 if (environment->GetVar("CHROME_WRAPPER", &wrapper_script)) |
489 return base::FilePath(wrapper_script); | 488 return base::FilePath(wrapper_script); |
490 } | |
491 | 489 |
492 // Just return the name of the executable path for Chrome. | 490 // Just return the name of the executable path for Chrome. |
493 base::FilePath chrome_exe_path; | 491 base::FilePath chrome_exe_path; |
494 PathService::Get(base::FILE_EXE, &chrome_exe_path); | 492 PathService::Get(base::FILE_EXE, &chrome_exe_path); |
495 return chrome_exe_path; | 493 return chrome_exe_path; |
496 } | 494 } |
497 | 495 |
498 } // namespace | 496 } // namespace |
499 | 497 |
500 // static | 498 // static |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 argv.push_back(kXdgSettingsDefaultBrowser); | 538 argv.push_back(kXdgSettingsDefaultBrowser); |
541 | 539 |
542 std::string browser; | 540 std::string browser; |
543 // We don't care about the return value here. | 541 // We don't care about the return value here. |
544 base::GetAppOutput(base::CommandLine(argv), &browser); | 542 base::GetAppOutput(base::CommandLine(argv), &browser); |
545 return browser.find("irefox") != std::string::npos; | 543 return browser.find("irefox") != std::string::npos; |
546 } | 544 } |
547 | 545 |
548 namespace shell_integration_linux { | 546 namespace shell_integration_linux { |
549 | 547 |
550 bool GetDataWriteLocation(base::Environment* env, base::FilePath* search_path) { | 548 base::FilePath GetDataWriteLocation(base::Environment* env) { |
551 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 549 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
552 | 550 |
553 std::string xdg_data_home; | 551 return base::nix::GetXDGDirectory(env, "XDG_DATA_HOME", ".local/share"); |
554 std::string home; | |
555 if (env->GetVar("XDG_DATA_HOME", &xdg_data_home) && !xdg_data_home.empty()) { | |
556 *search_path = base::FilePath(xdg_data_home); | |
557 return true; | |
558 } else if (env->GetVar("HOME", &home) && !home.empty()) { | |
559 *search_path = base::FilePath(home).Append(".local").Append("share"); | |
560 return true; | |
561 } | |
562 return false; | |
563 } | 552 } |
564 | 553 |
565 std::vector<base::FilePath> GetDataSearchLocations(base::Environment* env) { | 554 std::vector<base::FilePath> GetDataSearchLocations(base::Environment* env) { |
566 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 555 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
567 | 556 |
568 std::vector<base::FilePath> search_paths; | 557 std::vector<base::FilePath> search_paths; |
569 | 558 base::FilePath write_location = GetDataWriteLocation(env); |
570 base::FilePath write_location; | 559 search_paths.push_back(write_location); |
571 if (GetDataWriteLocation(env, &write_location)) | |
572 search_paths.push_back(write_location); | |
573 | 560 |
574 std::string xdg_data_dirs; | 561 std::string xdg_data_dirs; |
575 if (env->GetVar("XDG_DATA_DIRS", &xdg_data_dirs) && !xdg_data_dirs.empty()) { | 562 if (env->GetVar("XDG_DATA_DIRS", &xdg_data_dirs) && !xdg_data_dirs.empty()) { |
576 base::StringTokenizer tokenizer(xdg_data_dirs, ":"); | 563 base::StringTokenizer tokenizer(xdg_data_dirs, ":"); |
577 while (tokenizer.GetNext()) { | 564 while (tokenizer.GetNext()) { |
578 base::FilePath data_dir(tokenizer.token()); | 565 base::FilePath data_dir(tokenizer.token()); |
579 search_paths.push_back(data_dir); | 566 search_paths.push_back(data_dir); |
580 } | 567 } |
581 } else { | 568 } else { |
582 search_paths.push_back(base::FilePath("/usr/local/share")); | 569 search_paths.push_back(base::FilePath("/usr/local/share")); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 PathService::Get(base::DIR_USER_DESKTOP, &desktop_path); | 624 PathService::Get(base::DIR_USER_DESKTOP, &desktop_path); |
638 return GetExistingShortcutLocations(env, profile_path, extension_id, | 625 return GetExistingShortcutLocations(env, profile_path, extension_id, |
639 desktop_path); | 626 desktop_path); |
640 } | 627 } |
641 | 628 |
642 web_app::ShortcutLocations GetExistingShortcutLocations( | 629 web_app::ShortcutLocations GetExistingShortcutLocations( |
643 base::Environment* env, | 630 base::Environment* env, |
644 const base::FilePath& profile_path, | 631 const base::FilePath& profile_path, |
645 const std::string& extension_id, | 632 const std::string& extension_id, |
646 const base::FilePath& desktop_path) { | 633 const base::FilePath& desktop_path) { |
647 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 634 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
648 | 635 |
649 base::FilePath shortcut_filename = GetExtensionShortcutFilename( | 636 base::FilePath shortcut_filename = GetExtensionShortcutFilename( |
650 profile_path, extension_id); | 637 profile_path, extension_id); |
651 DCHECK(!shortcut_filename.empty()); | 638 DCHECK(!shortcut_filename.empty()); |
652 web_app::ShortcutLocations locations; | 639 web_app::ShortcutLocations locations; |
653 | 640 |
654 // Determine whether there is a shortcut on desktop. | 641 // Determine whether there is a shortcut on desktop. |
655 if (!desktop_path.empty()) { | 642 if (!desktop_path.empty()) { |
656 locations.on_desktop = | 643 locations.on_desktop = |
657 base::PathExists(desktop_path.Append(shortcut_filename)); | 644 base::PathExists(desktop_path.Append(shortcut_filename)); |
(...skipping 10 matching lines...) Expand all Loading... |
668 ? web_app::APP_MENU_LOCATION_HIDDEN | 655 ? web_app::APP_MENU_LOCATION_HIDDEN |
669 : web_app::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS; | 656 : web_app::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS; |
670 } | 657 } |
671 | 658 |
672 return locations; | 659 return locations; |
673 } | 660 } |
674 | 661 |
675 bool GetExistingShortcutContents(base::Environment* env, | 662 bool GetExistingShortcutContents(base::Environment* env, |
676 const base::FilePath& desktop_filename, | 663 const base::FilePath& desktop_filename, |
677 std::string* output) { | 664 std::string* output) { |
678 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 665 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
679 | 666 |
680 std::vector<base::FilePath> search_paths = GetDataSearchLocations(env); | 667 std::vector<base::FilePath> search_paths = GetDataSearchLocations(env); |
681 | 668 |
682 for (std::vector<base::FilePath>::const_iterator i = search_paths.begin(); | 669 for (std::vector<base::FilePath>::const_iterator i = search_paths.begin(); |
683 i != search_paths.end(); ++i) { | 670 i != search_paths.end(); ++i) { |
684 base::FilePath path = i->Append("applications").Append(desktop_filename); | 671 base::FilePath path = i->Append("applications").Append(desktop_filename); |
685 VLOG(1) << "Looking for desktop file in " << path.value(); | 672 VLOG(1) << "Looking for desktop file in " << path.value(); |
686 if (base::PathExists(path)) { | 673 if (base::PathExists(path)) { |
687 VLOG(1) << "Found desktop file at " << path.value(); | 674 VLOG(1) << "Found desktop file at " << path.value(); |
688 return base::ReadFileToString(path, output); | 675 return base::ReadFileToString(path, output); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
729 base::i18n::ReplaceIllegalCharactersInPath(&filename, '_'); | 716 base::i18n::ReplaceIllegalCharactersInPath(&filename, '_'); |
730 // Spaces in filenames break xdg-desktop-menu | 717 // Spaces in filenames break xdg-desktop-menu |
731 // (see https://bugs.freedesktop.org/show_bug.cgi?id=66605). | 718 // (see https://bugs.freedesktop.org/show_bug.cgi?id=66605). |
732 base::ReplaceChars(filename, " ", "_", &filename); | 719 base::ReplaceChars(filename, " ", "_", &filename); |
733 return base::FilePath(filename.append(".desktop")); | 720 return base::FilePath(filename.append(".desktop")); |
734 } | 721 } |
735 | 722 |
736 std::vector<base::FilePath> GetExistingProfileShortcutFilenames( | 723 std::vector<base::FilePath> GetExistingProfileShortcutFilenames( |
737 const base::FilePath& profile_path, | 724 const base::FilePath& profile_path, |
738 const base::FilePath& directory) { | 725 const base::FilePath& directory) { |
739 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 726 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 727 |
740 // Use a prefix, because xdg-desktop-menu requires it. | 728 // Use a prefix, because xdg-desktop-menu requires it. |
741 std::string prefix(chrome::kBrowserProcessExecutableName); | 729 std::string prefix(chrome::kBrowserProcessExecutableName); |
742 prefix.append("-"); | 730 prefix.append("-"); |
743 std::string suffix("-"); | 731 std::string suffix("-"); |
744 suffix.append(profile_path.BaseName().value()); | 732 suffix.append(profile_path.BaseName().value()); |
745 base::i18n::ReplaceIllegalCharactersInPath(&suffix, '_'); | 733 base::i18n::ReplaceIllegalCharactersInPath(&suffix, '_'); |
746 // Spaces in filenames break xdg-desktop-menu | 734 // Spaces in filenames break xdg-desktop-menu |
747 // (see https://bugs.freedesktop.org/show_bug.cgi?id=66605). | 735 // (see https://bugs.freedesktop.org/show_bug.cgi?id=66605). |
748 base::ReplaceChars(suffix, " ", "_", &suffix); | 736 base::ReplaceChars(suffix, " ", "_", &suffix); |
749 std::string glob = prefix + "*" + suffix + ".desktop"; | 737 std::string glob = prefix + "*" + suffix + ".desktop"; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
894 return output_buffer; | 882 return output_buffer; |
895 #else | 883 #else |
896 NOTIMPLEMENTED(); | 884 NOTIMPLEMENTED(); |
897 return std::string(); | 885 return std::string(); |
898 #endif | 886 #endif |
899 } | 887 } |
900 | 888 |
901 bool CreateDesktopShortcut( | 889 bool CreateDesktopShortcut( |
902 const web_app::ShortcutInfo& shortcut_info, | 890 const web_app::ShortcutInfo& shortcut_info, |
903 const web_app::ShortcutLocations& creation_locations) { | 891 const web_app::ShortcutLocations& creation_locations) { |
904 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 892 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
905 | 893 |
906 base::FilePath shortcut_filename; | 894 base::FilePath shortcut_filename; |
907 if (!shortcut_info.extension_id.empty()) { | 895 if (!shortcut_info.extension_id.empty()) { |
908 shortcut_filename = GetExtensionShortcutFilename( | 896 shortcut_filename = GetExtensionShortcutFilename( |
909 shortcut_info.profile_path, shortcut_info.extension_id); | 897 shortcut_info.profile_path, shortcut_info.extension_id); |
910 // For extensions we do not want duplicate shortcuts. So, delete any that | 898 // For extensions we do not want duplicate shortcuts. So, delete any that |
911 // already exist and replace them. | 899 // already exist and replace them. |
912 if (creation_locations.on_desktop) | 900 if (creation_locations.on_desktop) |
913 DeleteShortcutOnDesktop(shortcut_filename); | 901 DeleteShortcutOnDesktop(shortcut_filename); |
914 | 902 |
(...skipping 10 matching lines...) Expand all Loading... |
925 std::string icon_name = | 913 std::string icon_name = |
926 CreateShortcutIcon(shortcut_info.favicon, shortcut_filename); | 914 CreateShortcutIcon(shortcut_info.favicon, shortcut_filename); |
927 | 915 |
928 std::string app_name = | 916 std::string app_name = |
929 web_app::GenerateApplicationNameFromInfo(shortcut_info); | 917 web_app::GenerateApplicationNameFromInfo(shortcut_info); |
930 | 918 |
931 bool success = true; | 919 bool success = true; |
932 | 920 |
933 base::FilePath chrome_exe_path = GetChromeExePath(); | 921 base::FilePath chrome_exe_path = GetChromeExePath(); |
934 if (chrome_exe_path.empty()) { | 922 if (chrome_exe_path.empty()) { |
935 LOG(WARNING) << "Could not get executable path."; | 923 NOTREACHED(); |
936 return false; | 924 return false; |
937 } | 925 } |
938 | 926 |
939 if (creation_locations.on_desktop) { | 927 if (creation_locations.on_desktop) { |
940 std::string contents = GetDesktopFileContents( | 928 std::string contents = GetDesktopFileContents( |
941 chrome_exe_path, | 929 chrome_exe_path, |
942 app_name, | 930 app_name, |
943 shortcut_info.url, | 931 shortcut_info.url, |
944 shortcut_info.extension_id, | 932 shortcut_info.extension_id, |
945 shortcut_info.title, | 933 shortcut_info.title, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
987 success = CreateShortcutInApplicationsMenu( | 975 success = CreateShortcutInApplicationsMenu( |
988 shortcut_filename, contents, directory_filename, directory_contents) && | 976 shortcut_filename, contents, directory_filename, directory_contents) && |
989 success; | 977 success; |
990 | 978 |
991 return success; | 979 return success; |
992 } | 980 } |
993 | 981 |
994 bool CreateAppListDesktopShortcut( | 982 bool CreateAppListDesktopShortcut( |
995 const std::string& wm_class, | 983 const std::string& wm_class, |
996 const std::string& title) { | 984 const std::string& title) { |
997 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 985 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
998 | 986 |
999 base::FilePath desktop_name(kAppListDesktopName); | 987 base::FilePath desktop_name(kAppListDesktopName); |
1000 base::FilePath shortcut_filename = desktop_name.AddExtension("desktop"); | 988 base::FilePath shortcut_filename = desktop_name.AddExtension("desktop"); |
1001 | 989 |
1002 // We do not want duplicate shortcuts. Delete any that already exist and | 990 // We do not want duplicate shortcuts. Delete any that already exist and |
1003 // replace them. | 991 // replace them. |
1004 DeleteShortcutInApplicationsMenu(shortcut_filename, base::FilePath()); | 992 DeleteShortcutInApplicationsMenu(shortcut_filename, base::FilePath()); |
1005 | 993 |
1006 base::FilePath chrome_exe_path = GetChromeExePath(); | 994 base::FilePath chrome_exe_path = GetChromeExePath(); |
1007 if (chrome_exe_path.empty()) { | 995 if (chrome_exe_path.empty()) { |
1008 LOG(WARNING) << "Could not get executable path."; | 996 NOTREACHED(); |
1009 return false; | 997 return false; |
1010 } | 998 } |
1011 | 999 |
1012 gfx::ImageFamily icon_images; | 1000 gfx::ImageFamily icon_images; |
1013 ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance(); | 1001 ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance(); |
1014 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_16)); | 1002 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_16)); |
1015 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_32)); | 1003 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_32)); |
1016 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_48)); | 1004 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_48)); |
1017 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_256)); | 1005 icon_images.Add(*resource_bundle.GetImageSkiaNamed(IDR_APP_LIST_256)); |
1018 std::string icon_name = CreateShortcutIcon(icon_images, desktop_name); | 1006 std::string icon_name = CreateShortcutIcon(icon_images, desktop_name); |
1019 | 1007 |
1020 base::CommandLine command_line(chrome_exe_path); | 1008 base::CommandLine command_line(chrome_exe_path); |
1021 command_line.AppendSwitch(switches::kShowAppList); | 1009 command_line.AppendSwitch(switches::kShowAppList); |
1022 std::string contents = | 1010 std::string contents = |
1023 GetDesktopFileContentsForCommand(command_line, | 1011 GetDesktopFileContentsForCommand(command_line, |
1024 wm_class, | 1012 wm_class, |
1025 GURL(), | 1013 GURL(), |
1026 base::UTF8ToUTF16(title), | 1014 base::UTF8ToUTF16(title), |
1027 icon_name, | 1015 icon_name, |
1028 kAppListCategories, | 1016 kAppListCategories, |
1029 false); | 1017 false); |
1030 return CreateShortcutInApplicationsMenu( | 1018 return CreateShortcutInApplicationsMenu( |
1031 shortcut_filename, contents, base::FilePath(), ""); | 1019 shortcut_filename, contents, base::FilePath(), ""); |
1032 } | 1020 } |
1033 | 1021 |
1034 void DeleteDesktopShortcuts(const base::FilePath& profile_path, | 1022 void DeleteDesktopShortcuts(const base::FilePath& profile_path, |
1035 const std::string& extension_id) { | 1023 const std::string& extension_id) { |
1036 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 1024 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
1037 | 1025 |
1038 base::FilePath shortcut_filename = GetExtensionShortcutFilename( | 1026 base::FilePath shortcut_filename = GetExtensionShortcutFilename( |
1039 profile_path, extension_id); | 1027 profile_path, extension_id); |
1040 DCHECK(!shortcut_filename.empty()); | 1028 DCHECK(!shortcut_filename.empty()); |
1041 | 1029 |
1042 DeleteShortcutOnDesktop(shortcut_filename); | 1030 DeleteShortcutOnDesktop(shortcut_filename); |
1043 // Delete shortcuts from |kDirectoryFilename|. | 1031 // Delete shortcuts from |kDirectoryFilename|. |
1044 // Note that it is possible that shortcuts were not created in the Chrome Apps | 1032 // Note that it is possible that shortcuts were not created in the Chrome Apps |
1045 // directory. It doesn't matter: this will still delete the shortcut even if | 1033 // directory. It doesn't matter: this will still delete the shortcut even if |
1046 // it isn't in the directory. | 1034 // it isn't in the directory. |
1047 DeleteShortcutInApplicationsMenu(shortcut_filename, | 1035 DeleteShortcutInApplicationsMenu(shortcut_filename, |
1048 base::FilePath(kDirectoryFilename)); | 1036 base::FilePath(kDirectoryFilename)); |
1049 } | 1037 } |
1050 | 1038 |
1051 void DeleteAllDesktopShortcuts(const base::FilePath& profile_path) { | 1039 void DeleteAllDesktopShortcuts(const base::FilePath& profile_path) { |
1052 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 1040 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
1053 | 1041 |
1054 scoped_ptr<base::Environment> env(base::Environment::Create()); | 1042 scoped_ptr<base::Environment> env(base::Environment::Create()); |
1055 | 1043 |
1056 // Delete shortcuts from Desktop. | 1044 // Delete shortcuts from Desktop. |
1057 base::FilePath desktop_path; | 1045 base::FilePath desktop_path; |
1058 if (PathService::Get(base::DIR_USER_DESKTOP, &desktop_path)) { | 1046 if (PathService::Get(base::DIR_USER_DESKTOP, &desktop_path)) { |
1059 std::vector<base::FilePath> shortcut_filenames_desktop = | 1047 std::vector<base::FilePath> shortcut_filenames_desktop = |
1060 GetExistingProfileShortcutFilenames(profile_path, desktop_path); | 1048 GetExistingProfileShortcutFilenames(profile_path, desktop_path); |
1061 for (std::vector<base::FilePath>::const_iterator it = | 1049 for (const auto& shortcut : shortcut_filenames_desktop) { |
1062 shortcut_filenames_desktop.begin(); | 1050 DeleteShortcutOnDesktop(shortcut); |
1063 it != shortcut_filenames_desktop.end(); ++it) { | |
1064 DeleteShortcutOnDesktop(*it); | |
1065 } | 1051 } |
1066 } | 1052 } |
1067 | 1053 |
1068 // Delete shortcuts from |kDirectoryFilename|. | 1054 // Delete shortcuts from |kDirectoryFilename|. |
1069 base::FilePath applications_menu; | 1055 base::FilePath applications_menu = GetDataWriteLocation(env.get()); |
1070 if (GetDataWriteLocation(env.get(), &applications_menu)) { | 1056 applications_menu = applications_menu.AppendASCII("applications"); |
1071 applications_menu = applications_menu.AppendASCII("applications"); | 1057 std::vector<base::FilePath> shortcut_filenames_app_menu = |
1072 std::vector<base::FilePath> shortcut_filenames_app_menu = | 1058 GetExistingProfileShortcutFilenames(profile_path, applications_menu); |
1073 GetExistingProfileShortcutFilenames(profile_path, applications_menu); | 1059 for (const auto& menu : shortcut_filenames_app_menu) { |
1074 for (std::vector<base::FilePath>::const_iterator it = | 1060 DeleteShortcutInApplicationsMenu(menu, base::FilePath(kDirectoryFilename)); |
1075 shortcut_filenames_app_menu.begin(); | |
1076 it != shortcut_filenames_app_menu.end(); ++it) { | |
1077 DeleteShortcutInApplicationsMenu(*it, | |
1078 base::FilePath(kDirectoryFilename)); | |
1079 } | |
1080 } | 1061 } |
1081 } | 1062 } |
1082 | 1063 |
1083 } // namespace shell_integration_linux | 1064 } // namespace shell_integration_linux |
OLD | NEW |