// Copyright (c) 2011 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/wizard_controller.h" #include #include #include #include #include #include "base/command_line.h" #include "base/file_util.h" #include "base/logging.h" #include "base/threading/thread_restrictions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/cros/cros_library.h" #include "chrome/browser/chromeos/cros/cryptohome_library.h" #include "chrome/browser/chromeos/customization_document.h" #include "chrome/browser/chromeos/language_preferences.h" #include "chrome/browser/chromeos/login/account_screen.h" #include "chrome/browser/chromeos/login/enterprise_enrollment_screen.h" #include "chrome/browser/chromeos/login/eula_view.h" #include "chrome/browser/chromeos/login/existing_user_controller.h" #include "chrome/browser/chromeos/login/helper.h" #include "chrome/browser/chromeos/login/html_page_screen.h" #include "chrome/browser/chromeos/login/login_display_host.h" #include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/network_screen.h" #include "chrome/browser/chromeos/login/registration_screen.h" #include "chrome/browser/chromeos/login/update_screen.h" #include "chrome/browser/chromeos/login/user_image_screen.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/login/wizard_accessibility_helper.h" #include "chrome/browser/chromeos/metrics_cros_settings_provider.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/common/pref_names.h" #include "content/common/notification_service.h" #include "content/common/notification_type.h" #include "ui/base/l10n/l10n_util.h" #include "views/accelerator.h" #include "views/view.h" #include "views/widget/widget_gtk.h" namespace { // A boolean pref of the EULA accepted flag. const char kEulaAccepted[] = "EulaAccepted"; // A string pref with initial locale set in VPD or manifest. const char kInitialLocale[] = "intl.initial_locale"; // A boolean pref of the OOBE complete flag (first OOBE part before login). const char kOobeComplete[] = "OobeComplete"; // A boolean pref of the device registered flag (second part after first login). const char kDeviceRegistered[] = "DeviceRegistered"; // Path to flag file indicating that both parts of OOBE were completed. const char kOobeCompleteFlagFilePath[] = "/home/chronos/.oobe_completed"; // Time in seconds that we wait for the device to reboot. // If reboot didn't happen, ask user to reboot device manually. const int kWaitForRebootTimeSec = 3; // Interval in ms which is used for smooth screen showing. static int kShowDelayMs = 400; // RootView of the Widget WizardController creates. Contains the contents of the // WizardController. class ContentView : public views::View { public: ContentView() : accel_toggle_accessibility_( chromeos::WizardAccessibilityHelper::GetAccelerator()) { #if defined(OFFICIAL_BUILD) accel_cancel_update_ = views::Accelerator(ui::VKEY_ESCAPE, true, true, true); #else accel_cancel_update_ = views::Accelerator(ui::VKEY_ESCAPE, false, false, false); accel_account_screen_ = views::Accelerator(ui::VKEY_A, false, true, true); accel_login_screen_ = views::Accelerator(ui::VKEY_L, false, true, true); accel_network_screen_ = views::Accelerator(ui::VKEY_N, false, true, true); accel_update_screen_ = views::Accelerator(ui::VKEY_U, false, true, true); accel_image_screen_ = views::Accelerator(ui::VKEY_I, false, true, true); accel_eula_screen_ = views::Accelerator(ui::VKEY_E, false, true, true); accel_register_screen_ = views::Accelerator(ui::VKEY_R, false, true, true); accel_enterprise_enrollment_screen_ = views::Accelerator(ui::VKEY_P, false, true, true); AddAccelerator(accel_account_screen_); AddAccelerator(accel_login_screen_); AddAccelerator(accel_network_screen_); AddAccelerator(accel_update_screen_); AddAccelerator(accel_image_screen_); AddAccelerator(accel_eula_screen_); AddAccelerator(accel_register_screen_); AddAccelerator(accel_enterprise_enrollment_screen_); #endif AddAccelerator(accel_toggle_accessibility_); AddAccelerator(accel_cancel_update_); } ~ContentView() { NotificationService::current()->Notify( NotificationType::WIZARD_CONTENT_VIEW_DESTROYED, NotificationService::AllSources(), NotificationService::NoDetails()); } bool AcceleratorPressed(const views::Accelerator& accel) { WizardController* controller = WizardController::default_controller(); if (!controller) return false; if (accel == accel_toggle_accessibility_) { chromeos::WizardAccessibilityHelper::GetInstance()->ToggleAccessibility(); } else if (accel == accel_cancel_update_) { controller->CancelOOBEUpdate(); #if !defined(OFFICIAL_BUILD) } else if (accel == accel_account_screen_) { controller->ShowAccountScreen(); } else if (accel == accel_login_screen_) { controller->ShowLoginScreen(); } else if (accel == accel_network_screen_) { controller->ShowNetworkScreen(); } else if (accel == accel_update_screen_) { controller->ShowUpdateScreen(); } else if (accel == accel_image_screen_) { controller->ShowUserImageScreen(); } else if (accel == accel_eula_screen_) { controller->ShowEulaScreen(); } else if (accel == accel_register_screen_) { controller->ShowRegistrationScreen(); } else if (accel == accel_enterprise_enrollment_screen_) { controller->ShowEnterpriseEnrollmentScreen(); #endif } else { return false; } return true; } virtual void Layout() { for (int i = 0; i < child_count(); ++i) { views::View* cur = GetChildViewAt(i); if (cur->IsVisible()) cur->SetBounds(0, 0, width(), height()); } } private: #if !defined(OFFICIAL_BUILD) views::Accelerator accel_account_screen_; views::Accelerator accel_login_screen_; views::Accelerator accel_network_screen_; views::Accelerator accel_update_screen_; views::Accelerator accel_image_screen_; views::Accelerator accel_eula_screen_; views::Accelerator accel_register_screen_; views::Accelerator accel_enterprise_enrollment_screen_; #endif views::Accelerator accel_toggle_accessibility_; views::Accelerator accel_cancel_update_; DISALLOW_COPY_AND_ASSIGN(ContentView); }; // Saves boolean "Local State" preference and forces its persistence to disk. void SaveBoolPreferenceForced(const char* pref_name, bool value) { PrefService* prefs = g_browser_process->local_state(); prefs->SetBoolean(pref_name, value); prefs->SavePersistentPrefs(); } // Saves integer "Local State" preference and forces its persistence to disk. void SaveIntegerPreferenceForced(const char* pref_name, int value) { PrefService* prefs = g_browser_process->local_state(); prefs->SetInteger(pref_name, value); prefs->SavePersistentPrefs(); } // Saves string "Local State" preference and forces its persistence to disk. void SaveStringPreferenceForced(const char* pref_name, const std::string& value) { PrefService* prefs = g_browser_process->local_state(); prefs->SetString(pref_name, value); prefs->SavePersistentPrefs(); } } // namespace const char WizardController::kNetworkScreenName[] = "network"; const char WizardController::kLoginScreenName[] = "login"; const char WizardController::kAccountScreenName[] = "account"; const char WizardController::kUpdateScreenName[] = "update"; const char WizardController::kUserImageScreenName[] = "image"; const char WizardController::kEulaScreenName[] = "eula"; const char WizardController::kRegistrationScreenName[] = "register"; const char WizardController::kHTMLPageScreenName[] = "html"; const char WizardController::kEnterpriseEnrollmentScreenName[] = "enroll"; // Passing this parameter as a "first screen" initiates full OOBE flow. const char WizardController::kOutOfBoxScreenName[] = "oobe"; // Special test value that commands not to create any window yet. const char WizardController::kTestNoScreenName[] = "test:nowindow"; // Initialize default controller. // static WizardController* WizardController::default_controller_ = NULL; /////////////////////////////////////////////////////////////////////////////// // WizardController, public: WizardController::WizardController(chromeos::LoginDisplayHost* host, const gfx::Rect& screen_bounds) : widget_(NULL), contents_(NULL), screen_bounds_(screen_bounds), current_screen_(NULL), initial_show_(true), is_active_(true), #if defined(OFFICIAL_BUILD) is_official_build_(true), #else is_official_build_(false), #endif is_out_of_box_(false), host_(host), observer_(NULL), usage_statistics_reporting_(true) { DCHECK(default_controller_ == NULL); default_controller_ = this; } WizardController::~WizardController() { if (widget_) { widget_->Close(); widget_ = NULL; } if (default_controller_ == this) { default_controller_ = NULL; } else { NOTREACHED() << "More than one controller are alive."; } chromeos::WizardAccessibilityHelper::GetInstance()-> UnregisterNotifications(); } void WizardController::Init(const std::string& first_screen_name) { VLOG(1) << "Starting OOBE wizard with screen: " << first_screen_name; DCHECK(!contents_); first_screen_name_ = first_screen_name; contents_ = new ContentView(); bool oobe_complete = IsOobeCompleted(); if (!oobe_complete || first_screen_name == kOutOfBoxScreenName) { is_out_of_box_ = true; } ShowFirstScreen(first_screen_name); } void WizardController::CancelOOBEUpdate() { if (update_screen_.get() && update_screen_.get() == current_screen_) { GetUpdateScreen()->CancelUpdate(); } } chromeos::NetworkScreen* WizardController::GetNetworkScreen() { if (!network_screen_.get()) network_screen_.reset(new chromeos::NetworkScreen(this)); return network_screen_.get(); } chromeos::AccountScreen* WizardController::GetAccountScreen() { if (!account_screen_.get()) account_screen_.reset(new chromeos::AccountScreen(this)); return account_screen_.get(); } chromeos::UpdateScreen* WizardController::GetUpdateScreen() { if (!update_screen_.get()) { update_screen_.reset(new chromeos::UpdateScreen(this)); update_screen_->SetRebootCheckDelay(kWaitForRebootTimeSec); } return update_screen_.get(); } chromeos::UserImageScreen* WizardController::GetUserImageScreen() { if (!user_image_screen_.get()) user_image_screen_.reset(new chromeos::UserImageScreen(this)); return user_image_screen_.get(); } chromeos::EulaScreen* WizardController::GetEulaScreen() { if (!eula_screen_.get()) eula_screen_.reset(new chromeos::EulaScreen(this)); return eula_screen_.get(); } chromeos::RegistrationScreen* WizardController::GetRegistrationScreen() { if (!registration_screen_.get()) registration_screen_.reset(new chromeos::RegistrationScreen(this)); return registration_screen_.get(); } chromeos::HTMLPageScreen* WizardController::GetHTMLPageScreen() { if (!html_page_screen_.get()) { CommandLine* command_line = CommandLine::ForCurrentProcess(); std::string url; // It's strange but args may contains empty strings. for (size_t i = 0; i < command_line->args().size(); i++) { if (!command_line->args()[i].empty()) { DCHECK(url.empty()) << "More than one URL in command line"; url = command_line->args()[i]; } } DCHECK(!url.empty()) << "No URL in commane line"; html_page_screen_.reset(new chromeos::HTMLPageScreen(this, url)); } return html_page_screen_.get(); } chromeos::EnterpriseEnrollmentScreen* WizardController::GetEnterpriseEnrollmentScreen() { if (!enterprise_enrollment_screen_.get()) { enterprise_enrollment_screen_.reset( new chromeos::EnterpriseEnrollmentScreen(this)); } return enterprise_enrollment_screen_.get(); } void WizardController::ShowNetworkScreen() { SetStatusAreaVisible(false); SetCurrentScreen(GetNetworkScreen()); host_->SetOobeProgress(chromeos::BackgroundView::SELECT_NETWORK); } void WizardController::ShowLoginScreen() { SetStatusAreaVisible(true); host_->SetOobeProgress(chromeos::BackgroundView::SIGNIN); host_->StartSignInScreen(); smooth_show_timer_.Stop(); if (widget_) { widget_->Close(); widget_ = NULL; } is_active_ = false; } void WizardController::ShowAccountScreen() { VLOG(1) << "Showing create account screen."; SetStatusAreaVisible(true); SetCurrentScreen(GetAccountScreen()); } void WizardController::ShowUpdateScreen() { VLOG(1) << "Showing update screen."; SetStatusAreaVisible(true); SetCurrentScreen(GetUpdateScreen()); // There is no special step for update. #if defined(OFFICIAL_BUILD) host_->SetOobeProgress(chromeos::BackgroundView::EULA); #else host_->SetOobeProgress(chromeos::BackgroundView::SELECT_NETWORK); #endif } void WizardController::ShowUserImageScreen() { VLOG(1) << "Showing user image screen."; SetStatusAreaVisible(false); SetCurrentScreen(GetUserImageScreen()); host_->SetOobeProgress(chromeos::BackgroundView::PICTURE); host_->SetShutdownButtonEnabled(false); } void WizardController::ShowEulaScreen() { VLOG(1) << "Showing EULA screen."; SetStatusAreaVisible(false); SetCurrentScreen(GetEulaScreen()); #if defined(OFFICIAL_BUILD) host_->SetOobeProgress(chromeos::BackgroundView::EULA); #endif } void WizardController::ShowRegistrationScreen() { if (!IsRegisterScreenDefined()) { VLOG(1) << "Skipping registration screen: manifest not defined or invalid " "URL."; OnRegistrationSkipped(); return; } VLOG(1) << "Showing registration screen."; SetStatusAreaVisible(true); SetCurrentScreen(GetRegistrationScreen()); #if defined(OFFICIAL_BUILD) host_->SetOobeProgress(chromeos::BackgroundView::REGISTRATION); #endif } void WizardController::ShowHTMLPageScreen() { VLOG(1) << "Showing HTML page screen."; SetStatusAreaVisible(true); host_->SetOobeProgressBarVisible(false); SetCurrentScreen(GetHTMLPageScreen()); } void WizardController::ShowEnterpriseEnrollmentScreen() { SetStatusAreaVisible(true); host_->SetOobeProgress(chromeos::BackgroundView::SIGNIN); SetCurrentScreen(GetEnterpriseEnrollmentScreen()); } void WizardController::SkipRegistration() { if (current_screen_ == GetRegistrationScreen()) OnRegistrationSkipped(); else LOG(ERROR) << "Registration screen is not active."; } // static void WizardController::RegisterPrefs(PrefService* local_state) { local_state->RegisterBooleanPref(kOobeComplete, false); local_state->RegisterIntegerPref(kDeviceRegistered, -1); local_state->RegisterBooleanPref(kEulaAccepted, false); local_state->RegisterStringPref(kInitialLocale, "en-US"); // Check if the pref is already registered in case // Preferences::RegisterUserPrefs runs before this code in the future. if (local_state->FindPreference(prefs::kAccessibilityEnabled) == NULL) { local_state->RegisterBooleanPref(prefs::kAccessibilityEnabled, false); } } /////////////////////////////////////////////////////////////////////////////// // WizardController, ExitHandlers: void WizardController::OnNetworkConnected() { if (is_official_build_) { if (!IsEulaAccepted()) { ShowEulaScreen(); } else { // Possible cases: // 1. EULA was accepted, forced shutdown/reboot during update. // 2. EULA was accepted, planned reboot after update. // Make sure that device is up-to-date. InitiateOOBEUpdate(); } } else { InitiateOOBEUpdate(); } } void WizardController::OnNetworkOffline() { // TODO(dpolukhin): if(is_out_of_box_) we cannot work offline and // should report some error message here and stay on the same screen. ShowLoginScreen(); } void WizardController::OnAccountCreateBack() { ShowLoginScreen(); } void WizardController::OnAccountCreated() { ShowLoginScreen(); // TODO(dpolukhin): clear password memory for real. Now it is not // a problem because we can't extract password from the form. password_.clear(); } void WizardController::OnConnectionFailed() { // TODO(dpolukhin): show error message after login screen is displayed. ShowLoginScreen(); } void WizardController::OnUpdateCompleted() { OnOOBECompleted(); } void WizardController::OnEulaAccepted() { MarkEulaAccepted(); chromeos::MetricsCrosSettingsProvider::SetMetricsStatus( usage_statistics_reporting_); InitiateOOBEUpdate(); } void WizardController::OnUpdateErrorCheckingForUpdate() { // TODO(nkostylev): Update should be required during OOBE. // We do not want to block users from being able to proceed to the login // screen if there is any error checking for an update. // They could use "browse without sign-in" feature to set up the network to be // able to perform the update later. OnOOBECompleted(); } void WizardController::OnUpdateErrorUpdating() { // If there was an error while getting or applying the update, // return to network selection screen. // TODO(nkostylev): Show message to the user explaining update error. // TODO(nkostylev): Update should be required during OOBE. // Temporary fix, need to migrate to new API. http://crosbug.com/4321 OnOOBECompleted(); } void WizardController::OnUserImageSelected() { // Notify host that we're about to launch browser session. // Host will mark itself (and all controllers/windows) for deletion. host_->OnSessionStart(); // Launch browser after controller is deleted and its windows are closed. BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, NewRunnableFunction(&chromeos::LoginUtils::DoBrowserLaunch, ProfileManager::GetDefaultProfile())); // TODO(avayvod): Sync image with Google Sync. } void WizardController::OnUserImageSkipped() { OnUserImageSelected(); } void WizardController::OnRegistrationSuccess() { MarkDeviceRegistered(); if (chromeos::UserManager::Get()->IsLoggedInAsGuest()) { chromeos::LoginUtils::Get()->CompleteOffTheRecordLogin(start_url_); } else { ShowUserImageScreen(); } } void WizardController::OnRegistrationSkipped() { // TODO(nkostylev): Track in a histogram? OnRegistrationSuccess(); } void WizardController::OnEnterpriseEnrollmentDone() { ShowLoginScreen(); } void WizardController::OnOOBECompleted() { MarkOobeCompleted(); ShowLoginScreen(); } void WizardController::InitiateOOBEUpdate() { GetUpdateScreen()->StartUpdate(); SetCurrentScreenSmooth(GetUpdateScreen(), true); } /////////////////////////////////////////////////////////////////////////////// // WizardController, private: views::Widget* WizardController::CreateScreenWindow( const gfx::Rect& bounds, bool initial_show) { views::Widget::CreateParams widget_params( views::Widget::CreateParams::TYPE_WINDOW); widget_params.transparent = true; widget_ = views::Widget::CreateWidget(widget_params); // Window transparency makes background flicker through controls that // are constantly updating its contents (like image view with video // stream). Hence enabling double buffer. static_cast(widget_)->EnableDoubleBuffer(true); widget_->Init(NULL, bounds); std::vector params; // For initial show WM would animate background window. // Otherwise it stays unchaged. params.push_back(initial_show); chromeos::WmIpc::instance()->SetWindowType( widget_->GetNativeView(), chromeos::WM_IPC_WINDOW_LOGIN_GUEST, ¶ms); widget_->SetContentsView(contents_); return widget_; } gfx::Rect WizardController::GetWizardScreenBounds(int screen_width, int screen_height) const { int offset_x = (screen_bounds_.width() - screen_width) / 2; int offset_y = (screen_bounds_.height() - screen_height) / 2; int window_x = screen_bounds_.x() + offset_x; int window_y = screen_bounds_.y() + offset_y; return gfx::Rect(window_x, window_y, screen_width, screen_height); } void WizardController::SetCurrentScreen(WizardScreen* new_current) { SetCurrentScreenSmooth(new_current, false); } void WizardController::ShowCurrentScreen() { // ShowCurrentScreen may get called by smooth_show_timer_ even after // flow has been switched to sign in screen (ExistingUserController). if (!is_active_) return; smooth_show_timer_.Stop(); bool force_widget_show = false; views::Widget* window = NULL; gfx::Rect current_bounds; if (widget_) current_bounds = widget_->GetClientAreaScreenBounds(); gfx::Size new_screen_size = current_screen_->GetScreenSize(); gfx::Rect new_bounds = GetWizardScreenBounds(new_screen_size.width(), new_screen_size.height()); if (new_bounds != current_bounds) { if (widget_) widget_->Close(); force_widget_show = true; window = CreateScreenWindow(new_bounds, initial_show_); } current_screen_->Show(); contents_->Layout(); contents_->SchedulePaint(); if (force_widget_show) { // This keeps the window from flashing at startup. GdkWindow* gdk_window = window->GetNativeView()->window; gdk_window_set_back_pixmap(gdk_window, NULL, false); if (widget_) widget_->Show(); } } void WizardController::SetCurrentScreenSmooth(WizardScreen* new_current, bool use_smoothing) { if (current_screen_ == new_current || new_current == NULL) return; smooth_show_timer_.Stop(); if (current_screen_) { initial_show_ = false; current_screen_->Hide(); } current_screen_ = new_current; if (use_smoothing) { smooth_show_timer_.Start( base::TimeDelta::FromMilliseconds(kShowDelayMs), this, &WizardController::ShowCurrentScreen); contents_->Layout(); contents_->SchedulePaint(); } else { ShowCurrentScreen(); } } void WizardController::SetStatusAreaVisible(bool visible) { host_->SetStatusAreaVisible(visible); } void WizardController::ShowFirstScreen(const std::string& first_screen_name) { if (first_screen_name == kNetworkScreenName) { ShowNetworkScreen(); } else if (first_screen_name == kLoginScreenName) { ShowLoginScreen(); } else if (first_screen_name == kAccountScreenName) { ShowAccountScreen(); } else if (first_screen_name == kUpdateScreenName) { InitiateOOBEUpdate(); } else if (first_screen_name == kUserImageScreenName) { ShowUserImageScreen(); } else if (first_screen_name == kEulaScreenName) { ShowEulaScreen(); } else if (first_screen_name == kRegistrationScreenName) { if (is_official_build_) { ShowRegistrationScreen(); } else { // Just proceed to image screen. OnRegistrationSuccess(); } } else if (first_screen_name == kHTMLPageScreenName) { ShowHTMLPageScreen(); } else if (first_screen_name == kEnterpriseEnrollmentScreenName) { ShowEnterpriseEnrollmentScreen(); } else if (first_screen_name != kTestNoScreenName) { if (is_out_of_box_) { ShowNetworkScreen(); } else { ShowLoginScreen(); } } } // static bool WizardController::IsEulaAccepted() { return g_browser_process->local_state()->GetBoolean(kEulaAccepted); } // static bool WizardController::IsOobeCompleted() { return g_browser_process->local_state()->GetBoolean(kOobeComplete); } // static void WizardController::MarkEulaAccepted() { SaveBoolPreferenceForced(kEulaAccepted, true); } // static void WizardController::MarkOobeCompleted() { SaveBoolPreferenceForced(kOobeComplete, true); } static void CreateOobeCompleteFlagFile() { // Create flag file for boot-time init scripts. FilePath oobe_complete_path(kOobeCompleteFlagFilePath); if (!file_util::PathExists(oobe_complete_path)) { FILE* oobe_flag_file = file_util::OpenFile(oobe_complete_path, "w+b"); if (oobe_flag_file == NULL) DLOG(WARNING) << kOobeCompleteFlagFilePath << " doesn't exist."; else file_util::CloseFile(oobe_flag_file); } } // static bool WizardController::IsDeviceRegistered() { int value = g_browser_process->local_state()->GetInteger(kDeviceRegistered); if (value > 0) { // Recreate flag file in case it was lost. BrowserThread::PostTask( BrowserThread::FILE, FROM_HERE, NewRunnableFunction(&CreateOobeCompleteFlagFile)); return true; } else if (value == 0) { return false; } else { // Pref is not set. For compatibility check flag file. It causes blocking // IO on UI thread. But it's required for update from old versions. base::ThreadRestrictions::ScopedAllowIO allow_io; FilePath oobe_complete_flag_file_path(kOobeCompleteFlagFilePath); bool file_exists = file_util::PathExists(oobe_complete_flag_file_path); SaveIntegerPreferenceForced(kDeviceRegistered, file_exists ? 1 : 0); return file_exists; } } // static void WizardController::MarkDeviceRegistered() { SaveIntegerPreferenceForced(kDeviceRegistered, 1); BrowserThread::PostTask( BrowserThread::FILE, FROM_HERE, NewRunnableFunction(&CreateOobeCompleteFlagFile)); } // static std::string WizardController::GetInitialLocale() { std::string locale = g_browser_process->local_state()->GetString(kInitialLocale); if (!l10n_util::IsValidLocaleSyntax(locale)) locale = "en-US"; return locale; } // static void WizardController::SetInitialLocale(const std::string& locale) { if (l10n_util::IsValidLocaleSyntax(locale)) SaveStringPreferenceForced(kInitialLocale, locale); else NOTREACHED(); } // static bool WizardController::IsRegisterScreenDefined() { const chromeos::StartupCustomizationDocument* manifest = chromeos::StartupCustomizationDocument::GetInstance(); return manifest->IsReady() && GURL(manifest->registration_url()).is_valid(); } /////////////////////////////////////////////////////////////////////////////// // WizardController, chromeos::ScreenObserver overrides: void WizardController::OnExit(ExitCodes exit_code) { LOG(INFO) << "Wizard screen exit code: " << exit_code; switch (exit_code) { case NETWORK_CONNECTED: OnNetworkConnected(); break; case NETWORK_OFFLINE: OnNetworkOffline(); break; case ACCOUNT_CREATE_BACK: OnAccountCreateBack(); break; case ACCOUNT_CREATED: OnAccountCreated(); break; case CONNECTION_FAILED: OnConnectionFailed(); break; case UPDATE_INSTALLED: case UPDATE_NOUPDATE: OnUpdateCompleted(); break; case UPDATE_ERROR_CHECKING_FOR_UPDATE: OnUpdateErrorCheckingForUpdate(); break; case UPDATE_ERROR_UPDATING: OnUpdateErrorUpdating(); break; case USER_IMAGE_SELECTED: OnUserImageSelected(); break; case USER_IMAGE_SKIPPED: OnUserImageSkipped(); break; case EULA_ACCEPTED: OnEulaAccepted(); break; case EULA_BACK: ShowNetworkScreen(); break; case REGISTRATION_SUCCESS: OnRegistrationSuccess(); break; case REGISTRATION_SKIPPED: OnRegistrationSkipped(); break; case ENTERPRISE_ENROLLMENT_CANCELLED: case ENTERPRISE_ENROLLMENT_COMPLETED: OnEnterpriseEnrollmentDone(); break; default: NOTREACHED(); } } void WizardController::OnSetUserNamePassword(const std::string& username, const std::string& password) { username_ = username; password_ = password; } /////////////////////////////////////////////////////////////////////////////// // WizardController, WizardScreen overrides: views::View* WizardController::GetWizardView() { return contents_; } chromeos::ScreenObserver* WizardController::GetObserver(WizardScreen* screen) { return observer_ ? observer_ : this; } void WizardController::SetZeroDelays() { kShowDelayMs = 0; }