Skip to content

Commit

Permalink
Added user image screen for new user login (or old user logging in th…
Browse files Browse the repository at this point in the history
…rough

new user screen). If user takes snapshot and hits OK on image screen, the
snapshot becomes user image. If user presses Cancel, his image is downloaded
via Contacts API.

BUG=cros:3175
TEST=Login via new user login window. Verify that both use cases work if you logout after the browser is shown.

Review URL: http://codereview.chromium.org/2578001

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48828 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
avayvod@chromium.org committed Jun 3, 2010
1 parent f4badfb commit 64ec034
Show file tree
Hide file tree
Showing 18 changed files with 1,152 additions and 28 deletions.
410 changes: 410 additions & 0 deletions chrome/browser/chromeos/login/camera.cc

Large diffs are not rendered by default.

115 changes: 115 additions & 0 deletions chrome/browser/chromeos/login/camera.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_CAMERA_H_
#define CHROME_BROWSER_CHROMEOS_LOGIN_CAMERA_H_

#include <string>
#include <vector>

#include "base/timer.h"

class SkBitmap;

namespace base {
class TimeDelta;
} // namespace base

namespace chromeos {

// Class that wraps interaction with video capturing device. Returns
// frames captured with specified intervals of time via delegate interface.
class Camera {
public:
class Delegate {
public:
virtual ~Delegate() {}

// Called with specified intervals with decoded frame as a parameter.
virtual void OnVideoFrameCaptured(const SkBitmap& frame) = 0;
};

explicit Camera(Delegate* delegate);
~Camera();

// Initializes camera device. Returns true if succeeded, false otherwise.
// Does nothing on subsequent calls until Uninitialize is called.
// Sets the desired width and height of the frame to receive from camera.
bool Initialize(int desired_width, int desired_height);

// Uninitializes the camera. Can be called anytime, any number of times.
void Uninitialize();

// Starts capturing video frames with specified interval.
// Does nothing on subsequent calls until StopCapturing is called.
// Returns true if succeeded, false otherwise.
bool StartCapturing(const base::TimeDelta& interval);

// Stops capturing video frames. Can be called anytime, any number of
// times.
void StopCapturing();

private:
// Tries to open the device with specified name. Returns opened device
// descriptor if succeeds, -1 otherwise.
int OpenDevice(const char* device_name) const;

// Initializes reading mode for the device. Returns true on success, false
// otherwise.
bool InitializeReadingMode(int fd);

// Unmaps video buffers stored in |buffers_|.
void UnmapVideoBuffers();

// Called by |timer_| to get the frame from video device and send it to
// |delegate_| via its method.
void OnCapture();

// Reads a frame from the video device. If retry is needed, returns false.
// Otherwise, returns true despite of success status.
bool ReadFrame();

// Transforms raw data received from camera into SkBitmap with desired
// size and notifies the delegate that the image is ready.
void ProcessImage(void* data);

// Defines a buffer in memory where one frame from the camera is stored.
struct VideoBuffer {
void* start;
size_t length;
};

// Delegate that receives the frames from the camera.
Delegate* delegate_;

// Name of the device file, i.e. "/dev/video0".
std::string device_name_;

// File descriptor of the opened device.
int device_descriptor_;

// Vector of buffers where to store video frames from camera.
std::vector<VideoBuffer> buffers_;

// Timer for getting frames.
base::RepeatingTimer<Camera> timer_;

// Desired size of the frame to get from camera. If it doesn't match
// camera's supported resolution, higher resolution is selected (if
// available) and frame is cropped. If higher resolution is not available,
// the highest is selected and resized.
int desired_width_;
int desired_height_;

// Size of the frame that camera will give to us. It may not match the
// desired size.
int frame_width_;
int frame_height_;

DISALLOW_COPY_AND_ASSIGN(Camera);
};

} // namespace chromeos

#endif // CHROME_BROWSER_CHROMEOS_LOGIN_CAMERA_H_
5 changes: 1 addition & 4 deletions chrome/browser/chromeos/login/cookie_fetcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,7 @@ void CookieFetcher::OnURLFetchComplete(const URLFetcher* source,
}

