Pass login-manager switch value to login wizard to determine which screen to
start with.
Refactored LoginObserver to ScreenObserver that could be used by other
screens as well.

BUG=34716
TEST=Currently there just should be no regression for Chrome based login
manager.
Review URL: http://codereview.chromium.org/574014

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38297 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index 34b4e67..21cc36c7 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -578,7 +578,8 @@
 
 #if defined(OS_CHROMEOS)
   if (parsed_command_line.HasSwitch(switches::kLoginManager)) {
-    browser::ShowLoginWizard();
+    browser::ShowLoginWizard(
+        parsed_command_line.GetSwitchValueASCII(switches::kLoginManager));
   }
 #endif  // OS_CHROMEOS
 
diff --git a/chrome/browser/chromeos/login/login_manager_view.cc b/chrome/browser/chromeos/login/login_manager_view.cc
index 35b8ff8..17905e2 100644
--- a/chrome/browser/chromeos/login/login_manager_view.cc
+++ b/chrome/browser/chromeos/login/login_manager_view.cc
@@ -7,6 +7,8 @@
 #include <signal.h>
 #include <sys/types.h>
 
+#include <vector>
+
 #include "app/l10n_util.h"
 #include "app/resource_bundle.h"
 #include "base/file_path.h"
@@ -17,6 +19,7 @@
 #include "chrome/browser/chromeos/cros/login_library.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "chrome/browser/chromeos/login/image_background.h"
+#include "chrome/browser/chromeos/login/screen_observer.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/common/chrome_switches.h"
 #include "grit/generated_resources.h"
@@ -35,23 +38,25 @@
 using views::View;
 using views::Widget;
 
-static const int kTitleY = 50;
-static const int kPanelSpacing = 36;
-static const int kVersionPad = 4;
-static const int kTextfieldWidth = 286;
-static const int kRowPad = 10;
-static const int kLabelPad = 2;
-static const int kCornerPad = 6;
-static const int kCornerRadius = 12;
-static const int kShadowOffset = 4;
-static const SkColor kErrorColor = 0xFF8F384F;
-static const SkColor kBackground = SK_ColorWHITE;
-static const SkColor kLabelColor = 0xFF808080;
-static const SkColor kVersionColor = 0xFFA0A0A0;
-static const char *kDefaultDomain = "@gmail.com";
+namespace {
+
+const int kTitleY = 50;
+const int kPanelSpacing = 36;
+const int kVersionPad = 4;
+const int kTextfieldWidth = 286;
+const int kRowPad = 10;
+const int kLabelPad = 2;
+const int kCornerPad = 6;
+const int kCornerRadius = 12;
+const int kShadowOffset = 4;
+const SkColor kErrorColor = 0xFF8F384F;
+const SkColor kBackground = SK_ColorWHITE;
+const SkColor kLabelColor = 0xFF808080;
+const SkColor kVersionColor = 0xFFA0A0A0;
+const char *kDefaultDomain = "@gmail.com";
 
 // Set to true to run on linux and test login.
-static const bool kStubOutLogin = false;
+const bool kStubOutLogin = false;
 
 // This Painter can be used to draw a background with a shadowed panel with
 // rounded corners.
@@ -92,8 +97,13 @@
   }
 };
 
