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