| 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 #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 18 matching lines...) Expand all  Loading... | 
| 29 #include "base/posix/eintr_wrapper.h" | 29 #include "base/posix/eintr_wrapper.h" | 
| 30 #include "base/process/kill.h" | 30 #include "base/process/kill.h" | 
| 31 #include "base/process/launch.h" | 31 #include "base/process/launch.h" | 
| 32 #include "base/strings/string_number_conversions.h" | 32 #include "base/strings/string_number_conversions.h" | 
| 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/shell_integration.h" | 
| 40 #include "chrome/common/chrome_constants.h" | 40 #include "chrome/common/chrome_constants.h" | 
| 41 #include "chrome/common/chrome_switches.h" | 41 #include "chrome/common/chrome_switches.h" | 
| 42 #include "chrome/common/chrome_version_info.h" | 42 #include "chrome/common/chrome_version_info.h" | 
| 43 #include "content/public/browser/browser_thread.h" | 43 #include "content/public/browser/browser_thread.h" | 
| 44 #include "grit/chrome_unscaled_resources.h" | 44 #include "grit/chrome_unscaled_resources.h" | 
| 45 #include "ui/base/resource/resource_bundle.h" | 45 #include "ui/base/resource/resource_bundle.h" | 
| 46 #include "ui/gfx/image/image_family.h" | 46 #include "ui/gfx/image/image_family.h" | 
| 47 #include "url/gurl.h" | 47 #include "url/gurl.h" | 
| 48 | 48 | 
| 49 using content::BrowserThread; | 49 using content::BrowserThread; | 
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 609 } | 609 } | 
| 610 | 610 | 
| 611 std::string GetIconName() { | 611 std::string GetIconName() { | 
| 612 #if defined(GOOGLE_CHROME_BUILD) | 612 #if defined(GOOGLE_CHROME_BUILD) | 
| 613   return "google-chrome"; | 613   return "google-chrome"; | 
| 614 #else  // CHROMIUM_BUILD | 614 #else  // CHROMIUM_BUILD | 
| 615   return "chromium-browser"; | 615   return "chromium-browser"; | 
| 616 #endif | 616 #endif | 
| 617 } | 617 } | 
| 618 | 618 | 
| 619 ShellIntegration::ShortcutLocations GetExistingShortcutLocations( | 619 web_app::ShortcutLocations GetExistingShortcutLocations( | 
| 620     base::Environment* env, | 620     base::Environment* env, | 
| 621     const base::FilePath& profile_path, | 621     const base::FilePath& profile_path, | 
| 622     const std::string& extension_id) { | 622     const std::string& extension_id) { | 
| 623   base::FilePath desktop_path; | 623   base::FilePath desktop_path; | 
| 624   // If Get returns false, just leave desktop_path empty. | 624   // If Get returns false, just leave desktop_path empty. | 
| 625   PathService::Get(base::DIR_USER_DESKTOP, &desktop_path); | 625   PathService::Get(base::DIR_USER_DESKTOP, &desktop_path); | 
| 626   return GetExistingShortcutLocations(env, profile_path, extension_id, | 626   return GetExistingShortcutLocations(env, profile_path, extension_id, | 
| 627                                       desktop_path); | 627                                       desktop_path); | 
| 628 } | 628 } | 
| 629 | 629 | 
| 630 ShellIntegration::ShortcutLocations GetExistingShortcutLocations( | 630 web_app::ShortcutLocations GetExistingShortcutLocations( | 
| 631     base::Environment* env, | 631     base::Environment* env, | 
| 632     const base::FilePath& profile_path, | 632     const base::FilePath& profile_path, | 
| 633     const std::string& extension_id, | 633     const std::string& extension_id, | 
| 634     const base::FilePath& desktop_path) { | 634     const base::FilePath& desktop_path) { | 
| 635   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 635   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 
| 636 | 636 | 
| 637   base::FilePath shortcut_filename = GetExtensionShortcutFilename( | 637   base::FilePath shortcut_filename = GetExtensionShortcutFilename( | 
| 638       profile_path, extension_id); | 638       profile_path, extension_id); | 
| 639   DCHECK(!shortcut_filename.empty()); | 639   DCHECK(!shortcut_filename.empty()); | 
| 640   ShellIntegration::ShortcutLocations locations; | 640   web_app::ShortcutLocations locations; | 
| 641 | 641 | 
| 642   // Determine whether there is a shortcut on desktop. | 642   // Determine whether there is a shortcut on desktop. | 
| 643   if (!desktop_path.empty()) { | 643   if (!desktop_path.empty()) { | 
| 644     locations.on_desktop = | 644     locations.on_desktop = | 
| 645         base::PathExists(desktop_path.Append(shortcut_filename)); | 645         base::PathExists(desktop_path.Append(shortcut_filename)); | 
| 646   } | 646   } | 
| 647 | 647 | 
| 648   // Determine whether there is a shortcut in the applications directory. | 648   // Determine whether there is a shortcut in the applications directory. | 
| 649   std::string shortcut_contents; | 649   std::string shortcut_contents; | 
| 650   if (GetExistingShortcutContents(env, shortcut_filename, &shortcut_contents)) { | 650   if (GetExistingShortcutContents(env, shortcut_filename, &shortcut_contents)) { | 
| 651     // Whether this counts as "hidden" or "APP_MENU_LOCATION_SUBDIR_CHROMEAPPS" | 651     // Whether this counts as "hidden" or "APP_MENU_LOCATION_SUBDIR_CHROMEAPPS" | 
| 652     // depends on whether it contains NoDisplay=true. Since these shortcuts are | 652     // depends on whether it contains NoDisplay=true. Since these shortcuts are | 
| 653     // for apps, they are always in the "Chrome Apps" directory. | 653     // for apps, they are always in the "Chrome Apps" directory. | 
| 654     if (GetNoDisplayFromDesktopFile(shortcut_contents)) { | 654     if (GetNoDisplayFromDesktopFile(shortcut_contents)) { | 
| 655       locations.hidden = true; | 655       locations.hidden = true; | 
| 656     } else { | 656     } else { | 
| 657       locations.applications_menu_location = | 657       locations.applications_menu_location = | 
| 658           ShellIntegration::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS; | 658           web_app::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS; | 
| 659     } | 659     } | 
| 660   } | 660   } | 
| 661 | 661 | 
| 662   return locations; | 662   return locations; | 
| 663 } | 663 } | 
| 664 | 664 | 
| 665 bool GetExistingShortcutContents(base::Environment* env, | 665 bool GetExistingShortcutContents(base::Environment* env, | 
| 666                                  const base::FilePath& desktop_filename, | 666                                  const base::FilePath& desktop_filename, | 
| 667                                  std::string* output) { | 667                                  std::string* output) { | 
| 668   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 668   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 863       output_buffer += data_dump; | 863       output_buffer += data_dump; | 
| 864     } | 864     } | 
| 865     g_free(data_dump); | 865     g_free(data_dump); | 
| 866   } | 866   } | 
| 867 | 867 | 
| 868   g_key_file_free(key_file); | 868   g_key_file_free(key_file); | 
| 869   return output_buffer; | 869   return output_buffer; | 
| 870 } | 870 } | 
| 871 | 871 | 
| 872 bool CreateDesktopShortcut( | 872 bool CreateDesktopShortcut( | 
| 873     const ShellIntegration::ShortcutInfo& shortcut_info, | 873     const web_app::ShortcutInfo& shortcut_info, | 
| 874     const ShellIntegration::ShortcutLocations& creation_locations) { | 874     const web_app::ShortcutLocations& creation_locations) { | 
| 875   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 875   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 
| 876 | 876 | 
| 877   base::FilePath shortcut_filename; | 877   base::FilePath shortcut_filename; | 
| 878   if (!shortcut_info.extension_id.empty()) { | 878   if (!shortcut_info.extension_id.empty()) { | 
| 879     shortcut_filename = GetExtensionShortcutFilename( | 879     shortcut_filename = GetExtensionShortcutFilename( | 
| 880         shortcut_info.profile_path, shortcut_info.extension_id); | 880         shortcut_info.profile_path, shortcut_info.extension_id); | 
| 881     // For extensions we do not want duplicate shortcuts. So, delete any that | 881     // For extensions we do not want duplicate shortcuts. So, delete any that | 
| 882     // already exist and replace them. | 882     // already exist and replace them. | 
| 883     if (creation_locations.on_desktop) | 883     if (creation_locations.on_desktop) | 
| 884       DeleteShortcutOnDesktop(shortcut_filename); | 884       DeleteShortcutOnDesktop(shortcut_filename); | 
| 885     // The 'applications_menu_location' and 'hidden' locations are actually the | 885     // The 'applications_menu_location' and 'hidden' locations are actually the | 
| 886     // same place ('applications'). | 886     // same place ('applications'). | 
| 887     if (creation_locations.applications_menu_location != | 887     if (creation_locations.applications_menu_location != | 
| 888             ShellIntegration::APP_MENU_LOCATION_NONE || | 888             web_app::APP_MENU_LOCATION_NONE || | 
| 889         creation_locations.hidden) | 889         creation_locations.hidden) | 
| 890       DeleteShortcutInApplicationsMenu(shortcut_filename, base::FilePath()); | 890       DeleteShortcutInApplicationsMenu(shortcut_filename, base::FilePath()); | 
| 891   } else { | 891   } else { | 
| 892     shortcut_filename = GetWebShortcutFilename(shortcut_info.url); | 892     shortcut_filename = GetWebShortcutFilename(shortcut_info.url); | 
| 893   } | 893   } | 
| 894   if (shortcut_filename.empty()) | 894   if (shortcut_filename.empty()) | 
| 895     return false; | 895     return false; | 
| 896 | 896 | 
| 897   std::string icon_name = | 897   std::string icon_name = | 
| 898       CreateShortcutIcon(shortcut_info.favicon, shortcut_filename); | 898       CreateShortcutIcon(shortcut_info.favicon, shortcut_filename); | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 915         shortcut_info.url, | 915         shortcut_info.url, | 
| 916         shortcut_info.extension_id, | 916         shortcut_info.extension_id, | 
| 917         shortcut_info.title, | 917         shortcut_info.title, | 
| 918         icon_name, | 918         icon_name, | 
| 919         shortcut_info.profile_path, | 919         shortcut_info.profile_path, | 
| 920         false); | 920         false); | 
| 921     success = CreateShortcutOnDesktop(shortcut_filename, contents); | 921     success = CreateShortcutOnDesktop(shortcut_filename, contents); | 
| 922   } | 922   } | 
| 923 | 923 | 
| 924   if (creation_locations.applications_menu_location != | 924   if (creation_locations.applications_menu_location != | 
| 925           ShellIntegration::APP_MENU_LOCATION_NONE || | 925           web_app::APP_MENU_LOCATION_NONE || | 
| 926       creation_locations.hidden) { | 926       creation_locations.hidden) { | 
| 927     base::FilePath directory_filename; | 927     base::FilePath directory_filename; | 
| 928     std::string directory_contents; | 928     std::string directory_contents; | 
| 929     switch (creation_locations.applications_menu_location) { | 929     switch (creation_locations.applications_menu_location) { | 
| 930       case ShellIntegration::APP_MENU_LOCATION_NONE: | 930       case web_app::APP_MENU_LOCATION_NONE: | 
| 931       case ShellIntegration::APP_MENU_LOCATION_ROOT: | 931       case web_app::APP_MENU_LOCATION_ROOT: | 
| 932         break; | 932         break; | 
| 933       case ShellIntegration::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS: | 933       case web_app::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS: | 
| 934         directory_filename = base::FilePath(kDirectoryFilename); | 934         directory_filename = base::FilePath(kDirectoryFilename); | 
| 935         directory_contents = ShellIntegrationLinux::GetDirectoryFileContents( | 935         directory_contents = ShellIntegrationLinux::GetDirectoryFileContents( | 
| 936             ShellIntegration::GetAppShortcutsSubdirName(), ""); | 936             ShellIntegration::GetAppShortcutsSubdirName(), ""); | 
| 937         break; | 937         break; | 
| 938       default: | 938       default: | 
| 939         NOTREACHED(); | 939         NOTREACHED(); | 
| 940         break; | 940         break; | 
| 941     } | 941     } | 
| 942     // Set NoDisplay=true if hidden but not in the applications menu. This will | 942     // Set NoDisplay=true if hidden but not in the applications menu. This will | 
| 943     // hide the application from user-facing menus. | 943     // hide the application from user-facing menus. | 
| 944     std::string contents = ShellIntegrationLinux::GetDesktopFileContents( | 944     std::string contents = ShellIntegrationLinux::GetDesktopFileContents( | 
| 945         chrome_exe_path, | 945         chrome_exe_path, | 
| 946         app_name, | 946         app_name, | 
| 947         shortcut_info.url, | 947         shortcut_info.url, | 
| 948         shortcut_info.extension_id, | 948         shortcut_info.extension_id, | 
| 949         shortcut_info.title, | 949         shortcut_info.title, | 
| 950         icon_name, | 950         icon_name, | 
| 951         shortcut_info.profile_path, | 951         shortcut_info.profile_path, | 
| 952         creation_locations.applications_menu_location == | 952         creation_locations.applications_menu_location == | 
| 953             ShellIntegration::APP_MENU_LOCATION_NONE); | 953             web_app::APP_MENU_LOCATION_NONE); | 
| 954     success = CreateShortcutInApplicationsMenu( | 954     success = CreateShortcutInApplicationsMenu( | 
| 955         shortcut_filename, contents, directory_filename, directory_contents) && | 955         shortcut_filename, contents, directory_filename, directory_contents) && | 
| 956         success; | 956         success; | 
| 957   } | 957   } | 
| 958 | 958 | 
| 959   return success; | 959   return success; | 
| 960 } | 960 } | 
| 961 | 961 | 
| 962 bool CreateAppListDesktopShortcut( | 962 bool CreateAppListDesktopShortcut( | 
| 963     const std::string& wm_class, | 963     const std::string& wm_class, | 
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1037     for (std::vector<base::FilePath>::const_iterator it = | 1037     for (std::vector<base::FilePath>::const_iterator it = | 
| 1038          shortcut_filenames_app_menu.begin(); | 1038          shortcut_filenames_app_menu.begin(); | 
| 1039          it != shortcut_filenames_app_menu.end(); ++it) { | 1039          it != shortcut_filenames_app_menu.end(); ++it) { | 
| 1040       DeleteShortcutInApplicationsMenu(*it, | 1040       DeleteShortcutInApplicationsMenu(*it, | 
| 1041                                        base::FilePath(kDirectoryFilename)); | 1041                                        base::FilePath(kDirectoryFilename)); | 
| 1042     } | 1042     } | 
| 1043   } | 1043   } | 
| 1044 } | 1044 } | 
| 1045 | 1045 | 
| 1046 }  // namespace ShellIntegrationLinux | 1046 }  // namespace ShellIntegrationLinux | 
| OLD | NEW | 
|---|