wizard_controller.cc revision f2477e01787aa58f445919b809d89e252beef54f
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/chromeos/login/wizard_controller.h"
6
7#include <signal.h>
8#include <stdlib.h>
9#include <sys/types.h>
10
11#include <string>
12#include <vector>
13
14#include "base/bind.h"
15#include "base/command_line.h"
16#include "base/logging.h"
17#include "base/metrics/histogram.h"
18#include "base/prefs/pref_registry_simple.h"
19#include "base/prefs/pref_service.h"
20#include "base/threading/thread_restrictions.h"
21#include "base/values.h"
22#include "chrome/browser/browser_process.h"
23#include "chrome/browser/chrome_notification_types.h"
24#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
25#include "chrome/browser/chromeos/customization_document.h"
26#include "chrome/browser/chromeos/login/enrollment/enrollment_screen.h"
27#include "chrome/browser/chromeos/login/existing_user_controller.h"
28#include "chrome/browser/chromeos/login/helper.h"
29#include "chrome/browser/chromeos/login/hwid_checker.h"
30#include "chrome/browser/chromeos/login/login_display_host.h"
31#include "chrome/browser/chromeos/login/login_utils.h"
32#include "chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.h"
33#include "chrome/browser/chromeos/login/oobe_display.h"
34#include "chrome/browser/chromeos/login/screens/error_screen.h"
35#include "chrome/browser/chromeos/login/screens/eula_screen.h"
36#include "chrome/browser/chromeos/login/screens/kiosk_autolaunch_screen.h"
37#include "chrome/browser/chromeos/login/screens/kiosk_enable_screen.h"
38#include "chrome/browser/chromeos/login/screens/network_screen.h"
39#include "chrome/browser/chromeos/login/screens/reset_screen.h"
40#include "chrome/browser/chromeos/login/screens/terms_of_service_screen.h"
41#include "chrome/browser/chromeos/login/screens/update_screen.h"
42#include "chrome/browser/chromeos/login/screens/user_image_screen.h"
43#include "chrome/browser/chromeos/login/screens/wrong_hwid_screen.h"
44#include "chrome/browser/chromeos/login/startup_utils.h"
45#include "chrome/browser/chromeos/login/user_manager.h"
46#include "chrome/browser/chromeos/net/network_portal_detector.h"
47#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
48#include "chrome/browser/chromeos/settings/cros_settings.h"
49#include "chrome/browser/policy/browser_policy_connector.h"
50#include "chrome/browser/profiles/profile.h"
51#include "chrome/browser/profiles/profile_manager.h"
52#include "chrome/browser/ui/options/options_util.h"
53#include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
54#include "chrome/common/chrome_constants.h"
55#include "chrome/common/pref_names.h"
56#include "chromeos/chromeos_constants.h"
57#include "chromeos/dbus/dbus_thread_manager.h"
58#include "chromeos/dbus/session_manager_client.h"
59#include "chromeos/network/network_state_handler.h"
60#include "chromeos/settings/cros_settings_names.h"
61#include "components/breakpad/app/breakpad_linux.h"
62#include "content/public/browser/browser_thread.h"
63#include "ui/base/accelerators/accelerator.h"
64#include "ui/base/l10n/l10n_util.h"
65
66using content::BrowserThread;
67
68// If reboot didn't happen, ask user to reboot device manually.
69const int kWaitForRebootTimeSec = 3;
70
71// Interval in ms which is used for smooth screen showing.
72static int kShowDelayMs = 400;
73
74namespace chromeos {
75
76const char WizardController::kNetworkScreenName[] = "network";
77const char WizardController::kLoginScreenName[] = "login";
78const char WizardController::kUpdateScreenName[] = "update";
79const char WizardController::kUserImageScreenName[] = "image";
80const char WizardController::kEulaScreenName[] = "eula";
81const char WizardController::kEnrollmentScreenName[] = "enroll";
82const char WizardController::kResetScreenName[] = "reset";
83const char WizardController::kKioskEnableScreenName[] = "kiosk-enable";
84const char WizardController::kKioskAutolaunchScreenName[] = "autolaunch";
85const char WizardController::kErrorScreenName[] = "error-message";
86const char WizardController::kTermsOfServiceScreenName[] = "tos";
87const char WizardController::kWrongHWIDScreenName[] = "wrong-hwid";
88const char WizardController::kLocallyManagedUserCreationScreenName[] =
89  "locally-managed-user-creation-flow";
90const char WizardController::kAppLaunchSplashScreenName[] =
91  "app-launch-splash";
92
93// Passing this parameter as a "first screen" initiates full OOBE flow.
94const char WizardController::kOutOfBoxScreenName[] = "oobe";
95
96// Special test value that commands not to create any window yet.
97const char WizardController::kTestNoScreenName[] = "test:nowindow";
98
99// Initialize default controller.
100// static
101WizardController* WizardController::default_controller_ = NULL;
102
103// static
104bool WizardController::skip_post_login_screens_ = false;
105
106// static
107bool WizardController::zero_delay_enabled_ = false;
108
109///////////////////////////////////////////////////////////////////////////////
110// WizardController, public:
111
112PrefService* WizardController::local_state_for_testing_ = NULL;
113
114WizardController::WizardController(chromeos::LoginDisplayHost* host,
115                                   chromeos::OobeDisplay* oobe_display)
116    : current_screen_(NULL),
117      previous_screen_(NULL),
118#if defined(GOOGLE_CHROME_BUILD)
119      is_official_build_(true),
120#else
121      is_official_build_(false),
122#endif
123      is_out_of_box_(false),
124      host_(host),
125      oobe_display_(oobe_display),
126      usage_statistics_reporting_(true),
127      skip_update_enroll_after_eula_(false),
128      login_screen_started_(false),
129      user_image_screen_return_to_previous_hack_(false),
130      weak_factory_(this) {
131  DCHECK(default_controller_ == NULL);
132  default_controller_ = this;
133}
134
135WizardController::~WizardController() {
136  if (default_controller_ == this) {
137    default_controller_ = NULL;
138  } else {
139    NOTREACHED() << "More than one controller are alive.";
140  }
141}
142
143void WizardController::Init(
144    const std::string& first_screen_name,
145    scoped_ptr<base::DictionaryValue> screen_parameters) {
146  VLOG(1) << "Starting OOBE wizard with screen: " << first_screen_name;
147  first_screen_name_ = first_screen_name;
148  screen_parameters_ = screen_parameters.Pass();
149
150  bool oobe_complete = StartupUtils::IsOobeCompleted();
151  if (!oobe_complete || first_screen_name == kOutOfBoxScreenName)
152    is_out_of_box_ = true;
153
154  // This is a hacky way to check for local state corruption, because
155  // it depends on the fact that the local state is loaded
156  // synchroniously and at the first demand. IsEnterpriseManaged()
157  // check is required because currently powerwash is disabled for
158  // enterprise-entrolled devices.
159  //
160  // TODO (ygorshenin@): implement handling of the local state
161  // corruption in the case of asynchronious loading.
162  //
163  // TODO (ygorshenin@): remove IsEnterpriseManaged() check once
164  // crbug.com/241313 will be fixed.
165  if (!g_browser_process->browser_policy_connector()->IsEnterpriseManaged()) {
166    const PrefService::PrefInitializationStatus status =
167        GetLocalState()->GetInitializationStatus();
168    if (status == PrefService::INITIALIZATION_STATUS_ERROR) {
169      OnLocalStateInitialized(false);
170      return;
171    } else if (status == PrefService::INITIALIZATION_STATUS_WAITING) {
172      GetLocalState()->AddPrefInitObserver(
173          base::Bind(&WizardController::OnLocalStateInitialized,
174                     weak_factory_.GetWeakPtr()));
175    }
176  }
177
178  AdvanceToScreen(first_screen_name);
179  if (!IsMachineHWIDCorrect() && !StartupUtils::IsDeviceRegistered() &&
180      first_screen_name.empty())
181    ShowWrongHWIDScreen();
182}
183
184chromeos::NetworkScreen* WizardController::GetNetworkScreen() {
185  if (!network_screen_.get())
186    network_screen_.reset(new chromeos::NetworkScreen(
187        this, oobe_display_->GetNetworkScreenActor()));
188  return network_screen_.get();
189}
190
191chromeos::UpdateScreen* WizardController::GetUpdateScreen() {
192  if (!update_screen_.get()) {
193    update_screen_.reset(new chromeos::UpdateScreen(
194        this, oobe_display_->GetUpdateScreenActor()));
195    update_screen_->SetRebootCheckDelay(kWaitForRebootTimeSec);
196  }
197  return update_screen_.get();
198}
199
200chromeos::UserImageScreen* WizardController::GetUserImageScreen() {
201  if (!user_image_screen_.get())
202    user_image_screen_.reset(
203        new chromeos::UserImageScreen(
204            this, oobe_display_->GetUserImageScreenActor()));
205  return user_image_screen_.get();
206}
207
208chromeos::EulaScreen* WizardController::GetEulaScreen() {
209  if (!eula_screen_.get())
210    eula_screen_.reset(new chromeos::EulaScreen(
211        this, oobe_display_->GetEulaScreenActor()));
212  return eula_screen_.get();
213}
214
215chromeos::EnrollmentScreen*
216    WizardController::GetEnrollmentScreen() {
217  if (!enrollment_screen_.get()) {
218    enrollment_screen_.reset(
219        new chromeos::EnrollmentScreen(
220            this, oobe_display_->GetEnrollmentScreenActor()));
221  }
222  return enrollment_screen_.get();
223}
224
225chromeos::ResetScreen* WizardController::GetResetScreen() {
226  if (!reset_screen_.get()) {
227    reset_screen_.reset(
228        new chromeos::ResetScreen(this, oobe_display_->GetResetScreenActor()));
229  }
230  return reset_screen_.get();
231}
232
233chromeos::KioskEnableScreen* WizardController::GetKioskEnableScreen() {
234  if (!kiosk_enable_screen_.get()) {
235    kiosk_enable_screen_.reset(
236        new chromeos::KioskEnableScreen(
237            this,
238            oobe_display_->GetKioskEnableScreenActor()));
239  }
240  return kiosk_enable_screen_.get();
241}
242
243chromeos::KioskAutolaunchScreen* WizardController::GetKioskAutolaunchScreen() {
244  if (!autolaunch_screen_.get()) {
245    autolaunch_screen_.reset(
246        new chromeos::KioskAutolaunchScreen(
247            this, oobe_display_->GetKioskAutolaunchScreenActor()));
248  }
249  return autolaunch_screen_.get();
250}
251
252chromeos::TermsOfServiceScreen* WizardController::GetTermsOfServiceScreen() {
253  if (!terms_of_service_screen_.get()) {
254    terms_of_service_screen_.reset(
255        new chromeos::TermsOfServiceScreen(
256            this, oobe_display_->GetTermsOfServiceScreenActor()));
257  }
258  return terms_of_service_screen_.get();
259}
260
261chromeos::WrongHWIDScreen* WizardController::GetWrongHWIDScreen() {
262  if (!wrong_hwid_screen_.get()) {
263    wrong_hwid_screen_.reset(
264        new chromeos::WrongHWIDScreen(
265            this, oobe_display_->GetWrongHWIDScreenActor()));
266  }
267  return wrong_hwid_screen_.get();
268}
269
270chromeos::LocallyManagedUserCreationScreen*
271    WizardController::GetLocallyManagedUserCreationScreen() {
272  if (!locally_managed_user_creation_screen_.get()) {
273    locally_managed_user_creation_screen_.reset(
274        new chromeos::LocallyManagedUserCreationScreen(
275            this, oobe_display_->GetLocallyManagedUserCreationScreenActor()));
276  }
277  return locally_managed_user_creation_screen_.get();
278}
279
280void WizardController::ShowNetworkScreen() {
281  VLOG(1) << "Showing network screen.";
282  SetStatusAreaVisible(false);
283  SetCurrentScreen(GetNetworkScreen());
284}
285
286void WizardController::ShowLoginScreen(const LoginScreenContext& context) {
287  if (!time_eula_accepted_.is_null()) {
288    base::TimeDelta delta = base::Time::Now() - time_eula_accepted_;
289    UMA_HISTOGRAM_MEDIUM_TIMES("OOBE.EULAToSignInTime", delta);
290  }
291  VLOG(1) << "Showing login screen.";
292  SetStatusAreaVisible(true);
293  host_->StartSignInScreen(context);
294  smooth_show_timer_.Stop();
295  oobe_display_ = NULL;
296  login_screen_started_ = true;
297}
298
299void WizardController::ResumeLoginScreen() {
300  VLOG(1) << "Resuming login screen.";
301  SetStatusAreaVisible(true);
302  host_->ResumeSignInScreen();
303  smooth_show_timer_.Stop();
304  oobe_display_ = NULL;
305}
306
307void WizardController::ShowUpdateScreen() {
308  VLOG(1) << "Showing update screen.";
309  SetStatusAreaVisible(true);
310  SetCurrentScreen(GetUpdateScreen());
311}
312
313void WizardController::ShowUserImageScreen() {
314  const chromeos::UserManager* user_manager = chromeos::UserManager::Get();
315  // Skip user image selection for public sessions and ephemeral logins.
316  if (user_manager->IsLoggedInAsPublicAccount() ||
317      user_manager->IsCurrentUserNonCryptohomeDataEphemeral()) {
318    OnUserImageSkipped();
319    return;
320  }
321  VLOG(1) << "Showing user image screen.";
322
323  bool profile_picture_enabled = true;
324  std::string user_id;
325  if (screen_parameters_.get()) {
326    screen_parameters_->GetBoolean("profile_picture_enabled",
327        &profile_picture_enabled);
328    screen_parameters_->GetString("user_id", &user_id);
329  }
330
331  // Status area has been already shown at sign in screen so it
332  // doesn't make sense to hide it here and then show again at user session as
333  // this produces undesired UX transitions.
334  SetStatusAreaVisible(true);
335
336  UserImageScreen* screen = GetUserImageScreen();
337  if (!user_id.empty())
338    screen->SetUserID(user_id);
339  screen->SetProfilePictureEnabled(profile_picture_enabled);
340
341  SetCurrentScreen(screen);
342}
343
344void WizardController::ShowEulaScreen() {
345  VLOG(1) << "Showing EULA screen.";
346  SetStatusAreaVisible(false);
347  SetCurrentScreen(GetEulaScreen());
348}
349
350void WizardController::ShowEnrollmentScreen() {
351  SetStatusAreaVisible(true);
352
353  bool is_auto_enrollment = false;
354  std::string user;
355  if (screen_parameters_.get()) {
356    screen_parameters_->GetBoolean("is_auto_enrollment", &is_auto_enrollment);
357    screen_parameters_->GetString("user", &user);
358  }
359
360  EnrollmentScreen* screen = GetEnrollmentScreen();
361  screen->SetParameters(is_auto_enrollment,
362                        !ShouldAutoStartEnrollment() || CanExitEnrollment(),
363                        user);
364  SetCurrentScreen(screen);
365}
366
367void WizardController::ShowResetScreen() {
368  VLOG(1) << "Showing reset screen.";
369  SetStatusAreaVisible(false);
370  SetCurrentScreen(GetResetScreen());
371}
372
373void WizardController::ShowKioskEnableScreen() {
374  VLOG(1) << "Showing kiosk enable screen.";
375  SetStatusAreaVisible(false);
376  SetCurrentScreen(GetKioskEnableScreen());
377}
378
379void WizardController::ShowKioskAutolaunchScreen() {
380  VLOG(1) << "Showing kiosk autolaunch screen.";
381  SetStatusAreaVisible(false);
382  SetCurrentScreen(GetKioskAutolaunchScreen());
383}
384
385void WizardController::ShowTermsOfServiceScreen() {
386  // Only show the Terms of Service when logging into a public account and Terms
387  // of Service have been specified through policy. In all other cases, advance
388  // to the user image screen immediately.
389  if (!chromeos::UserManager::Get()->IsLoggedInAsPublicAccount() ||
390      !ProfileManager::GetDefaultProfile()->GetPrefs()->IsManagedPreference(
391          prefs::kTermsOfServiceURL)) {
392    ShowUserImageScreen();
393    return;
394  }
395
396  VLOG(1) << "Showing Terms of Service screen.";
397  SetStatusAreaVisible(true);
398  SetCurrentScreen(GetTermsOfServiceScreen());
399}
400
401void WizardController::ShowWrongHWIDScreen() {
402  VLOG(1) << "Showing wrong HWID screen.";
403  SetStatusAreaVisible(false);
404  SetCurrentScreen(GetWrongHWIDScreen());
405}
406
407void WizardController::ShowLocallyManagedUserCreationScreen() {
408  VLOG(1) << "Showing Locally managed user creation screen screen.";
409  SetStatusAreaVisible(true);
410  LocallyManagedUserCreationScreen* screen =
411      GetLocallyManagedUserCreationScreen();
412  SetCurrentScreen(screen);
413}
414
415void WizardController::SkipToLoginForTesting(
416    const LoginScreenContext& context) {
417  StartupUtils::MarkEulaAccepted();
418  PerformPostEulaActions();
419  PerformPostUpdateActions();
420  ShowLoginScreen(context);
421}
422
423void WizardController::SkipPostLoginScreensForTesting() {
424  skip_post_login_screens_ = true;
425}
426
427void WizardController::AddObserver(Observer* observer) {
428  observer_list_.AddObserver(observer);
429}
430
431void WizardController::RemoveObserver(Observer* observer) {
432  observer_list_.RemoveObserver(observer);
433}
434
435void WizardController::OnSessionStart() {
436  FOR_EACH_OBSERVER(Observer, observer_list_, OnSessionStart());
437}
438
439void WizardController::SkipUpdateEnrollAfterEula() {
440  skip_update_enroll_after_eula_ = true;
441}
442
443///////////////////////////////////////////////////////////////////////////////
444// WizardController, ExitHandlers:
445void WizardController::OnNetworkConnected() {
446  if (is_official_build_) {
447    if (!StartupUtils::IsEulaAccepted()) {
448      ShowEulaScreen();
449    } else {
450      // Possible cases:
451      // 1. EULA was accepted, forced shutdown/reboot during update.
452      // 2. EULA was accepted, planned reboot after update.
453      // Make sure that device is up-to-date.
454      InitiateOOBEUpdate();
455    }
456  } else {
457    InitiateOOBEUpdate();
458  }
459}
460
461void WizardController::OnNetworkOffline() {
462  // TODO(dpolukhin): if(is_out_of_box_) we cannot work offline and
463  // should report some error message here and stay on the same screen.
464  ShowLoginScreen(LoginScreenContext());
465}
466
467void WizardController::OnConnectionFailed() {
468  // TODO(dpolukhin): show error message after login screen is displayed.
469  ShowLoginScreen(LoginScreenContext());
470}
471
472void WizardController::OnUpdateCompleted() {
473  OnOOBECompleted();
474}
475
476void WizardController::OnEulaAccepted() {
477  time_eula_accepted_ = base::Time::Now();
478  StartupUtils::MarkEulaAccepted();
479  bool uma_enabled =
480      OptionsUtil::ResolveMetricsReportingEnabled(usage_statistics_reporting_);
481
482  CrosSettings::Get()->SetBoolean(kStatsReportingPref, uma_enabled);
483  if (uma_enabled) {
484#if defined(GOOGLE_CHROME_BUILD)
485    // The crash reporter initialization needs IO to complete.
486    base::ThreadRestrictions::ScopedAllowIO allow_io;
487    breakpad::InitCrashReporter();
488#endif
489  }
490
491  if (skip_update_enroll_after_eula_) {
492    PerformPostEulaActions();
493    PerformPostUpdateActions();
494    ShowEnrollmentScreen();
495  } else {
496    InitiateOOBEUpdate();
497  }
498}
499
500void WizardController::OnUpdateErrorCheckingForUpdate() {
501  // TODO(nkostylev): Update should be required during OOBE.
502  // We do not want to block users from being able to proceed to the login
503  // screen if there is any error checking for an update.
504  // They could use "browse without sign-in" feature to set up the network to be
505  // able to perform the update later.
506  OnOOBECompleted();
507}
508
509void WizardController::OnUpdateErrorUpdating() {
510  // If there was an error while getting or applying the update,
511  // return to network selection screen.
512  // TODO(nkostylev): Show message to the user explaining update error.
513  // TODO(nkostylev): Update should be required during OOBE.
514  // Temporary fix, need to migrate to new API. http://crosbug.com/4321
515  OnOOBECompleted();
516}
517
518void WizardController::EnableUserImageScreenReturnToPreviousHack() {
519  user_image_screen_return_to_previous_hack_ = true;
520}
521
522void WizardController::OnUserImageSelected() {
523  if (user_image_screen_return_to_previous_hack_) {
524    user_image_screen_return_to_previous_hack_ = false;
525    DCHECK(previous_screen_);
526    if (previous_screen_) {
527      SetCurrentScreen(previous_screen_);
528      return;
529    }
530  }
531  // Launch browser and delete login host controller.
532  BrowserThread::PostTask(
533      BrowserThread::UI,
534      FROM_HERE,
535      base::Bind(&chromeos::LoginUtils::DoBrowserLaunch,
536                 base::Unretained(chromeos::LoginUtils::Get()),
537                 ProfileManager::GetDefaultProfile(), host_));
538  host_ = NULL;
539  // TODO(avayvod): Sync image with Google Sync.
540}
541
542void WizardController::OnUserImageSkipped() {
543  OnUserImageSelected();
544}
545
546void WizardController::OnEnrollmentDone() {
547  // Mark OOBE as completed only if enterprise enrollment was part of the
548  // forced flow (i.e. app kiosk).
549  if (ShouldAutoStartEnrollment())
550    PerformPostUpdateActions();
551
552  // TODO(mnissler): Unify the logic for auto-login for Public Sessions and
553  // Kiosk Apps and make this code cover both cases: http://crbug.com/234694.
554  if (KioskAppManager::Get()->IsAutoLaunchEnabled())
555    AutoLaunchKioskApp();
556  else
557    ShowLoginScreen(LoginScreenContext());
558}
559
560void WizardController::OnResetCanceled() {
561  if (previous_screen_)
562    SetCurrentScreen(previous_screen_);
563  else
564    ShowLoginScreen(LoginScreenContext());
565}
566
567void WizardController::OnKioskAutolaunchCanceled() {
568  ShowLoginScreen(LoginScreenContext());
569}
570
571void WizardController::OnKioskAutolaunchConfirmed() {
572  DCHECK(KioskAppManager::Get()->IsAutoLaunchEnabled());
573  AutoLaunchKioskApp();
574}
575
576void WizardController::OnKioskEnableCompleted() {
577  ShowLoginScreen(LoginScreenContext());
578}
579
580void WizardController::OnWrongHWIDWarningSkipped() {
581  if (previous_screen_)
582    SetCurrentScreen(previous_screen_);
583  else
584    ShowLoginScreen(LoginScreenContext());
585}
586
587void WizardController::OnAutoEnrollmentDone() {
588  VLOG(1) << "Automagic enrollment done, resuming previous signin";
589  ResumeLoginScreen();
590}
591
592void WizardController::OnOOBECompleted() {
593  if (ShouldAutoStartEnrollment()) {
594    ShowEnrollmentScreen();
595  } else {
596    PerformPostUpdateActions();
597    ShowLoginScreen(LoginScreenContext());
598  }
599}
600
601void WizardController::OnTermsOfServiceDeclined() {
602  // If the user declines the Terms of Service, end the session and return to
603  // the login screen.
604  DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
605}
606
607void WizardController::OnTermsOfServiceAccepted() {
608  // If the user accepts the Terms of Service, advance to the user image screen.
609  ShowUserImageScreen();
610}
611
612void WizardController::InitiateOOBEUpdate() {
613  PerformPostEulaActions();
614  SetCurrentScreenSmooth(GetUpdateScreen(), true);
615  GetUpdateScreen()->StartNetworkCheck();
616}
617
618void WizardController::PerformPostEulaActions() {
619  // Now that EULA has been accepted (for official builds), enable portal check.
620  // ChromiumOS builds would go though this code path too.
621  NetworkHandler::Get()->network_state_handler()->SetCheckPortalList(
622      NetworkStateHandler::kDefaultCheckPortalList);
623  host_->CheckForAutoEnrollment();
624  host_->PrewarmAuthentication();
625  NetworkPortalDetector::Get()->Enable(true);
626}
627
628void WizardController::PerformPostUpdateActions() {
629  StartupUtils::MarkOobeCompleted();
630}
631
632void WizardController::SetCurrentScreen(WizardScreen* new_current) {
633  SetCurrentScreenSmooth(new_current, false);
634}
635
636void WizardController::ShowCurrentScreen() {
637  // ShowCurrentScreen may get called by smooth_show_timer_ even after
638  // flow has been switched to sign in screen (ExistingUserController).
639  if (!oobe_display_)
640    return;
641
642  smooth_show_timer_.Stop();
643
644  FOR_EACH_OBSERVER(Observer, observer_list_, OnScreenChanged(current_screen_));
645
646  oobe_display_->ShowScreen(current_screen_);
647}
648
649void WizardController::SetCurrentScreenSmooth(WizardScreen* new_current,
650                                              bool use_smoothing) {
651  if (current_screen_ == new_current ||
652      new_current == NULL ||
653      oobe_display_ == NULL) {
654    return;
655  }
656
657  smooth_show_timer_.Stop();
658
659  if (current_screen_)
660    oobe_display_->HideScreen(current_screen_);
661
662  previous_screen_ = current_screen_;
663  current_screen_ = new_current;
664
665  if (use_smoothing) {
666    smooth_show_timer_.Start(
667        FROM_HERE,
668        base::TimeDelta::FromMilliseconds(kShowDelayMs),
669        this,
670        &WizardController::ShowCurrentScreen);
671  } else {
672    ShowCurrentScreen();
673  }
674}
675
676void WizardController::SetStatusAreaVisible(bool visible) {
677  host_->SetStatusAreaVisible(visible);
678}
679
680void WizardController::AdvanceToScreenWithParams(
681    const std::string& screen_name,
682    base::DictionaryValue* screen_parameters) {
683  screen_parameters_.reset(screen_parameters);
684  AdvanceToScreen(screen_name);
685}
686
687void WizardController::AdvanceToScreen(const std::string& screen_name) {
688  if (screen_name == kNetworkScreenName) {
689    ShowNetworkScreen();
690  } else if (screen_name == kLoginScreenName) {
691    ShowLoginScreen(LoginScreenContext());
692  } else if (screen_name == kUpdateScreenName) {
693    InitiateOOBEUpdate();
694  } else if (screen_name == kUserImageScreenName) {
695    ShowUserImageScreen();
696  } else if (screen_name == kEulaScreenName) {
697    ShowEulaScreen();
698  } else if (screen_name == kResetScreenName) {
699    ShowResetScreen();
700  } else if (screen_name == kKioskEnableScreenName) {
701    ShowKioskEnableScreen();
702  } else if (screen_name == kKioskAutolaunchScreenName) {
703    ShowKioskAutolaunchScreen();
704  } else if (screen_name == kEnrollmentScreenName) {
705    ShowEnrollmentScreen();
706  } else if (screen_name == kTermsOfServiceScreenName) {
707    ShowTermsOfServiceScreen();
708  } else if (screen_name == kWrongHWIDScreenName) {
709    ShowWrongHWIDScreen();
710  } else if (screen_name == kLocallyManagedUserCreationScreenName) {
711    ShowLocallyManagedUserCreationScreen();
712  } else if (screen_name == kAppLaunchSplashScreenName) {
713    AutoLaunchKioskApp();
714  } else if (screen_name != kTestNoScreenName) {
715    if (is_out_of_box_) {
716      ShowNetworkScreen();
717    } else {
718      ShowLoginScreen(LoginScreenContext());
719    }
720  }
721}
722
723///////////////////////////////////////////////////////////////////////////////
724// WizardController, chromeos::ScreenObserver overrides:
725void WizardController::OnExit(ExitCodes exit_code) {
726  LOG(INFO) << "Wizard screen exit code: " << exit_code;
727  switch (exit_code) {
728    case NETWORK_CONNECTED:
729      OnNetworkConnected();
730      break;
731    case CONNECTION_FAILED:
732      OnConnectionFailed();
733      break;
734    case UPDATE_INSTALLED:
735    case UPDATE_NOUPDATE:
736      OnUpdateCompleted();
737      break;
738    case UPDATE_ERROR_CHECKING_FOR_UPDATE:
739      OnUpdateErrorCheckingForUpdate();
740      break;
741    case UPDATE_ERROR_UPDATING:
742      OnUpdateErrorUpdating();
743      break;
744    case USER_IMAGE_SELECTED:
745      OnUserImageSelected();
746      break;
747    case EULA_ACCEPTED:
748      OnEulaAccepted();
749      break;
750    case EULA_BACK:
751      ShowNetworkScreen();
752      break;
753    case ENTERPRISE_ENROLLMENT_COMPLETED:
754      OnEnrollmentDone();
755      break;
756    case ENTERPRISE_ENROLLMENT_BACK:
757      ShowNetworkScreen();
758      break;
759    case RESET_CANCELED:
760      OnResetCanceled();
761      break;
762    case KIOSK_AUTOLAUNCH_CANCELED:
763      OnKioskAutolaunchCanceled();
764      break;
765    case KIOSK_AUTOLAUNCH_CONFIRMED:
766      OnKioskAutolaunchConfirmed();
767      break;
768    case KIOSK_ENABLE_COMPLETED:
769      OnKioskEnableCompleted();
770      break;
771    case ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED:
772      OnAutoEnrollmentDone();
773      break;
774    case TERMS_OF_SERVICE_DECLINED:
775      OnTermsOfServiceDeclined();
776      break;
777    case TERMS_OF_SERVICE_ACCEPTED:
778      OnTermsOfServiceAccepted();
779      break;
780    case WRONG_HWID_WARNING_SKIPPED:
781      OnWrongHWIDWarningSkipped();
782      break;
783    default:
784      NOTREACHED();
785  }
786}
787
788void WizardController::OnSetUserNamePassword(const std::string& username,
789                                             const std::string& password) {
790  username_ = username;
791  password_ = password;
792}
793
794void WizardController::SetUsageStatisticsReporting(bool val) {
795  usage_statistics_reporting_ = val;
796}
797
798bool WizardController::GetUsageStatisticsReporting() const {
799  return usage_statistics_reporting_;
800}
801
802chromeos::ErrorScreen* WizardController::GetErrorScreen() {
803  if (!error_screen_.get()) {
804    error_screen_.reset(
805        new chromeos::ErrorScreen(this, oobe_display_->GetErrorScreenActor()));
806  }
807  return error_screen_.get();
808}
809
810void WizardController::ShowErrorScreen() {
811  VLOG(1) << "Showing error screen.";
812  SetCurrentScreen(GetErrorScreen());
813}
814
815void WizardController::HideErrorScreen(WizardScreen* parent_screen) {
816  DCHECK(parent_screen);
817  VLOG(1) << "Hiding error screen.";
818  SetCurrentScreen(parent_screen);
819}
820
821void WizardController::AutoLaunchKioskApp() {
822  KioskAppManager::App app_data;
823  std::string app_id = KioskAppManager::Get()->GetAutoLaunchApp();
824  CHECK(KioskAppManager::Get()->GetApp(app_id, &app_data));
825
826  host_->StartAppLaunch(app_id);
827}
828
829// static
830bool WizardController::IsZeroDelayEnabled() {
831  return zero_delay_enabled_;
832}
833
834// static
835void WizardController::SetZeroDelays() {
836  kShowDelayMs = 0;
837  zero_delay_enabled_ = true;
838}
839
840bool WizardController::ShouldAutoStartEnrollment() const {
841  return g_browser_process->browser_policy_connector()->
842      GetDeviceCloudPolicyManager()->ShouldAutoStartEnrollment();
843}
844
845bool WizardController::CanExitEnrollment() const {
846  return g_browser_process->browser_policy_connector()->
847      GetDeviceCloudPolicyManager()->CanExitEnrollment();
848}
849
850void WizardController::OnLocalStateInitialized(bool /* succeeded */) {
851  if (GetLocalState()->GetInitializationStatus() !=
852      PrefService::INITIALIZATION_STATUS_ERROR) {
853    return;
854  }
855  GetErrorScreen()->SetUIState(ErrorScreen::UI_STATE_LOCAL_STATE_ERROR);
856  SetStatusAreaVisible(false);
857  ShowErrorScreen();
858}
859
860PrefService* WizardController::GetLocalState() {
861  if (local_state_for_testing_)
862    return local_state_for_testing_;
863  return g_browser_process->local_state();
864}
865
866}  // namespace chromeos
867