| 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 <objbase.h> // For CoInitialize(). | 5 #include <objbase.h> // For CoInitialize(). |
| 6 | 6 |
| 7 #include "base/base_paths.h" | 7 #include "base/base_paths.h" |
| 8 #include "base/command_line.h" |
| 8 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 9 #include "base/location.h" | 10 #include "base/location.h" |
| 10 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 11 #include "base/path_service.h" | 12 #include "base/path_service.h" |
| 13 #include "base/string16.h" |
| 12 #include "base/test/scoped_path_override.h" | 14 #include "base/test/scoped_path_override.h" |
| 13 #include "base/string16.h" | |
| 14 #include "base/test/test_shortcut_win.h" | 15 #include "base/test/test_shortcut_win.h" |
| 15 #include "base/win/shortcut.h" | 16 #include "base/win/shortcut.h" |
| 16 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
| 17 #include "chrome/browser/profiles/profile_manager.h" | 18 #include "chrome/browser/profiles/profile_manager.h" |
| 18 #include "chrome/browser/profiles/profile_shortcut_manager.h" | 19 #include "chrome/browser/profiles/profile_shortcut_manager.h" |
| 19 #include "chrome/browser/profiles/profile_shortcut_manager_win.h" | 20 #include "chrome/browser/profiles/profile_shortcut_manager_win.h" |
| 21 #include "chrome/common/chrome_paths.h" |
| 22 #include "chrome/common/chrome_switches.h" |
| 20 #include "chrome/installer/util/browser_distribution.h" | 23 #include "chrome/installer/util/browser_distribution.h" |
| 21 #include "chrome/installer/util/product.h" | 24 #include "chrome/installer/util/product.h" |
| 22 #include "chrome/installer/util/shell_util.h" | 25 #include "chrome/installer/util/shell_util.h" |
| 23 #include "chrome/test/base/testing_browser_process.h" | 26 #include "chrome/test/base/testing_browser_process.h" |
| 24 #include "chrome/test/base/testing_profile.h" | 27 #include "chrome/test/base/testing_profile.h" |
| 25 #include "chrome/test/base/testing_profile_manager.h" | 28 #include "chrome/test/base/testing_profile_manager.h" |
| 26 #include "content/public/test/test_browser_thread.h" | 29 #include "content/public/test/test_browser_thread.h" |
| 27 #include "testing/gtest/include/gtest/gtest.h" | 30 #include "testing/gtest/include/gtest/gtest.h" |
| 28 | 31 |
| 29 using content::BrowserThread; | 32 using content::BrowserThread; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 | 137 |
| 135 // Ensure that the corresponding icon exists. | 138 // Ensure that the corresponding icon exists. |
| 136 const FilePath icon_path = | 139 const FilePath icon_path = |
| 137 profile_path.AppendASCII(profiles::internal::kProfileIconFileName); | 140 profile_path.AppendASCII(profiles::internal::kProfileIconFileName); |
| 138 EXPECT_TRUE(file_util::PathExists(icon_path)) << location.ToString(); | 141 EXPECT_TRUE(file_util::PathExists(icon_path)) << location.ToString(); |
| 139 | 142 |
| 140 base::win::ShortcutProperties expected_properties; | 143 base::win::ShortcutProperties expected_properties; |
| 141 expected_properties.set_target(GetExePath()); | 144 expected_properties.set_target(GetExePath()); |
| 142 expected_properties.set_description(GetDistribution()->GetAppDescription()); | 145 expected_properties.set_description(GetDistribution()->GetAppDescription()); |
| 143 expected_properties.set_dual_mode(false); | 146 expected_properties.set_dual_mode(false); |
| 144 expected_properties.set_arguments( | 147 const CommandLine command_line = |
| 145 profiles::internal::CreateProfileShortcutFlags(profile_path)); | 148 profiles::internal::CreateCommandLineForProfileShortcut(GetExePath(), |
| 149 profile_path); |
| 150 expected_properties.set_arguments(command_line.GetArgumentsString()); |
| 146 expected_properties.set_icon(icon_path, 0); | 151 expected_properties.set_icon(icon_path, 0); |
| 147 base::win::ValidateShortcut(shortcut_path, expected_properties); | 152 base::win::ValidateShortcut(shortcut_path, expected_properties); |
| 148 } | 153 } |
| 149 | 154 |
| 150 // Calls base::win::ValidateShortcut() with expected properties for | 155 // Calls base::win::ValidateShortcut() with expected properties for |
| 151 // |profile_name|'s shortcut. | 156 // |profile_name|'s shortcut. |
| 152 void ValidateProfileShortcut(const tracked_objects::Location& location, | 157 void ValidateProfileShortcut(const tracked_objects::Location& location, |
| 153 const string16& profile_name, | 158 const string16& profile_name, |
| 154 const FilePath& profile_path) { | 159 const FilePath& profile_path) { |
| 155 ValidateProfileShortcutAtPath( | 160 ValidateProfileShortcutAtPath( |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 ShellUtil::SHORTCUT_LOCATION_DESKTOP, distribution, properties, | 223 ShellUtil::SHORTCUT_LOCATION_DESKTOP, distribution, properties, |
| 219 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)) << location.ToString(); | 224 ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)) << location.ToString(); |
| 220 const FilePath system_level_shortcut_path = | 225 const FilePath system_level_shortcut_path = |
| 221 GetSystemShortcutsDirectory().Append( | 226 GetSystemShortcutsDirectory().Append( |
| 222 distribution->GetAppShortCutName() + installer::kLnkExt); | 227 distribution->GetAppShortCutName() + installer::kLnkExt); |
| 223 EXPECT_TRUE(file_util::PathExists(system_level_shortcut_path)) | 228 EXPECT_TRUE(file_util::PathExists(system_level_shortcut_path)) |
| 224 << location.ToString(); | 229 << location.ToString(); |
| 225 return system_level_shortcut_path; | 230 return system_level_shortcut_path; |
| 226 } | 231 } |
| 227 | 232 |
| 233 // Returns the CommandLine of the shortcut at |shortcut_path|. |
| 234 CommandLine GetShortcutCommandLine(const tracked_objects::Location& location, |
| 235 const FilePath& shortcut_path) { |
| 236 FilePath target_path; |
| 237 string16 shortcut_args; |
| 238 const bool success = base::win::ResolveShortcut(shortcut_path, &target_path, |
| 239 &shortcut_args); |
| 240 EXPECT_TRUE(success) << location.ToString(); |
| 241 return CommandLine::FromString(target_path.value() + L" " + shortcut_args); |
| 242 } |
| 243 |
| 244 // Replaces the command line args of the shortcut at |shortcut_path| with |
| 245 // the ones in |command_line|. |
| 246 void SetShortcutCommandLine(const tracked_objects::Location& location, |
| 247 const FilePath& shortcut_path, |
| 248 const CommandLine& command_line) { |
| 249 ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER); |
| 250 properties.set_shortcut_name( |
| 251 shortcut_path.BaseName().RemoveExtension().value()); |
| 252 properties.set_arguments(command_line.GetArgumentsString()); |
| 253 const bool success = ShellUtil::CreateOrUpdateShortcut( |
| 254 ShellUtil::SHORTCUT_LOCATION_DESKTOP, GetDistribution(), properties, |
| 255 ShellUtil::SHELL_SHORTCUT_UPDATE_EXISTING); |
| 256 ASSERT_TRUE(success) << location.ToString(); |
| 257 } |
| 258 |
| 259 // Makes a copy of |command_line| with the --user-data-dir argument set to |
| 260 // |user_data_dir|. Removes the argument if |user_data_dir| is empty. |
| 261 CommandLine ReplaceCommandLineUserDataDir(const CommandLine& command_line, |
| 262 const FilePath& user_data_dir) { |
| 263 CommandLine result(command_line.GetProgram()); |
| 264 const CommandLine::SwitchMap& switches = command_line.GetSwitches(); |
| 265 for (CommandLine::SwitchMap::const_iterator it = switches.begin(); |
| 266 it != switches.end(); ++it) { |
| 267 if (it->first != switches::kUserDataDir) |
| 268 result.AppendSwitchNative(it->first, it->second); |
| 269 } |
| 270 if (!user_data_dir.empty()) |
| 271 result.AppendSwitchPath(switches::kUserDataDir, user_data_dir); |
| 272 return result; |
| 273 } |
| 274 |
| 275 // Creates a copy of the shortcut at |shortcut_path| and makes the copy have |
| 276 // |user_data_dir| specified as a custom --user-data-dir argument. Removes |
| 277 // any --user-data-dir argument if |user_data_dir| is empty. |
| 278 FilePath CopyShortcutAndSetUserDataDir( |
| 279 const tracked_objects::Location& location, |
| 280 const FilePath& shortcut_path, |
| 281 const string16& new_shortcut_name, |
| 282 const FilePath& user_data_dir) { |
| 283 const FilePath new_shortcut_path = |
| 284 GetUserShortcutsDirectory().Append(new_shortcut_name); |
| 285 EXPECT_TRUE(file_util::CopyFile(shortcut_path, new_shortcut_path)) |
| 286 << location.ToString(); |
| 287 const CommandLine command_line = |
| 288 GetShortcutCommandLine(FROM_HERE, shortcut_path); |
| 289 SetShortcutCommandLine(location, new_shortcut_path, |
| 290 ReplaceCommandLineUserDataDir(command_line, |
| 291 user_data_dir)); |
| 292 return new_shortcut_path; |
| 293 } |
| 294 |
| 228 void RenameProfile(const tracked_objects::Location& location, | 295 void RenameProfile(const tracked_objects::Location& location, |
| 229 const FilePath& profile_path, | 296 const FilePath& profile_path, |
| 230 const string16& new_profile_name) { | 297 const string16& new_profile_name) { |
| 231 const size_t profile_index = | 298 const size_t profile_index = |
| 232 profile_info_cache_->GetIndexOfProfileWithPath(profile_2_path_); | 299 profile_info_cache_->GetIndexOfProfileWithPath(profile_2_path_); |
| 233 ASSERT_NE(std::string::npos, profile_index); | 300 ASSERT_NE(std::string::npos, profile_index); |
| 234 ASSERT_NE(profile_info_cache_->GetNameOfProfileAtIndex(profile_index), | 301 ASSERT_NE(profile_info_cache_->GetNameOfProfileAtIndex(profile_index), |
| 235 new_profile_name); | 302 new_profile_name); |
| 236 profile_info_cache_->SetNameOfProfileAtIndex(profile_index, | 303 profile_info_cache_->SetNameOfProfileAtIndex(profile_index, |
| 237 new_profile_name); | 304 new_profile_name); |
| 238 RunPendingTasks(); | 305 RunPendingTasks(); |
| 239 } | 306 } |
| 240 | 307 |
| 241 BrowserDistribution* GetDistribution() { | 308 BrowserDistribution* GetDistribution() { |
| 242 return BrowserDistribution::GetDistribution(); | 309 return BrowserDistribution::GetDistribution(); |
| 243 } | 310 } |
| 244 | 311 |
| 245 FilePath GetExePath() { | 312 FilePath GetExePath() { |
| 246 FilePath exe_path; | 313 FilePath exe_path; |
| 247 EXPECT_TRUE(PathService::Get(base::FILE_EXE, &exe_path)); | 314 EXPECT_TRUE(PathService::Get(base::FILE_EXE, &exe_path)); |
| 248 return exe_path; | 315 return exe_path; |
| 249 } | 316 } |
| 250 | 317 |
| 318 FilePath GetUserDataDir() { |
| 319 FilePath user_data_dir; |
| 320 EXPECT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)); |
| 321 return user_data_dir; |
| 322 } |
| 323 |
| 251 FilePath GetUserShortcutsDirectory() { | 324 FilePath GetUserShortcutsDirectory() { |
| 252 FilePath user_shortcuts_directory; | 325 FilePath user_shortcuts_directory; |
| 253 EXPECT_TRUE(ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP, | 326 EXPECT_TRUE(ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP, |
| 254 GetDistribution(), | 327 GetDistribution(), |
| 255 ShellUtil::CURRENT_USER, | 328 ShellUtil::CURRENT_USER, |
| 256 &user_shortcuts_directory)); | 329 &user_shortcuts_directory)); |
| 257 return user_shortcuts_directory; | 330 return user_shortcuts_directory; |
| 258 } | 331 } |
| 259 | 332 |
| 260 FilePath GetSystemShortcutsDirectory() { | 333 FilePath GetSystemShortcutsDirectory() { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 BrowserDistribution* distribution = GetDistribution(); | 390 BrowserDistribution* distribution = GetDistribution(); |
| 318 EXPECT_EQ(distribution->GetAppShortCutName() + installer::kLnkExt, | 391 EXPECT_EQ(distribution->GetAppShortCutName() + installer::kLnkExt, |
| 319 profiles::internal::GetShortcutFilenameForProfile(string16(), | 392 profiles::internal::GetShortcutFilenameForProfile(string16(), |
| 320 distribution)); | 393 distribution)); |
| 321 } | 394 } |
| 322 | 395 |
| 323 TEST_F(ProfileShortcutManagerTest, ShortcutFlags) { | 396 TEST_F(ProfileShortcutManagerTest, ShortcutFlags) { |
| 324 const string16 kProfileName = L"MyProfileX"; | 397 const string16 kProfileName = L"MyProfileX"; |
| 325 const FilePath profile_path = | 398 const FilePath profile_path = |
| 326 profile_info_cache_->GetUserDataDir().Append(kProfileName); | 399 profile_info_cache_->GetUserDataDir().Append(kProfileName); |
| 327 EXPECT_EQ(L"--profile-directory=\"" + kProfileName + L"\"", | 400 const CommandLine command_line = |
| 328 profiles::internal::CreateProfileShortcutFlags(profile_path)); | 401 profiles::internal::CreateCommandLineForProfileShortcut(GetExePath(), |
| 402 profile_path); |
| 403 EXPECT_EQ(kProfileName, |
| 404 command_line.GetSwitchValueNative(switches::kProfileDirectory)); |
| 329 } | 405 } |
| 330 | 406 |
| 331 TEST_F(ProfileShortcutManagerTest, DesktopShortcutsCreate) { | 407 TEST_F(ProfileShortcutManagerTest, DesktopShortcutsCreate) { |
| 332 SetupDefaultProfileShortcut(FROM_HERE); | 408 SetupDefaultProfileShortcut(FROM_HERE); |
| 333 // Validation is done by |ValidateProfileShortcutAtPath()| which is called | 409 // Validation is done by |ValidateProfileShortcutAtPath()| which is called |
| 334 // by |CreateProfileWithShortcut()|. | 410 // by |CreateProfileWithShortcut()|. |
| 335 CreateProfileWithShortcut(FROM_HERE, profile_2_name_, profile_2_path_); | 411 CreateProfileWithShortcut(FROM_HERE, profile_2_name_, profile_2_path_); |
| 336 } | 412 } |
| 337 | 413 |
| 338 TEST_F(ProfileShortcutManagerTest, DesktopShortcutsUpdate) { | 414 TEST_F(ProfileShortcutManagerTest, DesktopShortcutsUpdate) { |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 profile_info_cache_->DeleteProfileFromCache(profile_2_path_); | 808 profile_info_cache_->DeleteProfileFromCache(profile_2_path_); |
| 733 RunPendingTasks(); | 809 RunPendingTasks(); |
| 734 | 810 |
| 735 // Verify that only the system-level shortcut still exists. | 811 // Verify that only the system-level shortcut still exists. |
| 736 EXPECT_TRUE(file_util::PathExists(system_level_shortcut_path)); | 812 EXPECT_TRUE(file_util::PathExists(system_level_shortcut_path)); |
| 737 EXPECT_FALSE(file_util::PathExists( | 813 EXPECT_FALSE(file_util::PathExists( |
| 738 GetDefaultShortcutPathForProfile(string16()))); | 814 GetDefaultShortcutPathForProfile(string16()))); |
| 739 EXPECT_FALSE(file_util::PathExists(profile_1_shortcut_path)); | 815 EXPECT_FALSE(file_util::PathExists(profile_1_shortcut_path)); |
| 740 EXPECT_FALSE(file_util::PathExists(profile_2_shortcut_path)); | 816 EXPECT_FALSE(file_util::PathExists(profile_2_shortcut_path)); |
| 741 } | 817 } |
| 818 |
| 819 TEST_F(ProfileShortcutManagerTest, DefaultUserDataDir_UpdateUserDataShortcuts) { |
| 820 // Checks that other shortcuts with --user-data-dir specified are not touched. |
| 821 ASSERT_TRUE(profiles::internal::GetCustomUserDataDirectory().empty()); |
| 822 SetupAndCreateTwoShortcuts(FROM_HERE); |
| 823 |
| 824 const FilePath profile_1_shortcut_path = |
| 825 GetDefaultShortcutPathForProfile(profile_1_name_); |
| 826 // Ensure that --user-data-dir is not specified by default. |
| 827 ASSERT_FALSE(GetShortcutCommandLine(FROM_HERE, profile_1_shortcut_path) |
| 828 .HasSwitch(switches::kUserDataDir)); |
| 829 |
| 830 const FilePath shortcut_with_current_user_data_path = |
| 831 CopyShortcutAndSetUserDataDir(FROM_HERE, profile_1_shortcut_path, |
| 832 L"Copied1.lnk", GetUserDataDir()); |
| 833 |
| 834 base::ScopedTempDir temp_dir; |
| 835 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 836 const FilePath shortcut_with_other_user_data_path = |
| 837 CopyShortcutAndSetUserDataDir(FROM_HERE, profile_1_shortcut_path, |
| 838 L"Copied2.lnk", temp_dir.path()); |
| 839 |
| 840 // Now, delete the profile and ensure that the original shortcut and the |
| 841 // shortcuts with the current user data dir set explictly get deleted, but |
| 842 // not the one specifying a different one. |
| 843 profile_info_cache_->DeleteProfileFromCache(profile_1_path_); |
| 844 RunPendingTasks(); |
| 845 |
| 846 EXPECT_FALSE(file_util::PathExists(profile_1_shortcut_path)); |
| 847 EXPECT_FALSE(file_util::PathExists(shortcut_with_current_user_data_path)); |
| 848 EXPECT_TRUE(file_util::PathExists(shortcut_with_other_user_data_path)); |
| 849 } |
| 850 |
| 851 TEST_F(ProfileShortcutManagerTest, CustomUserDataDir_UpdateUserDataShortcuts) { |
| 852 // Overrides the user data dir with a custom one (simulating a custom |
| 853 // --user-data-dir specified on the command line) and ensure things behave |
| 854 // as expected. |
| 855 base::ScopedPathOverride fake_custom_user_data_dir(chrome::DIR_USER_DATA); |
| 856 ASSERT_FALSE(profiles::internal::GetCustomUserDataDirectory().empty()); |
| 857 SetupAndCreateTwoShortcuts(FROM_HERE); |
| 858 |
| 859 const FilePath profile_1_shortcut_path = |
| 860 GetDefaultShortcutPathForProfile(profile_1_name_); |
| 861 // Ensure that the custom --user-data-dir has been specified. |
| 862 ASSERT_EQ(GetUserDataDir(), |
| 863 GetShortcutCommandLine(FROM_HERE, profile_1_shortcut_path) |
| 864 .GetSwitchValuePath(switches::kUserDataDir)); |
| 865 |
| 866 const FilePath shortcut_with_empty_user_data_path = |
| 867 CopyShortcutAndSetUserDataDir(FROM_HERE, profile_1_shortcut_path, |
| 868 L"Copied1.lnk", FilePath()); |
| 869 |
| 870 base::ScopedTempDir temp_dir; |
| 871 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 872 const FilePath shortcut_with_other_user_data_path = |
| 873 CopyShortcutAndSetUserDataDir(FROM_HERE, profile_1_shortcut_path, |
| 874 L"Copied2.lnk", temp_dir.path()); |
| 875 |
| 876 // Now, delete the profile and ensure that the original shortcut got deleted, |
| 877 // but the shortcuts without user data dir and with a different one did not. |
| 878 profile_info_cache_->DeleteProfileFromCache(profile_1_path_); |
| 879 RunPendingTasks(); |
| 880 |
| 881 EXPECT_FALSE(file_util::PathExists(profile_1_shortcut_path)); |
| 882 EXPECT_TRUE(file_util::PathExists(shortcut_with_empty_user_data_path)); |
| 883 EXPECT_TRUE(file_util::PathExists(shortcut_with_other_user_data_path)); |
| 884 } |
| OLD | NEW |