-LoginManagerView::LoginManagerView() {
-  Init();
+}  // namespace
+
+LoginManagerView::LoginManagerView(chromeos::ScreenObserver* observer)
+    : observer_(observer) {
+}
+
+LoginManagerView::~LoginManagerView() {
 }
 
 void LoginManagerView::Init() {
@@ -252,7 +262,7 @@
 
 void LoginManagerView::SetupSession(const std::string& username) {
   if (observer_) {
-    observer_->OnLogin();
+    observer_->OnExit(chromeos::ScreenObserver::LOGIN_SIGN_IN_SELECTED);
   }
   if (username.find("@google.com") != std::string::npos) {
     // This isn't thread-safe.  However, the login window is specifically
@@ -263,7 +273,6 @@
   }
   if (chromeos::LoginLibrary::EnsureLoaded())
     chromeos::LoginLibrary::Get()->StartSession(username, "");
-
 }
 
 void LoginManagerView::Login() {
diff --git a/chrome/browser/chromeos/login/login_manager_view.h b/chrome/browser/chromeos/login/login_manager_view.h
index a13a89e1..7d02ed7 100644
--- a/chrome/browser/chromeos/login/login_manager_view.h
+++ b/chrome/browser/chromeos/login/login_manager_view.h
@@ -14,25 +14,22 @@
 #include "views/widget/widget_gtk.h"
 #include "views/window/window_delegate.h"
 
+namespace chromeos {
+class ScreenObserver;
+}  // namespace chromeos
+
 namespace views {
 class Label;
 class NativeButton;
-} // namespace views
+}  // namespace views
 
 class LoginManagerView : public views::View,
                          public views::WindowDelegate,
                          public views::Textfield::Controller,
                          public views::ButtonListener {
  public:
-  // Observer for login related events.
-  class LoginObserver {
-   public:
-    virtual ~LoginObserver() {}
-    virtual void OnLogin() = 0;
-  };
-
-  LoginManagerView();
-  virtual ~LoginManagerView() {}
+  explicit LoginManagerView(chromeos::ScreenObserver* observer);
+  virtual ~LoginManagerView();
 
   // Initialize the controls on the dialog.
   void Init();
@@ -56,29 +53,7 @@
   virtual void ContentsChanged(views::Textfield* sender,
                                const string16& new_contents) {}
 
-  void set_observer(LoginObserver* observer) {
-    observer_ = observer;
-  }
-
-  // Creates all examples and start UI event loop.
  private:
-  views::Textfield* username_field_;
-  views::Textfield* password_field_;
-  views::Label* os_version_label_;
-  views::Label* title_label_;
-  views::Label* username_label_;
-  views::Label* password_label_;
-  views::Label* error_label_;
-  views::NativeButton* sign_in_button_;
-
-  // Handles asynchronously loading the version.
-  chromeos::VersionLoader loader_;
-
-  // Used to request the version.
-  CancelableRequestConsumer consumer_;
-
-  LoginObserver* observer_;
-
   // Given a |username| and |password|, this method attempts to authenticate to
   // the Google accounts servers.
   // Returns true upon success and false on failure.
@@ -103,6 +78,24 @@
   // Attempt to login with the current field values.
   void Login();
 
+  views::Textfield* username_field_;
+  views::Textfield* password_field_;
+  views::Label* os_version_label_;
+  views::Label* title_label_;
+  views::Label* username_label_;
+  views::Label* password_label_;
+  views::Label* error_label_;
+  views::NativeButton* sign_in_button_;
+
+  // Handles asynchronously loading the version.
+  chromeos::VersionLoader loader_;
+
+  // Used to request the version.
+  CancelableRequestConsumer consumer_;
+
+  // Notifications receiver.
+  chromeos::ScreenObserver* observer_;
+
   DISALLOW_COPY_AND_ASSIGN(LoginManagerView);
 };
 
diff --git a/chrome/browser/chromeos/login/login_wizard_view.cc b/chrome/browser/chromeos/login/login_wizard_view.cc
index eb2852d..e658c688 100644
--- a/chrome/browser/chromeos/login/login_wizard_view.cc
+++ b/chrome/browser/chromeos/login/login_wizard_view.cc
@@ -10,6 +10,8 @@
 #include <X11/cursorfont.h>
 #include <X11/Xcursor/Xcursor.h>
 
+#include <string>
+
 #include "app/l10n_util.h"
 #include "app/resource_bundle.h"
 #include "base/file_path.h"
@@ -17,6 +19,7 @@
 #include "base/process_util.h"
 #include "chrome/browser/chromeos/cros/login_library.h"
 #include "chrome/browser/chromeos/login/image_background.h"
+#include "chrome/browser/chromeos/login/login_manager_view.h"
 #include "chrome/browser/chromeos/status/clock_menu_button.h"
 #include "chrome/browser/chromeos/status/status_area_view.h"
 #include "chrome/browser/views/browser_dialogs.h"
@@ -31,8 +34,15 @@
 using views::View;
 using views::Widget;
 
-static const int kLoginWidth = 700;
-static const int kLoginHeight = 350;
+namespace {
+
+const int kLoginWidth = 700;
+const int kLoginHeight = 350;
+
+// Names of screens to start login wizard with.
+const char kLoginManager[] = "login";
+
+}  // namespace
 
 namespace browser {
 
@@ -65,13 +75,14 @@
 // Subclass of WindowGtk, for use as the top level login window.
 class LoginWizardWindow : public views::WindowGtk {
  public:
-  static LoginWizardWindow* CreateLoginWizardWindow() {
+  static LoginWizardWindow* CreateLoginWizardWindow(
+      const std::string start_screen_name) {
     LoginWizardView* login_wizard = new LoginWizardView();
     LoginWizardWindow* login_wizard_window =
         new LoginWizardWindow(login_wizard);
     login_wizard_window->GetNonClientView()->SetFrameView(
         new LoginWizardNonClientFrameView());
-    login_wizard->Init();
+    login_wizard->Init(start_screen_name);
     login_wizard_window->Init(NULL, gfx::Rect());
 
     // This keeps the window from flashing at startup.
@@ -98,9 +109,9 @@
 };
 
 // Declared in browser_dialogs.h so that others don't need to depend on our .h.
-void ShowLoginWizard() {
+void ShowLoginWizard(const std::string& start_screen_name) {
   views::WindowGtk* window =
-      LoginWizardWindow::CreateLoginWizardWindow();
+      LoginWizardWindow::CreateLoginWizardWindow(start_screen_name);
   window->Show();
   if (chromeos::LoginLibrary::EnsureLoaded()) {
     chromeos::LoginLibrary::Get()->EmitLoginPromptReady();
@@ -113,65 +124,108 @@
 
 }  // namespace browser
 
-LoginWizardView::LoginWizardView() {
+///////////////////////////////////////////////////////////////////////////////
+// LoginWizardView, public:
+LoginWizardView::LoginWizardView()
+    : background_pixbuf_(NULL),
+      status_area_(NULL),
+      current_(NULL),
+      login_manager_(NULL) {
 }
 
 LoginWizardView::~LoginWizardView() {
   MessageLoop::current()->Quit();
 }
 
-void LoginWizardView::Init() {
-  InitWizardWindow();
-  // TODO(nkostylev): Select initial wizard view based on OOBE switch.
-  InitLoginWindow();
+void LoginWizardView::Init(const std::string& start_view_name) {
+  // Load and set the background.
+  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+  background_pixbuf_ = rb.GetPixbufNamed(IDR_LOGIN_BACKGROUND);
+  set_background(new views::ImageBackground(background_pixbuf_));
+
+  // Store the dimensions of the background image to use it later.
+  int width = gdk_pixbuf_get_width(background_pixbuf_);
+  int height = gdk_pixbuf_get_height(background_pixbuf_);
+  dimensions_.SetSize(width, height);
+
+  InitStatusArea();
+
+  // Create and initialize all views, hidden.
+  InitLoginManager();
+
+  // Select the view to start with and show it.
+  if (start_view_name == kLoginManager) {
+    current_ = login_manager_;
+  } else {
+    // Default to login manager.
+    current_ = login_manager_;
+  }
+  current_->SetVisible(true);
 }
 
-gfx::Size LoginWizardView::GetPreferredSize() {
-  return dimensions_;
-}
-
-void LoginWizardView::OnLogin() {
+///////////////////////////////////////////////////////////////////////////////
+// LoginWizardView, ExitHandlers:
+void LoginWizardView::OnLoginSignInSelected() {
   if (window()) {
     window()->Close();
   }
 }
 
-void LoginWizardView::InitLoginWindow() {
-  LoginManagerView* login_view = new LoginManagerView();
-  login_view->set_observer(this);
-  login_view->SetBounds((dimensions_.width() - kLoginWidth) / 2,
-                        (dimensions_.height() - kLoginHeight) / 2,
-                        kLoginWidth,
-                        kLoginHeight);
-  AddChildView(login_view);
-}
-
-void LoginWizardView::InitWizardWindow() {
-  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
-  background_pixbuf_ = rb.GetPixbufNamed(IDR_LOGIN_BACKGROUND);
-  int width = gdk_pixbuf_get_width(background_pixbuf_);
-  int height = gdk_pixbuf_get_height(background_pixbuf_);
-  dimensions_.SetSize(width, height);
-  set_background(new views::ImageBackground(background_pixbuf_));
-
+///////////////////////////////////////////////////////////////////////////////
+// LoginWizardView, private:
+void LoginWizardView::InitStatusArea() {
   status_area_ = new chromeos::StatusAreaView(this);
   status_area_->Init();
   gfx::Size status_area_size = status_area_->GetPreferredSize();
+  // TODO(avayvod): Check this on RTL interface.
   status_area_->SetBounds(dimensions_.width() - status_area_size.width(), 0,
                           status_area_size.width(),
                           status_area_size.height());
   AddChildView(status_area_);
 }
 
+void LoginWizardView::InitLoginManager() {
+  login_manager_ = new LoginManagerView(this);
+  login_manager_->Init();
+  login_manager_->SetBounds((dimensions_.width() - kLoginWidth) / 2,
+                            (dimensions_.height() - kLoginHeight) / 2,
+                            kLoginWidth,
+                            kLoginHeight);
+  login_manager_->SetVisible(false);
+  AddChildView(login_manager_);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// LoginWizardView, chromeos::ScreenObserver overrides:
+void LoginWizardView::OnExit(ExitCodes exit_code) {
+  switch (exit_code) {
+    case LOGIN_SIGN_IN_SELECTED:
+      OnLoginSignInSelected();
+      break;
+    default:
+      NOTREACHED();
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// LoginWizardView, views::View overrides:
+gfx::Size LoginWizardView::GetPreferredSize() {
+  return dimensions_;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// LoginWizardView, views::WindowDelegate overrides:
 views::View* LoginWizardView::GetContentsView() {
   return this;
 }
 
-// StatusAreaHost overrides.
+///////////////////////////////////////////////////////////////////////////////
+// LoginWizardView, StatusAreaHost overrides.
 gfx::NativeWindow LoginWizardView::GetNativeWindow() const {
   return window()->GetNativeWindow();
 }
 
+
 bool LoginWizardView::ShouldOpenButtonOptions(
     const views::View* button_view) const {
   if (button_view == status_area_->clock_view()) {
diff --git a/chrome/browser/chromeos/login/login_wizard_view.h b/chrome/browser/chromeos/login/login_wizard_view.h
index a99829b..0ba162a 100644
--- a/chrome/browser/chromeos/login/login_wizard_view.h
+++ b/chrome/browser/chromeos/login/login_wizard_view.h
@@ -5,12 +5,16 @@
 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_LOGIN_WIZARD_VIEW_H_
 #define CHROME_BROWSER_CHROMEOS_LOGIN_LOGIN_WIZARD_VIEW_H_
 
+#include <string>
+
 #include "app/gfx/canvas.h"
-#include "chrome/browser/chromeos/login/login_manager_view.h"
+#include "chrome/browser/chromeos/login/screen_observer.h"
 #include "chrome/browser/chromeos/status/status_area_host.h"
 #include "views/view.h"
 #include "views/window/window_delegate.h"
 
+class LoginManagerView;
+
 namespace chromeos {
 class StatusAreaView;
 }  // namespace chromeos
@@ -18,14 +22,21 @@
 // View for the wizard that will launch OOBE steps or login screen.
 class LoginWizardView : public views::View,
                         public views::WindowDelegate,
-                        public LoginManagerView::LoginObserver,
-                        public chromeos::StatusAreaHost {
+                        public chromeos::StatusAreaHost,
+                        public chromeos::ScreenObserver {
  public:
   LoginWizardView();
   virtual ~LoginWizardView();
 
   // Initializes wizard windows and controls (status bar).
-  void Init();
+  void Init(const std::string& start_view_name);
+
+ private:
+  // Exit handlers:
+  void OnLoginSignInSelected();
+
+  // Overriden from chromeos::ScreenObserver:
+  virtual void OnExit(ExitCodes exit_code);
 
   // Overridden from views::View:
   virtual gfx::Size GetPreferredSize();
@@ -33,21 +44,15 @@
   // Overridden from views::WindowDelegate:
   virtual views::View* GetContentsView();
 
-  // LoginObserver notification.
-  virtual void OnLogin();
-
   // Overriden from StatusAreaHost:
   virtual gfx::NativeWindow GetNativeWindow() const;
   virtual bool ShouldOpenButtonOptions(const views::View* button_view) const;
   virtual void OpenButtonOptions(const views::View* button_view) const;
   virtual bool IsButtonVisible(const views::View* button_view) const;
 
- private:
-  // Creates login window.
-  void InitLoginWindow();
-
-  // Creates main wizard window with status bar.
-  void InitWizardWindow();
+  // Initializers for all child views.
+  void InitStatusArea();
+  void InitLoginManager();
 
   // Background for the wizard view.
   GdkPixbuf* background_pixbuf_;
@@ -58,6 +63,12 @@
   // Status area view.
   chromeos::StatusAreaView* status_area_;
 
+  // View that's shown to the user at the moment.
+  views::View* current_;
+
+  // Login manager view.
+  LoginManagerView* login_manager_;
+
   DISALLOW_COPY_AND_ASSIGN(LoginWizardView);
 };
 
diff --git a/chrome/browser/chromeos/login/screen_observer.h b/chrome/browser/chromeos/login/screen_observer.h
new file mode 100644
index 0000000..b50016b
--- /dev/null
+++ b/chrome/browser/chromeos/login/screen_observer.h
@@ -0,0 +1,33 @@
+// 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_SCREEN_OBSERVER_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREEN_OBSERVER_H_
+
+namespace chromeos {
+
+// Interface that handles notifications received from any of login wizard
+// screens.
+class ScreenObserver {
+ public:
+  // Each login screen or a view shown within login wizard view is itself a
+  // state. Upon exit each view returns one of the results by calling
+  // OnExit() method. Depending on the result and the current view or state
+  // login wizard decides what is the next view to show. There must be an
+  // exit code for each way to exit the screen for each screen.
+  enum ExitCodes {
+    LOGIN_SIGN_IN_SELECTED,
+  };
+
+  // Method called by a screen when user's done with it.
+  virtual void OnExit(ExitCodes exit_code) = 0;
+
+ protected:
+  virtual ~ScreenObserver() {}
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_SCREEN_OBSERVER_H_
+
diff --git a/chrome/browser/views/browser_dialogs.h b/chrome/browser/views/browser_dialogs.h
index 37c73cc6..f73bdf6 100644
--- a/chrome/browser/views/browser_dialogs.h
+++ b/chrome/browser/views/browser_dialogs.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_VIEWS_BROWSER_DIALOGS_H_
 #define CHROME_BROWSER_VIEWS_BROWSER_DIALOGS_H_
 
+#include <string>
+
 #include "app/gfx/native_widget_types.h"
 
 // This file contains functions for running a variety of browser dialogs and
@@ -90,7 +92,7 @@
 
 #if defined(OS_CHROMEOS)
 // Shows the Login Wizard.
-void ShowLoginWizard();
+void ShowLoginWizard(const std::string& start_screen);
 #endif
 
 // Shows a dialog box that allows a search engine to be edited. |template_url|
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 7be4f86..8390e30fe 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -299,6 +299,7 @@
         'browser/chromeos/login/login_manager_view.h',
         'browser/chromeos/login/login_wizard_view.cc',
         'browser/chromeos/login/login_wizard_view.h',
+        'browser/chromeos/login/screen_observer.h',
         'browser/chromeos/login/user_manager.cc',
         'browser/chromeos/login/user_manager.h',
         'browser/chromeos/main_menu.cc',