void CookieFetcher::DelegateImpl::DoLaunch(Profile* profile) {
FilePath user_data_dir;
PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
ProfileManager* profile_manager = g_browser_process->profile_manager();
if (profile == profile_manager->GetDefaultProfile(user_data_dir)) {
if (profile == ProfileManager::GetDefaultProfile()) {
LoginUtils::DoBrowserLaunch(profile);
} else {
LOG(ERROR) <<
Expand Down
33 changes: 30 additions & 3 deletions chrome/browser/chromeos/login/login_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ class LoginUtilsImpl : public LoginUtils,
// Authenticator and must delete it when done.
virtual Authenticator* CreateAuthenticator(LoginStatusConsumer* consumer);

// Used to postpone browser launch via DoBrowserLaunch() if some post
// login screen is to be shown.
virtual void EnableBrowserLaunch(bool enable);

// Returns if browser launch enabled now or not.
virtual bool IsBrowserLaunchEnabled() const;

// Returns auth token for 'cp' Contacts service.
virtual const std::string& GetAuthToken() const { return auth_token_; }

// NotificationObserver implementation.
virtual void Observe(NotificationType type,
const NotificationSource& source,
Expand All @@ -101,6 +111,13 @@ class LoginUtilsImpl : public LoginUtils,
bool wifi_connecting_;
base::Time wifi_connect_start_time_;

// Indicates if DoBrowserLaunch will actually launch the browser or not.
bool browser_launch_enabled_;

// Auth token for Contacts service. Received by GoogleAuthenticator as
// part of ClientLogin response.
std::string auth_token_;

DISALLOW_COPY_AND_ASSIGN(LoginUtilsImpl);
};

Expand Down Expand Up @@ -175,9 +192,7 @@ void LoginUtilsImpl::CompleteLogin(const std::string& username,
// delete itself.
CookieFetcher* cf = new CookieFetcher(profile);
cf->AttemptFetch(credentials);
std::string auth = get_auth_token(credentials);
if (!auth.empty())
new UserImageDownloader(username, auth);
auth_token_ = get_auth_token(credentials);
}

void LoginUtilsImpl::CompleteOffTheRecordLogin() {
Expand All @@ -200,6 +215,14 @@ Authenticator* LoginUtilsImpl::CreateAuthenticator(
return new GoogleAuthenticator(consumer);
}

void LoginUtilsImpl::EnableBrowserLaunch(bool enable) {
browser_launch_enabled_ = enable;
}

bool LoginUtilsImpl::IsBrowserLaunchEnabled() const {
return browser_launch_enabled_;
}

void LoginUtilsImpl::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
Expand Down Expand Up @@ -231,6 +254,10 @@ void LoginUtils::DoBrowserLaunch(Profile* profile) {
return;
}

// Browser launch was disabled due to some post login screen.
if (!LoginUtils::Get()->IsBrowserLaunchEnabled())
return;

LOG(INFO) << "Launching browser...";
BrowserInit browser_init;
int return_code;
Expand Down
10 changes: 10 additions & 0 deletions chrome/browser/chromeos/login/login_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ class LoginUtils {
// Creates and returns the authenticator to use. The caller owns the returned
// Authenticator and must delete it when done.
virtual Authenticator* CreateAuthenticator(LoginStatusConsumer* consumer) = 0;

// Used to postpone browser launch via DoBrowserLaunch() if some post
// login screen is to be shown.
virtual void EnableBrowserLaunch(bool enable) = 0;

// Returns if browser launch enabled now or not.
virtual bool IsBrowserLaunchEnabled() const = 0;

// Returns auth token for 'cp' Contacts service.
virtual const std::string& GetAuthToken() const = 0;
};

} // namespace chromeos
Expand Down
12 changes: 12 additions & 0 deletions chrome/browser/chromeos/login/mock_authenticator.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,21 @@ class MockLoginUtils : public LoginUtils {
consumer, expected_username_, expected_password_);
}

virtual void EnableBrowserLaunch(bool enable) {
}

virtual bool IsBrowserLaunchEnabled() const {
return true;
}

virtual const std::string& GetAuthToken() const {
return auth_token_;
}

private:
std::string expected_username_;
std::string expected_password_;
std::string auth_token_;

DISALLOW_COPY_AND_ASSIGN(MockLoginUtils);
};
Expand Down
2 changes: 2 additions & 0 deletions chrome/browser/chromeos/login/screen_observer.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class ScreenObserver {
UPDATE_NOUPDATE,
UPDATE_ERROR_CHECKING_FOR_UPDATE,
UPDATE_ERROR_UPDATING,
USER_IMAGE_SELECTED,
USER_IMAGE_SKIPPED,
EXIT_CODES_COUNT // not a real code, must be the last
};

Expand Down
4 changes: 2 additions & 2 deletions chrome/browser/chromeos/login/user_image_downloader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ UserImageDownloader::UserImageDownloader(const std::string& username,
: username_(username),
auth_token_(auth_token) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
if (auth_token.empty())
if (auth_token_.empty())
return;

profile_fetcher_.reset(new URLFetcher(GURL(kUserInfoURL),
Expand All @@ -49,7 +49,7 @@ UserImageDownloader::UserImageDownloader(const std::string& username,
profile_fetcher_->set_request_context(
ProfileManager::GetDefaultProfile()->GetRequestContext());
profile_fetcher_->set_extra_request_headers(
StringPrintf(kAuthorizationHeader, auth_token.c_str()));
StringPrintf(kAuthorizationHeader, auth_token_.c_str()));
profile_fetcher_->Start();
}

Expand Down
3 changes: 2 additions & 1 deletion chrome/browser/chromeos/login/user_image_downloader.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ namespace chromeos {
class UserImageDownloader : public URLFetcher::Delegate,
public UtilityProcessHost::Client {
public:
// Starts downloading the picture upon successful login.
// |auth_token| is a authentication token received in ClientLogin
// response, used for requests sent to Contacts API.
// Starts downloading the picture. Object is deleted as reference counted
// object.
UserImageDownloader(const std::string& username,
const std::string& auth_token);

Expand Down
84 changes: 84 additions & 0 deletions chrome/browser/chromeos/login/user_image_screen.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/login/user_image_screen.h"

#include "base/compiler_specific.h"
#include "base/time.h"
#include "chrome/browser/chromeos/login/login_utils.h"
#include "chrome/browser/chromeos/login/screen_observer.h"
#include "chrome/browser/chromeos/login/user_image_downloader.h"
#include "chrome/browser/chromeos/login/user_image_view.h"
#include "chrome/browser/chromeos/login/user_manager.h"

namespace chromeos {

namespace {

// The resolution of the picture we want to get from the camera.
const int kFrameWidth = 480;
const int kFrameHeight = 480;

// Frame rate in milliseconds for video capturing.
// We want 25 FPS.
const int kFrameRate = 40;

} // namespace

UserImageScreen::UserImageScreen(WizardScreenDelegate* delegate)
: ViewScreen<UserImageView>(delegate),
ALLOW_THIS_IN_INITIALIZER_LIST(camera_(new Camera(this))) {
if (!camera_->Initialize(kFrameWidth, kFrameHeight))
camera_.reset();
}

UserImageScreen::~UserImageScreen() {
}

void UserImageScreen::Refresh() {
if (camera_.get())
camera_->StartCapturing(base::TimeDelta::FromMilliseconds(kFrameRate));
}

void UserImageScreen::Hide() {
if (camera_.get())
camera_->StopCapturing();
ViewScreen<UserImageView>::Hide();
}

UserImageView* UserImageScreen::AllocateView() {
return new UserImageView(this);
}

void UserImageScreen::OnVideoFrameCaptured(const SkBitmap& frame) {
if (view())
view()->UpdateVideoFrame(frame);
}

void UserImageScreen::OnOK(const SkBitmap& image) {
UserManager* user_manager = UserManager::Get();
if (user_manager) {
// TODO(avayvod): Check that there's logged in user actually.
const UserManager::User& user = user_manager->logged_in_user();
user_manager->SaveUserImage(user.email(), image);
}
if (delegate())
delegate()->GetObserver(this)->OnExit(ScreenObserver::USER_IMAGE_SELECTED);
}

void UserImageScreen::OnCancel() {
// Download user image from his Google account.
UserManager* user_manager = UserManager::Get();
if (user_manager) {
// TODO(avayvod): Check that there's logged in user actually.
const UserManager::User& user = user_manager->logged_in_user();
new UserImageDownloader(user.email(),
LoginUtils::Get()->GetAuthToken());
}
if (delegate())
delegate()->GetObserver(this)->OnExit(ScreenObserver::USER_IMAGE_SKIPPED);
}

} // namespace chromeos

Loading

0 comments on commit 64ec034

Please sign in to comment.