Chromium Code Reviews| Index: chrome/browser/shell_integration_win.cc |
| diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc |
| index 5dd80834c0ab7b81ce673f99f255d24c920ac2c2..d3876c2ee8da4eccabb1b54072e13dead915d5a0 100644 |
| --- a/chrome/browser/shell_integration_win.cc |
| +++ b/chrome/browser/shell_integration_win.cc |
| @@ -26,6 +26,7 @@ |
| #include "chrome/common/chrome_constants.h" |
| #include "chrome/common/chrome_paths_internal.h" |
| #include "chrome/common/chrome_switches.h" |
| +#include "chrome/installer/launcher_support/chrome_launcher_support.h" |
| #include "chrome/installer/setup/setup_util.h" |
| #include "chrome/installer/util/browser_distribution.h" |
| #include "chrome/installer/util/create_reg_key_work_item.h" |
| @@ -43,6 +44,9 @@ namespace { |
| const wchar_t kAppListAppNameSuffix[] = L"AppList"; |
| +// How many seconds to delay migrating app host shortcuts. |
| +const int64 kMigrateAppHostShortcutsDelaySeconds = 15; |
|
huangs
2013/04/19 15:21:28
This appears unused.
|
| + |
| // Helper function for ShellIntegration::GetAppId to generates profile id |
| // from profile path. "profile_id" is composed of sanitized basenames of |
| // user data dir and profile dir joined by a ".". |
| @@ -90,12 +94,18 @@ string16 GetAppListAppName() { |
| // |is_per_user_install|). |
| string16 GetExpectedAppId(const CommandLine& command_line, |
| bool is_per_user_install) { |
| - base::FilePath profile_path; |
| - if (command_line.HasSwitch(switches::kUserDataDir)) { |
| - profile_path = |
| - command_line.GetSwitchValuePath(switches::kUserDataDir).AppendASCII( |
| - chrome::kInitialProfile); |
| - } |
| + base::FilePath user_data_dir; |
| + chrome::GetDefaultUserDataDirectory(&user_data_dir); |
| + if (command_line.HasSwitch(switches::kUserDataDir)) |
| + user_data_dir = command_line.GetSwitchValuePath(switches::kUserDataDir); |
| + |
| + base::FilePath profile_subdir; |
| + profile_subdir.AppendASCII(chrome::kInitialProfile); |
| + if (command_line.HasSwitch(switches::kProfileDirectory)) |
| + profile_subdir = |
| + command_line.GetSwitchValuePath(switches::kProfileDirectory); |
| + |
| + base::FilePath profile_path = user_data_dir.Append(profile_subdir); |
| string16 app_name; |
| if (command_line.HasSwitch(switches::kApp)) { |
| @@ -114,7 +124,35 @@ string16 GetExpectedAppId(const CommandLine& command_line, |
| return ShellIntegration::GetAppModelIdForProfile(app_name, profile_path); |
| } |
| -void MigrateChromiumShortcutsCallback() { |
| +// Locations to check for shortcuts migration. |
| +static const struct { |
| + int location_id; |
| + const wchar_t* sub_dir; |
| +} kLocations[] = { |
| + { |
| + base::DIR_IMPLICIT_APP_SHORTCUTS, |
| + NULL |
| + }, { |
| + base::DIR_TASKBAR_PINS, |
| + NULL |
| + }, { |
| + base::DIR_USER_DESKTOP, |
| + NULL |
| + }, { |
| + base::DIR_START_MENU, |
| + NULL |
| + }, { |
| + base::DIR_APP_DATA, |
| + L"Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\StartMenu" |
| + } |
| +}; |
| + |
| +void MigrateShortcutsCallback() { |
| + ShellIntegration::MigrateAppHostShortcuts(); |
| + ShellIntegration::MigrateChromiumShortcuts(); |
| +} |
| + |
| +void MigrateAppHostShortcutsCallback() { |
| // This should run on the file thread. |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| @@ -123,25 +161,40 @@ void MigrateChromiumShortcutsCallback() { |
| if (!PathService::Get(base::FILE_EXE, &chrome_exe)) |
| return; |
| - // Locations to check for shortcuts migration. |
| - static const struct { |
| - int location_id; |
| - const wchar_t* sub_dir; |
| - } kLocations[] = { |
| - { |
| - base::DIR_TASKBAR_PINS, |
| - NULL |
| - }, { |
| - base::DIR_USER_DESKTOP, |
| - NULL |
| - }, { |
| - base::DIR_START_MENU, |
| - NULL |
| - }, { |
| - base::DIR_APP_DATA, |
| - L"Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\StartMenu" |
| + // Get the app_host.exe path. |
| + bool is_per_user_install = |
| + InstallUtil::IsPerUserInstall(chrome_exe.value().c_str()); |
| + base::FilePath app_host_exe = GetAppHostPathForInstallationLevel( |
|
huangs
2013/04/19 15:21:28
Does this code account for the case:
1. Chrome is
|
| + is_per_user_install ? chrome_launcher_support::USER_LEVEL_INSTALLATION |
| + : chrome_launcher_support::SYSTEM_LEVEL_INSTALLATION); |
| + |
| + for (int i = 0; i < arraysize(kLocations); ++i) { |
| + base::FilePath path; |
| + if (!PathService::Get(kLocations[i].location_id, &path)) { |
| + NOTREACHED(); |
| + continue; |
| } |
| - }; |
| + |
| + if (kLocations[i].sub_dir) |
| + path = path.Append(kLocations[i].sub_dir); |
| + |
| + // Recurse when looking for user-pinned shortcuts as they exist in |
| + // subdirectories. |
| + bool recursive = |
| + (kLocations[i].location_id == base::DIR_IMPLICIT_APP_SHORTCUTS); |
| + ShellIntegration::MigrateAppHostShortcutsInPathInternal( |
| + chrome_exe, app_host_exe, path, recursive); |
| + } |
| +} |
| + |
| +void MigrateChromiumShortcutsCallback() { |
| + // This should run on the file thread. |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| + |
| + // Get full path of chrome. |
| + base::FilePath chrome_exe; |
| + if (!PathService::Get(base::FILE_EXE, &chrome_exe)) |
| + return; |
| for (int i = 0; i < arraysize(kLocations); ++i) { |
| base::FilePath path; |
| @@ -364,14 +417,9 @@ void ShellIntegration::MigrateChromiumShortcuts() { |
| if (base::win::GetVersion() < base::win::VERSION_WIN7) |
| return; |
| - // This needs to happen eventually (e.g. so that the appid is fixed and the |
| - // run-time Chrome icon is merged with the taskbar shortcut), but this is not |
| - // urgent and shouldn't delay Chrome startup. |
| - static const int64 kMigrateChromiumShortcutsDelaySeconds = 15; |
| - BrowserThread::PostDelayedTask( |
| + BrowserThread::PostTask( |
|
gab
2013/04/19 18:34:50
No need for a second task here given this is alrea
|
| BrowserThread::FILE, FROM_HERE, |
| - base::Bind(&MigrateChromiumShortcutsCallback), |
| - base::TimeDelta::FromSeconds(kMigrateChromiumShortcutsDelaySeconds)); |
| + base::Bind(&MigrateChromiumShortcutsCallback)); |
| } |
| int ShellIntegration::MigrateShortcutsInPathInternal( |
| @@ -489,6 +537,58 @@ int ShellIntegration::MigrateShortcutsInPathInternal( |
| return shortcuts_migrated; |
| } |
| +void ShellIntegration::MigrateShortcuts() { |
| + // These migrations need to happen eventually (e.g. so that the appid is fixed |
| + // and the run-time Chrome icon is merged with the taskbar shortcut), but this |
| + // is not urgent and shouldn't delay Chrome startup. |
| + const int64 kMigrateShortcutsDelaySeconds = 15; |
| + |
| + BrowserThread::PostDelayedTask( |
| + BrowserThread::FILE, FROM_HERE, |
| + base::Bind(&MigrateShortcutsCallback), |
| + base::TimeDelta::FromSeconds(kMigrateShortcutsDelaySeconds)); |
| +} |
| + |
| +void ShellIntegration::MigrateAppHostShortcuts() { |
| + BrowserThread::PostTask( |
| + BrowserThread::FILE, FROM_HERE, |
| + base::Bind(&MigrateAppHostShortcutsCallback)); |
| +} |
| + |
| +int ShellIntegration::MigrateAppHostShortcutsInPathInternal( |
| + const base::FilePath& chrome_exe, |
| + const base::FilePath& app_host_exe, |
| + const base::FilePath& path, |
| + bool recursive) { |
| + int shortcuts_migrated = 0; |
| + base::FilePath target_path; |
| + string16 arguments; |
| + file_util::FileEnumerator shortcuts_enum( |
| + path, recursive, file_util::FileEnumerator::FILES); |
| + for (base::FilePath shortcut = shortcuts_enum.Next(); !shortcut.empty(); |
| + shortcut = shortcuts_enum.Next()) { |
| + // TODO(gab): Use ProgramCompare instead of comparing FilePaths below once |
| + // it is fixed to work with FilePaths with spaces. |
|
gab
2013/04/19 18:34:50
PS: This has been fixed, you can now use InstallUt
|
| + if (shortcut.Extension() != installer::kLnkExt || |
| + !base::win::ResolveShortcut(shortcut, &target_path, &arguments) || |
| + app_host_exe != target_path) { |
| + continue; |
| + } |
| + |
| + // Any properties that need to be updated on the shortcut will be stored in |
| + // |updated_properties|. |
| + base::win::ShortcutProperties updated_properties; |
| + updated_properties.set_target(chrome_exe); |
| + |
| + if (base::win::CreateOrUpdateShortcutLink( |
| + shortcut, updated_properties, |
| + base::win::SHORTCUT_UPDATE_EXISTING)) { |
| + ++shortcuts_migrated; |
| + } |
| + } |
| + return shortcuts_migrated; |
| +} |
| + |
| base::FilePath ShellIntegration::GetStartMenuShortcut( |
| const base::FilePath& chrome_exe) { |
| static const int kFolderIds[] = { |