user_image_screen.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1// Copyright (c) 2010 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_screen.h" 6 7#include "base/compiler_specific.h" 8#include "base/threading/thread_restrictions.h" 9#include "base/time.h" 10#include "chrome/browser/chromeos/login/login_utils.h" 11#include "chrome/browser/chromeos/login/screen_observer.h" 12#include "chrome/browser/chromeos/login/user_image_downloader.h" 13#include "chrome/browser/chromeos/login/user_image_view.h" 14#include "chrome/browser/chromeos/login/user_manager.h" 15#include "chrome/common/notification_service.h" 16#include "chrome/common/notification_type.h" 17#include "grit/theme_resources.h" 18#include "ui/base/resource/resource_bundle.h" 19 20namespace chromeos { 21 22namespace { 23 24// The resolution of the picture we want to get from the camera. 25const int kFrameWidth = 480; 26const int kFrameHeight = 480; 27 28// Maximum number of capture failures we ignore before we try to initialize 29// the camera again. 30const int kMaxCaptureFailureCounter = 5; 31 32// Maximum number of camera initialization retries. 33const int kMaxCameraInitFailureCounter = 3; 34 35// Name for camera thread. 36const char kCameraThreadName[] = "Chrome_CameraThread"; 37 38} // namespace 39 40UserImageScreen::UserImageScreen(WizardScreenDelegate* delegate) 41 : ViewScreen<UserImageView>(delegate), 42 capture_failure_counter_(0), 43 camera_init_failure_counter_(0) { 44 camera_thread_.reset(new base::Thread(kCameraThreadName)); 45 registrar_.Add( 46 this, 47 NotificationType::SCREEN_LOCK_STATE_CHANGED, 48 NotificationService::AllSources()); 49} 50 51UserImageScreen::~UserImageScreen() { 52 if (camera_.get()) 53 camera_->set_delegate(NULL); 54 { 55 // A ScopedAllowIO object is required to join the thread when calling Stop. 56 // See http://crosbug.com/11392. 57 base::ThreadRestrictions::ScopedAllowIO allow_io_for_thread_join; 58 camera_thread_.reset(); 59 } 60} 61 62void UserImageScreen::Refresh() { 63 camera_thread_->Start(); 64 camera_ = new Camera(this, camera_thread_.get(), true); 65 InitCamera(); 66} 67 68void UserImageScreen::Hide() { 69 if (camera_.get()) 70 camera_->StopCapturing(); 71 ViewScreen<UserImageView>::Hide(); 72} 73 74UserImageView* UserImageScreen::AllocateView() { 75 return new UserImageView(this); 76} 77 78void UserImageScreen::OnInitializeSuccess() { 79 if (camera_.get()) 80 camera_->StartCapturing(); 81} 82 83void UserImageScreen::OnInitializeFailure() { 84 ++camera_init_failure_counter_; 85 if (camera_init_failure_counter_ > kMaxCameraInitFailureCounter) { 86 if (view()) 87 view()->ShowCameraError(); 88 return; 89 } 90 // Retry initializing the camera. 91 if (camera_.get()) { 92 camera_->Uninitialize(); 93 InitCamera(); 94 } 95} 96 97void UserImageScreen::OnStartCapturingSuccess() { 98} 99 100void UserImageScreen::OnStartCapturingFailure() { 101 // Try to reinitialize camera. 102 OnInitializeFailure(); 103} 104 105void UserImageScreen::OnCaptureSuccess() { 106 capture_failure_counter_ = 0; 107 camera_init_failure_counter_ = 0; 108 if (view() && camera_.get()) { 109 SkBitmap frame; 110 camera_->GetFrame(&frame); 111 if (!frame.isNull()) 112 view()->UpdateVideoFrame(frame); 113 } 114} 115 116void UserImageScreen::OnCaptureFailure() { 117 ++capture_failure_counter_; 118 if (capture_failure_counter_ < kMaxCaptureFailureCounter) 119 return; 120 121 capture_failure_counter_ = 0; 122 OnInitializeFailure(); 123} 124 125void UserImageScreen::OnOK(const SkBitmap& image) { 126 if (camera_.get()) 127 camera_->Uninitialize(); 128 UserManager* user_manager = UserManager::Get(); 129 DCHECK(user_manager); 130 131 const UserManager::User& user = user_manager->logged_in_user(); 132 DCHECK(!user.email().empty()); 133 134 user_manager->SetLoggedInUserImage(image); 135 user_manager->SaveUserImage(user.email(), image); 136 if (delegate()) 137 delegate()->GetObserver(this)->OnExit(ScreenObserver::USER_IMAGE_SELECTED); 138} 139 140void UserImageScreen::OnSkip() { 141 if (camera_.get()) 142 camera_->Uninitialize(); 143 if (delegate()) 144 delegate()->GetObserver(this)->OnExit(ScreenObserver::USER_IMAGE_SKIPPED); 145} 146 147void UserImageScreen::Observe(NotificationType type, 148 const NotificationSource& source, 149 const NotificationDetails& details) { 150 if (type != NotificationType::SCREEN_LOCK_STATE_CHANGED || 151 !camera_.get()) 152 return; 153 154 bool is_screen_locked = *Details<bool>(details).ptr(); 155 if (is_screen_locked) 156 camera_->Uninitialize(); 157 else 158 InitCamera(); 159} 160 161void UserImageScreen::InitCamera() { 162 if (view()) 163 view()->ShowCameraInitializing(); 164 camera_->Initialize(kFrameWidth, kFrameHeight); 165} 166 167} // namespace chromeos 168 169