147667a179f3c09d975566daf2d6e8ab8f800bf3
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / wizard_controller.cc
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/callback_helpers.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/strings/utf_string_conversions.h"
21 #include "base/threading/thread_restrictions.h"
22 #include "base/values.h"
23 #include "chrome/browser/browser_process.h"
24 #include "chrome/browser/chrome_notification_types.h"
25 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
26 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
27 #include "chrome/browser/chromeos/customization_document.h"
28 #include "chrome/browser/chromeos/geolocation/simple_geolocation_provider.h"
29 #include "chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.h"
30 #include "chrome/browser/chromeos/login/enrollment/enrollment_screen.h"
31 #include "chrome/browser/chromeos/login/existing_user_controller.h"
32 #include "chrome/browser/chromeos/login/helper.h"
33 #include "chrome/browser/chromeos/login/hwid_checker.h"
34 #include "chrome/browser/chromeos/login/login_utils.h"
35 #include "chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.h"
36 #include "chrome/browser/chromeos/login/screens/error_screen.h"
37 #include "chrome/browser/chromeos/login/screens/eula_screen.h"
38 #include "chrome/browser/chromeos/login/screens/hid_detection_screen.h"
39 #include "chrome/browser/chromeos/login/screens/kiosk_autolaunch_screen.h"
40 #include "chrome/browser/chromeos/login/screens/kiosk_enable_screen.h"
41 #include "chrome/browser/chromeos/login/screens/network_screen.h"
42 #include "chrome/browser/chromeos/login/screens/reset_screen.h"
43 #include "chrome/browser/chromeos/login/screens/terms_of_service_screen.h"
44 #include "chrome/browser/chromeos/login/screens/update_screen.h"
45 #include "chrome/browser/chromeos/login/screens/user_image_screen.h"
46 #include "chrome/browser/chromeos/login/screens/wrong_hwid_screen.h"
47 #include "chrome/browser/chromeos/login/startup_utils.h"
48 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
49 #include "chrome/browser/chromeos/login/ui/oobe_display.h"
50 #include "chrome/browser/chromeos/login/users/user_manager.h"
51 #include "chrome/browser/chromeos/net/delay_network_call.h"
52 #include "chrome/browser/chromeos/net/network_portal_detector.h"
53 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
54 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
55 #include "chrome/browser/chromeos/settings/cros_settings.h"
56 #include "chrome/browser/chromeos/timezone/timezone_provider.h"
57 #include "chrome/browser/profiles/profile.h"
58 #include "chrome/browser/profiles/profile_manager.h"
59 #include "chrome/browser/ui/options/options_util.h"
60 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
61 #include "chrome/common/chrome_constants.h"
62 #include "chrome/common/pref_names.h"
63 #include "chromeos/audio/cras_audio_handler.h"
64 #include "chromeos/chromeos_constants.h"
65 #include "chromeos/chromeos_switches.h"
66 #include "chromeos/dbus/dbus_thread_manager.h"
67 #include "chromeos/dbus/session_manager_client.h"
68 #include "chromeos/network/network_state.h"
69 #include "chromeos/network/network_state_handler.h"
70 #include "chromeos/settings/cros_settings_names.h"
71 #include "chromeos/settings/timezone_settings.h"
72 #include "components/breakpad/app/breakpad_linux.h"
73 #include "content/public/browser/browser_thread.h"
74 #include "content/public/browser/notification_types.h"
75 #include "ui/base/accelerators/accelerator.h"
76 #include "ui/base/l10n/l10n_util.h"
77
78 using content::BrowserThread;
79
80 namespace {
81 // If reboot didn't happen, ask user to reboot device manually.
82 const int kWaitForRebootTimeSec = 3;
83
84 // Interval in ms which is used for smooth screen showing.
85 static int kShowDelayMs = 400;
86
87 // Total timezone resolving process timeout.
88 const unsigned int kResolveTimeZoneTimeoutSeconds = 60;
89
90 // Stores the list of all screens that should be shown when resuming OOBE.
91 const char *kResumableScreens[] = {
92   chromeos::WizardController::kNetworkScreenName,
93   chromeos::WizardController::kUpdateScreenName,
94   chromeos::WizardController::kEulaScreenName,
95   chromeos::WizardController::kEnrollmentScreenName,
96   chromeos::WizardController::kTermsOfServiceScreenName,
97   chromeos::WizardController::kAutoEnrollmentCheckScreenName
98 };
99
100 // Checks flag for HID-detection screen show.
101 bool CanShowHIDDetectionScreen() {
102   return !CommandLine::ForCurrentProcess()->HasSwitch(
103         chromeos::switches::kDisableHIDDetectionOnOOBE);
104 }
105
106 bool IsResumableScreen(const std::string& screen) {
107   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kResumableScreens); ++i) {
108     if (screen == kResumableScreens[i])
109       return true;
110   }
111   return false;
112 }
113
114 }  // namespace
115
116 namespace chromeos {
117
118 const char WizardController::kNetworkScreenName[] = "network";
119 const char WizardController::kLoginScreenName[] = "login";
120 const char WizardController::kUpdateScreenName[] = "update";
121 const char WizardController::kUserImageScreenName[] = "image";
122 const char WizardController::kEulaScreenName[] = "eula";
123 const char WizardController::kEnrollmentScreenName[] = "enroll";
124 const char WizardController::kResetScreenName[] = "reset";
125 const char WizardController::kKioskEnableScreenName[] = "kiosk-enable";
126 const char WizardController::kKioskAutolaunchScreenName[] = "autolaunch";
127 const char WizardController::kErrorScreenName[] = "error-message";
128 const char WizardController::kTermsOfServiceScreenName[] = "tos";
129 const char WizardController::kAutoEnrollmentCheckScreenName[] =
130   "auto-enrollment-check";
131 const char WizardController::kWrongHWIDScreenName[] = "wrong-hwid";
132 const char WizardController::kLocallyManagedUserCreationScreenName[] =
133   "locally-managed-user-creation-flow";
134 const char WizardController::kAppLaunchSplashScreenName[] =
135   "app-launch-splash";
136 const char WizardController::kHIDDetectionScreenName[] = "hid-detection";
137
138 // static
139 const int WizardController::kMinAudibleOutputVolumePercent = 10;
140
141 // Passing this parameter as a "first screen" initiates full OOBE flow.
142 const char WizardController::kOutOfBoxScreenName[] = "oobe";
143
144 // Special test value that commands not to create any window yet.
145 const char WizardController::kTestNoScreenName[] = "test:nowindow";
146
147 // Initialize default controller.
148 // static
149 WizardController* WizardController::default_controller_ = NULL;
150
151 // static
152 bool WizardController::skip_post_login_screens_ = false;
153
154 // static
155 bool WizardController::zero_delay_enabled_ = false;
156
157 ///////////////////////////////////////////////////////////////////////////////
158 // WizardController, public:
159
160 PrefService* WizardController::local_state_for_testing_ = NULL;
161
162 WizardController::WizardController(chromeos::LoginDisplayHost* host,
163                                    chromeos::OobeDisplay* oobe_display)
164     : current_screen_(NULL),
165       previous_screen_(NULL),
166 #if defined(GOOGLE_CHROME_BUILD)
167       is_official_build_(true),
168 #else
169       is_official_build_(false),
170 #endif
171       is_out_of_box_(false),
172       host_(host),
173       oobe_display_(oobe_display),
174       usage_statistics_reporting_(true),
175       skip_update_enroll_after_eula_(false),
176       login_screen_started_(false),
177       user_image_screen_return_to_previous_hack_(false),
178       timezone_resolved_(false),
179       weak_factory_(this) {
180   DCHECK(default_controller_ == NULL);
181   default_controller_ = this;
182   AccessibilityManager* accessibility_manager = AccessibilityManager::Get();
183   CHECK(accessibility_manager);
184   accessibility_subscription_ = accessibility_manager->RegisterCallback(
185       base::Bind(&WizardController::OnAccessibilityStatusChanged,
186                  base::Unretained(this)));
187 }
188
189 WizardController::~WizardController() {
190   if (default_controller_ == this) {
191     default_controller_ = NULL;
192   } else {
193     NOTREACHED() << "More than one controller are alive.";
194   }
195 }
196
197 void WizardController::Init(
198     const std::string& first_screen_name,
199     scoped_ptr<base::DictionaryValue> screen_parameters) {
200   VLOG(1) << "Starting OOBE wizard with screen: " << first_screen_name;
201   first_screen_name_ = first_screen_name;
202   screen_parameters_ = screen_parameters.Pass();
203
204   bool oobe_complete = StartupUtils::IsOobeCompleted();
205   if (!oobe_complete || first_screen_name == kOutOfBoxScreenName)
206     is_out_of_box_ = true;
207
208   // This is a hacky way to check for local state corruption, because
209   // it depends on the fact that the local state is loaded
210   // synchroniously and at the first demand. IsEnterpriseManaged()
211   // check is required because currently powerwash is disabled for
212   // enterprise-entrolled devices.
213   //
214   // TODO (ygorshenin@): implement handling of the local state
215   // corruption in the case of asynchronious loading.
216   //
217   // TODO (ygorshenin@): remove IsEnterpriseManaged() check once
218   // crbug.com/241313 will be fixed.
219   policy::BrowserPolicyConnectorChromeOS* connector =
220       g_browser_process->platform_part()->browser_policy_connector_chromeos();
221   if (!connector->IsEnterpriseManaged()) {
222     const PrefService::PrefInitializationStatus status =
223         GetLocalState()->GetInitializationStatus();
224     if (status == PrefService::INITIALIZATION_STATUS_ERROR) {
225       OnLocalStateInitialized(false);
226       return;
227     } else if (status == PrefService::INITIALIZATION_STATUS_WAITING) {
228       GetLocalState()->AddPrefInitObserver(
229           base::Bind(&WizardController::OnLocalStateInitialized,
230                      weak_factory_.GetWeakPtr()));
231     }
232   }
233
234   const std::string screen_pref =
235       GetLocalState()->GetString(prefs::kOobeScreenPending);
236   if (is_out_of_box_ && !screen_pref.empty() && (first_screen_name.empty() ||
237       first_screen_name == WizardController::kTestNoScreenName)) {
238     first_screen_name_ = screen_pref;
239   }
240
241   AdvanceToScreen(first_screen_name_);
242   if (!IsMachineHWIDCorrect() && !StartupUtils::IsDeviceRegistered() &&
243       first_screen_name_.empty())
244     ShowWrongHWIDScreen();
245 }
246
247 chromeos::NetworkScreen* WizardController::GetNetworkScreen() {
248   if (!network_screen_.get())
249     network_screen_.reset(new chromeos::NetworkScreen(
250         this, oobe_display_->GetNetworkScreenActor()));
251   return network_screen_.get();
252 }
253
254 chromeos::UpdateScreen* WizardController::GetUpdateScreen() {
255   if (!update_screen_.get()) {
256     update_screen_.reset(new chromeos::UpdateScreen(
257         this, oobe_display_->GetUpdateScreenActor()));
258     update_screen_->SetRebootCheckDelay(kWaitForRebootTimeSec);
259   }
260   return update_screen_.get();
261 }
262
263 chromeos::UserImageScreen* WizardController::GetUserImageScreen() {
264   if (!user_image_screen_.get())
265     user_image_screen_.reset(
266         new chromeos::UserImageScreen(
267             this, oobe_display_->GetUserImageScreenActor()));
268   return user_image_screen_.get();
269 }
270
271 chromeos::EulaScreen* WizardController::GetEulaScreen() {
272   if (!eula_screen_.get())
273     eula_screen_.reset(new chromeos::EulaScreen(
274         this, oobe_display_->GetEulaScreenActor()));
275   return eula_screen_.get();
276 }
277
278 chromeos::EnrollmentScreen*
279     WizardController::GetEnrollmentScreen() {
280   if (!enrollment_screen_.get()) {
281     enrollment_screen_.reset(
282         new chromeos::EnrollmentScreen(
283             this, oobe_display_->GetEnrollmentScreenActor()));
284   }
285   return enrollment_screen_.get();
286 }
287
288 chromeos::ResetScreen* WizardController::GetResetScreen() {
289   if (!reset_screen_.get()) {
290     reset_screen_.reset(
291         new chromeos::ResetScreen(this, oobe_display_->GetResetScreenActor()));
292   }
293   return reset_screen_.get();
294 }
295
296 chromeos::KioskEnableScreen* WizardController::GetKioskEnableScreen() {
297   if (!kiosk_enable_screen_.get()) {
298     kiosk_enable_screen_.reset(
299         new chromeos::KioskEnableScreen(
300             this,
301             oobe_display_->GetKioskEnableScreenActor()));
302   }
303   return kiosk_enable_screen_.get();
304 }
305
306 chromeos::KioskAutolaunchScreen* WizardController::GetKioskAutolaunchScreen() {
307   if (!autolaunch_screen_.get()) {
308     autolaunch_screen_.reset(
309         new chromeos::KioskAutolaunchScreen(
310             this, oobe_display_->GetKioskAutolaunchScreenActor()));
311   }
312   return autolaunch_screen_.get();
313 }
314
315 chromeos::TermsOfServiceScreen* WizardController::GetTermsOfServiceScreen() {
316   if (!terms_of_service_screen_.get()) {
317     terms_of_service_screen_.reset(
318         new chromeos::TermsOfServiceScreen(
319             this, oobe_display_->GetTermsOfServiceScreenActor()));
320   }
321   return terms_of_service_screen_.get();
322 }
323
324 chromeos::WrongHWIDScreen* WizardController::GetWrongHWIDScreen() {
325   if (!wrong_hwid_screen_.get()) {
326     wrong_hwid_screen_.reset(
327         new chromeos::WrongHWIDScreen(
328             this, oobe_display_->GetWrongHWIDScreenActor()));
329   }
330   return wrong_hwid_screen_.get();
331 }
332
333 chromeos::AutoEnrollmentCheckScreen*
334     WizardController::GetAutoEnrollmentCheckScreen() {
335   if (!auto_enrollment_check_screen_.get()) {
336     auto_enrollment_check_screen_.reset(
337         new chromeos::AutoEnrollmentCheckScreen(
338             this,
339             oobe_display_->GetAutoEnrollmentCheckScreenActor()));
340   }
341   return auto_enrollment_check_screen_.get();
342 }
343
344 chromeos::LocallyManagedUserCreationScreen*
345     WizardController::GetLocallyManagedUserCreationScreen() {
346   if (!locally_managed_user_creation_screen_.get()) {
347     locally_managed_user_creation_screen_.reset(
348         new chromeos::LocallyManagedUserCreationScreen(
349             this, oobe_display_->GetLocallyManagedUserCreationScreenActor()));
350   }
351   return locally_managed_user_creation_screen_.get();
352 }
353
354 chromeos::HIDDetectionScreen* WizardController::GetHIDDetectionScreen() {
355   if (!hid_detection_screen_.get()) {
356     hid_detection_screen_.reset(
357         new chromeos::HIDDetectionScreen(
358             this, oobe_display_->GetHIDDetectionScreenActor()));
359   }
360   return hid_detection_screen_.get();
361 }
362
363 void WizardController::ShowNetworkScreen() {
364   VLOG(1) << "Showing network screen.";
365   // Hide the status area initially; it only appears after OOBE first animates
366   // in. Keep it visible if the user goes back to the existing network screen.
367   SetStatusAreaVisible(network_screen_.get());
368   SetCurrentScreen(GetNetworkScreen());
369 }
370
371 void WizardController::ShowLoginScreen(const LoginScreenContext& context) {
372   if (!time_eula_accepted_.is_null()) {
373     base::TimeDelta delta = base::Time::Now() - time_eula_accepted_;
374     UMA_HISTOGRAM_MEDIUM_TIMES("OOBE.EULAToSignInTime", delta);
375   }
376   VLOG(1) << "Showing login screen.";
377   SetStatusAreaVisible(true);
378   host_->StartSignInScreen(context);
379   smooth_show_timer_.Stop();
380   oobe_display_ = NULL;
381   login_screen_started_ = true;
382 }
383
384 void WizardController::ResumeLoginScreen() {
385   VLOG(1) << "Resuming login screen.";
386   SetStatusAreaVisible(true);
387   host_->ResumeSignInScreen();
388   smooth_show_timer_.Stop();
389   oobe_display_ = NULL;
390 }
391
392 void WizardController::ShowUpdateScreen() {
393   VLOG(1) << "Showing update screen.";
394   SetStatusAreaVisible(true);
395   SetCurrentScreen(GetUpdateScreen());
396 }
397
398 void WizardController::ShowUserImageScreen() {
399   const chromeos::UserManager* user_manager = chromeos::UserManager::Get();
400   // Skip user image selection for public sessions and ephemeral logins.
401   if (user_manager->IsLoggedInAsPublicAccount() ||
402       user_manager->IsCurrentUserNonCryptohomeDataEphemeral()) {
403     OnUserImageSkipped();
404     return;
405   }
406   VLOG(1) << "Showing user image screen.";
407
408   bool profile_picture_enabled = true;
409   std::string user_id;
410   if (screen_parameters_.get()) {
411     screen_parameters_->GetBoolean("profile_picture_enabled",
412         &profile_picture_enabled);
413     screen_parameters_->GetString("user_id", &user_id);
414   }
415
416   // Status area has been already shown at sign in screen so it
417   // doesn't make sense to hide it here and then show again at user session as
418   // this produces undesired UX transitions.
419   SetStatusAreaVisible(true);
420
421   UserImageScreen* screen = GetUserImageScreen();
422   if (!user_id.empty())
423     screen->SetUserID(user_id);
424   screen->SetProfilePictureEnabled(profile_picture_enabled);
425
426   SetCurrentScreen(screen);
427 }
428
429 void WizardController::ShowEulaScreen() {
430   VLOG(1) << "Showing EULA screen.";
431   SetStatusAreaVisible(true);
432   SetCurrentScreen(GetEulaScreen());
433 }
434
435 void WizardController::ShowEnrollmentScreen() {
436   VLOG(1) << "Showing enrollment screen.";
437
438   SetStatusAreaVisible(true);
439
440   bool is_auto_enrollment = false;
441   std::string user;
442   if (screen_parameters_.get()) {
443     screen_parameters_->GetBoolean("is_auto_enrollment", &is_auto_enrollment);
444     screen_parameters_->GetString("user", &user);
445   }
446
447   EnrollmentScreenActor::EnrollmentMode mode =
448       EnrollmentScreenActor::ENROLLMENT_MODE_MANUAL;
449   if (is_auto_enrollment)
450     mode = EnrollmentScreenActor::ENROLLMENT_MODE_AUTO;
451   else if (ShouldAutoStartEnrollment() && !CanExitEnrollment())
452     mode = EnrollmentScreenActor::ENROLLMENT_MODE_FORCED;
453
454   EnrollmentScreen* screen = GetEnrollmentScreen();
455   screen->SetParameters(mode, GetForcedEnrollmentDomain(), user);
456   SetCurrentScreen(screen);
457 }
458
459 void WizardController::ShowResetScreen() {
460   VLOG(1) << "Showing reset screen.";
461   SetStatusAreaVisible(false);
462   SetCurrentScreen(GetResetScreen());
463 }
464
465 void WizardController::ShowKioskEnableScreen() {
466   VLOG(1) << "Showing kiosk enable screen.";
467   SetStatusAreaVisible(false);
468   SetCurrentScreen(GetKioskEnableScreen());
469 }
470
471 void WizardController::ShowKioskAutolaunchScreen() {
472   VLOG(1) << "Showing kiosk autolaunch screen.";
473   SetStatusAreaVisible(false);
474   SetCurrentScreen(GetKioskAutolaunchScreen());
475 }
476
477 void WizardController::ShowTermsOfServiceScreen() {
478   // Only show the Terms of Service when logging into a public account and Terms
479   // of Service have been specified through policy. In all other cases, advance
480   // to the user image screen immediately.
481   if (!chromeos::UserManager::Get()->IsLoggedInAsPublicAccount() ||
482       !ProfileManager::GetActiveUserProfile()->GetPrefs()->
483           IsManagedPreference(prefs::kTermsOfServiceURL)) {
484     ShowUserImageScreen();
485     return;
486   }
487
488   VLOG(1) << "Showing Terms of Service screen.";
489   SetStatusAreaVisible(true);
490   SetCurrentScreen(GetTermsOfServiceScreen());
491 }
492
493 void WizardController::ShowWrongHWIDScreen() {
494   VLOG(1) << "Showing wrong HWID screen.";
495   SetStatusAreaVisible(false);
496   SetCurrentScreen(GetWrongHWIDScreen());
497 }
498
499 void WizardController::ShowAutoEnrollmentCheckScreen() {
500   VLOG(1) << "Showing Auto-enrollment check screen.";
501   SetStatusAreaVisible(true);
502   AutoEnrollmentCheckScreen* screen = GetAutoEnrollmentCheckScreen();
503   screen->set_auto_enrollment_controller(host_->GetAutoEnrollmentController());
504   SetCurrentScreen(screen);
505 }
506
507 void WizardController::ShowLocallyManagedUserCreationScreen() {
508   VLOG(1) << "Showing Locally managed user creation screen screen.";
509   SetStatusAreaVisible(true);
510   LocallyManagedUserCreationScreen* screen =
511       GetLocallyManagedUserCreationScreen();
512   SetCurrentScreen(screen);
513 }
514
515 void WizardController::ShowHIDDetectionScreen() {
516   VLOG(1) << "Showing HID discovery screen.";
517   SetStatusAreaVisible(true);
518   SetCurrentScreen(GetHIDDetectionScreen());
519 }
520
521 void WizardController::SkipToLoginForTesting(
522     const LoginScreenContext& context) {
523   VLOG(1) << "SkipToLoginForTesting.";
524   StartupUtils::MarkEulaAccepted();
525   PerformPostEulaActions();
526   OnOOBECompleted();
527 }
528
529 void WizardController::AddObserver(Observer* observer) {
530   observer_list_.AddObserver(observer);
531 }
532
533 void WizardController::RemoveObserver(Observer* observer) {
534   observer_list_.RemoveObserver(observer);
535 }
536
537 void WizardController::OnSessionStart() {
538   FOR_EACH_OBSERVER(Observer, observer_list_, OnSessionStart());
539 }
540
541 void WizardController::SkipUpdateEnrollAfterEula() {
542   skip_update_enroll_after_eula_ = true;
543 }
544
545 ///////////////////////////////////////////////////////////////////////////////
546 // WizardController, ExitHandlers:
547 void WizardController::OnHIDDetectionCompleted() {
548   // Check for tests configuration.
549   if (!StartupUtils::IsOobeCompleted())
550     ShowNetworkScreen();
551 }
552
553 void WizardController::OnNetworkConnected() {
554   if (is_official_build_) {
555     if (!StartupUtils::IsEulaAccepted()) {
556       ShowEulaScreen();
557     } else {
558       // Possible cases:
559       // 1. EULA was accepted, forced shutdown/reboot during update.
560       // 2. EULA was accepted, planned reboot after update.
561       // Make sure that device is up-to-date.
562       InitiateOOBEUpdate();
563     }
564   } else {
565     InitiateOOBEUpdate();
566   }
567 }
568
569 void WizardController::OnNetworkOffline() {
570   // TODO(dpolukhin): if(is_out_of_box_) we cannot work offline and
571   // should report some error message here and stay on the same screen.
572   ShowLoginScreen(LoginScreenContext());
573 }
574
575 void WizardController::OnConnectionFailed() {
576   // TODO(dpolukhin): show error message after login screen is displayed.
577   ShowLoginScreen(LoginScreenContext());
578 }
579
580 void WizardController::OnUpdateCompleted() {
581   ShowAutoEnrollmentCheckScreen();
582 }
583
584 void WizardController::OnEulaAccepted() {
585   time_eula_accepted_ = base::Time::Now();
586   StartupUtils::MarkEulaAccepted();
587   bool uma_enabled =
588       OptionsUtil::ResolveMetricsReportingEnabled(usage_statistics_reporting_);
589
590   CrosSettings::Get()->SetBoolean(kStatsReportingPref, uma_enabled);
591   if (uma_enabled) {
592 #if defined(GOOGLE_CHROME_BUILD)
593     // The crash reporter initialization needs IO to complete.
594     base::ThreadRestrictions::ScopedAllowIO allow_io;
595     breakpad::InitCrashReporter(std::string());
596 #endif
597   }
598
599   if (skip_update_enroll_after_eula_) {
600     PerformPostEulaActions();
601     ShowAutoEnrollmentCheckScreen();
602   } else {
603     InitiateOOBEUpdate();
604   }
605 }
606
607 void WizardController::OnUpdateErrorCheckingForUpdate() {
608   // TODO(nkostylev): Update should be required during OOBE.
609   // We do not want to block users from being able to proceed to the login
610   // screen if there is any error checking for an update.
611   // They could use "browse without sign-in" feature to set up the network to be
612   // able to perform the update later.
613   OnUpdateCompleted();
614 }
615
616 void WizardController::OnUpdateErrorUpdating() {
617   // If there was an error while getting or applying the update,
618   // return to network selection screen.
619   // TODO(nkostylev): Show message to the user explaining update error.
620   // TODO(nkostylev): Update should be required during OOBE.
621   // Temporary fix, need to migrate to new API. http://crosbug.com/4321
622   OnUpdateCompleted();
623 }
624
625 void WizardController::EnableUserImageScreenReturnToPreviousHack() {
626   user_image_screen_return_to_previous_hack_ = true;
627 }
628
629 void WizardController::OnUserImageSelected() {
630   if (user_image_screen_return_to_previous_hack_) {
631     user_image_screen_return_to_previous_hack_ = false;
632     DCHECK(previous_screen_);
633     if (previous_screen_) {
634       SetCurrentScreen(previous_screen_);
635       return;
636     }
637   }
638   // Launch browser and delete login host controller.
639   BrowserThread::PostTask(
640       BrowserThread::UI,
641       FROM_HERE,
642       base::Bind(&chromeos::LoginUtils::DoBrowserLaunch,
643                  base::Unretained(chromeos::LoginUtils::Get()),
644                  ProfileManager::GetActiveUserProfile(), host_));
645   host_ = NULL;
646 }
647
648 void WizardController::OnUserImageSkipped() {
649   OnUserImageSelected();
650 }
651
652 void WizardController::OnEnrollmentDone() {
653   // Mark OOBE as completed only if enterprise enrollment was part of the
654   // forced flow (i.e. app kiosk).
655   if (ShouldAutoStartEnrollment())
656     PerformOOBECompletedActions();
657
658   // TODO(mnissler): Unify the logic for auto-login for Public Sessions and
659   // Kiosk Apps and make this code cover both cases: http://crbug.com/234694.
660   if (KioskAppManager::Get()->IsAutoLaunchEnabled())
661     AutoLaunchKioskApp();
662   else
663     ShowLoginScreen(LoginScreenContext());
664 }
665
666 void WizardController::OnResetCanceled() {
667   if (previous_screen_) {
668     SetCurrentScreen(previous_screen_);
669   } else {
670     ShowLoginScreen(LoginScreenContext());
671   }
672 }
673
674 void WizardController::OnKioskAutolaunchCanceled() {
675   ShowLoginScreen(LoginScreenContext());
676 }
677
678 void WizardController::OnKioskAutolaunchConfirmed() {
679   DCHECK(KioskAppManager::Get()->IsAutoLaunchEnabled());
680   AutoLaunchKioskApp();
681 }
682
683 void WizardController::OnKioskEnableCompleted() {
684   ShowLoginScreen(LoginScreenContext());
685 }
686
687 void WizardController::OnWrongHWIDWarningSkipped() {
688   if (previous_screen_)
689     SetCurrentScreen(previous_screen_);
690   else
691     ShowLoginScreen(LoginScreenContext());
692 }
693
694 void WizardController::OnAutoEnrollmentDone() {
695   VLOG(1) << "Automagic enrollment done, resuming previous signin";
696   ResumeLoginScreen();
697 }
698
699 void WizardController::OnOOBECompleted() {
700   if (ShouldAutoStartEnrollment()) {
701     ShowEnrollmentScreen();
702   } else {
703     PerformOOBECompletedActions();
704     ShowLoginScreen(LoginScreenContext());
705   }
706 }
707
708 void WizardController::OnTermsOfServiceDeclined() {
709   // If the user declines the Terms of Service, end the session and return to
710   // the login screen.
711   DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
712 }
713
714 void WizardController::OnTermsOfServiceAccepted() {
715   // If the user accepts the Terms of Service, advance to the user image screen.
716   ShowUserImageScreen();
717 }
718
719 void WizardController::InitiateOOBEUpdate() {
720   PerformPostEulaActions();
721   SetCurrentScreenSmooth(GetUpdateScreen(), true);
722   GetUpdateScreen()->StartNetworkCheck();
723 }
724
725 void WizardController::StartTimezoneResolve() {
726   geolocation_provider_.reset(new SimpleGeolocationProvider(
727       g_browser_process->system_request_context(),
728       SimpleGeolocationProvider::DefaultGeolocationProviderURL()));
729   geolocation_provider_->RequestGeolocation(
730       base::TimeDelta::FromSeconds(kResolveTimeZoneTimeoutSeconds),
731       base::Bind(&WizardController::OnLocationResolved,
732                  weak_factory_.GetWeakPtr()));
733 }
734
735 void WizardController::PerformPostEulaActions() {
736   DelayNetworkCall(
737       base::Bind(&WizardController::StartTimezoneResolve,
738                  weak_factory_.GetWeakPtr()),
739       base::TimeDelta::FromMilliseconds(kDefaultNetworkRetryDelayMS));
740   DelayNetworkCall(
741       ServicesCustomizationDocument::GetInstance()
742           ->EnsureCustomizationAppliedClosure(),
743       base::TimeDelta::FromMilliseconds(kDefaultNetworkRetryDelayMS));
744
745   // Now that EULA has been accepted (for official builds), enable portal check.
746   // ChromiumOS builds would go though this code path too.
747   NetworkHandler::Get()->network_state_handler()->SetCheckPortalList(
748       NetworkStateHandler::kDefaultCheckPortalList);
749   host_->GetAutoEnrollmentController()->Start();
750   host_->PrewarmAuthentication();
751   NetworkPortalDetector::Get()->Enable(true);
752 }
753
754 void WizardController::PerformOOBECompletedActions() {
755   StartupUtils::MarkOobeCompleted();
756   UMA_HISTOGRAM_COUNTS_100(
757       "HIDDetection.TimesDialogShownPerOOBECompleted",
758       GetLocalState()->GetInteger(prefs::kTimesHIDDialogShown));
759   GetLocalState()->ClearPref(prefs::kTimesHIDDialogShown);
760 }
761
762 void WizardController::SetCurrentScreen(WizardScreen* new_current) {
763   SetCurrentScreenSmooth(new_current, false);
764 }
765
766 void WizardController::ShowCurrentScreen() {
767   // ShowCurrentScreen may get called by smooth_show_timer_ even after
768   // flow has been switched to sign in screen (ExistingUserController).
769   if (!oobe_display_)
770     return;
771
772   // First remember how far have we reached so that we can resume if needed.
773   if (is_out_of_box_ && IsResumableScreen(current_screen_->GetName()))
774     StartupUtils::SaveOobePendingScreen(current_screen_->GetName());
775
776   smooth_show_timer_.Stop();
777
778   FOR_EACH_OBSERVER(Observer, observer_list_, OnScreenChanged(current_screen_));
779
780   oobe_display_->ShowScreen(current_screen_);
781 }
782
783 void WizardController::SetCurrentScreenSmooth(WizardScreen* new_current,
784                                               bool use_smoothing) {
785   if (current_screen_ == new_current ||
786       new_current == NULL ||
787       oobe_display_ == NULL) {
788     return;
789   }
790
791   smooth_show_timer_.Stop();
792
793   if (current_screen_)
794     oobe_display_->HideScreen(current_screen_);
795
796   previous_screen_ = current_screen_;
797   current_screen_ = new_current;
798
799   if (use_smoothing) {
800     smooth_show_timer_.Start(
801         FROM_HERE,
802         base::TimeDelta::FromMilliseconds(kShowDelayMs),
803         this,
804         &WizardController::ShowCurrentScreen);
805   } else {
806     ShowCurrentScreen();
807   }
808 }
809
810 void WizardController::SetStatusAreaVisible(bool visible) {
811   host_->SetStatusAreaVisible(visible);
812 }
813
814 void WizardController::AdvanceToScreen(const std::string& screen_name) {
815   if (screen_name == kNetworkScreenName) {
816     ShowNetworkScreen();
817   } else if (screen_name == kLoginScreenName) {
818     ShowLoginScreen(LoginScreenContext());
819   } else if (screen_name == kUpdateScreenName) {
820     InitiateOOBEUpdate();
821   } else if (screen_name == kUserImageScreenName) {
822     ShowUserImageScreen();
823   } else if (screen_name == kEulaScreenName) {
824     ShowEulaScreen();
825   } else if (screen_name == kResetScreenName) {
826     ShowResetScreen();
827   } else if (screen_name == kKioskEnableScreenName) {
828     ShowKioskEnableScreen();
829   } else if (screen_name == kKioskAutolaunchScreenName) {
830     ShowKioskAutolaunchScreen();
831   } else if (screen_name == kEnrollmentScreenName) {
832     ShowEnrollmentScreen();
833   } else if (screen_name == kTermsOfServiceScreenName) {
834     ShowTermsOfServiceScreen();
835   } else if (screen_name == kWrongHWIDScreenName) {
836     ShowWrongHWIDScreen();
837   } else if (screen_name == kAutoEnrollmentCheckScreenName) {
838     ShowAutoEnrollmentCheckScreen();
839   } else if (screen_name == kLocallyManagedUserCreationScreenName) {
840     ShowLocallyManagedUserCreationScreen();
841   } else if (screen_name == kAppLaunchSplashScreenName) {
842     AutoLaunchKioskApp();
843   } else if (screen_name == kHIDDetectionScreenName) {
844     ShowHIDDetectionScreen();
845   } else if (screen_name != kTestNoScreenName) {
846     if (is_out_of_box_) {
847       if (CanShowHIDDetectionScreen())
848         ShowHIDDetectionScreen();
849       else
850         ShowNetworkScreen();
851     } else {
852       ShowLoginScreen(LoginScreenContext());
853     }
854   }
855 }
856
857 ///////////////////////////////////////////////////////////////////////////////
858 // WizardController, chromeos::ScreenObserver overrides:
859 void WizardController::OnExit(ExitCodes exit_code) {
860   VLOG(1) << "Wizard screen exit code: " << exit_code;
861   switch (exit_code) {
862     case HID_DETECTION_COMPLETED:
863       OnHIDDetectionCompleted();
864       break;
865     case NETWORK_CONNECTED:
866       OnNetworkConnected();
867       break;
868     case CONNECTION_FAILED:
869       OnConnectionFailed();
870       break;
871     case UPDATE_INSTALLED:
872     case UPDATE_NOUPDATE:
873       OnUpdateCompleted();
874       break;
875     case UPDATE_ERROR_CHECKING_FOR_UPDATE:
876       OnUpdateErrorCheckingForUpdate();
877       break;
878     case UPDATE_ERROR_UPDATING:
879       OnUpdateErrorUpdating();
880       break;
881     case USER_IMAGE_SELECTED:
882       OnUserImageSelected();
883       break;
884     case EULA_ACCEPTED:
885       OnEulaAccepted();
886       break;
887     case EULA_BACK:
888       ShowNetworkScreen();
889       break;
890     case ENTERPRISE_AUTO_ENROLLMENT_CHECK_COMPLETED:
891       if (skip_update_enroll_after_eula_)
892         ShowEnrollmentScreen();
893       else
894         OnOOBECompleted();
895       break;
896     case ENTERPRISE_ENROLLMENT_COMPLETED:
897       OnEnrollmentDone();
898       break;
899     case ENTERPRISE_ENROLLMENT_BACK:
900       ShowNetworkScreen();
901       break;
902     case RESET_CANCELED:
903       OnResetCanceled();
904       break;
905     case KIOSK_AUTOLAUNCH_CANCELED:
906       OnKioskAutolaunchCanceled();
907       break;
908     case KIOSK_AUTOLAUNCH_CONFIRMED:
909       OnKioskAutolaunchConfirmed();
910       break;
911     case KIOSK_ENABLE_COMPLETED:
912       OnKioskEnableCompleted();
913       break;
914     case ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED:
915       OnAutoEnrollmentDone();
916       break;
917     case TERMS_OF_SERVICE_DECLINED:
918       OnTermsOfServiceDeclined();
919       break;
920     case TERMS_OF_SERVICE_ACCEPTED:
921       OnTermsOfServiceAccepted();
922       break;
923     case WRONG_HWID_WARNING_SKIPPED:
924       OnWrongHWIDWarningSkipped();
925       break;
926     default:
927       NOTREACHED();
928   }
929 }
930
931 void WizardController::OnSetUserNamePassword(const std::string& username,
932                                              const std::string& password) {
933   username_ = username;
934   password_ = password;
935 }
936
937 void WizardController::SetUsageStatisticsReporting(bool val) {
938   usage_statistics_reporting_ = val;
939 }
940
941 bool WizardController::GetUsageStatisticsReporting() const {
942   return usage_statistics_reporting_;
943 }
944
945 chromeos::ErrorScreen* WizardController::GetErrorScreen() {
946   if (!error_screen_.get()) {
947     error_screen_.reset(
948         new chromeos::ErrorScreen(this, oobe_display_->GetErrorScreenActor()));
949   }
950   return error_screen_.get();
951 }
952
953 void WizardController::ShowErrorScreen() {
954   VLOG(1) << "Showing error screen.";
955   SetCurrentScreen(GetErrorScreen());
956 }
957
958 void WizardController::HideErrorScreen(WizardScreen* parent_screen) {
959   DCHECK(parent_screen);
960   VLOG(1) << "Hiding error screen.";
961   SetCurrentScreen(parent_screen);
962 }
963
964 void WizardController::OnAccessibilityStatusChanged(
965     const AccessibilityStatusEventDetails& details) {
966   enum AccessibilityNotificationType type = details.notification_type;
967   if (type == ACCESSIBILITY_MANAGER_SHUTDOWN) {
968     accessibility_subscription_.reset();
969     return;
970   } else if (type != ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK || !details.enabled) {
971     return;
972   }
973
974   CrasAudioHandler* cras = CrasAudioHandler::Get();
975   if (cras->IsOutputMuted()) {
976     cras->SetOutputMute(false);
977     cras->SetOutputVolumePercent(kMinAudibleOutputVolumePercent);
978   } else if (cras->GetOutputVolumePercent() < kMinAudibleOutputVolumePercent) {
979     cras->SetOutputVolumePercent(kMinAudibleOutputVolumePercent);
980   }
981 }
982
983 void WizardController::AutoLaunchKioskApp() {
984   KioskAppManager::App app_data;
985   std::string app_id = KioskAppManager::Get()->GetAutoLaunchApp();
986   CHECK(KioskAppManager::Get()->GetApp(app_id, &app_data));
987
988   host_->StartAppLaunch(app_id, false /* diagnostic_mode */);
989 }
990
991 // static
992 void WizardController::SetZeroDelays() {
993   kShowDelayMs = 0;
994   zero_delay_enabled_ = true;
995 }
996
997 // static
998 bool WizardController::IsZeroDelayEnabled() {
999   return zero_delay_enabled_;
1000 }
1001
1002 // static
1003 void WizardController::SkipPostLoginScreensForTesting() {
1004   skip_post_login_screens_ = true;
1005 }
1006
1007 // static
1008 bool WizardController::ShouldAutoStartEnrollment() {
1009   policy::BrowserPolicyConnectorChromeOS* connector =
1010       g_browser_process->platform_part()->browser_policy_connector_chromeos();
1011   return connector->GetDeviceCloudPolicyManager()->ShouldAutoStartEnrollment();
1012 }
1013
1014 // static
1015 bool WizardController::CanExitEnrollment() {
1016   policy::BrowserPolicyConnectorChromeOS* connector =
1017       g_browser_process->platform_part()->browser_policy_connector_chromeos();
1018   return connector->GetDeviceCloudPolicyManager()->CanExitEnrollment();
1019 }
1020
1021 // static
1022 std::string WizardController::GetForcedEnrollmentDomain() {
1023   policy::BrowserPolicyConnectorChromeOS* connector =
1024       g_browser_process->platform_part()->browser_policy_connector_chromeos();
1025   return connector->GetDeviceCloudPolicyManager()->GetForcedEnrollmentDomain();
1026 }
1027
1028 void WizardController::OnLocalStateInitialized(bool /* succeeded */) {
1029   if (GetLocalState()->GetInitializationStatus() !=
1030       PrefService::INITIALIZATION_STATUS_ERROR) {
1031     return;
1032   }
1033   GetErrorScreen()->SetUIState(ErrorScreen::UI_STATE_LOCAL_STATE_ERROR);
1034   SetStatusAreaVisible(false);
1035   ShowErrorScreen();
1036 }
1037
1038 PrefService* WizardController::GetLocalState() {
1039   if (local_state_for_testing_)
1040     return local_state_for_testing_;
1041   return g_browser_process->local_state();
1042 }
1043
1044 void WizardController::OnTimezoneResolved(
1045     scoped_ptr<TimeZoneResponseData> timezone,
1046     bool server_error) {
1047   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1048   DCHECK(timezone.get());
1049   // To check that "this" is not destroyed try to access some member
1050   // (timezone_provider_) in this case. Expect crash here.
1051   DCHECK(timezone_provider_.get());
1052
1053   timezone_resolved_ = true;
1054   base::ScopedClosureRunner inform_test(on_timezone_resolved_for_testing_);
1055   on_timezone_resolved_for_testing_.Reset();
1056
1057   VLOG(1) << "Resolved local timezone={" << timezone->ToStringForDebug()
1058           << "}.";
1059
1060   if (timezone->status != TimeZoneResponseData::OK) {
1061     LOG(WARNING) << "Resolve TimeZone: failed to resolve timezone.";
1062     return;
1063   }
1064
1065   policy::BrowserPolicyConnectorChromeOS* connector =
1066       g_browser_process->platform_part()->browser_policy_connector_chromeos();
1067   if (connector->IsEnterpriseManaged()) {
1068     std::string policy_timezone;
1069     if (chromeos::CrosSettings::Get()->GetString(
1070             chromeos::kSystemTimezonePolicy, &policy_timezone) &&
1071         !policy_timezone.empty()) {
1072       VLOG(1) << "Resolve TimeZone: TimeZone settings are overridden"
1073               << " by DevicePolicy.";
1074       return;
1075     }
1076   }
1077
1078   if (!timezone->timeZoneId.empty()) {
1079     VLOG(1) << "Resolve TimeZone: setting timezone to '" << timezone->timeZoneId
1080             << "'";
1081
1082     chromeos::system::TimezoneSettings::GetInstance()->SetTimezoneFromID(
1083         base::UTF8ToUTF16(timezone->timeZoneId));
1084   }
1085 }
1086
1087 TimeZoneProvider* WizardController::GetTimezoneProvider() {
1088   if (!timezone_provider_) {
1089     timezone_provider_.reset(
1090         new TimeZoneProvider(g_browser_process->system_request_context(),
1091                              DefaultTimezoneProviderURL()));
1092   }
1093   return timezone_provider_.get();
1094 }
1095
1096 void WizardController::OnLocationResolved(const Geoposition& position,
1097                                           bool server_error,
1098                                           const base::TimeDelta elapsed) {
1099   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1100
1101   const base::TimeDelta timeout =
1102       base::TimeDelta::FromSeconds(kResolveTimeZoneTimeoutSeconds);
1103   // Ignore invalid position.
1104   if (!position.Valid())
1105     return;
1106
1107   if (elapsed >= timeout) {
1108     LOG(WARNING) << "Resolve TimeZone: got location after timeout ("
1109                  << elapsed.InSecondsF() << " seconds elapsed). Ignored.";
1110     return;
1111   }
1112
1113   // WizardController owns TimezoneProvider, so timezone request is silently
1114   // cancelled on destruction.
1115   GetTimezoneProvider()->RequestTimezone(
1116       position,
1117       false,  // sensor
1118       timeout - elapsed,
1119       base::Bind(&WizardController::OnTimezoneResolved,
1120                  base::Unretained(this)));
1121 }
1122
1123 bool WizardController::SetOnTimeZoneResolvedForTesting(
1124     const base::Closure& callback) {
1125   if (timezone_resolved_)
1126     return false;
1127
1128   on_timezone_resolved_for_testing_ = callback;
1129   return true;
1130 }
1131
1132 }  // namespace chromeos