Home | History | Annotate | Download | only in login
      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