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 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/files/file_enumerator.h" | 14 #include "base/files/file_enumerator.h" |
15 #include "base/files/file_util.h" | 15 #include "base/files/file_util.h" |
16 #include "base/path_service.h" | 16 #include "base/path_service.h" |
17 #include "base/prefs/pref_service.h" | 17 #include "base/prefs/pref_service.h" |
18 #include "base/strings/string16.h" | 18 #include "base/strings/string16.h" |
19 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
20 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
21 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
22 #include "base/win/shortcut.h" | 22 #include "base/win/shortcut.h" |
23 #include "chrome/browser/app_icon_win.h" | 23 #include "chrome/browser/app_icon_win.h" |
24 #include "chrome/browser/browser_process.h" | 24 #include "chrome/browser/browser_process.h" |
25 #include "chrome/browser/chrome_notification_types.h" | 25 #include "chrome/browser/chrome_notification_types.h" |
26 #include "chrome/browser/profiles/profile_attributes_entry.h" | |
27 #include "chrome/browser/profiles/profile_attributes_storage.h" | |
26 #include "chrome/browser/profiles/profile_avatar_icon_util.h" | 28 #include "chrome/browser/profiles/profile_avatar_icon_util.h" |
27 #include "chrome/browser/profiles/profile_info_cache_observer.h" | 29 #include "chrome/browser/profiles/profile_info_cache_observer.h" |
28 #include "chrome/browser/profiles/profile_manager.h" | 30 #include "chrome/browser/profiles/profile_manager.h" |
29 #include "chrome/browser/shell_integration.h" | 31 #include "chrome/browser/shell_integration.h" |
30 #include "chrome/common/chrome_switches.h" | 32 #include "chrome/common/chrome_switches.h" |
31 #include "chrome/common/pref_names.h" | 33 #include "chrome/common/pref_names.h" |
32 #include "chrome/grit/chromium_strings.h" | 34 #include "chrome/grit/chromium_strings.h" |
33 #include "chrome/installer/util/browser_distribution.h" | 35 #include "chrome/installer/util/browser_distribution.h" |
34 #include "chrome/installer/util/product.h" | 36 #include "chrome/installer/util/product.h" |
35 #include "chrome/installer/util/shell_util.h" | 37 #include "chrome/installer/util/shell_util.h" |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
657 | 659 |
658 ProfileShortcutManagerWin::ProfileShortcutManagerWin(ProfileManager* manager) | 660 ProfileShortcutManagerWin::ProfileShortcutManagerWin(ProfileManager* manager) |
659 : profile_manager_(manager) { | 661 : profile_manager_(manager) { |
660 DCHECK_EQ( | 662 DCHECK_EQ( |
661 arraysize(kProfileAvatarIconResources2x), | 663 arraysize(kProfileAvatarIconResources2x), |
662 profiles::GetDefaultAvatarIconCount()); | 664 profiles::GetDefaultAvatarIconCount()); |
663 | 665 |
664 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, | 666 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, |
665 content::NotificationService::AllSources()); | 667 content::NotificationService::AllSources()); |
666 | 668 |
667 profile_manager_->GetProfileInfoCache().AddObserver(this); | 669 profile_manager_->GetProfileAttributesStorage().AddObserver(this); |
668 } | 670 } |
669 | 671 |
670 ProfileShortcutManagerWin::~ProfileShortcutManagerWin() { | 672 ProfileShortcutManagerWin::~ProfileShortcutManagerWin() { |
671 profile_manager_->GetProfileInfoCache().RemoveObserver(this); | 673 profile_manager_->GetProfileAttributesStorage().RemoveObserver(this); |
672 } | 674 } |
673 | 675 |
674 void ProfileShortcutManagerWin::CreateOrUpdateProfileIcon( | 676 void ProfileShortcutManagerWin::CreateOrUpdateProfileIcon( |
675 const base::FilePath& profile_path) { | 677 const base::FilePath& profile_path) { |
676 CreateOrUpdateShortcutsForProfileAtPath(profile_path, | 678 CreateOrUpdateShortcutsForProfileAtPath(profile_path, |
677 CREATE_OR_UPDATE_ICON_ONLY, | 679 CREATE_OR_UPDATE_ICON_ONLY, |
678 IGNORE_NON_PROFILE_SHORTCUTS); | 680 IGNORE_NON_PROFILE_SHORTCUTS); |
679 } | 681 } |
680 | 682 |
681 void ProfileShortcutManagerWin::CreateProfileShortcut( | 683 void ProfileShortcutManagerWin::CreateProfileShortcut( |
(...skipping 21 matching lines...) Expand all Loading... | |
703 const base::FilePath& profile_path, | 705 const base::FilePath& profile_path, |
704 base::CommandLine* command_line, | 706 base::CommandLine* command_line, |
705 base::string16* name, | 707 base::string16* name, |
706 base::FilePath* icon_path) { | 708 base::FilePath* icon_path) { |
707 base::FilePath chrome_exe; | 709 base::FilePath chrome_exe; |
708 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 710 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { |
709 NOTREACHED(); | 711 NOTREACHED(); |
710 return; | 712 return; |
711 } | 713 } |
712 | 714 |
713 const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); | 715 ProfileAttributesStorage& storage = |
714 size_t profile_index = cache.GetIndexOfProfileWithPath(profile_path); | 716 profile_manager_->GetProfileAttributesStorage(); |
715 DCHECK_LT(profile_index, cache.GetNumberOfProfiles()); | 717 ProfileAttributesEntry* entry; |
718 if (!storage.GetProfileAttributesWithPath(profile_path, &entry)) { | |
Mike Lerman
2015/08/06 16:06:20
Isn't this equivalent to DCHECK(storage.GetProfile
| |
719 NOTREACHED(); | |
720 return; | |
721 } | |
716 | 722 |
717 // The used profile name should be empty if there is only 1 profile. | 723 // The used profile name should be empty if there is only 1 profile. |
718 base::string16 shortcut_profile_name; | 724 base::string16 shortcut_profile_name; |
719 if (cache.GetNumberOfProfiles() > 1) | 725 if (storage.GetNumberOfProfiles() > 1) |
720 shortcut_profile_name = cache.GetNameOfProfileAtIndex(profile_index); | 726 shortcut_profile_name = entry->GetName(); |
721 | 727 |
722 *name = base::FilePath(profiles::internal::GetShortcutFilenameForProfile( | 728 *name = base::FilePath(profiles::internal::GetShortcutFilenameForProfile( |
723 shortcut_profile_name, | 729 shortcut_profile_name, |
724 BrowserDistribution::GetDistribution())).RemoveExtension().value(); | 730 BrowserDistribution::GetDistribution())).RemoveExtension().value(); |
725 | 731 |
726 command_line->ParseFromString(L"\"" + chrome_exe.value() + L"\" " + | 732 command_line->ParseFromString(L"\"" + chrome_exe.value() + L"\" " + |
727 profiles::internal::CreateProfileShortcutFlags(profile_path)); | 733 profiles::internal::CreateProfileShortcutFlags(profile_path)); |
728 | 734 |
729 *icon_path = profiles::internal::GetProfileIconPath(profile_path); | 735 *icon_path = profiles::internal::GetProfileIconPath(profile_path); |
730 } | 736 } |
731 | 737 |
732 void ProfileShortcutManagerWin::OnProfileAdded( | 738 void ProfileShortcutManagerWin::OnProfileAdded( |
733 const base::FilePath& profile_path) { | 739 const base::FilePath& profile_path) { |
734 CreateOrUpdateProfileIcon(profile_path); | 740 CreateOrUpdateProfileIcon(profile_path); |
735 if (profile_manager_->GetProfileInfoCache().GetNumberOfProfiles() == 2) { | 741 if (profile_manager_->GetProfileAttributesStorage(). |
742 GetNumberOfProfiles() == 2) { | |
736 // When the second profile is added, make existing non-profile shortcuts | 743 // When the second profile is added, make existing non-profile shortcuts |
737 // point to the first profile and be badged/named appropriately. | 744 // point to the first profile and be badged/named appropriately. |
738 CreateOrUpdateShortcutsForProfileAtPath(GetOtherProfilePath(profile_path), | 745 CreateOrUpdateShortcutsForProfileAtPath(GetOtherProfilePath(profile_path), |
739 UPDATE_EXISTING_ONLY, | 746 UPDATE_EXISTING_ONLY, |
740 UPDATE_NON_PROFILE_SHORTCUTS); | 747 UPDATE_NON_PROFILE_SHORTCUTS); |
741 } | 748 } |
742 } | 749 } |
743 | 750 |
744 void ProfileShortcutManagerWin::OnProfileWasRemoved( | 751 void ProfileShortcutManagerWin::OnProfileWasRemoved( |
745 const base::FilePath& profile_path, | 752 const base::FilePath& profile_path, |
746 const base::string16& profile_name) { | 753 const base::string16& profile_name) { |
747 const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); | 754 ProfileAttributesStorage& storage = |
755 profile_manager_->GetProfileAttributesStorage(); | |
748 // If there is only one profile remaining, remove the badging information | 756 // If there is only one profile remaining, remove the badging information |
749 // from an existing shortcut. | 757 // from an existing shortcut. |
750 const bool deleting_down_to_last_profile = (cache.GetNumberOfProfiles() == 1); | 758 const bool deleting_down_to_last_profile = storage.GetNumberOfProfiles() == 1; |
759 | |
751 if (deleting_down_to_last_profile) { | 760 if (deleting_down_to_last_profile) { |
761 // The remaining profile should be the last one still in |storage|. | |
762 std::vector<ProfileAttributesEntry*> entries = | |
763 storage.GetAllProfilesAttributes(); | |
764 DCHECK_EQ(1U, entries.size()); | |
Mike Lerman
2015/08/06 16:06:20
We're only in this condition if NumberOfProfiles()
| |
752 // This is needed to unbadge the icon. | 765 // This is needed to unbadge the icon. |
753 CreateOrUpdateShortcutsForProfileAtPath(cache.GetPathOfProfileAtIndex(0), | 766 CreateOrUpdateShortcutsForProfileAtPath(entries[0]->GetPath(), |
754 UPDATE_EXISTING_ONLY, | 767 UPDATE_EXISTING_ONLY, |
755 IGNORE_NON_PROFILE_SHORTCUTS); | 768 IGNORE_NON_PROFILE_SHORTCUTS); |
756 } | 769 } |
757 | 770 |
758 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 771 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
759 base::Bind(&DeleteDesktopShortcuts, | 772 base::Bind(&DeleteDesktopShortcuts, |
760 profile_path, | 773 profile_path, |
761 deleting_down_to_last_profile)); | 774 deleting_down_to_last_profile)); |
762 } | 775 } |
763 | 776 |
764 void ProfileShortcutManagerWin::OnProfileNameChanged( | 777 void ProfileShortcutManagerWin::OnProfileNameChanged( |
765 const base::FilePath& profile_path, | 778 const base::FilePath& profile_path, |
766 const base::string16& old_profile_name) { | 779 const base::string16& old_profile_name) { |
767 CreateOrUpdateShortcutsForProfileAtPath(profile_path, UPDATE_EXISTING_ONLY, | 780 CreateOrUpdateShortcutsForProfileAtPath(profile_path, UPDATE_EXISTING_ONLY, |
768 IGNORE_NON_PROFILE_SHORTCUTS); | 781 IGNORE_NON_PROFILE_SHORTCUTS); |
769 } | 782 } |
770 | 783 |
771 void ProfileShortcutManagerWin::OnProfileAvatarChanged( | 784 void ProfileShortcutManagerWin::OnProfileAvatarChanged( |
772 const base::FilePath& profile_path) { | 785 const base::FilePath& profile_path) { |
773 CreateOrUpdateProfileIcon(profile_path); | 786 CreateOrUpdateProfileIcon(profile_path); |
774 } | 787 } |
775 | 788 |
776 base::FilePath ProfileShortcutManagerWin::GetOtherProfilePath( | 789 base::FilePath ProfileShortcutManagerWin::GetOtherProfilePath( |
777 const base::FilePath& profile_path) { | 790 const base::FilePath& profile_path) { |
778 const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); | 791 ProfileAttributesStorage& storage = |
779 DCHECK_EQ(2U, cache.GetNumberOfProfiles()); | 792 profile_manager_->GetProfileAttributesStorage(); |
793 DCHECK_EQ(2U, storage.GetNumberOfProfiles()); | |
780 // Get the index of the current profile, in order to find the index of the | 794 // Get the index of the current profile, in order to find the index of the |
781 // other profile. | 795 // other profile. |
782 size_t current_profile_index = cache.GetIndexOfProfileWithPath(profile_path); | 796 ProfileAttributesEntry* current_entry; |
Mike Lerman
2015/08/06 16:06:20
I don't think you need all the extra checks. I thi
| |
783 size_t other_profile_index = (current_profile_index == 0) ? 1 : 0; | 797 if (!storage.GetProfileAttributesWithPath(profile_path, ¤t_entry)) { |
784 return cache.GetPathOfProfileAtIndex(other_profile_index); | 798 NOTREACHED(); |
799 return base::FilePath(); | |
800 } | |
801 | |
802 std::vector<ProfileAttributesEntry*> entries = | |
803 storage.GetAllProfilesAttributes(); | |
804 DCHECK_EQ(2U, entries.size()); | |
Mike Lerman
2015/08/06 16:06:20
you checked number of profiles == 2 at line 793, d
| |
805 ProfileAttributesEntry* other_entry = | |
806 entries[0]->GetPath() == current_entry->GetPath() ? | |
807 entries[1] : entries[0]; | |
808 return other_entry->GetPath(); | |
785 } | 809 } |
786 | 810 |
787 void ProfileShortcutManagerWin::CreateOrUpdateShortcutsForProfileAtPath( | 811 void ProfileShortcutManagerWin::CreateOrUpdateShortcutsForProfileAtPath( |
788 const base::FilePath& profile_path, | 812 const base::FilePath& profile_path, |
789 CreateOrUpdateMode create_mode, | 813 CreateOrUpdateMode create_mode, |
790 NonProfileShortcutAction action) { | 814 NonProfileShortcutAction action) { |
791 DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::UI) || | 815 DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::UI) || |
792 BrowserThread::CurrentlyOn(BrowserThread::UI)); | 816 BrowserThread::CurrentlyOn(BrowserThread::UI)); |
793 CreateOrUpdateShortcutsParams params(profile_path, create_mode, action); | 817 CreateOrUpdateShortcutsParams params(profile_path, create_mode, action); |
794 | 818 |
795 ProfileInfoCache* cache = &profile_manager_->GetProfileInfoCache(); | 819 ProfileAttributesStorage& storage = |
796 size_t profile_index = cache->GetIndexOfProfileWithPath(profile_path); | 820 profile_manager_->GetProfileAttributesStorage(); |
797 if (profile_index == std::string::npos) | 821 ProfileAttributesEntry* entry; |
822 if (!storage.GetProfileAttributesWithPath(profile_path, &entry)) { | |
Mike Lerman
2015/08/06 16:06:20
{ curlies }?
| |
798 return; | 823 return; |
799 bool remove_badging = cache->GetNumberOfProfiles() == 1; | 824 } |
825 bool remove_badging = storage.GetNumberOfProfiles() == 1; | |
800 | 826 |
801 params.old_profile_name = | 827 params.old_profile_name = entry->GetShortcutName(); |
802 cache->GetShortcutNameOfProfileAtIndex(profile_index); | |
803 | 828 |
804 // Exit early if the mode is to update existing profile shortcuts only and | 829 // Exit early if the mode is to update existing profile shortcuts only and |
805 // none were ever created for this profile, per the shortcut name not being | 830 // none were ever created for this profile, per the shortcut name not being |
806 // set in the profile info cache. | 831 // set in the profile info cache. |
807 if (params.old_profile_name.empty() && | 832 if (params.old_profile_name.empty() && |
808 create_mode == UPDATE_EXISTING_ONLY && | 833 create_mode == UPDATE_EXISTING_ONLY && |
809 action == IGNORE_NON_PROFILE_SHORTCUTS) { | 834 action == IGNORE_NON_PROFILE_SHORTCUTS) { |
810 return; | 835 return; |
811 } | 836 } |
812 | 837 |
813 if (!remove_badging) { | 838 if (!remove_badging) { |
814 params.profile_name = cache->GetNameOfProfileAtIndex(profile_index); | 839 params.profile_name = entry->GetName(); |
815 | 840 |
816 // The profile might be using the Gaia avatar, which is not in the | 841 // The profile might be using the Gaia avatar, which is not in the |
817 // resources array. | 842 // resources array. |
818 bool has_gaia_image = false; | 843 bool has_gaia_image = false; |
819 if (cache->IsUsingGAIAPictureOfProfileAtIndex(profile_index)) { | 844 if (entry->IsUsingGAIAPicture()) { |
820 const gfx::Image* image = | 845 const gfx::Image* image = entry->GetGAIAPicture(); |
821 cache->GetGAIAPictureOfProfileAtIndex(profile_index); | |
822 if (image) { | 846 if (image) { |
823 params.avatar_image_1x = GetSkBitmapCopy(*image); | 847 params.avatar_image_1x = GetSkBitmapCopy(*image); |
824 // Gaia images are 256px, which makes them big enough to use in the | 848 // Gaia images are 256px, which makes them big enough to use in the |
825 // large icon case as well. | 849 // large icon case as well. |
826 DCHECK_GE(image->Width(), IconUtil::kLargeIconSize); | 850 DCHECK_GE(image->Width(), IconUtil::kLargeIconSize); |
827 params.avatar_image_2x = params.avatar_image_1x; | 851 params.avatar_image_2x = params.avatar_image_1x; |
828 has_gaia_image = true; | 852 has_gaia_image = true; |
829 } | 853 } |
830 } | 854 } |
831 | 855 |
832 // If the profile isn't using a Gaia image, or if the Gaia image did not | 856 // If the profile isn't using a Gaia image, or if the Gaia image did not |
833 // exist, revert to the previously used avatar icon. | 857 // exist, revert to the previously used avatar icon. |
834 if (!has_gaia_image) { | 858 if (!has_gaia_image) { |
835 const size_t icon_index = | 859 const size_t icon_index = entry->GetAvatarIconIndex(); |
836 cache->GetAvatarIconIndexOfProfileAtIndex(profile_index); | |
837 const int resource_id_1x = | 860 const int resource_id_1x = |
838 profiles::GetDefaultAvatarIconResourceIDAtIndex(icon_index); | 861 profiles::GetDefaultAvatarIconResourceIDAtIndex(icon_index); |
839 const int resource_id_2x = kProfileAvatarIconResources2x[icon_index]; | 862 const int resource_id_2x = kProfileAvatarIconResources2x[icon_index]; |
840 // Make a copy of the SkBitmaps to ensure that we can safely use the image | 863 // Make a copy of the SkBitmaps to ensure that we can safely use the image |
841 // data on the FILE thread. | 864 // data on the FILE thread. |
842 params.avatar_image_1x = GetImageResourceSkBitmapCopy(resource_id_1x); | 865 params.avatar_image_1x = GetImageResourceSkBitmapCopy(resource_id_1x); |
843 params.avatar_image_2x = GetImageResourceSkBitmapCopy(resource_id_2x); | 866 params.avatar_image_2x = GetImageResourceSkBitmapCopy(resource_id_2x); |
844 } | 867 } |
845 } | 868 } |
846 BrowserThread::PostTask( | 869 BrowserThread::PostTask( |
847 BrowserThread::FILE, FROM_HERE, | 870 BrowserThread::FILE, FROM_HERE, |
848 base::Bind(&CreateOrUpdateDesktopShortcutsAndIconForProfile, params)); | 871 base::Bind(&CreateOrUpdateDesktopShortcutsAndIconForProfile, params)); |
849 | 872 |
850 cache->SetShortcutNameOfProfileAtIndex(profile_index, | 873 entry->SetShortcutName(params.profile_name); |
851 params.profile_name); | |
852 } | 874 } |
853 | 875 |
854 void ProfileShortcutManagerWin::Observe( | 876 void ProfileShortcutManagerWin::Observe( |
855 int type, | 877 int type, |
856 const content::NotificationSource& source, | 878 const content::NotificationSource& source, |
857 const content::NotificationDetails& details) { | 879 const content::NotificationDetails& details) { |
858 switch (type) { | 880 switch (type) { |
859 // This notification is triggered when a profile is loaded. | 881 // This notification is triggered when a profile is loaded. |
860 case chrome::NOTIFICATION_PROFILE_CREATED: { | 882 case chrome::NOTIFICATION_PROFILE_CREATED: { |
861 Profile* profile = | 883 Profile* profile = |
862 content::Source<Profile>(source).ptr()->GetOriginalProfile(); | 884 content::Source<Profile>(source).ptr()->GetOriginalProfile(); |
863 if (profile->GetPrefs()->GetInteger(prefs::kProfileIconVersion) < | 885 if (profile->GetPrefs()->GetInteger(prefs::kProfileIconVersion) < |
864 kCurrentProfileIconVersion) { | 886 kCurrentProfileIconVersion) { |
865 // Ensure the profile's icon file has been created. | 887 // Ensure the profile's icon file has been created. |
866 CreateOrUpdateProfileIcon(profile->GetPath()); | 888 CreateOrUpdateProfileIcon(profile->GetPath()); |
867 } | 889 } |
868 break; | 890 break; |
869 } | 891 } |
870 default: | 892 default: |
871 NOTREACHED(); | 893 NOTREACHED(); |
872 break; | 894 break; |
873 } | 895 } |
874 } | 896 } |
OLD | NEW |