1 // Copyright 2015 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_PROFILES_PROFILE_ATTRIBUTES_STORAGE_H_ 6 #define CHROME_BROWSER_PROFILES_PROFILE_ATTRIBUTES_STORAGE_H_ 7 8 #include <stddef.h> 9 10 #include <memory> 11 #include <string> 12 #include <unordered_map> 13 #include <vector> 14 15 #include "base/callback_forward.h" 16 #include "base/files/file_path.h" 17 #include "base/gtest_prod_util.h" 18 #include "base/memory/weak_ptr.h" 19 #include "base/observer_list.h" 20 #include "base/strings/string16.h" 21 #include "build/build_config.h" 22 #include "chrome/browser/profiles/profile_attributes_entry.h" 23 #include "chrome/browser/profiles/profile_info_cache_observer.h" 24 25 namespace base { 26 class SequencedTaskRunner; 27 } 28 29 namespace gfx { 30 class Image; 31 } 32 33 class AccountId; 34 class PrefService; 35 class ProfileAttributesEntry; 36 class ProfileAvatarDownloader; 37 38 class ProfileAttributesStorage 39 : public base::SupportsWeakPtr<ProfileAttributesStorage> { 40 public: 41 using Observer = ProfileInfoCacheObserver; 42 43 explicit ProfileAttributesStorage(PrefService* prefs); 44 ProfileAttributesStorage(const ProfileAttributesStorage&) = delete; 45 ProfileAttributesStorage& operator=(const ProfileAttributesStorage&) = delete; 46 virtual ~ProfileAttributesStorage(); 47 48 // If the |supervised_user_id| is non-empty, the profile will be marked to be 49 // omitted from the avatar-menu list on desktop versions. This is used while a 50 // supervised user is in the process of being registered with the server. Use 51 // ProfileAttributesEntry::SetIsOmitted() to clear the flag when the profile 52 // is ready to be shown in the menu. 53 virtual void AddProfile(const base::FilePath& profile_path, 54 const base::string16& name, 55 const std::string& gaia_id, 56 const base::string16& user_name, 57 bool is_consented_primary_account, 58 size_t icon_index, 59 const std::string& supervised_user_id, 60 const AccountId& account_id) = 0; 61 62 // Removes the profile matching given |account_id| from this storage. 63 // Calculates profile path and calls RemoveProfile() on it. 64 virtual void RemoveProfileByAccountId(const AccountId& account_id) = 0; 65 66 // Removes the profile at |profile_path| from this storage. Does not delete or 67 // affect the actual profile's data. 68 virtual void RemoveProfile(const base::FilePath& profile_path) = 0; 69 70 // Returns a vector containing one attributes entry per known profile. They 71 // are not sorted in any particular order. 72 std::vector<ProfileAttributesEntry*> GetAllProfilesAttributes(); 73 std::vector<ProfileAttributesEntry*> GetAllProfilesAttributesSortedByName(); 74 75 // Populates |entry| with the data for the profile at |path| and returns true 76 // if the operation is successful and |entry| can be used. Returns false 77 // otherwise. 78 // |entry| should not be cached as it may not reflect subsequent changes to 79 // the profile's metadata. 80 virtual bool GetProfileAttributesWithPath( 81 const base::FilePath& path, ProfileAttributesEntry** entry) = 0; 82 83 // Returns the count of known profiles. 84 virtual size_t GetNumberOfProfiles() const = 0; 85 86 // Returns a unique name that can be assigned to a newly created profile. 87 base::string16 ChooseNameForNewProfile(size_t icon_index) const; 88 89 // Determines whether |name| is one of the default assigned names. 90 // On Desktop, if |include_check_for_legacy_profile_name| is false, 91 // |IsDefaultProfileName()| would only return true if the |name| is in the 92 // form of |Person %n| which is the new default local profile name. If 93 // |include_check_for_legacy_profile_name| is true, we will also check if name 94 // is one of the legacy profile names (e.g. Saratoga, Default user, ..). 95 // For other platforms, so far |include_check_for_legacy_profile_name| 96 // is not used. 97 bool IsDefaultProfileName(const base::string16& name, 98 bool include_check_for_legacy_profile_name) const; 99 100 #if !defined(OS_ANDROID) 101 // Records statistics about a profile `entry` that is being deleted. If the 102 // profile has opened browser window(s) in the moment of deletion, this 103 // function must be called before these windows get closed. 104 void RecordDeletedProfileState(ProfileAttributesEntry* entry); 105 #endif 106 107 // Records statistics about profiles as would be visible in the profile picker 108 // (if we would display it in this moment). 109 void RecordProfilesState(); 110 111 // Returns an avatar icon index that can be assigned to a newly created 112 // profile. Note that the icon may not be unique since there are a limited 113 // set of default icons. 114 size_t ChooseAvatarIconIndexForNewProfile() const; 115 116 // Returns the decoded image at |image_path|. Used both by the GAIA profile 117 // image and the high res avatars. 118 const gfx::Image* LoadAvatarPictureFromPath( 119 const base::FilePath& profile_path, 120 const std::string& key, 121 const base::FilePath& image_path) const; 122 123 // Checks whether the high res avatar at index |icon_index| exists, and if it 124 // does not, calls |DownloadHighResAvatar|. 125 void DownloadHighResAvatarIfNeeded(size_t icon_index, 126 const base::FilePath& profile_path); 127 128 void AddObserver(Observer* observer); 129 void RemoveObserver(Observer* observer); 130 GetDisableAvatarDownloadForTesting()131 bool GetDisableAvatarDownloadForTesting() { 132 return disable_avatar_download_for_testing_; 133 } 134 set_disable_avatar_download_for_testing(bool disable_avatar_download_for_testing)135 void set_disable_avatar_download_for_testing( 136 bool disable_avatar_download_for_testing) { 137 disable_avatar_download_for_testing_ = disable_avatar_download_for_testing; 138 } 139 140 // Notifies observers. The following methods are accessed by 141 // ProfileAttributesEntry. 142 void NotifyOnProfileAvatarChanged(const base::FilePath& profile_path) const; 143 144 // Disables the periodic reporting of profile metrics, as this is causing 145 // tests to time out. DisableProfileMetricsForTesting()146 virtual void DisableProfileMetricsForTesting() {} 147 148 protected: 149 FRIEND_TEST_ALL_PREFIXES(ProfileInfoCacheTest, EntriesInAttributesStorage); 150 FRIEND_TEST_ALL_PREFIXES(ProfileAttributesStorageTest, 151 DownloadHighResAvatarTest); 152 FRIEND_TEST_ALL_PREFIXES(ProfileAttributesStorageTest, 153 NothingToDownloadHighResAvatarTest); 154 155 // Starts downloading the high res avatar at index |icon_index| for profile 156 // with path |profile_path|. 157 void DownloadHighResAvatar(size_t icon_index, 158 const base::FilePath& profile_path); 159 160 // Saves the avatar |image| at |image_path|. This is used both for the GAIA 161 // profile pictures and the ProfileAvatarDownloader that is used to download 162 // the high res avatars. 163 void SaveAvatarImageAtPath(const base::FilePath& profile_path, 164 gfx::Image image, 165 const std::string& key, 166 const base::FilePath& image_path, 167 base::OnceClosure callback); 168 169 PrefService* const prefs_; 170 mutable std::unordered_map<base::FilePath::StringType, 171 std::unique_ptr<ProfileAttributesEntry>> 172 profile_attributes_entries_; 173 174 mutable base::ObserverList<Observer>::Unchecked observer_list_; 175 176 // A cache of gaia/high res avatar profile pictures. This cache is updated 177 // lazily so it needs to be mutable. 178 mutable std::unordered_map<std::string, gfx::Image> cached_avatar_images_; 179 180 // Marks a profile picture as loading from disk. This prevents a picture from 181 // loading multiple times. 182 mutable std::unordered_map<std::string, bool> cached_avatar_images_loading_; 183 184 // Hash table of profile pictures currently being downloaded from the remote 185 // location and the ProfileAvatarDownloader instances downloading them. 186 // This prevents a picture from being downloaded multiple times. The 187 // ProfileAvatarDownloader instances are deleted when the download completes 188 // or when the ProfileInfoCache is destroyed. 189 std::unordered_map<std::string, std::unique_ptr<ProfileAvatarDownloader>> 190 avatar_images_downloads_in_progress_; 191 192 // Determines of the ProfileAvatarDownloader should be created and executed 193 // or not. Only set to true for tests. 194 bool disable_avatar_download_for_testing_ = false; 195 196 // Task runner used for file operation on avatar images. 197 scoped_refptr<base::SequencedTaskRunner> file_task_runner_; 198 199 private: 200 // Called when the picture given by |key| has been loaded from disk and 201 // decoded into |image|. 202 void OnAvatarPictureLoaded(const base::FilePath& profile_path, 203 const std::string& key, 204 gfx::Image image) const; 205 206 // Called when the picture given by |file_name| has been saved to disk. Used 207 // both for the GAIA profile picture and the high res avatar files. 208 void OnAvatarPictureSaved(const std::string& file_name, 209 const base::FilePath& profile_path, 210 base::OnceClosure callback, 211 bool success) const; 212 213 // Helper function that calls SaveAvatarImageAtPath without a callback. 214 void SaveAvatarImageAtPathNoCallback(const base::FilePath& profile_path, 215 gfx::Image image, 216 const std::string& key, 217 const base::FilePath& image_path); 218 219 // Notifies observers. 220 void NotifyOnProfileHighResAvatarLoaded( 221 const base::FilePath& profile_path) const; 222 }; 223 224 #endif // CHROME_BROWSER_PROFILES_PROFILE_ATTRIBUTES_STORAGE_H_ 225