diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-12 21:56:17 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-12 21:56:17 +0000 |
commit | 507c71074588f718be1808bc0ffe51f3733f6eb7 (patch) | |
tree | ffbb41b332917d81ec85bab2f7eea0910e046252 | |
parent | 8d614e3bd63a5c22730d27cccd01ea3c5ba17f64 (diff) | |
download | chromium_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
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 Binary files differnew file mode 100755 index 0000000..84cca96 --- /dev/null +++ b/chrome/app/theme/login_default.png diff --git a/chrome/app/theme/login_other.png b/chrome/app/theme/login_other.png Binary files differnew file mode 100755 index 0000000..452749b --- /dev/null +++ b/chrome/app/theme/login_other.png 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, + ¶ms); + 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, + ¶ms); + 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, + ¶ms); + + 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, ¶ms); + 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 |