summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-12 21:56:17 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-12 21:56:17 +0000
commit507c71074588f718be1808bc0ffe51f3733f6eb7 (patch)
treeffbb41b332917d81ec85bab2f7eea0910e046252
parent8d614e3bd63a5c22730d27cccd01ea3c5ba17f64 (diff)
downloadchromium_src-507c71074588f718be1808bc0ffe51f3733f6eb7.zip
chromium_src-507c71074588f718be1808bc0ffe51f3733f6eb7.tar.gz
chromium_src-507c71074588f718be1808bc0ffe51f3733f6eb7.tar.bz2
Adds the remaining chunks for the login panels. It's currently not the
defualt and hidden behind a switch. BUG=none TEST=none Review URL: http://codereview.chromium.org/906001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41494 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd3
-rwxr-xr-xchrome/app/theme/login_default.pngbin0 -> 2269 bytes
-rwxr-xr-xchrome/app/theme/login_other.pngbin0 -> 1991 bytes
-rw-r--r--chrome/app/theme/theme_resources.grd2
-rw-r--r--chrome/browser/chromeos/login/background_view.cc5
-rw-r--r--chrome/browser/chromeos/login/existing_user_controller.cc160
-rw-r--r--chrome/browser/chromeos/login/existing_user_controller.h95
-rw-r--r--chrome/browser/chromeos/login/login_manager_view.cc20
-rw-r--r--chrome/browser/chromeos/login/login_manager_view.h8
-rw-r--r--chrome/browser/chromeos/login/user_controller.cc234
-rw-r--r--chrome/browser/chromeos/login/user_controller.h105
-rw-r--r--chrome/browser/chromeos/login/user_manager.cc7
-rw-r--r--chrome/browser/chromeos/login/user_manager.h2
-rw-r--r--chrome/browser/chromeos/login/utils.cc12
-rw-r--r--chrome/browser/chromeos/login/utils.h7
-rw-r--r--chrome/browser/chromeos/login/wizard_controller.cc49
-rw-r--r--chrome/browser/chromeos/login/wizard_controller.h9
-rwxr-xr-xchrome/chrome_browser.gypi4
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h3
20 files changed, 689 insertions, 39 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index d8578aa..a772dd7 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -7048,6 +7048,9 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_NOTIFICATION_PANEL_TITLE" desc="Text for the title of the notification panel.">
Notifications
</message>
+ <message name="IDS_GUEST" desc="Shown in login panel for guest user">
+ Other user
+ </message>
<message name="IDS_LANGUAGES_MORE" desc="Main language list 'more' link. Expands all possible languages, not only the main ones.">
More...
</message>
diff --git a/chrome/app/theme/login_default.png b/chrome/app/theme/login_default.png
new file mode 100755
index 0000000..84cca96
--- /dev/null
+++ b/chrome/app/theme/login_default.png
Binary files differ
diff --git a/chrome/app/theme/login_other.png b/chrome/app/theme/login_other.png
new file mode 100755
index 0000000..452749b
--- /dev/null
+++ b/chrome/app/theme/login_other.png
Binary files differ
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd
index 2c58d2a..29a36c0 100644
--- a/chrome/app/theme/theme_resources.grd
+++ b/chrome/app/theme/theme_resources.grd
@@ -461,6 +461,8 @@
<include name="IDR_MEDIAPLAYER_PREV" file="mediaplayer_prev.png" type="BINDATA" />
<include name="IDR_MEDIAPLAYER_MENU" file="mediaplayer_menu.png" type="BINDATA" />
<include name="IDR_MEDIAPLAYER_VOL_HIGH" file="mediaplayer_vol_high.png" type="BINDATA" />
+ <include name="IDR_LOGIN_DEFAULT_USER" file="login_default.png" type="BINDATA" />
+ <include name="IDR_LOGIN_OTHER_USER" file="login_other.png" type="BINDATA" />
</if>
<if expr="(pp_ifdef('chromeos') or pp_ifdef('toolkit_views')) and pp_ifdef('_google_chrome')">
diff --git a/chrome/browser/chromeos/login/background_view.cc b/chrome/browser/chromeos/login/background_view.cc
index 35bfeb2..c4bf995 100644
--- a/chrome/browser/chromeos/login/background_view.cc
+++ b/chrome/browser/chromeos/login/background_view.cc
@@ -8,6 +8,7 @@
#include "chrome/browser/chromeos/status/clock_menu_button.h"
#include "chrome/browser/chromeos/status/network_menu_button.h"
#include "chrome/browser/chromeos/status/status_area_view.h"
+#include "chrome/browser/chromeos/wm_ipc.h"
#include "chrome/common/x11_util.h"
#include "views/screen.h"
#include "views/widget/widget_gtk.h"
@@ -53,6 +54,10 @@ views::Widget* BackgroundView::CreateWindowContainingView(
views::WidgetGtk* window =
new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
window->Init(NULL, CalculateWindowBounds(bounds));
+ chromeos::WmIpc::instance()->SetWindowType(
+ window->GetNativeView(),
+ chromeos::WmIpc::WINDOW_TYPE_LOGIN_BACKGROUND,
+ NULL);
*view = new BackgroundView();
window->SetContentsView(*view);
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
new file mode 100644
index 0000000..ac9b607
--- /dev/null
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -0,0 +1,160 @@
+// 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/existing_user_controller.h"
+
+#include <algorithm>
+#include <functional>
+
+#include "base/message_loop.h"
+#include "base/stl_util-inl.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/login_library.h"
+#include "chrome/browser/chromeos/login/authenticator.h"
+#include "chrome/browser/chromeos/login/background_view.h"
+#include "chrome/browser/chromeos/login/utils.h"
+#include "chrome/browser/chromeos/login/wizard_controller.h"
+#include "chrome/browser/chromeos/wm_ipc.h"
+#include "views/screen.h"
+#include "views/widget/widget.h"
+
+namespace chromeos {
+
+namespace {
+
+// Max number of users we'll show. The true max is the min of this and the
+// number of windows that fit on the screen.
+const size_t kMaxUsers = 6;
+
+// Used to indicate no user has been selected.
+const size_t kNoLogin = -1;
+
+} // namespace
+
+ExistingUserController::ExistingUserController(
+ const std::vector<UserManager::User>& users,
+ const gfx::Size& background_size)
+ : background_size_(background_size),
+ background_window_(NULL),
+ background_view_(NULL),
+ index_of_view_logging_in_(kNoLogin) {
+ DCHECK(!users.empty()); // There must be at least one user when using
+ // ExistingUserController.
+
+ // Caclulate the max number of users from available screen size.
+ size_t max_users = kMaxUsers;
+ int screen_width =
+ views::Screen::GetMonitorAreaNearestPoint(gfx::Point(0, 0)).width();
+ if (screen_width > 0) {
+ max_users = std::max(static_cast<size_t>(2), std::min(kMaxUsers,
+ static_cast<size_t>((screen_width - UserController::kSize)
+ / (UserController::kUnselectedSize +
+ UserController::kPadding))));
+ }
+
+ for (size_t i = 0, max = std::min(users.size(), max_users - 1); i < max;
+ ++i) {
+ controllers_.push_back(new UserController(this, users[i]));
+ }
+
+ // Add the view representing the guest user last.
+ controllers_.push_back(new UserController());
+}
+
+void ExistingUserController::Init() {
+ background_window_ = BackgroundView::CreateWindowContainingView(
+ gfx::Rect(0, 0, background_size_.width(), background_size_.height()),
+ &background_view_);
+ background_window_->Show();
+ for (size_t i = 0; i < controllers_.size(); ++i) {
+ (controllers_[i])->Init(static_cast<int>(i),
+ static_cast<int>(controllers_.size()));
+ }
+
+ WmMessageListener::instance()->AddObserver(this);
+
+ if (CrosLibrary::EnsureLoaded())
+ LoginLibrary::Get()->EmitLoginPromptReady();
+}
+
+ExistingUserController::~ExistingUserController() {
+ if (background_window_)
+ background_window_->Close();
+
+ WmMessageListener::instance()->RemoveObserver(this);
+
+ STLDeleteElements(&controllers_);
+}
+
+void ExistingUserController::Delete() {
+ delete this;
+}
+
+void ExistingUserController::ProcessWmMessage(const WmIpc::Message& message,
+ GdkWindow* window) {
+ if (message.type() != WmIpc::Message::CHROME_CREATE_GUEST_WINDOW)
+ return;
+
+ // WizardController takes care of deleting itself when done.
+ WizardController* controller = new WizardController();
+ controller->Init(std::string(), false);
+ controller->Show();
+
+ // Give the background window to the controller.
+ controller->OwnBackground(background_window_, background_view_);
+ background_window_ = NULL;
+
+ // And schedule us for deletion. We delay for a second as the window manager
+ // is doing an animation with our windows.
+ delete_timer_.Start(base::TimeDelta::FromSeconds(1), this,
+ &ExistingUserController::Delete);
+}
+
+void ExistingUserController::Login(UserController* source,
+ const string16& password) {
+ std::vector<UserController*>::const_iterator i =
+ std::find(controllers_.begin(), controllers_.end(), source);
+ DCHECK(i != controllers_.end());
+ index_of_view_logging_in_ = i - controllers_.begin();
+
+ authenticator_.reset(login_utils::CreateAuthenticator(this));
+ authenticator_->Authenticate(
+ controllers_[index_of_view_logging_in_]->user().email(),
+ UTF16ToUTF8(password));
+
+ // Disable clicking on other windows.
+ chromeos::WmIpc::Message message(
+ chromeos::WmIpc::Message::WM_SET_LOGIN_STATE);
+ message.set_param(0, 0);
+ chromeos::WmIpc::instance()->SendMessage(message);
+}
+
+void ExistingUserController::OnLoginFailure(const std::string error) {
+ LOG(INFO) << "OnLoginFailure";
+
+ // TODO: alert the user in some way to the failure.
+
+ controllers_[index_of_view_logging_in_]->SetPasswordEnabled(true);
+
+ // Reenable clicking on other windows.
+ chromeos::WmIpc::Message message(
+ chromeos::WmIpc::Message::WM_SET_LOGIN_STATE);
+ message.set_param(0, 1);
+ chromeos::WmIpc::instance()->SendMessage(message);
+}
+
+void ExistingUserController::OnLoginSuccess(const std::string username) {
+ // Hide the login windows now.
+ STLDeleteElements(&controllers_);
+
+ background_window_->Close();
+
+ chromeos::login_utils::CompleteLogin(username);
+
+ // Delay deletion as we're on the stack.
+ MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/existing_user_controller.h b/chrome/browser/chromeos/login/existing_user_controller.h
new file mode 100644
index 0000000..2c1b893
--- /dev/null
+++ b/chrome/browser/chromeos/login/existing_user_controller.h
@@ -0,0 +1,95 @@
+// 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_EXISTING_USER_CONTROLLER_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_EXISTING_USER_CONTROLLER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/gfx/size.h"
+#include "base/task.h"
+#include "base/timer.h"
+#include "chrome/browser/chromeos/login/login_status_consumer.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/browser/chromeos/login/user_controller.h"
+#include "chrome/browser/chromeos/wm_message_listener.h"
+
+class Authenticator;
+
+namespace views {
+class Wiget;
+}
+
+namespace chromeos {
+
+class BackgroundView;
+
+// ExistingUserController is used to handle login when someone has already
+// logged into the machine. When Init is invoked a UserController is created for
+// each of the Users's in the UserManager (including one for guest), and the
+// window manager is then told to show the windows. If the user clicks on the
+// guest entry the WizardWindow is swapped in.
+//
+// To use ExistingUserController create an instance of it and invoke Init.
+//
+// ExistingUserController maintains it's own life cycle and deletes itself when
+// the user logs in (or chooses to see other settings).
+class ExistingUserController : public WmMessageListener::Observer,
+ public UserController::Delegate,
+ public LoginStatusConsumer {
+ public:
+ // |login_size| is the size of the login window that is passed to the
+ // WizardWindow. |background_size| is not used if the user logs into using an
+ // existing user.
+ ExistingUserController(const std::vector<UserManager::User>& users,
+ const gfx::Size& background_size);
+
+ // Creates and shows the appropriate set of windows.
+ void Init();
+
+ private:
+ friend class DeleteTask<ExistingUserController>;
+
+ ~ExistingUserController();
+
+ // Cover for invoking the destructor. Used by delete_timer_.
+ void Delete();
+
+ // WmMessageListener::Observer:
+ virtual void ProcessWmMessage(const WmIpc::Message& message,
+ GdkWindow* window);
+
+ // UserController::Delegate:
+ virtual void Login(UserController* source, const string16& password);
+
+ // LoginStatusConsumer:
+ virtual void OnLoginFailure(const std::string error);
+ virtual void OnLoginSuccess(const std::string username);
+
+ // Size of the background window.
+ const gfx::Size background_size_;
+
+ // Background window/view.
+ views::Widget* background_window_;
+ BackgroundView* background_view_;
+
+ // The set of UserControllers.
+ std::vector<UserController*> controllers_;
+
+ // Used for logging in.
+ scoped_ptr<Authenticator> authenticator_;
+
+ // Index of view loggin in.
+ size_t index_of_view_logging_in_;
+
+ // See comment in ProcessWmMessage.
+ base::OneShotTimer<ExistingUserController> delete_timer_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExistingUserController);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_LOGIN_EXISTING_USER_CONTROLLER_H_
diff --git a/chrome/browser/chromeos/login/login_manager_view.cc b/chrome/browser/chromeos/login/login_manager_view.cc
index cae59a5..a0268c1 100644
--- a/chrome/browser/chromeos/login/login_manager_view.cc
+++ b/chrome/browser/chromeos/login/login_manager_view.cc
@@ -18,16 +18,12 @@
#include "base/process_util.h"
#include "base/string_util.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
-#include "chrome/browser/chromeos/cros/login_library.h"
#include "chrome/browser/chromeos/cros/network_library.h"
#include "chrome/browser/chromeos/login/authentication_notification_details.h"
-#include "chrome/browser/chromeos/login/google_authenticator.h"
-#include "chrome/browser/chromeos/login/pam_google_authenticator.h"
#include "chrome/browser/chromeos/login/rounded_rect_painter.h"
#include "chrome/browser/chromeos/login/screen_observer.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/login/utils.h"
-#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
@@ -76,13 +72,11 @@ LoginManagerView::LoginManagerView(ScreenObserver* observer)
observer_(observer),
error_id_(-1),
ALLOW_THIS_IN_INITIALIZER_LIST(focus_grabber_factory_(this)),
- focus_delayed_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- authenticator_(new PamGoogleAuthenticator(this))) {
+ focus_delayed_(false) {
if (kStubOutLogin)
authenticator_.reset(new StubAuthenticator(this));
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kInChromeAuth))
- authenticator_.reset(new GoogleAuthenticator(this));
+ else
+ authenticator_.reset(login_utils::CreateAuthenticator(this));
}
LoginManagerView::~LoginManagerView() {
@@ -327,16 +321,10 @@ void LoginManagerView::OnLoginFailure(const std::string error) {
void LoginManagerView::OnLoginSuccess(const std::string username) {
// TODO(cmasone): something sensible if errors occur.
- SetupSession(username);
- login_utils::CompleteLogin(username);
-}
-
-void LoginManagerView::SetupSession(const std::string& username) {
if (observer_) {
observer_->OnExit(ScreenObserver::LOGIN_SIGN_IN_SELECTED);
}
- if (CrosLibrary::EnsureLoaded())
- LoginLibrary::Get()->StartSession(username, "");
+ login_utils::CompleteLogin(username);
}
void LoginManagerView::ShowError(int error_id) {
diff --git a/chrome/browser/chromeos/login/login_manager_view.h b/chrome/browser/chromeos/login/login_manager_view.h
index e208973..36c619a 100644
--- a/chrome/browser/chromeos/login/login_manager_view.h
+++ b/chrome/browser/chromeos/login/login_manager_view.h
@@ -88,14 +88,6 @@ class LoginManagerView : public views::View,
bool Authenticate(const std::string& username,
const std::string& password);
- // This is not threadsafe; as authentication is supposed to happen on the main
- // thread before any other threads are started, so this should be ok.
- // That said, the only reason we're not threadsafe right now is that we're
- // munging the CommandLine::ForCurrentProcess() to enable auto-client-side-ssl
- // for Googlers. So, if we can do that differently to make this thread-safe,
- // that'd be A Good Thing (tm).
- void SetupSession(const std::string& username);
-
// Callback from chromeos::VersionLoader giving the version.
void OnOSVersion(VersionLoader::Handle handle,
std::string version);
diff --git a/chrome/browser/chromeos/login/user_controller.cc b/chrome/browser/chromeos/login/user_controller.cc
new file mode 100644
index 0000000..ed67da8
--- /dev/null
+++ b/chrome/browser/chromeos/login/user_controller.cc
@@ -0,0 +1,234 @@
+// 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_controller.h"
+
+#include "app/gfx/canvas.h"
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "views/background.h"
+#include "views/controls/image_view.h"
+#include "views/controls/label.h"
+#include "views/controls/button/native_button.h"
+#include "views/grid_layout.h"
+#include "views/widget/root_view.h"
+#include "views/widget/widget_gtk.h"
+
+using views::ColumnSet;
+using views::GridLayout;
+using views::WidgetGtk;
+
+namespace chromeos {
+
+namespace {
+
+// Gap between edge and image view, and image view and controls.
+const int kBorderSize = 4;
+
+// Gap between the border around the image/buttons and user name.
+const int kUserNameGap = 4;
+
+// Background color.
+const SkColor kBackgroundColor = SK_ColorWHITE;
+
+// Text color.
+const SkColor kTextColor = SK_ColorWHITE;
+
+} // namespace
+
+// static
+const int UserController::kSize = 260;
+
+// static
+const int UserController::kPadding = 20;
+
+// Max size needed when an entry is not selected.
+const int UserController::kUnselectedSize = 100;
+
+UserController::UserController()
+ : is_guest_(true),
+ delegate_(NULL),
+ password_field_(NULL),
+ submit_button_(NULL),
+ controls_window_(NULL),
+ image_window_(NULL),
+ border_window_(NULL),
+ label_window_(NULL),
+ unselected_label_window_(NULL) {
+}
+
+UserController::UserController(Delegate* delegate,
+ const UserManager::User& user)
+ : is_guest_(false),
+ user_(user),
+ delegate_(delegate),
+ password_field_(NULL),
+ submit_button_(NULL),
+ controls_window_(NULL),
+ image_window_(NULL),
+ border_window_(NULL),
+ label_window_(NULL),
+ unselected_label_window_(NULL) {
+}
+
+UserController::~UserController() {
+ controls_window_->Close();
+ image_window_->Close();
+ border_window_->Close();
+ label_window_->Close();
+ unselected_label_window_->Close();
+}
+
+void UserController::Init(int index, int total_user_count) {
+ int controls_height = 0;
+ controls_window_ = CreateControlsWindow(index, &controls_height);
+ image_window_ = CreateImageWindow(index);
+ border_window_ = CreateBorderWindow(index, total_user_count,
+ controls_height);
+ label_window_ = CreateLabelWindow(index, WmIpc::WINDOW_TYPE_LOGIN_LABEL);
+ unselected_label_window_ =
+ CreateLabelWindow(index, WmIpc::WINDOW_TYPE_LOGIN_UNSELECTED_LABEL);
+}
+
+void UserController::SetPasswordEnabled(bool enable) {
+ password_field_->SetEnabled(enable);
+ submit_button_->SetEnabled(enable);
+}
+
+void UserController::ButtonPressed(views::Button* sender,
+ const views::Event& event) {
+ Login();
+}
+
+bool UserController::HandleKeystroke(
+ views::Textfield* sender,
+ const views::Textfield::Keystroke& keystroke) {
+ if (keystroke.GetKeyboardCode() == base::VKEY_RETURN) {
+ Login();
+ return true;
+ }
+ return false;
+}
+
+void UserController::Login() {
+ // Delegate will reenable as necessary.
+ SetPasswordEnabled(false);
+
+ delegate_->Login(this, password_field_->text());
+}
+
+WidgetGtk* UserController::CreateControlsWindow(int index, int* height) {
+ password_field_ = new views::Textfield(views::Textfield::STYLE_PASSWORD);
+ password_field_->SetController(this);
+ submit_button_ = new views::NativeButton(
+ this, l10n_util::GetString(IDS_LOGIN_BUTTON));
+ views::View* control_view = new views::View();
+ GridLayout* layout = new GridLayout(control_view);
+ control_view->SetLayoutManager(layout);
+ views::ColumnSet* column_set = layout->AddColumnSet(0);
+ column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
+ GridLayout::USE_PREF, 0, 0);
+ column_set->AddPaddingColumn(0, kBorderSize);
+ column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0,
+ GridLayout::USE_PREF, 0, 0);
+
+ layout->StartRow(0, 0);
+ layout->AddView(password_field_);
+ layout->AddView(submit_button_);
+
+ WidgetGtk* window = new WidgetGtk(WidgetGtk::TYPE_WINDOW);
+ window->MakeTransparent();
+ window->Init(NULL, gfx::Rect());
+ window->SetContentsView(control_view);
+ gfx::Size pref = control_view->GetPreferredSize();
+ *height = pref.height();
+ std::vector<int> params;
+ params.push_back(index);
+ WmIpc::instance()->SetWindowType(
+ window->GetNativeView(),
+ WmIpc::WINDOW_TYPE_LOGIN_CONTROLS,
+ &params);
+ window->SetBounds(gfx::Rect(0, 0, kSize, pref.height()));
+ window->Show();
+ return window;
+}
+
+WidgetGtk* UserController::CreateImageWindow(int index) {
+ views::ImageView* image_view = new views::ImageView();
+ image_view->set_background(
+ views::Background::CreateSolidBackground(kBackgroundColor));
+ if (!is_guest_) {
+ image_view->SetImage(user_.image());
+ } else {
+ image_view->SetImage(*ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_LOGIN_OTHER_USER));
+ }
+ image_view->SetImageSize(gfx::Size(kSize, kSize));
+ WidgetGtk* window = new WidgetGtk(WidgetGtk::TYPE_WINDOW);
+ window->Init(NULL, gfx::Rect());
+ window->SetContentsView(image_view);
+ std::vector<int> params;
+ params.push_back(index);
+ WmIpc::instance()->SetWindowType(
+ window->GetNativeView(),
+ WmIpc::WINDOW_TYPE_LOGIN_IMAGE,
+ &params);
+ window->SetBounds(gfx::Rect(0, 0, kSize, kSize));
+ window->Show();
+ return window;
+}
+
+WidgetGtk* UserController::CreateBorderWindow(int index,
+ int total_user_count,
+ int controls_height) {
+ WidgetGtk* window = new WidgetGtk(WidgetGtk::TYPE_WINDOW);
+ window->Init(NULL, gfx::Rect());
+ window->GetRootView()->set_background(
+ views::Background::CreateSolidBackground(kBackgroundColor));
+ std::vector<int> params;
+ params.push_back(index);
+ params.push_back(total_user_count);
+ params.push_back(kUnselectedSize);
+ params.push_back(kPadding);
+ WmIpc::instance()->SetWindowType(
+ window->GetNativeView(),
+ WmIpc::WINDOW_TYPE_LOGIN_BORDER,
+ &params);
+
+ window->SetBounds(gfx::Rect(0, 0, kSize + kBorderSize * 2,
+ kSize + kBorderSize * 2 +
+ kBorderSize + controls_height));
+ window->Show();
+ return window;
+}
+
+WidgetGtk* UserController::CreateLabelWindow(int index,
+ WmIpc::WindowType type) {
+ const gfx::Font& font = (type == WmIpc::WINDOW_TYPE_LOGIN_LABEL) ?
+ ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::LargeFont) :
+ ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont);
+ int width = (type == WmIpc::WINDOW_TYPE_LOGIN_LABEL) ?
+ kSize : kUnselectedSize;
+ WidgetGtk* window = new WidgetGtk(WidgetGtk::TYPE_WINDOW);
+ window->MakeTransparent();
+ window->Init(NULL, gfx::Rect());
+ std::wstring text = is_guest_ ? l10n_util::GetString(IDS_GUEST) :
+ UTF8ToWide(user_.GetDisplayName());
+ views::Label* label = new views::Label(text);
+ label->SetColor(kTextColor);
+ label->SetFont(font);
+ window->SetContentsView(label);
+ int height = label->GetPreferredSize().height();
+ std::vector<int> params;
+ params.push_back(index);
+ WmIpc::instance()->SetWindowType(window->GetNativeView(), type, &params);
+ window->SetBounds(gfx::Rect(0, 0, width, height));
+ window->Show();
+ return window;
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/user_controller.h b/chrome/browser/chromeos/login/user_controller.h
new file mode 100644
index 0000000..65d0eae
--- /dev/null
+++ b/chrome/browser/chromeos/login/user_controller.h
@@ -0,0 +1,105 @@
+// 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_USER_CONTROLLER_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_USER_CONTROLLER_H_
+
+#include "base/string16.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/browser/chromeos/wm_ipc.h"
+#include "views/controls/button/button.h"
+#include "views/controls/textfield/textfield.h"
+
+namespace views {
+class NativeButton;
+class WidgetGtk;
+}
+
+namespace chromeos {
+
+// UserController manages the set of windows needed to login a single existing
+// user. ExistingUserController creates the nececessary set of UserControllers.
+class UserController : public views::ButtonListener,
+ public views::Textfield::Controller {
+ public:
+ class Delegate {
+ public:
+ virtual void Login(UserController* source,
+ const string16& password) = 0;
+ };
+
+ // Creates a UserController representing the guest (other user) login.
+ UserController();
+
+ // Creates a UserController for the specified user.
+ UserController(Delegate* delegate, const UserManager::User& user);
+
+ ~UserController();
+
+ // Initializes the UserController, creating the set of windows/controls.
+ // |index| is the index of this user, and |total_user_count| the total
+ // number of users.
+ void Init(int index, int total_user_count);
+
+ const UserManager::User& user() const { return user_; }
+
+ // Sets the enabled state of the password field to |enable|.
+ void SetPasswordEnabled(bool enable);
+
+ // ButtonListener:
+ virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+
+ // Textfield::Controller:
+ virtual void ContentsChanged(views::Textfield* sender,
+ const string16& new_contents) {}
+ virtual bool HandleKeystroke(views::Textfield* sender,
+ const views::Textfield::Keystroke& keystroke);
+
+ // Max size needed when an entry is selected.
+ static const int kSize;
+
+ // Padding between the user windows.
+ static const int kPadding;
+
+ // Max size needed when an entry is not selected.
+ static const int kUnselectedSize;
+
+ private:
+ // Invoked when the user wants to login. Forwards the call to the delegate.
+ void Login();
+
+ views::WidgetGtk* CreateControlsWindow(int index, int* height);
+ views::WidgetGtk* CreateImageWindow(int index);
+ views::WidgetGtk* CreateBorderWindow(int index,
+ int total_user_count,
+ int controls_height);
+ views::WidgetGtk* CreateLabelWindow(int index, WmIpc::WindowType type);
+
+ // Is this the guest user?
+ const bool is_guest_;
+
+ // If is_guest_ is false, this is the user being shown.
+ const UserManager::User user_;
+
+ Delegate* delegate_;
+
+ // For editing the password.
+ views::Textfield* password_field_;
+
+ // Button to start login.
+ views::NativeButton* submit_button_;
+
+ // A window is used to represent the individual chunks.
+ views::WidgetGtk* controls_window_;
+ views::WidgetGtk* image_window_;
+ views::WidgetGtk* border_window_;
+ views::WidgetGtk* label_window_;
+ views::WidgetGtk* unselected_label_window_;
+
+ DISALLOW_COPY_AND_ASSIGN(UserController);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_LOGIN_USER_CONTROLLER_H_
diff --git a/chrome/browser/chromeos/login/user_manager.cc b/chrome/browser/chromeos/login/user_manager.cc
index d10c2f8..2f8af0c 100644
--- a/chrome/browser/chromeos/login/user_manager.cc
+++ b/chrome/browser/chromeos/login/user_manager.cc
@@ -4,9 +4,11 @@
#include "chrome/browser/chromeos/login/user_manager.h"
+#include "app/resource_bundle.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/pref_service.h"
#include "chrome/common/notification_service.h"
+#include "grit/theme_resources.h"
namespace chromeos {
@@ -16,6 +18,11 @@ static const wchar_t kLoggedInUsers[] = L"LoggedInUsers";
// The one true UserManager.
static UserManager* user_manager_ = NULL;
+UserManager::User::User() {
+ image_ = *ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_LOGIN_DEFAULT_USER);
+}
+
std::string UserManager::User::GetDisplayName() const {
size_t i = email_.find('@');
if (i == 0 || i == std::string::npos) {
diff --git a/chrome/browser/chromeos/login/user_manager.h b/chrome/browser/chromeos/login/user_manager.h
index 4eadfcd..d86c0d5 100644
--- a/chrome/browser/chromeos/login/user_manager.h
+++ b/chrome/browser/chromeos/login/user_manager.h
@@ -20,7 +20,7 @@ class UserManager {
// A class representing information about a previously logged in user.
class User {
public:
- User() {}
+ User();
~User() {}
// The email the user used to log in.
diff --git a/chrome/browser/chromeos/login/utils.cc b/chrome/browser/chromeos/login/utils.cc
index 9417c41..0fd5126 100644
--- a/chrome/browser/chromeos/login/utils.cc
+++ b/chrome/browser/chromeos/login/utils.cc
@@ -9,8 +9,11 @@
#include "base/path_service.h"
#include "chrome/browser/browser_init.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/cros/login_library.h"
#include "chrome/browser/chromeos/external_cookie_handler.h"
#include "chrome/browser/chromeos/login/authentication_notification_details.h"
+#include "chrome/browser/chromeos/login/google_authenticator.h"
+#include "chrome/browser/chromeos/login/pam_google_authenticator.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/profile_manager.h"
@@ -26,6 +29,9 @@ namespace login_utils {
void CompleteLogin(const std::string& username) {
LOG(INFO) << "LoginManagerView: OnLoginSuccess()";
+ if (CrosLibrary::EnsureLoaded())
+ LoginLibrary::Get()->StartSession(username, "");
+
UserManager::Get()->UserLoggedIn(username);
// Send notification of success
@@ -52,6 +58,12 @@ void CompleteLogin(const std::string& username) {
&return_code);
}
+Authenticator* CreateAuthenticator(LoginStatusConsumer* consumer) {
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kInChromeAuth))
+ return new GoogleAuthenticator(consumer);
+ return new PamGoogleAuthenticator(consumer);
+}
+
} // namespace login_utils
} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/utils.h b/chrome/browser/chromeos/login/utils.h
index 652c6dc..b7e28a9 100644
--- a/chrome/browser/chromeos/login/utils.h
+++ b/chrome/browser/chromeos/login/utils.h
@@ -7,6 +7,9 @@
#include <string>
+class Authenticator;
+class LoginStatusConsumer;
+
namespace views {
class Widget;
}
@@ -19,6 +22,10 @@ namespace login_utils {
// and does other bookkeeping after logging in.
void CompleteLogin(const std::string& username);
+// Creates and returns the authenticator to use. The caller owns the returned
+// Authenticator and must delete it when done.
+Authenticator* CreateAuthenticator(LoginStatusConsumer* consumer);
+
} // namespace login_utils
} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index 59d3c5a..d930072 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -11,13 +11,17 @@
#include <string>
#include "app/resource_bundle.h"
+#include "base/command_line.h"
#include "base/logging.h" // For NOTREACHED.
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/login_library.h"
#include "chrome/browser/chromeos/login/account_screen.h"
#include "chrome/browser/chromeos/login/background_view.h"
+#include "chrome/browser/chromeos/login/existing_user_controller.h"
#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/browser/chromeos/wm_ipc.h"
+#include "chrome/common/chrome_switches.h"
#include "unicode/locid.h"
#include "views/painter.h"
#include "views/screen.h"
@@ -38,20 +42,26 @@ const char kUpdateScreenName[] = "update";
// WizardController.
class ContentView : public views::View {
public:
- ContentView(int window_x, int window_y, int screen_w, int screen_h)
+ ContentView(bool paint_background, int window_x, int window_y, int screen_w,
+ int screen_h)
: window_x_(window_x),
window_y_(window_y),
screen_w_(screen_w),
screen_h_(screen_h) {
- painter_.reset(chromeos::CreateWizardPainter(
- &chromeos::BorderDefinition::kWizardBorder));
+ if (paint_background) {
+ painter_.reset(chromeos::CreateWizardPainter(
+ &chromeos::BorderDefinition::kWizardBorder));
+ }
}
void PaintBackground(gfx::Canvas* canvas) {
- // TODO(sky): nuke this once new login manager is in place. This needs to
- // exist because with no window manager transparency isn't really supported.
- canvas->TranslateInt(-window_x_, -window_y_);
- painter_->Paint(screen_w_, screen_h_, canvas);
+ if (painter_.get()) {
+ // TODO(sky): nuke this once new login manager is in place. This needs to
+ // exist because with no window manager transparency isn't really
+ // supported.
+ canvas->TranslateInt(-window_x_, -window_y_);
+ painter_->Paint(screen_w_, screen_h_, canvas);
+ }
}
virtual void Layout() {
@@ -102,7 +112,8 @@ WizardController::~WizardController() {
default_controller_ = NULL;
}
-void WizardController::Init(const std::string& first_screen_name) {
+void WizardController::Init(const std::string& first_screen_name,
+ bool paint_background) {
DCHECK(!contents_);
gfx::Rect screen_bounds =
@@ -110,14 +121,21 @@ void WizardController::Init(const std::string& first_screen_name) {
int window_x = (screen_bounds.width() - kWizardScreenWidth) / 2;
int window_y = (screen_bounds.height() - kWizardScreenHeight) / 2;
- contents_ = new ContentView(window_x, window_y, screen_bounds.width(),
+ contents_ = new ContentView(paint_background, window_x, window_y,
+ screen_bounds.width(),
screen_bounds.height());
views::WidgetGtk* window =
new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
widget_ = window;
+ if (!paint_background)
+ window->MakeTransparent();
window->Init(NULL, gfx::Rect(window_x, window_y, kWizardScreenWidth,
kWizardScreenHeight));
+ chromeos::WmIpc::instance()->SetWindowType(
+ window->GetNativeView(),
+ chromeos::WmIpc::WINDOW_TYPE_LOGIN_GUEST,
+ NULL);
window->SetContentsView(contents_);
ShowFirstScreen(first_screen_name);
@@ -299,9 +317,20 @@ namespace browser {
// Declared in browser_dialogs.h so that others don't need to depend on our .h.
void ShowLoginWizard(const std::string& first_screen_name,
const gfx::Size& size) {
+ if (first_screen_name.empty() && chromeos::CrosLibrary::EnsureLoaded() &&
+ CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableLoginImages)) {
+ std::vector<chromeos::UserManager::User> users =
+ chromeos::UserManager::Get()->GetUsers();
+ if (!users.empty()) {
+ // ExistingUserController deletes itself.
+ (new chromeos::ExistingUserController(users, size))->Init();
+ return;
+ }
+ }
WizardController* controller = new WizardController();
controller->ShowBackground(size);
- controller->Init(first_screen_name);
+ controller->Init(first_screen_name, true);
controller->Show();
if (chromeos::CrosLibrary::EnsureLoaded())
chromeos::LoginLibrary::Get()->EmitLoginPromptReady();
diff --git a/chrome/browser/chromeos/login/wizard_controller.h b/chrome/browser/chromeos/login/wizard_controller.h
index 2975726..66ccbef 100644
--- a/chrome/browser/chromeos/login/wizard_controller.h
+++ b/chrome/browser/chromeos/login/wizard_controller.h
@@ -31,7 +31,7 @@ class WizardController : public chromeos::ScreenObserver,
public WizardScreenDelegate {
public:
WizardController();
- virtual ~WizardController();
+ ~WizardController();
// Returns the default wizard controller if it has been created.
static WizardController* default_controller() {
@@ -39,8 +39,11 @@ class WizardController : public chromeos::ScreenObserver,
}
// Shows the first screen defined by |first_screen_name| or by default
- // if the parameter is empty.
- void Init(const std::string& first_screen_name);
+ // if the parameter is empty. |paint_background| indicates whether a
+ // background should be painted. If |paint_background| is false, the window is
+ // made transparent.
+ void Init(const std::string& first_screen_name,
+ bool paint_background);
// Returns the view that contains all the other views.
views::View* contents() { return contents_; }
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index dd6524d..36259dc 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -355,6 +355,8 @@
'browser/chromeos/login/authenticator.h',
'browser/chromeos/login/background_view.cc',
'browser/chromeos/login/background_view.h',
+ 'browser/chromeos/login/existing_user_controller.cc',
+ 'browser/chromeos/login/existing_user_controller.h',
'browser/chromeos/login/google_authenticator.cc',
'browser/chromeos/login/google_authenticator.h',
'browser/chromeos/login/pam_google_authenticator.cc',
@@ -369,6 +371,8 @@
'browser/chromeos/login/screen_observer.h',
'browser/chromeos/login/update_view.cc',
'browser/chromeos/login/update_view.h',
+ 'browser/chromeos/login/user_controller.cc',
+ 'browser/chromeos/login/user_controller.h',
'browser/chromeos/login/user_manager.cc',
'browser/chromeos/login/user_manager.h',
'browser/chromeos/login/utils.cc',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 309c4ee..d4422350 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -764,6 +764,9 @@ const char kCookiePipe[] = "cookie-pipe";
// Document Viewer.
const char kEnableGView[] = "enable-gview";
+// Should we show the image based login?
+const char kEnableLoginImages[] = "enable-login-images";
+
// Enable Chrome-as-a-login-manager behavior.
const char kLoginManager[] = "login-manager";
// Enable Chrome to do ClientLogin on its own in the login-manager context.
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 3947388..b486aa4 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -13,7 +13,7 @@
namespace switches {
// -----------------------------------------------------------------------------
-// Can't find the switch yo are looking for? Try looking in
+// Can't find the switch you are looking for? Try looking in
// base/base_switches.cc instead.
// -----------------------------------------------------------------------------
@@ -218,6 +218,7 @@ extern const char kZygoteProcess[];
#if defined(OS_CHROMEOS)
extern const char kCookiePipe[];
extern const char kEnableGView[];
+extern const char kEnableLoginImages[];
extern const char kLoginManager[];
extern const char kInChromeAuth[];
// TODO(avayvod): Remove this flag when it's unnecessary for testing