| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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 #include "chrome/browser/chromeos/login/user_image_sync_observer.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/prefs/pref_change_registrar.h" | |
| 9 #include "base/prefs/scoped_user_pref_update.h" | |
| 10 #include "chrome/browser/browser_process.h" | |
| 11 #include "chrome/browser/chrome_notification_types.h" | |
| 12 #include "chrome/browser/chromeos/login/default_user_images.h" | |
| 13 #include "chrome/browser/chromeos/login/screens/user_image_screen.h" | |
| 14 #include "chrome/browser/chromeos/login/user.h" | |
| 15 #include "chrome/browser/chromeos/login/user_image_manager.h" | |
| 16 #include "chrome/browser/chromeos/login/wizard_controller.h" | |
| 17 #include "chrome/browser/chromeos/profiles/profile_helper.h" | |
| 18 #include "chrome/browser/prefs/pref_service_syncable.h" | |
| 19 #include "chrome/browser/profiles/profile.h" | |
| 20 #include "chrome/browser/profiles/profile_manager.h" | |
| 21 #include "chrome/common/pref_names.h" | |
| 22 #include "content/public/browser/notification_registrar.h" | |
| 23 #include "content/public/browser/notification_service.h" | |
| 24 | |
| 25 namespace chromeos { | |
| 26 namespace { | |
| 27 | |
| 28 // A dictionary containing info about user image. | |
| 29 const char kUserImageInfo[] = "user_image_info"; | |
| 30 // Path to value with image index. | |
| 31 const char kImageIndex[] = "image_index"; | |
| 32 | |
| 33 bool IsIndexSupported(int index) { | |
| 34 return (index >= kFirstDefaultImageIndex && index < kDefaultImagesCount) || | |
| 35 (index == User::kProfileImageIndex); | |
| 36 } | |
| 37 | |
| 38 Profile* GetUserProfile() { | |
| 39 ProfileManager* profile_manager = g_browser_process->profile_manager(); | |
| 40 if (!profile_manager || !profile_manager->IsLoggedIn()) | |
| 41 return NULL; | |
| 42 base::FilePath profile_path = profile_manager->user_data_dir().Append( | |
| 43 profile_manager->GetInitialProfileDir()); | |
| 44 return profile_manager->GetProfileByPath(profile_path); | |
| 45 } | |
| 46 | |
| 47 } // anonymous namespace | |
| 48 | |
| 49 UserImageSyncObserver::Observer::~Observer() {} | |
| 50 | |
| 51 UserImageSyncObserver::UserImageSyncObserver(const User* user) | |
| 52 : user_(user), | |
| 53 prefs_(NULL), | |
| 54 is_synced_(false), | |
| 55 local_image_changed_(false) { | |
| 56 notification_registrar_.reset(new content::NotificationRegistrar); | |
| 57 notification_registrar_->Add(this, | |
| 58 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED, | |
| 59 content::NotificationService::AllSources()); | |
| 60 Profile* profile = GetUserProfile(); | |
| 61 if (profile) { | |
| 62 OnProfileGained(profile); | |
| 63 } else { | |
| 64 notification_registrar_->Add(this, | |
| 65 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, | |
| 66 content::NotificationService::AllSources()); | |
| 67 } | |
| 68 } | |
| 69 | |
| 70 UserImageSyncObserver::~UserImageSyncObserver() { | |
| 71 if (!is_synced_ && prefs_) | |
| 72 prefs_->RemoveObserver(this); | |
| 73 if (pref_change_registrar_) | |
| 74 pref_change_registrar_->RemoveAll(); | |
| 75 } | |
| 76 | |
| 77 // static | |
| 78 void UserImageSyncObserver::RegisterProfilePrefs( | |
| 79 user_prefs::PrefRegistrySyncable* registry_) { | |
| 80 registry_->RegisterDictionaryPref( | |
| 81 kUserImageInfo, | |
| 82 user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF); | |
| 83 } | |
| 84 | |
| 85 void UserImageSyncObserver::AddObserver(Observer* observer) { | |
| 86 observer_list_.AddObserver(observer); | |
| 87 } | |
| 88 | |
| 89 void UserImageSyncObserver::RemoveObserver(Observer* observer) { | |
| 90 observer_list_.RemoveObserver(observer); | |
| 91 } | |
| 92 | |
| 93 void UserImageSyncObserver::OnProfileGained(Profile* profile) { | |
| 94 prefs_ = PrefServiceSyncable::FromProfile(profile); | |
| 95 pref_change_registrar_.reset(new PrefChangeRegistrar); | |
| 96 pref_change_registrar_->Init(prefs_); | |
| 97 pref_change_registrar_->Add(kUserImageInfo, | |
| 98 base::Bind(&UserImageSyncObserver::OnPreferenceChanged, | |
| 99 base::Unretained(this))); | |
| 100 is_synced_ = prefs_->IsPrioritySyncing(); | |
| 101 if (!is_synced_) { | |
| 102 prefs_->AddObserver(this); | |
| 103 } else { | |
| 104 OnInitialSync(); | |
| 105 } | |
| 106 } | |
| 107 | |
| 108 void UserImageSyncObserver::OnInitialSync() { | |
| 109 int synced_index; | |
| 110 bool local_image_updated = false; | |
| 111 if (!GetSyncedImageIndex(&synced_index) || local_image_changed_) { | |
| 112 UpdateSyncedImageFromLocal(); | |
| 113 } else if (IsIndexSupported(synced_index) && CanUpdateLocalImageNow()) { | |
| 114 UpdateLocalImageFromSynced(); | |
| 115 local_image_updated = true; | |
| 116 } | |
| 117 FOR_EACH_OBSERVER(UserImageSyncObserver::Observer, observer_list_, | |
| 118 OnInitialSync(local_image_updated)); | |
| 119 } | |
| 120 | |
| 121 void UserImageSyncObserver::OnPreferenceChanged(const std::string& pref_name) { | |
| 122 // OnPreferenceChanged can be called before OnIsSyncingChanged. | |
| 123 if (!is_synced_) { | |
| 124 is_synced_ = true; | |
| 125 prefs_->RemoveObserver(this); | |
| 126 OnInitialSync(); | |
| 127 } else if (CanUpdateLocalImageNow()) { | |
| 128 UpdateLocalImageFromSynced(); | |
| 129 } | |
| 130 } | |
| 131 | |
| 132 void UserImageSyncObserver::Observe( | |
| 133 int type, | |
| 134 const content::NotificationSource& source, | |
| 135 const content::NotificationDetails& details) { | |
| 136 if (type == chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED) { | |
| 137 Profile* profile = content::Details<Profile>(details).ptr(); | |
| 138 if (GetUserProfile() != profile) | |
| 139 return; | |
| 140 notification_registrar_->Remove( | |
| 141 this, | |
| 142 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, | |
| 143 content::NotificationService::AllSources()); | |
| 144 OnProfileGained(profile); | |
| 145 } else if (type == chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED) { | |
| 146 if (is_synced_) | |
| 147 UpdateSyncedImageFromLocal(); | |
| 148 else | |
| 149 local_image_changed_ = true; | |
| 150 } else { | |
| 151 NOTREACHED(); | |
| 152 } | |
| 153 } | |
| 154 | |
| 155 void UserImageSyncObserver::OnIsSyncingChanged() { | |
| 156 is_synced_ = prefs_->IsPrioritySyncing(); | |
| 157 if (is_synced_) { | |
| 158 prefs_->RemoveObserver(this); | |
| 159 OnInitialSync(); | |
| 160 } | |
| 161 } | |
| 162 | |
| 163 void UserImageSyncObserver::UpdateSyncedImageFromLocal() { | |
| 164 int local_index = user_->image_index(); | |
| 165 if (!IsIndexSupported(local_index)) { | |
| 166 local_index = User::kInvalidImageIndex; | |
| 167 } | |
| 168 int synced_index; | |
| 169 if (GetSyncedImageIndex(&synced_index) && (synced_index == local_index)) | |
| 170 return; | |
| 171 DictionaryPrefUpdate update(prefs_, kUserImageInfo); | |
| 172 base::DictionaryValue* dict = update.Get(); | |
| 173 dict->SetInteger(kImageIndex, local_index); | |
| 174 VLOG(1) << "Saved avatar index " << local_index << " to sync."; | |
| 175 } | |
| 176 | |
| 177 void UserImageSyncObserver::UpdateLocalImageFromSynced() { | |
| 178 int synced_index; | |
| 179 GetSyncedImageIndex(&synced_index); | |
| 180 int local_index = user_->image_index(); | |
| 181 if ((synced_index == local_index) || !IsIndexSupported(synced_index)) | |
| 182 return; | |
| 183 UserImageManager* image_manager = | |
| 184 UserManager::Get()->GetUserImageManager(user_->email()); | |
| 185 if (synced_index == User::kProfileImageIndex) { | |
| 186 image_manager->SaveUserImageFromProfileImage(); | |
| 187 } else { | |
| 188 image_manager->SaveUserDefaultImageIndex(synced_index); | |
| 189 } | |
| 190 VLOG(1) << "Loaded avatar index " << synced_index << " from sync."; | |
| 191 } | |
| 192 | |
| 193 bool UserImageSyncObserver::GetSyncedImageIndex(int* index) { | |
| 194 *index = User::kInvalidImageIndex; | |
| 195 const base::DictionaryValue* dict = prefs_->GetDictionary(kUserImageInfo); | |
| 196 return dict && dict->GetInteger(kImageIndex, index); | |
| 197 } | |
| 198 | |
| 199 bool UserImageSyncObserver::CanUpdateLocalImageNow() { | |
| 200 if (WizardController* wizard_controller = | |
| 201 WizardController::default_controller()) { | |
| 202 UserImageScreen* screen = wizard_controller->GetUserImageScreen(); | |
| 203 if (wizard_controller->current_screen() == screen) { | |
| 204 if (screen->user_selected_image()) | |
| 205 return false; | |
| 206 } | |
| 207 } | |
| 208 return true; | |
| 209 } | |
| 210 | |
| 211 } // namespace chromeos | |
| 212 | |
| OLD | NEW |