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