1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// found in the LICENSE file. 4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/chromeos/login/camera_controller.h" 6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/compiler_specific.h" 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/threading/thread_restrictions.h" 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace chromeos { 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace { 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Maximum number of capture failures we ignore before we try to initialize 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// the camera again. 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst int kMaxCaptureFailureCounter = 5; 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Maximum number of camera initialization retries. 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst int kMaxCameraInitFailureCounter = 3; 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Name for camera thread. 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kCameraThreadName[] = "Chrome_CameraThread"; 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace 25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenCameraController::CameraController(Delegate* delegate) 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : frame_width_(0), 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen frame_height_(0), 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen capture_failure_counter_(0), 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen camera_init_failure_counter_(0), 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen camera_thread_(new base::Thread(kCameraThreadName)), 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen delegate_(delegate) { 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen camera_thread_->Start(); 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenCameraController::~CameraController() { 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (camera_.get()) 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen camera_->set_delegate(NULL); 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // A ScopedAllowIO object is required to join the thread when calling Stop. 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // See http://crosbug.com/11392. 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::ThreadRestrictions::ScopedAllowIO allow_io_for_thread_join; 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen camera_thread_.reset(); 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid CameraController::Start() { 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen camera_ = new Camera(this, camera_thread_.get(), true); 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen camera_->Initialize(frame_width_, frame_height_); 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid CameraController::Stop() { 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!camera_.get()) 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen camera_->StopCapturing(); 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen camera_->Uninitialize(); 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid CameraController::GetFrame(SkBitmap* frame) const { 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (camera_.get()) 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen camera_->GetFrame(frame); 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid CameraController::OnInitializeSuccess() { 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(camera_.get()); 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen camera_->StartCapturing(); 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid CameraController::OnInitializeFailure() { 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ++camera_init_failure_counter_; 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (camera_init_failure_counter_ > kMaxCameraInitFailureCounter) { 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (delegate_) 73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen delegate_->OnCaptureFailure(); 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Retry initializing the camera. 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Start(); 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid CameraController::OnStartCapturingSuccess() { 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid CameraController::OnStartCapturingFailure() { 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Try to reinitialize camera. 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen OnInitializeFailure(); 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid CameraController::OnCaptureSuccess() { 89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(camera_.get()); 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen capture_failure_counter_ = 0; 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen camera_init_failure_counter_ = 0; 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (delegate_) 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen delegate_->OnCaptureSuccess(); 94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid CameraController::OnCaptureFailure() { 97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ++capture_failure_counter_; 98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (capture_failure_counter_ < kMaxCaptureFailureCounter) 99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen capture_failure_counter_ = 0; 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen OnInitializeFailure(); 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace chromeos 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 107