user_image_screen.cc revision 201ade2fbba22bfb27ae029f4d23fca6ded109a0
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 "app/resource_bundle.h"
8#include "base/compiler_specific.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
19namespace chromeos {
20
21namespace {
22
23// The resolution of the picture we want to get from the camera.
24const int kFrameWidth = 480;
25const int kFrameHeight = 480;
26
27// Maximum number of capture failures we ignore before we try to initialize
28// the camera again.
29const int kMaxCaptureFailureCounter = 5;
30
31// Maximum number of camera initialization retries.
32const int kMaxCameraInitFailureCounter = 3;
33
34// Name for camera thread.
35const char kCameraThreadName[] = "Chrome_CameraThread";
36
37}  // namespace
38
39UserImageScreen::UserImageScreen(WizardScreenDelegate* delegate)
40    : ViewScreen<UserImageView>(delegate),
41      capture_failure_counter_(0),
42      camera_init_failure_counter_(0),
43      camera_thread_(kCameraThreadName) {
44  registrar_.Add(
45      this,
46      NotificationType::SCREEN_LOCK_STATE_CHANGED,
47      NotificationService::AllSources());
48}
49
50UserImageScreen::~UserImageScreen() {
51  if (camera_.get())
52    camera_->set_delegate(NULL);
53}
54
55void UserImageScreen::Refresh() {
56  camera_thread_.Start();
57  camera_ = new Camera(this, &camera_thread_, true);
58  InitCamera();
59}
60
61void UserImageScreen::Hide() {
62  if (camera_.get())
63    camera_->StopCapturing();
64  ViewScreen<UserImageView>::Hide();
65}
66
67UserImageView* UserImageScreen::AllocateView() {
68  return new UserImageView(this);
69}
70
71void UserImageScreen::OnInitializeSuccess() {
72  if (camera_.get())
73    camera_->StartCapturing();
74}
75
76void UserImageScreen::OnInitializeFailure() {
77  ++camera_init_failure_counter_;
78  if (camera_init_failure_counter_ > kMaxCameraInitFailureCounter) {
79    if (view())
80      view()->ShowCameraError();
81    return;
82  }
83  // Retry initializing the camera.
84  if (camera_.get()) {
85    camera_->Uninitialize();
86    InitCamera();
87  }
88}
89
90void UserImageScreen::OnStartCapturingSuccess() {
91}
92
93void UserImageScreen::OnStartCapturingFailure() {
94  // Try to reinitialize camera.
95  OnInitializeFailure();
96}
97
98void UserImageScreen::OnCaptureSuccess() {
99  capture_failure_counter_ = 0;
100  camera_init_failure_counter_ = 0;
101  if (view() && camera_.get()) {
102    SkBitmap frame;
103    camera_->GetFrame(&frame);
104    if (!frame.isNull())
105      view()->UpdateVideoFrame(frame);
106  }
107}
108
109void UserImageScreen::OnCaptureFailure() {
110  ++capture_failure_counter_;
111  if (capture_failure_counter_ < kMaxCaptureFailureCounter)
112    return;
113
114  capture_failure_counter_ = 0;
115  OnInitializeFailure();
116}
117
118void UserImageScreen::OnOK(const SkBitmap& image) {
119  if (camera_.get())
120    camera_->Uninitialize();
121  UserManager* user_manager = UserManager::Get();
122  DCHECK(user_manager);
123
124  const UserManager::User& user = user_manager->logged_in_user();
125  DCHECK(!user.email().empty());
126
127  user_manager->SetLoggedInUserImage(image);
128  user_manager->SaveUserImage(user.email(), image);
129  if (delegate())
130    delegate()->GetObserver(this)->OnExit(ScreenObserver::USER_IMAGE_SELECTED);
131}
132
133void UserImageScreen::OnSkip() {
134  if (camera_.get())
135    camera_->Uninitialize();
136  UserManager* user_manager = UserManager::Get();
137  DCHECK(user_manager);
138
139  const UserManager::User& user = user_manager->logged_in_user();
140  DCHECK(!user.email().empty());
141
142  user_manager->SetDefaultUserImage(user.email());
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