| 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/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 11 #include "base/path_service.h" | 11 #include "base/path_service.h" |
| 12 #include "base/strings/string16.h" | 12 #include "base/strings/string16.h" |
| 13 #include "base/test/scoped_path_override.h" | 13 #include "base/test/scoped_path_override.h" |
| 14 #include "base/test/test_shortcut_win.h" | 14 #include "base/test/test_shortcut_win.h" |
| 15 #include "base/win/shortcut.h" | 15 #include "base/win/shortcut.h" |
| 16 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
| 17 #include "chrome/browser/profiles/profile_manager.h" | 17 #include "chrome/browser/profiles/profile_manager.h" |
| 18 #include "chrome/browser/profiles/profile_shortcut_manager.h" | 18 #include "chrome/browser/profiles/profile_shortcut_manager.h" |
| 19 #include "chrome/browser/profiles/profile_shortcut_manager_win.h" | 19 #include "chrome/browser/profiles/profile_shortcut_manager_win.h" |
| 20 #include "chrome/browser/shell_integration.h" | 20 #include "chrome/browser/shell_integration.h" |
| 21 #include "chrome/common/chrome_paths.h" |
| 21 #include "chrome/installer/util/browser_distribution.h" | 22 #include "chrome/installer/util/browser_distribution.h" |
| 22 #include "chrome/installer/util/product.h" | 23 #include "chrome/installer/util/product.h" |
| 23 #include "chrome/installer/util/shell_util.h" | 24 #include "chrome/installer/util/shell_util.h" |
| 24 #include "chrome/test/base/testing_browser_process.h" | 25 #include "chrome/test/base/testing_browser_process.h" |
| 25 #include "chrome/test/base/testing_profile.h" | 26 #include "chrome/test/base/testing_profile.h" |
| 26 #include "chrome/test/base/testing_profile_manager.h" | 27 #include "chrome/test/base/testing_profile_manager.h" |
| 27 #include "content/public/test/test_browser_thread.h" | 28 #include "content/public/test/test_browser_thread.h" |
| 28 #include "grit/chromium_strings.h" | 29 #include "grit/chromium_strings.h" |
| 29 #include "testing/gtest/include/gtest/gtest.h" | 30 #include "testing/gtest/include/gtest/gtest.h" |
| 30 #include "ui/base/l10n/l10n_util.h" | 31 #include "ui/base/l10n/l10n_util.h" |
| 31 | 32 |
| 32 using content::BrowserThread; | 33 using content::BrowserThread; |
| 33 | 34 |
| 34 class ProfileShortcutManagerTest : public testing::Test { | 35 class ProfileShortcutManagerTest : public testing::Test { |
| 35 protected: | 36 protected: |
| 36 ProfileShortcutManagerTest() | 37 ProfileShortcutManagerTest() |
| 37 : ui_thread_(BrowserThread::UI, &message_loop_), | 38 : ui_thread_(BrowserThread::UI, &message_loop_), |
| 38 file_thread_(BrowserThread::FILE, &message_loop_), | 39 file_thread_(BrowserThread::FILE, &message_loop_), |
| 39 profile_info_cache_(NULL), | 40 profile_info_cache_(NULL), |
| 40 fake_user_desktop_(base::DIR_USER_DESKTOP), | 41 fake_user_desktop_(base::DIR_USER_DESKTOP), |
| 41 fake_system_desktop_(base::DIR_COMMON_DESKTOP) { | 42 fake_system_desktop_(base::DIR_COMMON_DESKTOP), |
| 43 fake_user_data_(chrome::DIR_USER_DATA) { |
| 42 } | 44 } |
| 43 | 45 |
| 44 virtual void SetUp() OVERRIDE { | 46 virtual void SetUp() OVERRIDE { |
| 45 CoInitialize(NULL); | 47 CoInitialize(NULL); |
| 46 | 48 |
| 47 TestingBrowserProcess* browser_process = | 49 TestingBrowserProcess* browser_process = |
| 48 TestingBrowserProcess::GetGlobal(); | 50 TestingBrowserProcess::GetGlobal(); |
| 49 profile_manager_.reset(new TestingProfileManager(browser_process)); | 51 profile_manager_.reset(new TestingProfileManager(browser_process)); |
| 50 ASSERT_TRUE(profile_manager_->SetUp()); | 52 ASSERT_TRUE(profile_manager_->SetUp()); |
| 51 profile_info_cache_ = profile_manager_->profile_info_cache(); | 53 profile_info_cache_ = profile_manager_->profile_info_cache(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 64 | 66 |
| 65 // Delete all profiles and ensure their shortcuts got removed. | 67 // Delete all profiles and ensure their shortcuts got removed. |
| 66 const int num_profiles = profile_info_cache_->GetNumberOfProfiles(); | 68 const int num_profiles = profile_info_cache_->GetNumberOfProfiles(); |
| 67 for (int i = 0; i < num_profiles; ++i) { | 69 for (int i = 0; i < num_profiles; ++i) { |
| 68 const base::FilePath profile_path = | 70 const base::FilePath profile_path = |
| 69 profile_info_cache_->GetPathOfProfileAtIndex(0); | 71 profile_info_cache_->GetPathOfProfileAtIndex(0); |
| 70 string16 profile_name = profile_info_cache_->GetNameOfProfileAtIndex(0); | 72 string16 profile_name = profile_info_cache_->GetNameOfProfileAtIndex(0); |
| 71 profile_info_cache_->DeleteProfileFromCache(profile_path); | 73 profile_info_cache_->DeleteProfileFromCache(profile_path); |
| 72 RunPendingTasks(); | 74 RunPendingTasks(); |
| 73 ASSERT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_name)); | 75 ASSERT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_name)); |
| 76 // The icon file is not deleted until the profile directory is deleted. |
| 74 const base::FilePath icon_path = | 77 const base::FilePath icon_path = |
| 75 profile_path.AppendASCII(profiles::internal::kProfileIconFileName); | 78 profiles::internal::GetProfileIconPath(profile_path); |
| 76 ASSERT_FALSE(base::PathExists(icon_path)); | 79 ASSERT_TRUE(base::PathExists(icon_path)); |
| 77 } | 80 } |
| 78 } | 81 } |
| 79 | 82 |
| 80 base::FilePath CreateProfileDirectory(const string16& profile_name) { | 83 base::FilePath CreateProfileDirectory(const string16& profile_name) { |
| 81 const base::FilePath profile_path = | 84 const base::FilePath profile_path = |
| 82 profile_info_cache_->GetUserDataDir().Append(profile_name); | 85 profile_info_cache_->GetUserDataDir().Append(profile_name); |
| 83 file_util::CreateDirectoryW(profile_path); | 86 file_util::CreateDirectory(profile_path); |
| 84 return profile_path; | 87 return profile_path; |
| 85 } | 88 } |
| 86 | 89 |
| 87 void RunPendingTasks() { | 90 void RunPendingTasks() { |
| 88 base::MessageLoop::current()->PostTask(FROM_HERE, | 91 base::MessageLoop::current()->PostTask(FROM_HERE, |
| 89 base::MessageLoop::QuitClosure()); | 92 base::MessageLoop::QuitClosure()); |
| 90 base::MessageLoop::current()->Run(); | 93 base::MessageLoop::current()->Run(); |
| 91 } | 94 } |
| 92 | 95 |
| 93 void SetupDefaultProfileShortcut(const tracked_objects::Location& location) { | 96 void SetupDefaultProfileShortcut(const tracked_objects::Location& location) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 | 130 |
| 128 // Calls base::win::ValidateShortcut() with expected properties for the | 131 // Calls base::win::ValidateShortcut() with expected properties for the |
| 129 // shortcut at |shortcut_path| for the profile at |profile_path|. | 132 // shortcut at |shortcut_path| for the profile at |profile_path|. |
| 130 void ValidateProfileShortcutAtPath(const tracked_objects::Location& location, | 133 void ValidateProfileShortcutAtPath(const tracked_objects::Location& location, |
| 131 const base::FilePath& shortcut_path, | 134 const base::FilePath& shortcut_path, |
| 132 const base::FilePath& profile_path) { | 135 const base::FilePath& profile_path) { |
| 133 EXPECT_TRUE(base::PathExists(shortcut_path)) << location.ToString(); | 136 EXPECT_TRUE(base::PathExists(shortcut_path)) << location.ToString(); |
| 134 | 137 |
| 135 // Ensure that the corresponding icon exists. | 138 // Ensure that the corresponding icon exists. |
| 136 const base::FilePath icon_path = | 139 const base::FilePath icon_path = |
| 137 profile_path.AppendASCII(profiles::internal::kProfileIconFileName); | 140 profiles::internal::GetProfileIconPath(profile_path); |
| 138 EXPECT_TRUE(base::PathExists(icon_path)) << location.ToString(); | 141 EXPECT_TRUE(base::PathExists(icon_path)) << location.ToString(); |
| 139 | 142 |
| 140 base::win::ShortcutProperties expected_properties; | 143 base::win::ShortcutProperties expected_properties; |
| 141 expected_properties.set_app_id( | 144 expected_properties.set_app_id( |
| 142 ShellIntegration::GetChromiumModelIdForProfile(profile_path)); | 145 ShellIntegration::GetChromiumModelIdForProfile(profile_path)); |
| 143 expected_properties.set_target(GetExePath()); | 146 expected_properties.set_target(GetExePath()); |
| 144 expected_properties.set_description(GetDistribution()->GetAppDescription()); | 147 expected_properties.set_description(GetDistribution()->GetAppDescription()); |
| 145 expected_properties.set_dual_mode(false); | 148 expected_properties.set_dual_mode(false); |
| 146 expected_properties.set_arguments( | 149 expected_properties.set_arguments( |
| 147 profiles::internal::CreateProfileShortcutFlags(profile_path)); | 150 profiles::internal::CreateProfileShortcutFlags(profile_path)); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 } | 273 } |
| 271 | 274 |
| 272 base::MessageLoopForUI message_loop_; | 275 base::MessageLoopForUI message_loop_; |
| 273 content::TestBrowserThread ui_thread_; | 276 content::TestBrowserThread ui_thread_; |
| 274 content::TestBrowserThread file_thread_; | 277 content::TestBrowserThread file_thread_; |
| 275 scoped_ptr<TestingProfileManager> profile_manager_; | 278 scoped_ptr<TestingProfileManager> profile_manager_; |
| 276 scoped_ptr<ProfileShortcutManager> profile_shortcut_manager_; | 279 scoped_ptr<ProfileShortcutManager> profile_shortcut_manager_; |
| 277 ProfileInfoCache* profile_info_cache_; | 280 ProfileInfoCache* profile_info_cache_; |
| 278 base::ScopedPathOverride fake_user_desktop_; | 281 base::ScopedPathOverride fake_user_desktop_; |
| 279 base::ScopedPathOverride fake_system_desktop_; | 282 base::ScopedPathOverride fake_system_desktop_; |
| 283 base::ScopedPathOverride fake_user_data_; |
| 280 string16 profile_1_name_; | 284 string16 profile_1_name_; |
| 281 base::FilePath profile_1_path_; | 285 base::FilePath profile_1_path_; |
| 282 string16 profile_2_name_; | 286 string16 profile_2_name_; |
| 283 base::FilePath profile_2_path_; | 287 base::FilePath profile_2_path_; |
| 284 string16 profile_3_name_; | 288 string16 profile_3_name_; |
| 285 base::FilePath profile_3_path_; | 289 base::FilePath profile_3_path_; |
| 286 }; | 290 }; |
| 287 | 291 |
| 288 TEST_F(ProfileShortcutManagerTest, ShortcutFilename) { | 292 TEST_F(ProfileShortcutManagerTest, ShortcutFilename) { |
| 289 const string16 kProfileName = L"Harry"; | 293 const string16 kProfileName = L"Harry"; |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 | 757 |
| 754 // Delete the shortcut for the first profile, but keep the one for the 2nd. | 758 // Delete the shortcut for the first profile, but keep the one for the 2nd. |
| 755 ASSERT_TRUE(base::Delete(profile_1_shortcut_path, false)); | 759 ASSERT_TRUE(base::Delete(profile_1_shortcut_path, false)); |
| 756 ASSERT_FALSE(base::PathExists(profile_1_shortcut_path)); | 760 ASSERT_FALSE(base::PathExists(profile_1_shortcut_path)); |
| 757 ASSERT_TRUE(base::PathExists(profile_2_shortcut_path)); | 761 ASSERT_TRUE(base::PathExists(profile_2_shortcut_path)); |
| 758 | 762 |
| 759 const base::FilePath system_level_shortcut_path = | 763 const base::FilePath system_level_shortcut_path = |
| 760 CreateRegularSystemLevelShortcut(FROM_HERE); | 764 CreateRegularSystemLevelShortcut(FROM_HERE); |
| 761 | 765 |
| 762 // Delete the profile that has a shortcut, which will exercise the non-profile | 766 // Delete the profile that has a shortcut, which will exercise the non-profile |
| 763 // shortcut creation path in |DeleteDesktopShortcutsAndIconFile()|, which is | 767 // shortcut creation path in |DeleteDesktopShortcuts()|, which is |
| 764 // not covered by the |DeleteSecondToLastProfileWithSystemLevelShortcut| test. | 768 // not covered by the |DeleteSecondToLastProfileWithSystemLevelShortcut| test. |
| 765 profile_info_cache_->DeleteProfileFromCache(profile_2_path_); | 769 profile_info_cache_->DeleteProfileFromCache(profile_2_path_); |
| 766 RunPendingTasks(); | 770 RunPendingTasks(); |
| 767 | 771 |
| 768 // Verify that only the system-level shortcut still exists. | 772 // Verify that only the system-level shortcut still exists. |
| 769 EXPECT_TRUE(base::PathExists(system_level_shortcut_path)); | 773 EXPECT_TRUE(base::PathExists(system_level_shortcut_path)); |
| 770 EXPECT_FALSE(base::PathExists( | 774 EXPECT_FALSE(base::PathExists( |
| 771 GetDefaultShortcutPathForProfile(string16()))); | 775 GetDefaultShortcutPathForProfile(string16()))); |
| 772 EXPECT_FALSE(base::PathExists(profile_1_shortcut_path)); | 776 EXPECT_FALSE(base::PathExists(profile_1_shortcut_path)); |
| 773 EXPECT_FALSE(base::PathExists(profile_2_shortcut_path)); | 777 EXPECT_FALSE(base::PathExists(profile_2_shortcut_path)); |
| 774 } | 778 } |
| 779 |
| 780 TEST_F(ProfileShortcutManagerTest, CreateProfileIcon) { |
| 781 SetupDefaultProfileShortcut(FROM_HERE); |
| 782 |
| 783 const base::FilePath icon_path = |
| 784 profiles::internal::GetProfileIconPath(profile_1_path_); |
| 785 |
| 786 EXPECT_TRUE(base::PathExists(icon_path)); |
| 787 EXPECT_TRUE(base::Delete(icon_path, false)); |
| 788 EXPECT_FALSE(base::PathExists(icon_path)); |
| 789 |
| 790 profile_shortcut_manager_->CreateOrUpdateProfileIcon(profile_1_path_, |
| 791 base::Closure()); |
| 792 RunPendingTasks(); |
| 793 EXPECT_TRUE(base::PathExists(icon_path)); |
| 794 } |
| 795 |
| 796 TEST_F(ProfileShortcutManagerTest, UnbadgeProfileIconOnDeletion) { |
| 797 SetupDefaultProfileShortcut(FROM_HERE); |
| 798 const base::FilePath icon_path_1 = |
| 799 profiles::internal::GetProfileIconPath(profile_1_path_); |
| 800 const base::FilePath icon_path_2 = |
| 801 profiles::internal::GetProfileIconPath(profile_2_path_); |
| 802 |
| 803 // Default profile has unbadged icon to start. |
| 804 std::string unbadged_icon_1; |
| 805 EXPECT_TRUE(file_util::ReadFileToString(icon_path_1, &unbadged_icon_1)); |
| 806 |
| 807 // Creating a new profile adds a badge to both the new profile icon and the |
| 808 // default profile icon. Since they use the same icon index, the icon files |
| 809 // should be the same. |
| 810 CreateProfileWithShortcut(FROM_HERE, profile_2_name_, profile_2_path_); |
| 811 |
| 812 std::string badged_icon_1; |
| 813 EXPECT_TRUE(file_util::ReadFileToString(icon_path_1, &badged_icon_1)); |
| 814 std::string badged_icon_2; |
| 815 EXPECT_TRUE(file_util::ReadFileToString(icon_path_2, &badged_icon_2)); |
| 816 |
| 817 EXPECT_NE(badged_icon_1, unbadged_icon_1); |
| 818 EXPECT_EQ(badged_icon_1, badged_icon_2); |
| 819 |
| 820 // Deleting the default profile will unbadge the new profile's icon and should |
| 821 // result in an icon that is identical to the unbadged default profile icon. |
| 822 profile_info_cache_->DeleteProfileFromCache(profile_1_path_); |
| 823 RunPendingTasks(); |
| 824 |
| 825 std::string unbadged_icon_2; |
| 826 EXPECT_TRUE(file_util::ReadFileToString(icon_path_2, &unbadged_icon_2)); |
| 827 EXPECT_EQ(unbadged_icon_1, unbadged_icon_2); |
| 828 } |
| 829 |
| 830 TEST_F(ProfileShortcutManagerTest, ProfileIconOnAvatarChange) { |
| 831 SetupAndCreateTwoShortcuts(FROM_HERE); |
| 832 const base::FilePath icon_path_1 = |
| 833 profiles::internal::GetProfileIconPath(profile_1_path_); |
| 834 const base::FilePath icon_path_2 = |
| 835 profiles::internal::GetProfileIconPath(profile_2_path_); |
| 836 const size_t profile_index_1 = |
| 837 profile_info_cache_->GetIndexOfProfileWithPath(profile_1_path_); |
| 838 |
| 839 std::string badged_icon_1; |
| 840 EXPECT_TRUE(file_util::ReadFileToString(icon_path_1, &badged_icon_1)); |
| 841 std::string badged_icon_2; |
| 842 EXPECT_TRUE(file_util::ReadFileToString(icon_path_2, &badged_icon_2)); |
| 843 |
| 844 // Profile 1 and 2 are created with the same icon. |
| 845 EXPECT_EQ(badged_icon_1, badged_icon_2); |
| 846 |
| 847 // Change profile 1's icon. |
| 848 profile_info_cache_->SetAvatarIconOfProfileAtIndex(profile_index_1, 1); |
| 849 RunPendingTasks(); |
| 850 |
| 851 std::string new_badged_icon_1; |
| 852 EXPECT_TRUE(file_util::ReadFileToString(icon_path_1, &new_badged_icon_1)); |
| 853 EXPECT_NE(new_badged_icon_1, badged_icon_1); |
| 854 |
| 855 // Ensure the new icon is not the unbadged icon. |
| 856 profile_info_cache_->DeleteProfileFromCache(profile_2_path_); |
| 857 RunPendingTasks(); |
| 858 |
| 859 std::string unbadged_icon_1; |
| 860 EXPECT_TRUE(file_util::ReadFileToString(icon_path_1, &unbadged_icon_1)); |
| 861 EXPECT_NE(unbadged_icon_1, new_badged_icon_1); |
| 862 |
| 863 // Ensure the icon doesn't change on avatar change without 2 profiles. |
| 864 profile_info_cache_->SetAvatarIconOfProfileAtIndex(profile_index_1, 1); |
| 865 RunPendingTasks(); |
| 866 |
| 867 std::string unbadged_icon_1_a; |
| 868 EXPECT_TRUE(file_util::ReadFileToString(icon_path_1, &unbadged_icon_1_a)); |
| 869 EXPECT_EQ(unbadged_icon_1, unbadged_icon_1_a); |
| 870 } |
| OLD | NEW |