Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(106)

Side by Side Diff: chrome/browser/shell_integration_linux.cc

Issue 13864015: Move app launcher and chrome apps shortcut strings into the installer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@migrate_app_id_fix
Patch Set: fix linux unit tests Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include <glib.h> 8 #include <glib.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <sys/stat.h> 10 #include <sys/stat.h>
(...skipping 22 matching lines...) Expand all
33 #include "base/strings/string_tokenizer.h" 33 #include "base/strings/string_tokenizer.h"
34 #include "base/strings/string_util.h" 34 #include "base/strings/string_util.h"
35 #include "base/strings/utf_string_conversions.h" 35 #include "base/strings/utf_string_conversions.h"
36 #include "base/threading/thread.h" 36 #include "base/threading/thread.h"
37 #include "base/threading/thread_restrictions.h" 37 #include "base/threading/thread_restrictions.h"
38 #include "build/build_config.h" 38 #include "build/build_config.h"
39 #include "chrome/browser/web_applications/web_app.h" 39 #include "chrome/browser/web_applications/web_app.h"
40 #include "chrome/common/chrome_constants.h" 40 #include "chrome/common/chrome_constants.h"
41 #include "chrome/common/chrome_version_info.h" 41 #include "chrome/common/chrome_version_info.h"
42 #include "content/public/browser/browser_thread.h" 42 #include "content/public/browser/browser_thread.h"
43 #include "grit/chromium_strings.h"
44 #include "ui/base/l10n/l10n_util.h"
43 #include "ui/gfx/image/image_family.h" 45 #include "ui/gfx/image/image_family.h"
44 #include "url/gurl.h" 46 #include "url/gurl.h"
45 47
46 using content::BrowserThread; 48 using content::BrowserThread;
47 49
48 namespace { 50 namespace {
49 51
50 // Helper to launch xdg scripts. We don't want them to ask any questions on the 52 // Helper to launch xdg scripts. We don't want them to ask any questions on the
51 // terminal etc. The function returns true if the utility launches and exits 53 // terminal etc. The function returns true if the utility launches and exits
52 // cleanly, in which case |exit_code| returns the utility's exit code. 54 // cleanly, in which case |exit_code| returns the utility's exit code.
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 quoted += '\\'; 272 quoted += '\\';
271 break; 273 break;
272 } 274 }
273 quoted += arg[i]; 275 quoted += arg[i];
274 } 276 }
275 quoted += '"'; 277 quoted += '"';
276 278
277 return quoted; 279 return quoted;
278 } 280 }
279 281
282 // TODO(calamity): replace with
283 // BrowserDistribution::GetStartMenuShortcutSubfolder() once
284 // BrowserDistribution is cross-platform.
285 // Gets the name of the Chrome Apps menu folder in which to place app shortcuts.
286 string16 GetAppShortcutsSubdirName() {
gab 2013/10/03 17:22:49 I would prefer having only a single copy of this m
calamity 2013/10/14 02:24:25 Done.
287 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
288 if (channel == chrome::VersionInfo::CHANNEL_CANARY)
289 return l10n_util::GetStringUTF16(IDS_APP_SHORTCUTS_SUBDIR_NAME_CANARY);
290 return l10n_util::GetStringUTF16(IDS_APP_SHORTCUTS_SUBDIR_NAME);
291 }
292
280 const char kDesktopEntry[] = "Desktop Entry"; 293 const char kDesktopEntry[] = "Desktop Entry";
281 294
282 const char kXdgOpenShebang[] = "#!/usr/bin/env xdg-open"; 295 const char kXdgOpenShebang[] = "#!/usr/bin/env xdg-open";
283 296
284 const char kXdgSettings[] = "xdg-settings"; 297 const char kXdgSettings[] = "xdg-settings";
285 const char kXdgSettingsDefaultBrowser[] = "default-web-browser"; 298 const char kXdgSettingsDefaultBrowser[] = "default-web-browser";
286 const char kXdgSettingsDefaultSchemeHandler[] = "default-url-scheme-handler"; 299 const char kXdgSettingsDefaultSchemeHandler[] = "default-url-scheme-handler";
287 300
288 const char kDirectoryFilename[] = "chrome-apps.directory"; 301 const char kDirectoryFilename[] = "chrome-apps.directory";
289 302
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 } 601 }
589 602
590 ShellIntegration::ShortcutLocations GetExistingShortcutLocations( 603 ShellIntegration::ShortcutLocations GetExistingShortcutLocations(
591 base::Environment* env, 604 base::Environment* env,
592 const base::FilePath& profile_path, 605 const base::FilePath& profile_path,
593 const std::string& extension_id) { 606 const std::string& extension_id) {
594 base::FilePath desktop_path; 607 base::FilePath desktop_path;
595 // If Get returns false, just leave desktop_path empty. 608 // If Get returns false, just leave desktop_path empty.
596 PathService::Get(base::DIR_USER_DESKTOP, &desktop_path); 609 PathService::Get(base::DIR_USER_DESKTOP, &desktop_path);
597 return GetExistingShortcutLocations(env, profile_path, extension_id, 610 return GetExistingShortcutLocations(env, profile_path, extension_id,
598 desktop_path); 611 desktop_path);
599 } 612 }
600 613
601 ShellIntegration::ShortcutLocations GetExistingShortcutLocations( 614 ShellIntegration::ShortcutLocations GetExistingShortcutLocations(
602 base::Environment* env, 615 base::Environment* env,
603 const base::FilePath& profile_path, 616 const base::FilePath& profile_path,
604 const std::string& extension_id, 617 const std::string& extension_id,
605 const base::FilePath& desktop_path) { 618 const base::FilePath& desktop_path) {
606 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 619 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
607 620
608 base::FilePath shortcut_filename = GetExtensionShortcutFilename( 621 base::FilePath shortcut_filename = GetExtensionShortcutFilename(
609 profile_path, extension_id); 622 profile_path, extension_id);
610 DCHECK(!shortcut_filename.empty()); 623 DCHECK(!shortcut_filename.empty());
611 ShellIntegration::ShortcutLocations locations; 624 ShellIntegration::ShortcutLocations locations;
612 625
613 // Determine whether there is a shortcut on desktop. 626 // Determine whether there is a shortcut on desktop.
614 if (!desktop_path.empty()) { 627 if (!desktop_path.empty()) {
615 locations.on_desktop = 628 locations.on_desktop =
616 base::PathExists(desktop_path.Append(shortcut_filename)); 629 base::PathExists(desktop_path.Append(shortcut_filename));
617 } 630 }
618 631
619 // Determine whether there is a shortcut in the applications directory. 632 // Determine whether there is a shortcut in the applications directory.
620 std::string shortcut_contents; 633 std::string shortcut_contents;
621 if (GetExistingShortcutContents(env, shortcut_filename, &shortcut_contents)) { 634 if (GetExistingShortcutContents(env, shortcut_filename, &shortcut_contents)) {
622 // Whether this counts as "hidden" or "in_applications_menu" depends on 635 // Whether this counts as "hidden" or
623 // whether it contains NoDisplay=true. 636 // "in_applications_menu_chrome_apps_subdir" depends on whether it contains
637 // NoDisplay=true. Since these shortcuts are for apps, they are always in
638 // the "Chrome Apps" directory.
624 if (GetNoDisplayFromDesktopFile(shortcut_contents)) 639 if (GetNoDisplayFromDesktopFile(shortcut_contents))
625 locations.hidden = true; 640 locations.hidden = true;
626 else 641 else
627 locations.in_applications_menu = true; 642 locations.in_applications_menu_chrome_apps_subdir = true;
628 } 643 }
629 644
630 return locations; 645 return locations;
631 } 646 }
632 647
633 bool GetExistingShortcutContents(base::Environment* env, 648 bool GetExistingShortcutContents(base::Environment* env,
634 const base::FilePath& desktop_filename, 649 const base::FilePath& desktop_filename,
635 std::string* output) { 650 std::string* output) {
636 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 651 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
637 652
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 859 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
845 860
846 base::FilePath shortcut_filename; 861 base::FilePath shortcut_filename;
847 if (!shortcut_info.extension_id.empty()) { 862 if (!shortcut_info.extension_id.empty()) {
848 shortcut_filename = GetExtensionShortcutFilename( 863 shortcut_filename = GetExtensionShortcutFilename(
849 shortcut_info.profile_path, shortcut_info.extension_id); 864 shortcut_info.profile_path, shortcut_info.extension_id);
850 // For extensions we do not want duplicate shortcuts. So, delete any that 865 // For extensions we do not want duplicate shortcuts. So, delete any that
851 // already exist and replace them. 866 // already exist and replace them.
852 if (creation_locations.on_desktop) 867 if (creation_locations.on_desktop)
853 DeleteShortcutOnDesktop(shortcut_filename); 868 DeleteShortcutOnDesktop(shortcut_filename);
854 if (creation_locations.in_applications_menu || creation_locations.hidden) 869 // The 'InApplicationsMenu()' and 'hidden' locations are actually the same
870 // place ('applications').
871 if (creation_locations.InApplicationsMenu() || creation_locations.hidden)
855 DeleteShortcutInApplicationsMenu(shortcut_filename, base::FilePath()); 872 DeleteShortcutInApplicationsMenu(shortcut_filename, base::FilePath());
856 } else { 873 } else {
857 shortcut_filename = GetWebShortcutFilename(shortcut_info.url); 874 shortcut_filename = GetWebShortcutFilename(shortcut_info.url);
858 } 875 }
859 if (shortcut_filename.empty()) 876 if (shortcut_filename.empty())
860 return false; 877 return false;
861 878
862 std::string icon_name = CreateShortcutIcon(shortcut_info, shortcut_filename); 879 std::string icon_name = CreateShortcutIcon(shortcut_info, shortcut_filename);
863 880
864 std::string app_name = 881 std::string app_name =
(...skipping 14 matching lines...) Expand all
879 shortcut_info.url, 896 shortcut_info.url,
880 shortcut_info.extension_id, 897 shortcut_info.extension_id,
881 shortcut_info.extension_path, 898 shortcut_info.extension_path,
882 shortcut_info.title, 899 shortcut_info.title,
883 icon_name, 900 icon_name,
884 shortcut_info.profile_path, 901 shortcut_info.profile_path,
885 false); 902 false);
886 success = CreateShortcutOnDesktop(shortcut_filename, contents); 903 success = CreateShortcutOnDesktop(shortcut_filename, contents);
887 } 904 }
888 905
889 // The 'in_applications_menu' and 'hidden' locations are actually the same 906 if (creation_locations.InApplicationsMenu() || creation_locations.hidden) {
890 // place ('applications').
891 if (creation_locations.in_applications_menu || creation_locations.hidden) {
892 base::FilePath directory_filename; 907 base::FilePath directory_filename;
893 std::string directory_contents; 908 std::string directory_contents;
894 if (!creation_locations.applications_menu_subdir.empty()) { 909 if (creation_locations.in_applications_menu_chrome_apps_subdir) {
895 directory_filename = base::FilePath(kDirectoryFilename); 910 directory_filename = base::FilePath(kDirectoryFilename);
896 directory_contents = ShellIntegrationLinux::GetDirectoryFileContents( 911 directory_contents = ShellIntegrationLinux::GetDirectoryFileContents(
897 creation_locations.applications_menu_subdir, ""); 912 GetAppShortcutsSubdirName(), "");
898 } 913 }
899 // Set NoDisplay=true if hidden but not in_applications_menu. This will hide 914 // Set NoDisplay=true if hidden but not InApplicationsMenu(). This will hide
900 // the application from user-facing menus. 915 // the application from user-facing menus.
901 std::string contents = ShellIntegrationLinux::GetDesktopFileContents( 916 std::string contents = ShellIntegrationLinux::GetDesktopFileContents(
902 chrome_exe_path, 917 chrome_exe_path,
903 app_name, 918 app_name,
904 shortcut_info.url, 919 shortcut_info.url,
905 shortcut_info.extension_id, 920 shortcut_info.extension_id,
906 shortcut_info.extension_path, 921 shortcut_info.extension_path,
907 shortcut_info.title, 922 shortcut_info.title,
908 icon_name, 923 icon_name,
909 shortcut_info.profile_path, 924 shortcut_info.profile_path,
910 !creation_locations.in_applications_menu); 925 !creation_locations.InApplicationsMenu());
911 success = CreateShortcutInApplicationsMenu( 926 success = CreateShortcutInApplicationsMenu(
912 shortcut_filename, contents, directory_filename, directory_contents) && 927 shortcut_filename, contents, directory_filename, directory_contents) &&
913 success; 928 success;
914 } 929 }
915 930
916 return success; 931 return success;
917 } 932 }
918 933
919 void DeleteDesktopShortcuts(const base::FilePath& profile_path, 934 void DeleteDesktopShortcuts(const base::FilePath& profile_path,
920 const std::string& extension_id) { 935 const std::string& extension_id) {
921 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 936 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
922 937
923 base::FilePath shortcut_filename = GetExtensionShortcutFilename( 938 base::FilePath shortcut_filename = GetExtensionShortcutFilename(
924 profile_path, extension_id); 939 profile_path, extension_id);
925 DCHECK(!shortcut_filename.empty()); 940 DCHECK(!shortcut_filename.empty());
926 941
927 DeleteShortcutOnDesktop(shortcut_filename); 942 DeleteShortcutOnDesktop(shortcut_filename);
928 // Delete shortcuts from |kDirectoryFilename|. 943 // Delete shortcuts from |kDirectoryFilename|.
929 // Note that it is possible that shortcuts were not created in the Chrome Apps 944 // Note that it is possible that shortcuts were not created in the Chrome Apps
930 // directory (depending on the value of |applications_menu_subdir| when they 945 // directory. It doesn't matter: this will still delete the shortcut even if
931 // were created). It doesn't matter: this will still delete the shortcut even 946 // it isn't in the directory.
932 // if it isn't in the directory.
933 DeleteShortcutInApplicationsMenu(shortcut_filename, 947 DeleteShortcutInApplicationsMenu(shortcut_filename,
934 base::FilePath(kDirectoryFilename)); 948 base::FilePath(kDirectoryFilename));
935 } 949 }
936 950
937 void DeleteAllDesktopShortcuts(const base::FilePath& profile_path) { 951 void DeleteAllDesktopShortcuts(const base::FilePath& profile_path) {
938 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 952 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
939 953
940 scoped_ptr<base::Environment> env(base::Environment::Create()); 954 scoped_ptr<base::Environment> env(base::Environment::Create());
941 955
942 // Delete shortcuts from Desktop. 956 // Delete shortcuts from Desktop.
(...skipping 17 matching lines...) Expand all
960 for (std::vector<base::FilePath>::const_iterator it = 974 for (std::vector<base::FilePath>::const_iterator it =
961 shortcut_filenames_app_menu.begin(); 975 shortcut_filenames_app_menu.begin();
962 it != shortcut_filenames_app_menu.end(); ++it) { 976 it != shortcut_filenames_app_menu.end(); ++it) {
963 DeleteShortcutInApplicationsMenu(*it, 977 DeleteShortcutInApplicationsMenu(*it,
964 base::FilePath(kDirectoryFilename)); 978 base::FilePath(kDirectoryFilename));
965 } 979 }
966 } 980 }
967 } 981 }
968 982
969 } // namespace ShellIntegrationLinux 983 } // namespace ShellIntegrationLinux
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698