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