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