| 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/chromeos/login/screens/user_image_screen.h" | 5 #include "chrome/browser/chromeos/login/screens/user_image_screen.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 #include "third_party/skia/include/core/SkBitmap.h" | 41 #include "third_party/skia/include/core/SkBitmap.h" |
| 42 #include "ui/base/webui/web_ui_util.h" | 42 #include "ui/base/webui/web_ui_util.h" |
| 43 #include "ui/gfx/image/image_skia.h" | 43 #include "ui/gfx/image/image_skia.h" |
| 44 | 44 |
| 45 using content::BrowserThread; | 45 using content::BrowserThread; |
| 46 | 46 |
| 47 namespace chromeos { | 47 namespace chromeos { |
| 48 | 48 |
| 49 namespace { | 49 namespace { |
| 50 | 50 |
| 51 constexpr const char kContextKeyIsCameraPresent[] = "isCameraPresent"; |
| 52 constexpr const char kContextKeyProfilePictureDataURL[] = |
| 53 "profilePictureDataURL"; |
| 54 constexpr const char kContextKeySelectedImageURL[] = "selectedImageURL"; |
| 55 constexpr const char kContextKeyHasGaiaAccount[] = "hasGaiaAccount"; |
| 56 |
| 51 // Time histogram suffix for profile image download. | 57 // Time histogram suffix for profile image download. |
| 52 const char kProfileDownloadReason[] = "OOBE"; | 58 const char kProfileDownloadReason[] = "OOBE"; |
| 53 | 59 |
| 54 // Maximum amount of time to wait for the user image to sync. | 60 // Maximum amount of time to wait for the user image to sync. |
| 55 // The screen is shown iff sync failed or time limit exceeded. | 61 // The screen is shown iff sync failed or time limit exceeded. |
| 56 const int kSyncTimeoutSeconds = 10; | 62 const int kSyncTimeoutSeconds = 10; |
| 57 | 63 |
| 58 } // namespace | 64 } // namespace |
| 59 | 65 |
| 60 // static | 66 // static |
| 61 UserImageScreen* UserImageScreen::Get(ScreenManager* manager) { | 67 UserImageScreen* UserImageScreen::Get(ScreenManager* manager) { |
| 62 return static_cast<UserImageScreen*>( | 68 return static_cast<UserImageScreen*>( |
| 63 manager->GetScreen(OobeScreen::SCREEN_USER_IMAGE_PICKER)); | 69 manager->GetScreen(OobeScreen::SCREEN_USER_IMAGE_PICKER)); |
| 64 } | 70 } |
| 65 | 71 |
| 66 UserImageScreen::UserImageScreen(BaseScreenDelegate* base_screen_delegate, | 72 UserImageScreen::UserImageScreen(BaseScreenDelegate* base_screen_delegate, |
| 67 UserImageView* view) | 73 UserImageView* view) |
| 68 : UserImageModel(base_screen_delegate), | 74 : BaseScreen(base_screen_delegate, OobeScreen::SCREEN_USER_IMAGE_PICKER), |
| 69 view_(view), | 75 view_(view) { |
| 70 accept_photo_after_decoding_(false), | |
| 71 selected_image_(user_manager::User::USER_IMAGE_INVALID), | |
| 72 is_screen_ready_(false), | |
| 73 user_has_selected_image_(false) { | |
| 74 if (view_) | 76 if (view_) |
| 75 view_->Bind(*this); | 77 view_->Bind(this); |
| 76 user_manager::UserManager::Get()->AddObserver(this); | 78 user_manager::UserManager::Get()->AddObserver(this); |
| 77 GetContextEditor().SetString(kContextKeyProfilePictureDataURL, std::string()); | 79 GetContextEditor().SetString(kContextKeyProfilePictureDataURL, std::string()); |
| 78 } | 80 } |
| 79 | 81 |
| 80 UserImageScreen::~UserImageScreen() { | 82 UserImageScreen::~UserImageScreen() { |
| 81 user_manager::UserManager::Get()->RemoveObserver(this); | 83 user_manager::UserManager::Get()->RemoveObserver(this); |
| 82 CameraPresenceNotifier::GetInstance()->RemoveObserver(this); | 84 CameraPresenceNotifier::GetInstance()->RemoveObserver(this); |
| 83 if (view_) | 85 if (view_) |
| 84 view_->Unbind(); | 86 view_->Unbind(); |
| 85 } | 87 } |
| 86 | 88 |
| 87 void UserImageScreen::OnScreenReady() { | 89 void UserImageScreen::OnScreenReady() { |
| 88 is_screen_ready_ = true; | 90 is_screen_ready_ = true; |
| 89 if (!IsWaitingForSync()) | 91 if (!IsWaitingForSync()) |
| 90 HideCurtain(); | 92 HideCurtain(); |
| 91 } | 93 } |
| 92 | 94 |
| 93 void UserImageScreen::OnPhotoTaken(const std::string& raw_data) { | 95 void UserImageScreen::OnPhotoTaken(const std::string& raw_data) { |
| 94 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 96 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 95 user_photo_ = gfx::ImageSkia(); | 97 user_photo_ = gfx::ImageSkia(); |
| 96 ImageDecoder::Cancel(this); | 98 ImageDecoder::Cancel(this); |
| 97 ImageDecoder::Start(this, raw_data); | 99 ImageDecoder::Start(this, raw_data); |
| 98 } | 100 } |
| 99 | 101 |
| 100 void UserImageScreen::OnCameraPresenceCheckDone(bool is_camera_present) { | |
| 101 GetContextEditor().SetBoolean(kContextKeyIsCameraPresent, is_camera_present); | |
| 102 } | |
| 103 | |
| 104 void UserImageScreen::HideCurtain() { | |
| 105 // Skip user image selection for ephemeral users. | |
| 106 if (user_manager::UserManager::Get()->IsUserNonCryptohomeDataEphemeral( | |
| 107 GetUser()->GetAccountId())) { | |
| 108 ExitScreen(); | |
| 109 } | |
| 110 if (view_) | |
| 111 view_->HideCurtain(); | |
| 112 } | |
| 113 | |
| 114 void UserImageScreen::OnImageDecoded(const SkBitmap& decoded_image) { | |
| 115 user_photo_ = gfx::ImageSkia::CreateFrom1xBitmap(decoded_image); | |
| 116 if (accept_photo_after_decoding_) | |
| 117 OnImageAccepted(); | |
| 118 } | |
| 119 | |
| 120 void UserImageScreen::OnDecodeImageFailed() { | |
| 121 NOTREACHED() << "Failed to decode PNG image from WebUI"; | |
| 122 } | |
| 123 | |
| 124 void UserImageScreen::OnInitialSync(bool local_image_updated) { | |
| 125 DCHECK(sync_timer_); | |
| 126 ReportSyncResult(SyncResult::SUCCEEDED); | |
| 127 if (!local_image_updated) { | |
| 128 sync_timer_.reset(); | |
| 129 GetSyncObserver()->RemoveObserver(this); | |
| 130 if (is_screen_ready_) | |
| 131 HideCurtain(); | |
| 132 return; | |
| 133 } | |
| 134 ExitScreen(); | |
| 135 } | |
| 136 | |
| 137 void UserImageScreen::OnSyncTimeout() { | |
| 138 ReportSyncResult(SyncResult::TIMED_OUT); | |
| 139 sync_timer_.reset(); | |
| 140 GetSyncObserver()->RemoveObserver(this); | |
| 141 if (is_screen_ready_) | |
| 142 HideCurtain(); | |
| 143 } | |
| 144 | |
| 145 bool UserImageScreen::IsWaitingForSync() const { | |
| 146 return sync_timer_.get() && sync_timer_->IsRunning(); | |
| 147 } | |
| 148 | |
| 149 void UserImageScreen::OnUserImagePolicyChanged(const base::Value* previous, | |
| 150 const base::Value* current) { | |
| 151 if (current) { | |
| 152 base::ThreadTaskRunnerHandle::Get()->DeleteSoon( | |
| 153 FROM_HERE, policy_registrar_.release()); | |
| 154 ExitScreen(); | |
| 155 } | |
| 156 } | |
| 157 | |
| 158 void UserImageScreen::OnImageSelected(const std::string& image_type, | 102 void UserImageScreen::OnImageSelected(const std::string& image_type, |
| 159 const std::string& image_url, | 103 const std::string& image_url, |
| 160 bool is_user_selection) { | 104 bool is_user_selection) { |
| 161 if (is_user_selection) { | 105 if (is_user_selection) { |
| 162 user_has_selected_image_ = true; | 106 user_has_selected_image_ = true; |
| 163 } | 107 } |
| 164 if (image_url.empty()) | 108 if (image_url.empty()) |
| 165 return; | 109 return; |
| 166 int user_image_index = user_manager::User::USER_IMAGE_INVALID; | 110 int user_image_index = user_manager::User::USER_IMAGE_INVALID; |
| 167 if (image_type == "default" && | 111 if (image_type == "default" && |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 default_user_image::GetDefaultImageHistogramValue(selected_image_); | 146 default_user_image::GetDefaultImageHistogramValue(selected_image_); |
| 203 break; | 147 break; |
| 204 } | 148 } |
| 205 if (user_has_selected_image_) { | 149 if (user_has_selected_image_) { |
| 206 UMA_HISTOGRAM_ENUMERATION("UserImage.FirstTimeChoice", uma_index, | 150 UMA_HISTOGRAM_ENUMERATION("UserImage.FirstTimeChoice", uma_index, |
| 207 default_user_image::kHistogramImagesCount); | 151 default_user_image::kHistogramImagesCount); |
| 208 } | 152 } |
| 209 ExitScreen(); | 153 ExitScreen(); |
| 210 } | 154 } |
| 211 | 155 |
| 212 const user_manager::User* UserImageScreen::GetUser() { | 156 void UserImageScreen::OnViewDestroyed(UserImageView* view) { |
| 213 return user_manager::UserManager::Get()->GetActiveUser(); | 157 if (view_ == view) |
| 214 } | 158 view_ = nullptr; |
| 215 | |
| 216 UserImageManager* UserImageScreen::GetUserImageManager() { | |
| 217 return ChromeUserManager::Get()->GetUserImageManager( | |
| 218 GetUser()->GetAccountId()); | |
| 219 } | |
| 220 | |
| 221 UserImageSyncObserver* UserImageScreen::GetSyncObserver() { | |
| 222 return GetUserImageManager()->GetSyncObserver(); | |
| 223 } | 159 } |
| 224 | 160 |
| 225 void UserImageScreen::Show() { | 161 void UserImageScreen::Show() { |
| 226 if (!view_) | 162 if (!view_) |
| 227 return; | 163 return; |
| 228 | 164 |
| 229 DCHECK(!policy_registrar_); | 165 DCHECK(!policy_registrar_); |
| 230 if (Profile* profile = ProfileHelper::Get()->GetProfileByUser(GetUser())) { | 166 if (Profile* profile = ProfileHelper::Get()->GetProfileByUser(GetUser())) { |
| 231 policy::PolicyService* policy_service = | 167 policy::PolicyService* policy_service = |
| 232 policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile) | 168 policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile) |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 CameraPresenceNotifier::GetInstance()->RemoveObserver(this); | 230 CameraPresenceNotifier::GetInstance()->RemoveObserver(this); |
| 295 user_manager::UserManager::Get()->RemoveObserver(this); | 231 user_manager::UserManager::Get()->RemoveObserver(this); |
| 296 policy_registrar_.reset(); | 232 policy_registrar_.reset(); |
| 297 sync_timer_.reset(); | 233 sync_timer_.reset(); |
| 298 if (UserImageSyncObserver* sync_observer = GetSyncObserver()) | 234 if (UserImageSyncObserver* sync_observer = GetSyncObserver()) |
| 299 sync_observer->RemoveObserver(this); | 235 sync_observer->RemoveObserver(this); |
| 300 if (view_) | 236 if (view_) |
| 301 view_->Hide(); | 237 view_->Hide(); |
| 302 } | 238 } |
| 303 | 239 |
| 304 void UserImageScreen::OnViewDestroyed(UserImageView* view) { | 240 void UserImageScreen::OnCameraPresenceCheckDone(bool is_camera_present) { |
| 305 if (view_ == view) | 241 GetContextEditor().SetBoolean(kContextKeyIsCameraPresent, is_camera_present); |
| 306 view_ = nullptr; | 242 } |
| 243 |
| 244 void UserImageScreen::OnImageDecoded(const SkBitmap& decoded_image) { |
| 245 user_photo_ = gfx::ImageSkia::CreateFrom1xBitmap(decoded_image); |
| 246 if (accept_photo_after_decoding_) |
| 247 OnImageAccepted(); |
| 248 } |
| 249 |
| 250 void UserImageScreen::OnDecodeImageFailed() { |
| 251 NOTREACHED() << "Failed to decode PNG image from WebUI"; |
| 307 } | 252 } |
| 308 | 253 |
| 309 void UserImageScreen::OnUserImageChanged(const user_manager::User& user) { | 254 void UserImageScreen::OnUserImageChanged(const user_manager::User& user) { |
| 310 GetContextEditor().SetString( | 255 GetContextEditor().SetString( |
| 311 kContextKeySelectedImageURL, | 256 kContextKeySelectedImageURL, |
| 312 default_user_image::GetDefaultImageUrl(GetUser()->image_index())); | 257 default_user_image::GetDefaultImageUrl(GetUser()->image_index())); |
| 313 } | 258 } |
| 314 | 259 |
| 315 void UserImageScreen::OnUserProfileImageUpdateFailed( | 260 void UserImageScreen::OnUserProfileImageUpdateFailed( |
| 316 const user_manager::User& user) { | 261 const user_manager::User& user) { |
| 317 // User has a default profile image or fetching profile image has failed. | 262 // User has a default profile image or fetching profile image has failed. |
| 318 GetContextEditor().SetString(kContextKeyProfilePictureDataURL, std::string()); | 263 GetContextEditor().SetString(kContextKeyProfilePictureDataURL, std::string()); |
| 319 } | 264 } |
| 320 | 265 |
| 321 void UserImageScreen::OnUserProfileImageUpdated( | 266 void UserImageScreen::OnUserProfileImageUpdated( |
| 322 const user_manager::User& user, | 267 const user_manager::User& user, |
| 323 const gfx::ImageSkia& profile_image) { | 268 const gfx::ImageSkia& profile_image) { |
| 324 // We've got a new profile image. | 269 // We've got a new profile image. |
| 325 GetContextEditor().SetString( | 270 GetContextEditor().SetString( |
| 326 kContextKeyProfilePictureDataURL, | 271 kContextKeyProfilePictureDataURL, |
| 327 webui::GetBitmapDataUrl(*profile_image.bitmap())); | 272 webui::GetBitmapDataUrl(*profile_image.bitmap())); |
| 328 } | 273 } |
| 329 | 274 |
| 275 void UserImageScreen::OnInitialSync(bool local_image_updated) { |
| 276 DCHECK(sync_timer_); |
| 277 ReportSyncResult(SyncResult::SUCCEEDED); |
| 278 if (!local_image_updated) { |
| 279 sync_timer_.reset(); |
| 280 GetSyncObserver()->RemoveObserver(this); |
| 281 if (is_screen_ready_) |
| 282 HideCurtain(); |
| 283 return; |
| 284 } |
| 285 ExitScreen(); |
| 286 } |
| 287 |
| 288 void UserImageScreen::OnSyncTimeout() { |
| 289 ReportSyncResult(SyncResult::TIMED_OUT); |
| 290 sync_timer_.reset(); |
| 291 GetSyncObserver()->RemoveObserver(this); |
| 292 if (is_screen_ready_) |
| 293 HideCurtain(); |
| 294 } |
| 295 |
| 296 bool UserImageScreen::IsWaitingForSync() const { |
| 297 return sync_timer_.get() && sync_timer_->IsRunning(); |
| 298 } |
| 299 |
| 300 void UserImageScreen::OnUserImagePolicyChanged(const base::Value* previous, |
| 301 const base::Value* current) { |
| 302 if (current) { |
| 303 base::ThreadTaskRunnerHandle::Get()->DeleteSoon( |
| 304 FROM_HERE, policy_registrar_.release()); |
| 305 ExitScreen(); |
| 306 } |
| 307 } |
| 308 |
| 309 const user_manager::User* UserImageScreen::GetUser() { |
| 310 return user_manager::UserManager::Get()->GetActiveUser(); |
| 311 } |
| 312 |
| 313 UserImageManager* UserImageScreen::GetUserImageManager() { |
| 314 return ChromeUserManager::Get()->GetUserImageManager( |
| 315 GetUser()->GetAccountId()); |
| 316 } |
| 317 |
| 318 UserImageSyncObserver* UserImageScreen::GetSyncObserver() { |
| 319 return GetUserImageManager()->GetSyncObserver(); |
| 320 } |
| 321 |
| 322 void UserImageScreen::HideCurtain() { |
| 323 // Skip user image selection for ephemeral users. |
| 324 if (user_manager::UserManager::Get()->IsUserNonCryptohomeDataEphemeral( |
| 325 GetUser()->GetAccountId())) { |
| 326 ExitScreen(); |
| 327 } |
| 328 if (view_) |
| 329 view_->HideCurtain(); |
| 330 } |
| 331 |
| 330 void UserImageScreen::ExitScreen() { | 332 void UserImageScreen::ExitScreen() { |
| 331 policy_registrar_.reset(); | 333 policy_registrar_.reset(); |
| 332 sync_timer_.reset(); | 334 sync_timer_.reset(); |
| 333 if (UserImageSyncObserver* sync_observer = GetSyncObserver()) | 335 if (UserImageSyncObserver* sync_observer = GetSyncObserver()) |
| 334 sync_observer->RemoveObserver(this); | 336 sync_observer->RemoveObserver(this); |
| 335 Finish(BaseScreenDelegate::USER_IMAGE_SELECTED); | 337 Finish(BaseScreenDelegate::USER_IMAGE_SELECTED); |
| 336 } | 338 } |
| 337 | 339 |
| 338 void UserImageScreen::ReportSyncResult(SyncResult timed_out) const { | 340 void UserImageScreen::ReportSyncResult(SyncResult timed_out) const { |
| 339 base::TimeDelta duration = base::Time::Now() - sync_waiting_start_time_; | 341 base::TimeDelta duration = base::Time::Now() - sync_waiting_start_time_; |
| 340 UMA_HISTOGRAM_TIMES("Login.NewUserPriorityPrefsSyncTime", duration); | 342 UMA_HISTOGRAM_TIMES("Login.NewUserPriorityPrefsSyncTime", duration); |
| 341 UMA_HISTOGRAM_ENUMERATION("Login.NewUserPriorityPrefsSyncResult", | 343 UMA_HISTOGRAM_ENUMERATION("Login.NewUserPriorityPrefsSyncResult", |
| 342 static_cast<int>(timed_out), | 344 static_cast<int>(timed_out), |
| 343 static_cast<int>(SyncResult::COUNT)); | 345 static_cast<int>(SyncResult::COUNT)); |
| 344 } | 346 } |
| 345 | 347 |
| 346 } // namespace chromeos | 348 } // namespace chromeos |
| OLD | NEW |