| 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/profiles/profile_shortcut_manager_win.h" | 5 #include "chrome/browser/profiles/profile_shortcut_manager_win.h" |
| 6 | 6 |
| 7 #include <shlobj.h> // For SHChangeNotify(). | 7 #include <shlobj.h> // For SHChangeNotify(). |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 #include <set> | 11 #include <set> |
| 12 #include <string> | 12 #include <string> |
| 13 #include <vector> | 13 #include <vector> |
| 14 | 14 |
| 15 #include "base/bind.h" | 15 #include "base/bind.h" |
| 16 #include "base/command_line.h" | 16 #include "base/command_line.h" |
| 17 #include "base/files/file_enumerator.h" | 17 #include "base/files/file_enumerator.h" |
| 18 #include "base/files/file_util.h" | 18 #include "base/files/file_util.h" |
| 19 #include "base/macros.h" | 19 #include "base/macros.h" |
| 20 #include "base/path_service.h" | 20 #include "base/path_service.h" |
| 21 #include "base/strings/string16.h" | 21 #include "base/strings/string16.h" |
| 22 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
| 23 #include "base/strings/stringprintf.h" | 23 #include "base/strings/stringprintf.h" |
| 24 #include "base/strings/utf_string_conversions.h" | 24 #include "base/strings/utf_string_conversions.h" |
| 25 #include "base/win/shortcut.h" | 25 #include "base/win/shortcut.h" |
| 26 #include "chrome/browser/app_icon_win.h" | 26 #include "chrome/browser/app_icon_win.h" |
| 27 #include "chrome/browser/browser_process.h" | 27 #include "chrome/browser/browser_process.h" |
| 28 #include "chrome/browser/chrome_notification_types.h" | 28 #include "chrome/browser/chrome_notification_types.h" |
| 29 #include "chrome/browser/profiles/profile_attributes_entry.h" | |
| 30 #include "chrome/browser/profiles/profile_attributes_storage.h" | |
| 31 #include "chrome/browser/profiles/profile_avatar_icon_util.h" | 29 #include "chrome/browser/profiles/profile_avatar_icon_util.h" |
| 30 #include "chrome/browser/profiles/profile_info_cache_observer.h" |
| 32 #include "chrome/browser/profiles/profile_manager.h" | 31 #include "chrome/browser/profiles/profile_manager.h" |
| 33 #include "chrome/browser/shell_integration_win.h" | 32 #include "chrome/browser/shell_integration_win.h" |
| 34 #include "chrome/common/chrome_switches.h" | 33 #include "chrome/common/chrome_switches.h" |
| 35 #include "chrome/common/pref_names.h" | 34 #include "chrome/common/pref_names.h" |
| 36 #include "chrome/grit/chromium_strings.h" | 35 #include "chrome/grit/chromium_strings.h" |
| 37 #include "chrome/installer/util/browser_distribution.h" | 36 #include "chrome/installer/util/browser_distribution.h" |
| 38 #include "chrome/installer/util/product.h" | 37 #include "chrome/installer/util/product.h" |
| 39 #include "chrome/installer/util/shell_util.h" | 38 #include "chrome/installer/util/shell_util.h" |
| 40 #include "components/prefs/pref_service.h" | 39 #include "components/prefs/pref_service.h" |
| 41 #include "content/public/browser/browser_thread.h" | 40 #include "content/public/browser/browser_thread.h" |
| (...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 | 797 |
| 799 ProfileShortcutManagerWin::ProfileShortcutManagerWin(ProfileManager* manager) | 798 ProfileShortcutManagerWin::ProfileShortcutManagerWin(ProfileManager* manager) |
| 800 : profile_manager_(manager) { | 799 : profile_manager_(manager) { |
| 801 DCHECK_EQ( | 800 DCHECK_EQ( |
| 802 arraysize(kProfileAvatarIconResources2x), | 801 arraysize(kProfileAvatarIconResources2x), |
| 803 profiles::GetDefaultAvatarIconCount()); | 802 profiles::GetDefaultAvatarIconCount()); |
| 804 | 803 |
| 805 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, | 804 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, |
| 806 content::NotificationService::AllSources()); | 805 content::NotificationService::AllSources()); |
| 807 | 806 |
| 808 profile_manager_->GetProfileAttributesStorage().AddObserver(this); | 807 profile_manager_->GetProfileInfoCache().AddObserver(this); |
| 809 } | 808 } |
| 810 | 809 |
| 811 ProfileShortcutManagerWin::~ProfileShortcutManagerWin() { | 810 ProfileShortcutManagerWin::~ProfileShortcutManagerWin() { |
| 812 profile_manager_->GetProfileAttributesStorage().RemoveObserver(this); | 811 profile_manager_->GetProfileInfoCache().RemoveObserver(this); |
| 813 } | 812 } |
| 814 | 813 |
| 815 void ProfileShortcutManagerWin::CreateOrUpdateProfileIcon( | 814 void ProfileShortcutManagerWin::CreateOrUpdateProfileIcon( |
| 816 const base::FilePath& profile_path) { | 815 const base::FilePath& profile_path) { |
| 817 CreateOrUpdateShortcutsForProfileAtPath(profile_path, | 816 CreateOrUpdateShortcutsForProfileAtPath(profile_path, |
| 818 CREATE_OR_UPDATE_ICON_ONLY, | 817 CREATE_OR_UPDATE_ICON_ONLY, |
| 819 IGNORE_NON_PROFILE_SHORTCUTS); | 818 IGNORE_NON_PROFILE_SHORTCUTS); |
| 820 } | 819 } |
| 821 | 820 |
| 822 void ProfileShortcutManagerWin::CreateProfileShortcut( | 821 void ProfileShortcutManagerWin::CreateProfileShortcut( |
| (...skipping 21 matching lines...) Expand all Loading... |
| 844 const base::FilePath& profile_path, | 843 const base::FilePath& profile_path, |
| 845 base::CommandLine* command_line, | 844 base::CommandLine* command_line, |
| 846 base::string16* name, | 845 base::string16* name, |
| 847 base::FilePath* icon_path) { | 846 base::FilePath* icon_path) { |
| 848 base::FilePath chrome_exe; | 847 base::FilePath chrome_exe; |
| 849 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 848 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { |
| 850 NOTREACHED(); | 849 NOTREACHED(); |
| 851 return; | 850 return; |
| 852 } | 851 } |
| 853 | 852 |
| 854 ProfileAttributesStorage& storage = | 853 const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); |
| 855 profile_manager_->GetProfileAttributesStorage(); | 854 size_t profile_index = cache.GetIndexOfProfileWithPath(profile_path); |
| 856 ProfileAttributesEntry* entry; | 855 DCHECK_LT(profile_index, cache.GetNumberOfProfiles()); |
| 857 bool has_entry = storage.GetProfileAttributesWithPath(profile_path, &entry); | |
| 858 DCHECK(has_entry); | |
| 859 | 856 |
| 860 // The used profile name should be empty if there is only 1 profile. | 857 // The used profile name should be empty if there is only 1 profile. |
| 861 base::string16 shortcut_profile_name; | 858 base::string16 shortcut_profile_name; |
| 862 if (storage.GetNumberOfProfiles() > 1u) | 859 if (cache.GetNumberOfProfiles() > 1) |
| 863 shortcut_profile_name = entry->GetName(); | 860 shortcut_profile_name = cache.GetNameOfProfileAtIndex(profile_index); |
| 864 | 861 |
| 865 *name = base::FilePath(profiles::internal::GetShortcutFilenameForProfile( | 862 *name = base::FilePath(profiles::internal::GetShortcutFilenameForProfile( |
| 866 shortcut_profile_name, | 863 shortcut_profile_name, |
| 867 BrowserDistribution::GetDistribution())).RemoveExtension().value(); | 864 BrowserDistribution::GetDistribution())).RemoveExtension().value(); |
| 868 | 865 |
| 869 command_line->ParseFromString(L"\"" + chrome_exe.value() + L"\" " + | 866 command_line->ParseFromString(L"\"" + chrome_exe.value() + L"\" " + |
| 870 profiles::internal::CreateProfileShortcutFlags(profile_path)); | 867 profiles::internal::CreateProfileShortcutFlags(profile_path)); |
| 871 | 868 |
| 872 *icon_path = profiles::internal::GetProfileIconPath(profile_path); | 869 *icon_path = profiles::internal::GetProfileIconPath(profile_path); |
| 873 } | 870 } |
| 874 | 871 |
| 875 void ProfileShortcutManagerWin::OnProfileAdded( | 872 void ProfileShortcutManagerWin::OnProfileAdded( |
| 876 const base::FilePath& profile_path) { | 873 const base::FilePath& profile_path) { |
| 877 CreateOrUpdateProfileIcon(profile_path); | 874 CreateOrUpdateProfileIcon(profile_path); |
| 878 if (profile_manager_->GetProfileAttributesStorage().GetNumberOfProfiles() == | 875 if (profile_manager_->GetProfileInfoCache().GetNumberOfProfiles() == 2) { |
| 879 2u) { | |
| 880 // When the second profile is added, make existing non-profile shortcuts | 876 // When the second profile is added, make existing non-profile shortcuts |
| 881 // point to the first profile and be badged/named appropriately. | 877 // point to the first profile and be badged/named appropriately. |
| 882 CreateOrUpdateShortcutsForProfileAtPath(GetOtherProfilePath(profile_path), | 878 CreateOrUpdateShortcutsForProfileAtPath(GetOtherProfilePath(profile_path), |
| 883 UPDATE_EXISTING_ONLY, | 879 UPDATE_EXISTING_ONLY, |
| 884 UPDATE_NON_PROFILE_SHORTCUTS); | 880 UPDATE_NON_PROFILE_SHORTCUTS); |
| 885 } | 881 } |
| 886 } | 882 } |
| 887 | 883 |
| 888 void ProfileShortcutManagerWin::OnProfileWasRemoved( | 884 void ProfileShortcutManagerWin::OnProfileWasRemoved( |
| 889 const base::FilePath& profile_path, | 885 const base::FilePath& profile_path, |
| 890 const base::string16& profile_name) { | 886 const base::string16& profile_name) { |
| 891 ProfileAttributesStorage& storage = | 887 const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); |
| 892 profile_manager_->GetProfileAttributesStorage(); | |
| 893 // If there is only one profile remaining, remove the badging information | 888 // If there is only one profile remaining, remove the badging information |
| 894 // from an existing shortcut. | 889 // from an existing shortcut. |
| 895 const bool deleting_down_to_last_profile = | 890 const bool deleting_down_to_last_profile = (cache.GetNumberOfProfiles() == 1); |
| 896 (storage.GetNumberOfProfiles() == 1u); | |
| 897 if (deleting_down_to_last_profile) { | 891 if (deleting_down_to_last_profile) { |
| 898 // This is needed to unbadge the icon. | 892 // This is needed to unbadge the icon. |
| 899 CreateOrUpdateShortcutsForProfileAtPath( | 893 CreateOrUpdateShortcutsForProfileAtPath(cache.GetPathOfProfileAtIndex(0), |
| 900 storage.GetAllProfilesAttributes().front()->GetPath(), | 894 UPDATE_EXISTING_ONLY, |
| 901 UPDATE_EXISTING_ONLY, | 895 IGNORE_NON_PROFILE_SHORTCUTS); |
| 902 IGNORE_NON_PROFILE_SHORTCUTS); | |
| 903 } | 896 } |
| 904 | 897 |
| 905 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 898 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 906 base::Bind(&DeleteDesktopShortcuts, | 899 base::Bind(&DeleteDesktopShortcuts, |
| 907 profile_path, | 900 profile_path, |
| 908 deleting_down_to_last_profile)); | 901 deleting_down_to_last_profile)); |
| 909 } | 902 } |
| 910 | 903 |
| 911 void ProfileShortcutManagerWin::OnProfileNameChanged( | 904 void ProfileShortcutManagerWin::OnProfileNameChanged( |
| 912 const base::FilePath& profile_path, | 905 const base::FilePath& profile_path, |
| 913 const base::string16& old_profile_name) { | 906 const base::string16& old_profile_name) { |
| 914 CreateOrUpdateShortcutsForProfileAtPath(profile_path, UPDATE_EXISTING_ONLY, | 907 CreateOrUpdateShortcutsForProfileAtPath(profile_path, UPDATE_EXISTING_ONLY, |
| 915 IGNORE_NON_PROFILE_SHORTCUTS); | 908 IGNORE_NON_PROFILE_SHORTCUTS); |
| 916 } | 909 } |
| 917 | 910 |
| 918 void ProfileShortcutManagerWin::OnProfileAvatarChanged( | 911 void ProfileShortcutManagerWin::OnProfileAvatarChanged( |
| 919 const base::FilePath& profile_path) { | 912 const base::FilePath& profile_path) { |
| 920 CreateOrUpdateProfileIcon(profile_path); | 913 CreateOrUpdateProfileIcon(profile_path); |
| 921 } | 914 } |
| 922 | 915 |
| 923 base::FilePath ProfileShortcutManagerWin::GetOtherProfilePath( | 916 base::FilePath ProfileShortcutManagerWin::GetOtherProfilePath( |
| 924 const base::FilePath& profile_path) { | 917 const base::FilePath& profile_path) { |
| 925 const ProfileAttributesStorage& storage = | 918 const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); |
| 926 profile_manager_->GetProfileAttributesStorage(); | 919 DCHECK_EQ(2U, cache.GetNumberOfProfiles()); |
| 927 DCHECK_EQ(2u, storage.GetNumberOfProfiles()); | |
| 928 // Get the index of the current profile, in order to find the index of the | 920 // Get the index of the current profile, in order to find the index of the |
| 929 // other profile. | 921 // other profile. |
| 930 std::vector<ProfileAttributesEntry*> entries = g_browser_process-> | 922 size_t current_profile_index = cache.GetIndexOfProfileWithPath(profile_path); |
| 931 profile_manager()->GetProfileAttributesStorage(). | 923 size_t other_profile_index = (current_profile_index == 0) ? 1 : 0; |
| 932 GetAllProfilesAttributes(); | 924 return cache.GetPathOfProfileAtIndex(other_profile_index); |
| 933 for (ProfileAttributesEntry* entry : entries) { | |
| 934 base::FilePath path = entry->GetPath(); | |
| 935 if (path != profile_path) | |
| 936 return path; | |
| 937 } | |
| 938 NOTREACHED(); | |
| 939 return base::FilePath(); | |
| 940 } | 925 } |
| 941 | 926 |
| 942 void ProfileShortcutManagerWin::CreateOrUpdateShortcutsForProfileAtPath( | 927 void ProfileShortcutManagerWin::CreateOrUpdateShortcutsForProfileAtPath( |
| 943 const base::FilePath& profile_path, | 928 const base::FilePath& profile_path, |
| 944 CreateOrUpdateMode create_mode, | 929 CreateOrUpdateMode create_mode, |
| 945 NonProfileShortcutAction action) { | 930 NonProfileShortcutAction action) { |
| 946 DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::UI) || | 931 DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::UI) || |
| 947 BrowserThread::CurrentlyOn(BrowserThread::UI)); | 932 BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 948 CreateOrUpdateShortcutsParams params(profile_path, create_mode, action); | 933 CreateOrUpdateShortcutsParams params(profile_path, create_mode, action); |
| 949 | 934 |
| 950 ProfileAttributesStorage& storage = | 935 ProfileInfoCache* cache = &profile_manager_->GetProfileInfoCache(); |
| 951 profile_manager_->GetProfileAttributesStorage(); | 936 size_t profile_index = cache->GetIndexOfProfileWithPath(profile_path); |
| 952 ProfileAttributesEntry* entry; | 937 if (profile_index == std::string::npos) |
| 953 bool has_entry = storage.GetProfileAttributesWithPath(profile_path, &entry); | |
| 954 if (!has_entry) | |
| 955 return; | 938 return; |
| 956 bool remove_badging = (storage.GetNumberOfProfiles() == 1u); | 939 bool remove_badging = cache->GetNumberOfProfiles() == 1; |
| 957 | 940 |
| 958 params.old_profile_name = | 941 params.old_profile_name = |
| 959 entry->GetShortcutName(); | 942 cache->GetShortcutNameOfProfileAtIndex(profile_index); |
| 960 | 943 |
| 961 // Exit early if the mode is to update existing profile shortcuts only and | 944 // Exit early if the mode is to update existing profile shortcuts only and |
| 962 // none were ever created for this profile, per the shortcut name not being | 945 // none were ever created for this profile, per the shortcut name not being |
| 963 // set in the profile attributes storage. | 946 // set in the profile info cache. |
| 964 if (params.old_profile_name.empty() && | 947 if (params.old_profile_name.empty() && |
| 965 create_mode == UPDATE_EXISTING_ONLY && | 948 create_mode == UPDATE_EXISTING_ONLY && |
| 966 action == IGNORE_NON_PROFILE_SHORTCUTS) { | 949 action == IGNORE_NON_PROFILE_SHORTCUTS) { |
| 967 return; | 950 return; |
| 968 } | 951 } |
| 969 | 952 |
| 970 if (!remove_badging) { | 953 if (!remove_badging) { |
| 971 params.profile_name = entry->GetName(); | 954 params.profile_name = cache->GetNameOfProfileAtIndex(profile_index); |
| 972 | 955 |
| 973 // The profile might be using the Gaia avatar, which is not in the | 956 // The profile might be using the Gaia avatar, which is not in the |
| 974 // resources array. | 957 // resources array. |
| 975 bool has_gaia_image = false; | 958 bool has_gaia_image = false; |
| 976 if (entry->IsUsingGAIAPicture()) { | 959 if (cache->IsUsingGAIAPictureOfProfileAtIndex(profile_index)) { |
| 977 const gfx::Image* image = entry->GetGAIAPicture(); | 960 const gfx::Image* image = |
| 961 cache->GetGAIAPictureOfProfileAtIndex(profile_index); |
| 978 if (image) { | 962 if (image) { |
| 979 params.avatar_image_1x = GetSkBitmapCopy(*image); | 963 params.avatar_image_1x = GetSkBitmapCopy(*image); |
| 980 // Gaia images are 256px, which makes them big enough to use in the | 964 // Gaia images are 256px, which makes them big enough to use in the |
| 981 // large icon case as well. | 965 // large icon case as well. |
| 982 DCHECK_GE(image->Width(), IconUtil::kLargeIconSize); | 966 DCHECK_GE(image->Width(), IconUtil::kLargeIconSize); |
| 983 params.avatar_image_2x = params.avatar_image_1x; | 967 params.avatar_image_2x = params.avatar_image_1x; |
| 984 has_gaia_image = true; | 968 has_gaia_image = true; |
| 985 } | 969 } |
| 986 } | 970 } |
| 987 | 971 |
| 988 // If the profile isn't using a Gaia image, or if the Gaia image did not | 972 // If the profile isn't using a Gaia image, or if the Gaia image did not |
| 989 // exist, revert to the previously used avatar icon. | 973 // exist, revert to the previously used avatar icon. |
| 990 if (!has_gaia_image) { | 974 if (!has_gaia_image) { |
| 991 const size_t icon_index = entry->GetAvatarIconIndex(); | 975 const size_t icon_index = |
| 976 cache->GetAvatarIconIndexOfProfileAtIndex(profile_index); |
| 992 const int resource_id_1x = | 977 const int resource_id_1x = |
| 993 profiles::GetDefaultAvatarIconResourceIDAtIndex(icon_index); | 978 profiles::GetDefaultAvatarIconResourceIDAtIndex(icon_index); |
| 994 const int resource_id_2x = kProfileAvatarIconResources2x[icon_index]; | 979 const int resource_id_2x = kProfileAvatarIconResources2x[icon_index]; |
| 995 // Make a copy of the SkBitmaps to ensure that we can safely use the image | 980 // Make a copy of the SkBitmaps to ensure that we can safely use the image |
| 996 // data on the FILE thread. | 981 // data on the FILE thread. |
| 997 params.avatar_image_1x = GetImageResourceSkBitmapCopy(resource_id_1x); | 982 params.avatar_image_1x = GetImageResourceSkBitmapCopy(resource_id_1x); |
| 998 params.avatar_image_2x = GetImageResourceSkBitmapCopy(resource_id_2x); | 983 params.avatar_image_2x = GetImageResourceSkBitmapCopy(resource_id_2x); |
| 999 } | 984 } |
| 1000 } | 985 } |
| 1001 BrowserThread::PostTask( | 986 BrowserThread::PostTask( |
| 1002 BrowserThread::FILE, FROM_HERE, | 987 BrowserThread::FILE, FROM_HERE, |
| 1003 base::Bind(&CreateOrUpdateDesktopShortcutsAndIconForProfile, params)); | 988 base::Bind(&CreateOrUpdateDesktopShortcutsAndIconForProfile, params)); |
| 1004 | 989 |
| 1005 entry->SetShortcutName(params.profile_name); | 990 cache->SetShortcutNameOfProfileAtIndex(profile_index, |
| 991 params.profile_name); |
| 1006 } | 992 } |
| 1007 | 993 |
| 1008 void ProfileShortcutManagerWin::Observe( | 994 void ProfileShortcutManagerWin::Observe( |
| 1009 int type, | 995 int type, |
| 1010 const content::NotificationSource& source, | 996 const content::NotificationSource& source, |
| 1011 const content::NotificationDetails& details) { | 997 const content::NotificationDetails& details) { |
| 1012 switch (type) { | 998 switch (type) { |
| 1013 // This notification is triggered when a profile is loaded. | 999 // This notification is triggered when a profile is loaded. |
| 1014 case chrome::NOTIFICATION_PROFILE_CREATED: { | 1000 case chrome::NOTIFICATION_PROFILE_CREATED: { |
| 1015 Profile* profile = | 1001 Profile* profile = |
| 1016 content::Source<Profile>(source).ptr()->GetOriginalProfile(); | 1002 content::Source<Profile>(source).ptr()->GetOriginalProfile(); |
| 1017 if (profile->GetPrefs()->GetInteger(prefs::kProfileIconVersion) < | 1003 if (profile->GetPrefs()->GetInteger(prefs::kProfileIconVersion) < |
| 1018 kCurrentProfileIconVersion) { | 1004 kCurrentProfileIconVersion) { |
| 1019 // Ensure the profile's icon file has been created. | 1005 // Ensure the profile's icon file has been created. |
| 1020 CreateOrUpdateProfileIcon(profile->GetPath()); | 1006 CreateOrUpdateProfileIcon(profile->GetPath()); |
| 1021 } | 1007 } |
| 1022 break; | 1008 break; |
| 1023 } | 1009 } |
| 1024 default: | 1010 default: |
| 1025 NOTREACHED(); | 1011 NOTREACHED(); |
| 1026 break; | 1012 break; |
| 1027 } | 1013 } |
| 1028 } | 1014 } |
| OLD | NEW |