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.
5 #include "chrome/browser/chromeos/login/wizard_controller.h"
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 "chrome/browser/browser_process.h"
22 #include "chrome/browser/browser_process_platform_part.h"
23 #include "chrome/browser/chrome_notification_types.h"
24 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
25 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
26 #include "chrome/browser/chromeos/customization/customization_document.h"
27 #include "chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.h"
28 #include "chrome/browser/chromeos/login/enrollment/enrollment_screen.h"
29 #include "chrome/browser/chromeos/login/existing_user_controller.h"
30 #include "chrome/browser/chromeos/login/helper.h"
31 #include "chrome/browser/chromeos/login/hwid_checker.h"
32 #include "chrome/browser/chromeos/login/screens/device_disabled_screen.h"
33 #include "chrome/browser/chromeos/login/screens/enable_debugging_screen.h"
34 #include "chrome/browser/chromeos/login/screens/error_screen.h"
35 #include "chrome/browser/chromeos/login/screens/eula_screen.h"
36 #include "chrome/browser/chromeos/login/screens/hid_detection_screen.h"
37 #include "chrome/browser/chromeos/login/screens/kiosk_autolaunch_screen.h"
38 #include "chrome/browser/chromeos/login/screens/kiosk_enable_screen.h"
39 #include "chrome/browser/chromeos/login/screens/network_view.h"
40 #include "chrome/browser/chromeos/login/screens/reset_screen.h"
41 #include "chrome/browser/chromeos/login/screens/terms_of_service_screen.h"
42 #include "chrome/browser/chromeos/login/screens/update_screen.h"
43 #include "chrome/browser/chromeos/login/screens/user_image_screen.h"
44 #include "chrome/browser/chromeos/login/screens/wrong_hwid_screen.h"
45 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
46 #include "chrome/browser/chromeos/login/startup_utils.h"
47 #include "chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.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/net/delay_network_call.h"
51 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
52 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
53 #include "chrome/browser/chromeos/settings/cros_settings.h"
54 #include "chrome/browser/chromeos/system/device_disabling_manager.h"
55 #include "chrome/browser/lifetime/application_lifetime.h"
56 #include "chrome/browser/metrics/metrics_reporting_state.h"
57 #include "chrome/browser/profiles/profile.h"
58 #include "chrome/browser/profiles/profile_manager.h"
59 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
60 #include "chrome/common/chrome_constants.h"
61 #include "chrome/common/pref_names.h"
62 #include "chromeos/audio/cras_audio_handler.h"
63 #include "chromeos/chromeos_constants.h"
64 #include "chromeos/chromeos_switches.h"
65 #include "chromeos/dbus/dbus_thread_manager.h"
66 #include "chromeos/dbus/session_manager_client.h"
67 #include "chromeos/geolocation/simple_geolocation_provider.h"
68 #include "chromeos/network/network_state.h"
69 #include "chromeos/network/network_state_handler.h"
70 #include "chromeos/network/portal_detector/network_portal_detector.h"
71 #include "chromeos/settings/cros_settings_names.h"
72 #include "chromeos/settings/cros_settings_provider.h"
73 #include "chromeos/settings/timezone_settings.h"
74 #include "chromeos/timezone/timezone_provider.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"
84 using content::BrowserThread
;
87 // Interval in ms which is used for smooth screen showing.
88 static int kShowDelayMs
= 400;
90 // Total timezone resolving process timeout.
91 const unsigned int kResolveTimeZoneTimeoutSeconds
= 60;
93 // Stores the list of all screens that should be shown when resuming OOBE.
94 const char *kResumableScreens
[] = {
95 chromeos::WizardController::kNetworkScreenName
,
96 chromeos::WizardController::kUpdateScreenName
,
97 chromeos::WizardController::kEulaScreenName
,
98 chromeos::WizardController::kEnrollmentScreenName
,
99 chromeos::WizardController::kTermsOfServiceScreenName
,
100 chromeos::WizardController::kAutoEnrollmentCheckScreenName
103 // Checks flag for HID-detection screen show.
104 bool CanShowHIDDetectionScreen() {
105 return !base::CommandLine::ForCurrentProcess()->HasSwitch(
106 chromeos::switches::kDisableHIDDetectionOnOOBE
);
109 bool IsResumableScreen(const std::string
& screen
) {
110 for (size_t i
= 0; i
< arraysize(kResumableScreens
); ++i
) {
111 if (screen
== kResumableScreens
[i
])
117 void RecordUMAHistogramForOOBEStepCompletionTime(std::string screen_name
,
118 base::TimeDelta step_time
) {
119 screen_name
[0] = std::toupper(screen_name
[0]);
120 std::string histogram_name
= "OOBE.StepCompletionTime." + screen_name
;
121 // Equivalent to using UMA_HISTOGRAM_MEDIUM_TIMES. UMA_HISTOGRAM_MEDIUM_TIMES
122 // can not be used here, because |histogram_name| is calculated dynamically
123 // and changes from call to call.
124 base::HistogramBase
* histogram
= base::Histogram::FactoryTimeGet(
126 base::TimeDelta::FromMilliseconds(10),
127 base::TimeDelta::FromMinutes(3),
129 base::HistogramBase::kUmaTargetedHistogramFlag
);
130 histogram
->AddTime(step_time
);
133 bool IsRemoraRequisition() {
134 return g_browser_process
->platform_part()
135 ->browser_policy_connector_chromeos()
136 ->GetDeviceCloudPolicyManager()
137 ->IsRemoraRequisition();
140 #if defined(GOOGLE_CHROME_BUILD)
141 void InitializeCrashReporter() {
142 // The crash reporter initialization needs IO to complete.
143 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
144 breakpad::InitCrashReporter(std::string());
152 const char WizardController::kNetworkScreenName
[] = "network";
153 const char WizardController::kLoginScreenName
[] = "login";
154 const char WizardController::kUpdateScreenName
[] = "update";
155 const char WizardController::kUserImageScreenName
[] = "image";
156 const char WizardController::kEulaScreenName
[] = "eula";
157 const char WizardController::kEnableDebuggingScreenName
[] = "debugging";
158 const char WizardController::kEnrollmentScreenName
[] = "enroll";
159 const char WizardController::kResetScreenName
[] = "reset";
160 const char WizardController::kKioskEnableScreenName
[] = "kiosk-enable";
161 const char WizardController::kKioskAutolaunchScreenName
[] = "autolaunch";
162 const char WizardController::kErrorScreenName
[] = "error-message";
163 const char WizardController::kTermsOfServiceScreenName
[] = "tos";
164 const char WizardController::kAutoEnrollmentCheckScreenName
[] =
165 "auto-enrollment-check";
166 const char WizardController::kWrongHWIDScreenName
[] = "wrong-hwid";
167 const char WizardController::kSupervisedUserCreationScreenName
[] =
168 "supervised-user-creation-flow";
169 const char WizardController::kAppLaunchSplashScreenName
[] =
171 const char WizardController::kHIDDetectionScreenName
[] = "hid-detection";
172 const char WizardController::kControllerPairingScreenName
[] =
173 "controller-pairing";
174 const char WizardController::kHostPairingScreenName
[] = "host-pairing";
175 const char WizardController::kDeviceDisabledScreenName
[] = "device-disabled";
178 const int WizardController::kMinAudibleOutputVolumePercent
= 10;
180 // Passing this parameter as a "first screen" initiates full OOBE flow.
181 const char WizardController::kOutOfBoxScreenName
[] = "oobe";
183 // Special test value that commands not to create any window yet.
184 const char WizardController::kTestNoScreenName
[] = "test:nowindow";
186 // Initialize default controller.
188 WizardController
* WizardController::default_controller_
= NULL
;
191 bool WizardController::skip_post_login_screens_
= false;
194 bool WizardController::zero_delay_enabled_
= false;
196 ///////////////////////////////////////////////////////////////////////////////
197 // WizardController, public:
199 PrefService
* WizardController::local_state_for_testing_
= NULL
;
201 WizardController::WizardController(LoginDisplayHost
* host
,
202 OobeDisplay
* oobe_display
)
203 : current_screen_(NULL
),
204 previous_screen_(NULL
),
205 #if defined(GOOGLE_CHROME_BUILD)
206 is_official_build_(true),
208 is_official_build_(false),
210 is_out_of_box_(false),
212 oobe_display_(oobe_display
),
213 usage_statistics_reporting_(true),
214 skip_update_enroll_after_eula_(false),
215 retry_auto_enrollment_check_(false),
216 login_screen_started_(false),
217 user_image_screen_return_to_previous_hack_(false),
218 timezone_resolved_(false),
219 shark_controller_detected_(false),
220 weak_factory_(this) {
221 DCHECK(default_controller_
== NULL
);
222 default_controller_
= this;
223 AccessibilityManager
* accessibility_manager
= AccessibilityManager::Get();
224 CHECK(accessibility_manager
);
225 accessibility_subscription_
= accessibility_manager
->RegisterCallback(
226 base::Bind(&WizardController::OnAccessibilityStatusChanged
,
227 base::Unretained(this)));
230 WizardController::~WizardController() {
231 if (default_controller_
== this) {
232 default_controller_
= NULL
;
234 NOTREACHED() << "More than one controller are alive.";
238 void WizardController::Init(const std::string
& first_screen_name
) {
239 VLOG(1) << "Starting OOBE wizard with screen: " << first_screen_name
;
240 first_screen_name_
= first_screen_name
;
242 bool oobe_complete
= StartupUtils::IsOobeCompleted();
243 if (!oobe_complete
|| first_screen_name
== kOutOfBoxScreenName
)
244 is_out_of_box_
= true;
246 // This is a hacky way to check for local state corruption, because
247 // it depends on the fact that the local state is loaded
248 // synchroniously and at the first demand. IsEnterpriseManaged()
249 // check is required because currently powerwash is disabled for
250 // enterprise-entrolled devices.
252 // TODO (ygorshenin@): implement handling of the local state
253 // corruption in the case of asynchronious loading.
255 // TODO (ygorshenin@): remove IsEnterpriseManaged() check once
256 // crbug.com/241313 will be fixed.
257 policy::BrowserPolicyConnectorChromeOS
* connector
=
258 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
259 if (!connector
->IsEnterpriseManaged()) {
260 const PrefService::PrefInitializationStatus status
=
261 GetLocalState()->GetInitializationStatus();
262 if (status
== PrefService::INITIALIZATION_STATUS_ERROR
) {
263 OnLocalStateInitialized(false);
265 } else if (status
== PrefService::INITIALIZATION_STATUS_WAITING
) {
266 GetLocalState()->AddPrefInitObserver(
267 base::Bind(&WizardController::OnLocalStateInitialized
,
268 weak_factory_
.GetWeakPtr()));
272 // Use the saved screen preference from Local State.
273 const std::string screen_pref
=
274 GetLocalState()->GetString(prefs::kOobeScreenPending
);
275 if (is_out_of_box_
&& !screen_pref
.empty() && !IsHostPairingOobe() &&
276 (first_screen_name
.empty() ||
277 first_screen_name
== WizardController::kTestNoScreenName
)) {
278 first_screen_name_
= screen_pref
;
281 AdvanceToScreen(first_screen_name_
);
282 if (!IsMachineHWIDCorrect() && !StartupUtils::IsDeviceRegistered() &&
283 first_screen_name_
.empty())
284 ShowWrongHWIDScreen();
287 ErrorScreen
* WizardController::GetErrorScreen() {
288 return static_cast<ErrorScreen
*>(GetScreen(kErrorScreenName
));
291 BaseScreen
* WizardController::CreateScreen(const std::string
& screen_name
) {
292 if (screen_name
== kNetworkScreenName
) {
293 scoped_ptr
<NetworkScreen
> screen(
294 new NetworkScreen(this, this, oobe_display_
->GetNetworkView()));
295 screen
->Initialize(nullptr /* context */);
296 return screen
.release();
297 } else if (screen_name
== kErrorScreenName
) {
298 return new ErrorScreen(this, oobe_display_
->GetErrorScreenActor());
299 } else if (screen_name
== kUpdateScreenName
) {
300 scoped_ptr
<UpdateScreen
> screen(new UpdateScreen(
301 this, oobe_display_
->GetUpdateView(), remora_controller_
.get()));
302 screen
->Initialize(nullptr /* context */);
303 return screen
.release();
304 } else if (screen_name
== kUserImageScreenName
) {
305 return new UserImageScreen(this, oobe_display_
->GetUserImageView());
306 } else if (screen_name
== kEulaScreenName
) {
307 return new EulaScreen(this, this, oobe_display_
->GetEulaView());
308 } else if (screen_name
== kEnrollmentScreenName
) {
309 return new EnrollmentScreen(this,
310 oobe_display_
->GetEnrollmentScreenActor());
311 } else if (screen_name
== kResetScreenName
) {
312 return new ResetScreen(this, oobe_display_
->GetResetScreenActor());
313 } else if (screen_name
== kEnableDebuggingScreenName
) {
314 return new EnableDebuggingScreen(
315 this, oobe_display_
->GetEnableDebuggingScreenActor());
316 } else if (screen_name
== kKioskEnableScreenName
) {
317 return new KioskEnableScreen(this,
318 oobe_display_
->GetKioskEnableScreenActor());
319 } else if (screen_name
== kKioskAutolaunchScreenName
) {
320 return new KioskAutolaunchScreen(
321 this, oobe_display_
->GetKioskAutolaunchScreenActor());
322 } else if (screen_name
== kTermsOfServiceScreenName
) {
323 return new TermsOfServiceScreen(
324 this, oobe_display_
->GetTermsOfServiceScreenActor());
325 } else if (screen_name
== kWrongHWIDScreenName
) {
326 return new WrongHWIDScreen(this, oobe_display_
->GetWrongHWIDScreenActor());
327 } else if (screen_name
== kSupervisedUserCreationScreenName
) {
328 return new SupervisedUserCreationScreen(
329 this, oobe_display_
->GetSupervisedUserCreationScreenActor());
330 } else if (screen_name
== kHIDDetectionScreenName
) {
331 return new HIDDetectionScreen(this,
332 oobe_display_
->GetHIDDetectionScreenActor());
333 } else if (screen_name
== kAutoEnrollmentCheckScreenName
) {
334 return new AutoEnrollmentCheckScreen(
335 this, oobe_display_
->GetAutoEnrollmentCheckScreenActor());
336 } else if (screen_name
== kControllerPairingScreenName
) {
337 if (!shark_controller_
) {
338 shark_controller_
.reset(
339 new pairing_chromeos::BluetoothControllerPairingController());
341 return new ControllerPairingScreen(
344 oobe_display_
->GetControllerPairingScreenActor(),
345 shark_controller_
.get());
346 } else if (screen_name
== kHostPairingScreenName
) {
347 if (!remora_controller_
) {
348 remora_controller_
.reset(
349 new pairing_chromeos::BluetoothHostPairingController());
350 remora_controller_
->StartPairing();
352 return new HostPairingScreen(this,
354 oobe_display_
->GetHostPairingScreenActor(),
355 remora_controller_
.get());
356 } else if (screen_name
== kDeviceDisabledScreenName
) {
357 return new DeviceDisabledScreen(
358 this, oobe_display_
->GetDeviceDisabledScreenActor());
364 void WizardController::ShowNetworkScreen() {
365 VLOG(1) << "Showing network screen.";
366 // Hide the status area initially; it only appears after OOBE first animates
367 // in. Keep it visible if the user goes back to the existing network screen.
368 SetStatusAreaVisible(HasScreen(kNetworkScreenName
));
369 SetCurrentScreen(GetScreen(kNetworkScreenName
));
371 MaybeStartListeningForSharkConnection();
374 void WizardController::ShowLoginScreen(const LoginScreenContext
& context
) {
375 if (!time_eula_accepted_
.is_null()) {
376 base::TimeDelta delta
= base::Time::Now() - time_eula_accepted_
;
377 UMA_HISTOGRAM_MEDIUM_TIMES("OOBE.EULAToSignInTime", delta
);
379 VLOG(1) << "Showing login screen.";
380 SetStatusAreaVisible(true);
381 host_
->StartSignInScreen(context
);
382 smooth_show_timer_
.Stop();
383 oobe_display_
= NULL
;
384 login_screen_started_
= true;
387 void WizardController::ShowUpdateScreen() {
388 VLOG(1) << "Showing update screen.";
389 SetStatusAreaVisible(true);
390 SetCurrentScreen(GetScreen(kUpdateScreenName
));
393 void WizardController::ShowUserImageScreen() {
394 const user_manager::UserManager
* user_manager
=
395 user_manager::UserManager::Get();
396 // Skip user image selection for public sessions and ephemeral logins.
397 if (user_manager
->IsLoggedInAsPublicAccount() ||
398 user_manager
->IsCurrentUserNonCryptohomeDataEphemeral()) {
399 OnUserImageSkipped();
402 VLOG(1) << "Showing user image screen.";
404 // Status area has been already shown at sign in screen so it
405 // doesn't make sense to hide it here and then show again at user session as
406 // this produces undesired UX transitions.
407 SetStatusAreaVisible(true);
409 SetCurrentScreen(GetScreen(kUserImageScreenName
));
412 void WizardController::ShowEulaScreen() {
413 VLOG(1) << "Showing EULA screen.";
414 SetStatusAreaVisible(true);
415 SetCurrentScreen(GetScreen(kEulaScreenName
));
418 void WizardController::ShowEnrollmentScreen() {
419 // Update the enrollment configuration and start the screen.
420 prescribed_enrollment_config_
= g_browser_process
->platform_part()
421 ->browser_policy_connector_chromeos()
422 ->GetPrescribedEnrollmentConfig();
423 StartEnrollmentScreen();
426 void WizardController::ShowResetScreen() {
427 VLOG(1) << "Showing reset screen.";
428 SetStatusAreaVisible(false);
429 SetCurrentScreen(GetScreen(kResetScreenName
));
432 void WizardController::ShowKioskEnableScreen() {
433 VLOG(1) << "Showing kiosk enable screen.";
434 SetStatusAreaVisible(false);
435 SetCurrentScreen(GetScreen(kKioskEnableScreenName
));
438 void WizardController::ShowKioskAutolaunchScreen() {
439 VLOG(1) << "Showing kiosk autolaunch screen.";
440 SetStatusAreaVisible(false);
441 SetCurrentScreen(GetScreen(kKioskAutolaunchScreenName
));
444 void WizardController::ShowEnableDebuggingScreen() {
445 VLOG(1) << "Showing enable developer features screen.";
446 SetStatusAreaVisible(false);
447 SetCurrentScreen(GetScreen(kEnableDebuggingScreenName
));
450 void WizardController::ShowTermsOfServiceScreen() {
451 // Only show the Terms of Service when logging into a public account and Terms
452 // of Service have been specified through policy. In all other cases, advance
453 // to the user image screen immediately.
454 if (!user_manager::UserManager::Get()->IsLoggedInAsPublicAccount() ||
455 !ProfileManager::GetActiveUserProfile()->GetPrefs()->IsManagedPreference(
456 prefs::kTermsOfServiceURL
)) {
457 ShowUserImageScreen();
461 VLOG(1) << "Showing Terms of Service screen.";
462 SetStatusAreaVisible(true);
463 SetCurrentScreen(GetScreen(kTermsOfServiceScreenName
));
466 void WizardController::ShowWrongHWIDScreen() {
467 VLOG(1) << "Showing wrong HWID screen.";
468 SetStatusAreaVisible(false);
469 SetCurrentScreen(GetScreen(kWrongHWIDScreenName
));
472 void WizardController::ShowAutoEnrollmentCheckScreen() {
473 VLOG(1) << "Showing Auto-enrollment check screen.";
474 SetStatusAreaVisible(true);
475 AutoEnrollmentCheckScreen
* screen
= AutoEnrollmentCheckScreen::Get(this);
476 if (retry_auto_enrollment_check_
)
477 screen
->ClearState();
478 screen
->set_auto_enrollment_controller(host_
->GetAutoEnrollmentController());
479 SetCurrentScreen(screen
);
482 void WizardController::ShowSupervisedUserCreationScreen() {
483 VLOG(1) << "Showing Locally managed user creation screen screen.";
484 SetStatusAreaVisible(true);
485 SetCurrentScreen(GetScreen(kSupervisedUserCreationScreenName
));
488 void WizardController::ShowHIDDetectionScreen() {
489 VLOG(1) << "Showing HID discovery screen.";
490 SetStatusAreaVisible(true);
491 SetCurrentScreen(GetScreen(kHIDDetectionScreenName
));
492 MaybeStartListeningForSharkConnection();
495 void WizardController::ShowControllerPairingScreen() {
496 VLOG(1) << "Showing controller pairing screen.";
497 SetStatusAreaVisible(false);
498 SetCurrentScreen(GetScreen(kControllerPairingScreenName
));
501 void WizardController::ShowHostPairingScreen() {
502 VLOG(1) << "Showing host pairing screen.";
503 SetStatusAreaVisible(false);
504 SetCurrentScreen(GetScreen(kHostPairingScreenName
));
507 void WizardController::ShowDeviceDisabledScreen() {
508 VLOG(1) << "Showing device disabled screen.";
509 SetStatusAreaVisible(true);
510 SetCurrentScreen(GetScreen(kDeviceDisabledScreenName
));
513 void WizardController::SkipToLoginForTesting(
514 const LoginScreenContext
& context
) {
515 VLOG(1) << "SkipToLoginForTesting.";
516 StartupUtils::MarkEulaAccepted();
517 PerformPostEulaActions();
518 OnDeviceDisabledChecked(false /* device_disabled */);
521 void WizardController::AddObserver(Observer
* observer
) {
522 observer_list_
.AddObserver(observer
);
525 void WizardController::RemoveObserver(Observer
* observer
) {
526 observer_list_
.RemoveObserver(observer
);
529 void WizardController::OnSessionStart() {
530 FOR_EACH_OBSERVER(Observer
, observer_list_
, OnSessionStart());
533 void WizardController::SkipUpdateEnrollAfterEula() {
534 skip_update_enroll_after_eula_
= true;
537 ///////////////////////////////////////////////////////////////////////////////
538 // WizardController, ExitHandlers:
539 void WizardController::OnHIDDetectionCompleted() {
540 // Check for tests configuration.
541 if (!StartupUtils::IsOobeCompleted())
545 void WizardController::OnNetworkConnected() {
546 if (is_official_build_
) {
547 if (!StartupUtils::IsEulaAccepted()) {
551 // 1. EULA was accepted, forced shutdown/reboot during update.
552 // 2. EULA was accepted, planned reboot after update.
553 // Make sure that device is up-to-date.
554 InitiateOOBEUpdate();
557 InitiateOOBEUpdate();
561 void WizardController::OnNetworkOffline() {
562 // TODO(dpolukhin): if(is_out_of_box_) we cannot work offline and
563 // should report some error message here and stay on the same screen.
564 ShowLoginScreen(LoginScreenContext());
567 void WizardController::OnConnectionFailed() {
568 // TODO(dpolukhin): show error message after login screen is displayed.
569 ShowLoginScreen(LoginScreenContext());
572 void WizardController::OnUpdateCompleted() {
573 const bool is_shark
= g_browser_process
->platform_part()
574 ->browser_policy_connector_chromeos()
575 ->GetDeviceCloudPolicyManager()
576 ->IsSharkRequisition();
578 ShowControllerPairingScreen();
580 ShowAutoEnrollmentCheckScreen();
584 void WizardController::OnEulaAccepted() {
585 time_eula_accepted_
= base::Time::Now();
586 StartupUtils::MarkEulaAccepted();
587 InitiateMetricsReportingChange(
588 usage_statistics_reporting_
,
589 base::Bind(&WizardController::InitiateMetricsReportingChangeCallback
,
590 weak_factory_
.GetWeakPtr()));
592 if (skip_update_enroll_after_eula_
) {
593 PerformPostEulaActions();
594 ShowAutoEnrollmentCheckScreen();
596 InitiateOOBEUpdate();
600 void WizardController::InitiateMetricsReportingChangeCallback(bool enabled
) {
601 CrosSettings::Get()->SetBoolean(kStatsReportingPref
, enabled
);
604 #if defined(GOOGLE_CHROME_BUILD)
605 if (!content::BrowserThread::PostBlockingPoolTask(
606 FROM_HERE
, base::Bind(&InitializeCrashReporter
))) {
607 LOG(ERROR
) << "Failed to start crash reporter initialization.";
612 void WizardController::OnUpdateErrorCheckingForUpdate() {
613 // TODO(nkostylev): Update should be required during OOBE.
614 // We do not want to block users from being able to proceed to the login
615 // screen if there is any error checking for an update.
616 // They could use "browse without sign-in" feature to set up the network to be
617 // able to perform the update later.
621 void WizardController::OnUpdateErrorUpdating() {
622 // If there was an error while getting or applying the update,
623 // return to network selection screen.
624 // TODO(nkostylev): Show message to the user explaining update error.
625 // TODO(nkostylev): Update should be required during OOBE.
626 // Temporary fix, need to migrate to new API. http://crosbug.com/4321
630 void WizardController::EnableUserImageScreenReturnToPreviousHack() {
631 user_image_screen_return_to_previous_hack_
= true;
634 void WizardController::OnUserImageSelected() {
635 if (user_image_screen_return_to_previous_hack_
) {
636 user_image_screen_return_to_previous_hack_
= false;
637 DCHECK(previous_screen_
);
638 if (previous_screen_
) {
639 SetCurrentScreen(previous_screen_
);
643 if (!time_oobe_started_
.is_null()) {
644 base::TimeDelta delta
= base::Time::Now() - time_oobe_started_
;
645 UMA_HISTOGRAM_CUSTOM_TIMES(
646 "OOBE.BootToSignInCompleted",
648 base::TimeDelta::FromMilliseconds(10),
649 base::TimeDelta::FromMinutes(30),
651 time_oobe_started_
= base::Time();
654 // Launch browser and delete login host controller.
655 BrowserThread::PostTask(
656 BrowserThread::UI
, FROM_HERE
,
657 base::Bind(&UserSessionManager::DoBrowserLaunch
,
658 base::Unretained(UserSessionManager::GetInstance()),
659 ProfileManager::GetActiveUserProfile(), host_
));
663 void WizardController::OnUserImageSkipped() {
664 OnUserImageSelected();
667 void WizardController::OnEnrollmentDone() {
668 // If the enrollment screen was shown as part of OOBE, OOBE is considered
669 // finished only after the enrollment screen is done. This is relevant for
670 // forced enrollment flows, e.g. for remora devices and forced re-enrollment.
671 if (prescribed_enrollment_config_
.should_enroll())
672 PerformOOBECompletedActions();
674 // TODO(mnissler): Unify the logic for auto-login for Public Sessions and
675 // Kiosk Apps and make this code cover both cases: http://crbug.com/234694.
676 if (KioskAppManager::Get()->IsAutoLaunchEnabled())
677 AutoLaunchKioskApp();
679 ShowLoginScreen(LoginScreenContext());
682 void WizardController::OnDeviceModificationCanceled() {
683 if (previous_screen_
) {
684 SetCurrentScreen(previous_screen_
);
686 ShowLoginScreen(LoginScreenContext());
690 void WizardController::OnKioskAutolaunchCanceled() {
691 ShowLoginScreen(LoginScreenContext());
694 void WizardController::OnKioskAutolaunchConfirmed() {
695 DCHECK(KioskAppManager::Get()->IsAutoLaunchEnabled());
696 AutoLaunchKioskApp();
699 void WizardController::OnKioskEnableCompleted() {
700 ShowLoginScreen(LoginScreenContext());
703 void WizardController::OnWrongHWIDWarningSkipped() {
704 if (previous_screen_
)
705 SetCurrentScreen(previous_screen_
);
707 ShowLoginScreen(LoginScreenContext());
710 void WizardController::OnTermsOfServiceDeclined() {
711 // If the user declines the Terms of Service, end the session and return to
713 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
716 void WizardController::OnTermsOfServiceAccepted() {
717 // If the user accepts the Terms of Service, advance to the user image screen.
718 ShowUserImageScreen();
721 void WizardController::OnControllerPairingFinished() {
722 ShowAutoEnrollmentCheckScreen();
725 void WizardController::OnHostPairingFinished() {
726 InitiateOOBEUpdate();
729 void WizardController::OnAutoEnrollmentCheckCompleted() {
730 // Check whether the device is disabled. OnDeviceDisabledChecked() will be
731 // invoked when the result of this check is known. Until then, the current
732 // screen will remain visible and will continue showing a spinner.
733 g_browser_process
->platform_part()->device_disabling_manager()->
734 CheckWhetherDeviceDisabledDuringOOBE(base::Bind(
735 &WizardController::OnDeviceDisabledChecked
,
736 weak_factory_
.GetWeakPtr()));
739 void WizardController::OnDeviceDisabledChecked(bool device_disabled
) {
740 prescribed_enrollment_config_
= g_browser_process
->platform_part()
741 ->browser_policy_connector_chromeos()
742 ->GetPrescribedEnrollmentConfig();
743 if (device_disabled
) {
744 ShowDeviceDisabledScreen();
745 } else if (skip_update_enroll_after_eula_
||
746 prescribed_enrollment_config_
.should_enroll()) {
747 StartEnrollmentScreen();
749 PerformOOBECompletedActions();
750 ShowLoginScreen(LoginScreenContext());
754 void WizardController::InitiateOOBEUpdate() {
755 VLOG(1) << "InitiateOOBEUpdate";
756 PerformPostEulaActions();
757 SetCurrentScreenSmooth(GetScreen(kUpdateScreenName
), true);
758 UpdateScreen::Get(this)->StartNetworkCheck();
761 void WizardController::StartTimezoneResolve() {
762 geolocation_provider_
.reset(new SimpleGeolocationProvider(
763 g_browser_process
->system_request_context(),
764 SimpleGeolocationProvider::DefaultGeolocationProviderURL()));
765 geolocation_provider_
->RequestGeolocation(
766 base::TimeDelta::FromSeconds(kResolveTimeZoneTimeoutSeconds
),
767 base::Bind(&WizardController::OnLocationResolved
,
768 weak_factory_
.GetWeakPtr()));
771 void WizardController::PerformPostEulaActions() {
773 base::TimeDelta::FromMilliseconds(kDefaultNetworkRetryDelayMS
),
774 base::Bind(&WizardController::StartTimezoneResolve
,
775 weak_factory_
.GetWeakPtr()));
777 base::TimeDelta::FromMilliseconds(kDefaultNetworkRetryDelayMS
),
778 ServicesCustomizationDocument::GetInstance()
779 ->EnsureCustomizationAppliedClosure());
781 // Now that EULA has been accepted (for official builds), enable portal check.
782 // ChromiumOS builds would go though this code path too.
783 NetworkHandler::Get()->network_state_handler()->SetCheckPortalList(
784 NetworkStateHandler::kDefaultCheckPortalList
);
785 host_
->GetAutoEnrollmentController()->Start();
786 host_
->PrewarmAuthentication();
787 NetworkPortalDetector::Get()->Enable(true);
790 void WizardController::PerformOOBECompletedActions() {
791 UMA_HISTOGRAM_COUNTS_100(
792 "HIDDetection.TimesDialogShownPerOOBECompleted",
793 GetLocalState()->GetInteger(prefs::kTimesHIDDialogShown
));
794 GetLocalState()->ClearPref(prefs::kTimesHIDDialogShown
);
795 StartupUtils::MarkOobeCompleted();
797 // Restart to make the login page pick up the policy changes resulting from
798 // enrollment recovery.
799 // TODO(tnagel): Find a way to update login page without reboot.
800 if (prescribed_enrollment_config_
.mode
==
801 policy::EnrollmentConfig::MODE_RECOVERY
) {
802 chrome::AttemptRestart();
806 void WizardController::SetCurrentScreen(BaseScreen
* new_current
) {
807 SetCurrentScreenSmooth(new_current
, false);
810 void WizardController::ShowCurrentScreen() {
811 // ShowCurrentScreen may get called by smooth_show_timer_ even after
812 // flow has been switched to sign in screen (ExistingUserController).
816 // First remember how far have we reached so that we can resume if needed.
817 if (is_out_of_box_
&& IsResumableScreen(current_screen_
->GetName()))
818 StartupUtils::SaveOobePendingScreen(current_screen_
->GetName());
820 smooth_show_timer_
.Stop();
822 FOR_EACH_OBSERVER(Observer
, observer_list_
, OnScreenChanged(current_screen_
));
824 current_screen_
->Show();
827 void WizardController::SetCurrentScreenSmooth(BaseScreen
* new_current
,
828 bool use_smoothing
) {
829 if (current_screen_
== new_current
||
830 new_current
== NULL
||
831 oobe_display_
== NULL
) {
835 smooth_show_timer_
.Stop();
838 current_screen_
->Hide();
840 std::string screen_id
= new_current
->GetName();
841 if (IsOOBEStepToTrack(screen_id
))
842 screen_show_times_
[screen_id
] = base::Time::Now();
844 previous_screen_
= current_screen_
;
845 current_screen_
= new_current
;
848 smooth_show_timer_
.Start(
850 base::TimeDelta::FromMilliseconds(kShowDelayMs
),
852 &WizardController::ShowCurrentScreen
);
858 void WizardController::SetStatusAreaVisible(bool visible
) {
859 host_
->SetStatusAreaVisible(visible
);
862 void WizardController::OnHIDScreenNecessityCheck(bool screen_needed
) {
866 ShowHIDDetectionScreen();
871 void WizardController::AdvanceToScreen(const std::string
& screen_name
) {
872 if (screen_name
== kNetworkScreenName
) {
874 } else if (screen_name
== kLoginScreenName
) {
875 ShowLoginScreen(LoginScreenContext());
876 } else if (screen_name
== kUpdateScreenName
) {
877 InitiateOOBEUpdate();
878 } else if (screen_name
== kUserImageScreenName
) {
879 ShowUserImageScreen();
880 } else if (screen_name
== kEulaScreenName
) {
882 } else if (screen_name
== kResetScreenName
) {
884 } else if (screen_name
== kKioskEnableScreenName
) {
885 ShowKioskEnableScreen();
886 } else if (screen_name
== kKioskAutolaunchScreenName
) {
887 ShowKioskAutolaunchScreen();
888 } else if (screen_name
== kEnableDebuggingScreenName
) {
889 ShowEnableDebuggingScreen();
890 } else if (screen_name
== kEnrollmentScreenName
) {
891 ShowEnrollmentScreen();
892 } else if (screen_name
== kTermsOfServiceScreenName
) {
893 ShowTermsOfServiceScreen();
894 } else if (screen_name
== kWrongHWIDScreenName
) {
895 ShowWrongHWIDScreen();
896 } else if (screen_name
== kAutoEnrollmentCheckScreenName
) {
897 ShowAutoEnrollmentCheckScreen();
898 } else if (screen_name
== kSupervisedUserCreationScreenName
) {
899 ShowSupervisedUserCreationScreen();
900 } else if (screen_name
== kAppLaunchSplashScreenName
) {
901 AutoLaunchKioskApp();
902 } else if (screen_name
== kHIDDetectionScreenName
) {
903 ShowHIDDetectionScreen();
904 } else if (screen_name
== kControllerPairingScreenName
) {
905 ShowControllerPairingScreen();
906 } else if (screen_name
== kHostPairingScreenName
) {
907 ShowHostPairingScreen();
908 } else if (screen_name
== kDeviceDisabledScreenName
) {
909 ShowDeviceDisabledScreen();
910 } else if (screen_name
!= kTestNoScreenName
) {
911 if (is_out_of_box_
) {
912 time_oobe_started_
= base::Time::Now();
913 if (IsHostPairingOobe()) {
914 ShowHostPairingScreen();
915 } else if (CanShowHIDDetectionScreen()) {
916 base::Callback
<void(bool)> on_check
= base::Bind(
917 &WizardController::OnHIDScreenNecessityCheck
,
918 weak_factory_
.GetWeakPtr());
919 oobe_display_
->GetHIDDetectionScreenActor()->CheckIsScreenRequired(
925 ShowLoginScreen(LoginScreenContext());
930 ///////////////////////////////////////////////////////////////////////////////
931 // WizardController, BaseScreenDelegate overrides:
932 void WizardController::OnExit(BaseScreen
& /* screen */,
934 const ::login::ScreenContext
* /* context */) {
935 VLOG(1) << "Wizard screen exit code: " << exit_code
;
936 std::string previous_screen_id
= current_screen_
->GetName();
937 if (IsOOBEStepToTrack(previous_screen_id
)) {
938 RecordUMAHistogramForOOBEStepCompletionTime(
940 base::Time::Now() - screen_show_times_
[previous_screen_id
]);
943 case HID_DETECTION_COMPLETED
:
944 OnHIDDetectionCompleted();
946 case NETWORK_CONNECTED
:
947 OnNetworkConnected();
949 case CONNECTION_FAILED
:
950 OnConnectionFailed();
952 case UPDATE_INSTALLED
:
953 case UPDATE_NOUPDATE
:
956 case UPDATE_ERROR_CHECKING_FOR_UPDATE
:
957 OnUpdateErrorCheckingForUpdate();
959 case UPDATE_ERROR_UPDATING
:
960 OnUpdateErrorUpdating();
962 case USER_IMAGE_SELECTED
:
963 OnUserImageSelected();
971 case ENABLE_DEBUGGING_CANCELED
:
972 OnDeviceModificationCanceled();
974 case ENABLE_DEBUGGING_FINISHED
:
975 OnDeviceModificationCanceled();
977 case ENTERPRISE_AUTO_ENROLLMENT_CHECK_COMPLETED
:
978 OnAutoEnrollmentCheckCompleted();
980 case ENTERPRISE_ENROLLMENT_COMPLETED
:
983 case ENTERPRISE_ENROLLMENT_BACK
:
984 retry_auto_enrollment_check_
= true;
985 ShowAutoEnrollmentCheckScreen();
988 OnDeviceModificationCanceled();
990 case KIOSK_AUTOLAUNCH_CANCELED
:
991 OnKioskAutolaunchCanceled();
993 case KIOSK_AUTOLAUNCH_CONFIRMED
:
994 OnKioskAutolaunchConfirmed();
996 case KIOSK_ENABLE_COMPLETED
:
997 OnKioskEnableCompleted();
999 case TERMS_OF_SERVICE_DECLINED
:
1000 OnTermsOfServiceDeclined();
1002 case TERMS_OF_SERVICE_ACCEPTED
:
1003 OnTermsOfServiceAccepted();
1005 case WRONG_HWID_WARNING_SKIPPED
:
1006 OnWrongHWIDWarningSkipped();
1008 case CONTROLLER_PAIRING_FINISHED
:
1009 OnControllerPairingFinished();
1011 case HOST_PAIRING_FINISHED
:
1012 OnHostPairingFinished();
1019 void WizardController::ShowErrorScreen() {
1020 VLOG(1) << "Showing error screen.";
1021 SetCurrentScreen(GetScreen(kErrorScreenName
));
1024 void WizardController::HideErrorScreen(BaseScreen
* parent_screen
) {
1025 DCHECK(parent_screen
);
1026 VLOG(1) << "Hiding error screen.";
1027 SetCurrentScreen(parent_screen
);
1030 void WizardController::SetUsageStatisticsReporting(bool val
) {
1031 usage_statistics_reporting_
= val
;
1034 bool WizardController::GetUsageStatisticsReporting() const {
1035 return usage_statistics_reporting_
;
1038 void WizardController::SetHostConfiguration() {
1039 if (shark_controller_
) {
1040 NetworkScreen
* network_screen
= NetworkScreen::Get(this);
1041 shark_controller_
->SetHostConfiguration(
1042 true, // Eula must be accepted before we get this far.
1043 network_screen
->GetApplicationLocale(), network_screen
->GetTimezone(),
1044 GetUsageStatisticsReporting(), network_screen
->GetInputMethod());
1048 void WizardController::ConfigureHost(bool accepted_eula
,
1049 const std::string
& lang
,
1050 const std::string
& timezone
,
1052 const std::string
& keyboard_layout
) {
1053 VLOG(1) << "ConfigureHost locale=" << lang
<< ", timezone=" << timezone
1054 << ", keyboard_layout=" << keyboard_layout
;
1055 if (accepted_eula
) // Always true.
1056 StartupUtils::MarkEulaAccepted();
1057 SetUsageStatisticsReporting(send_reports
);
1059 NetworkScreen
* network_screen
= NetworkScreen::Get(this);
1060 network_screen
->SetApplicationLocale(lang
);
1061 network_screen
->SetTimezone(timezone
);
1062 network_screen
->SetInputMethod(keyboard_layout
);
1065 void WizardController::OnEnableDebuggingScreenRequested() {
1066 if (!login_screen_started())
1067 AdvanceToScreen(WizardController::kEnableDebuggingScreenName
);
1070 void WizardController::OnAccessibilityStatusChanged(
1071 const AccessibilityStatusEventDetails
& details
) {
1072 enum AccessibilityNotificationType type
= details
.notification_type
;
1073 if (type
== ACCESSIBILITY_MANAGER_SHUTDOWN
) {
1074 accessibility_subscription_
.reset();
1076 } else if (type
!= ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK
|| !details
.enabled
) {
1080 CrasAudioHandler
* cras
= CrasAudioHandler::Get();
1081 if (cras
->IsOutputMuted()) {
1082 cras
->SetOutputMute(false);
1083 cras
->SetOutputVolumePercent(kMinAudibleOutputVolumePercent
);
1084 } else if (cras
->GetOutputVolumePercent() < kMinAudibleOutputVolumePercent
) {
1085 cras
->SetOutputVolumePercent(kMinAudibleOutputVolumePercent
);
1089 void WizardController::AutoLaunchKioskApp() {
1090 KioskAppManager::App app_data
;
1091 std::string app_id
= KioskAppManager::Get()->GetAutoLaunchApp();
1092 CHECK(KioskAppManager::Get()->GetApp(app_id
, &app_data
));
1094 // Wait for the |CrosSettings| to become either trusted or permanently
1096 const CrosSettingsProvider::TrustedStatus status
=
1097 CrosSettings::Get()->PrepareTrustedValues(base::Bind(
1098 &WizardController::AutoLaunchKioskApp
,
1099 weak_factory_
.GetWeakPtr()));
1100 if (status
== CrosSettingsProvider::TEMPORARILY_UNTRUSTED
)
1103 if (status
== CrosSettingsProvider::PERMANENTLY_UNTRUSTED
) {
1104 // If the |cros_settings_| are permanently untrusted, show an error message
1105 // and refuse to auto-launch the kiosk app.
1106 GetErrorScreen()->SetUIState(ErrorScreen::UI_STATE_LOCAL_STATE_ERROR
);
1107 SetStatusAreaVisible(false);
1112 bool device_disabled
= false;
1113 CrosSettings::Get()->GetBoolean(kDeviceDisabled
, &device_disabled
);
1114 if (device_disabled
&& system::DeviceDisablingManager::
1115 HonorDeviceDisablingDuringNormalOperation()) {
1116 // If the device is disabled, bail out. A device disabled screen will be
1117 // shown by the DeviceDisablingManager.
1121 const bool diagnostic_mode
= false;
1122 const bool auto_launch
= true;
1123 host_
->StartAppLaunch(app_id
, diagnostic_mode
, auto_launch
);
1127 void WizardController::SetZeroDelays() {
1129 zero_delay_enabled_
= true;
1133 bool WizardController::IsZeroDelayEnabled() {
1134 return zero_delay_enabled_
;
1138 bool WizardController::IsOOBEStepToTrack(const std::string
& screen_id
) {
1139 return (screen_id
== kHIDDetectionScreenName
||
1140 screen_id
== kNetworkScreenName
||
1141 screen_id
== kUpdateScreenName
||
1142 screen_id
== kUserImageScreenName
||
1143 screen_id
== kEulaScreenName
||
1144 screen_id
== kLoginScreenName
||
1145 screen_id
== kWrongHWIDScreenName
);
1149 void WizardController::SkipPostLoginScreensForTesting() {
1150 skip_post_login_screens_
= true;
1153 void WizardController::OnLocalStateInitialized(bool /* succeeded */) {
1154 if (GetLocalState()->GetInitializationStatus() !=
1155 PrefService::INITIALIZATION_STATUS_ERROR
) {
1158 GetErrorScreen()->SetUIState(ErrorScreen::UI_STATE_LOCAL_STATE_ERROR
);
1159 SetStatusAreaVisible(false);
1163 PrefService
* WizardController::GetLocalState() {
1164 if (local_state_for_testing_
)
1165 return local_state_for_testing_
;
1166 return g_browser_process
->local_state();
1169 void WizardController::OnTimezoneResolved(
1170 scoped_ptr
<TimeZoneResponseData
> timezone
,
1171 bool server_error
) {
1172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1173 DCHECK(timezone
.get());
1174 // To check that "this" is not destroyed try to access some member
1175 // (timezone_provider_) in this case. Expect crash here.
1176 DCHECK(timezone_provider_
.get());
1178 timezone_resolved_
= true;
1179 base::ScopedClosureRunner
inform_test(on_timezone_resolved_for_testing_
);
1180 on_timezone_resolved_for_testing_
.Reset();
1182 VLOG(1) << "Resolved local timezone={" << timezone
->ToStringForDebug()
1185 if (timezone
->status
!= TimeZoneResponseData::OK
) {
1186 LOG(WARNING
) << "Resolve TimeZone: failed to resolve timezone.";
1190 policy::BrowserPolicyConnectorChromeOS
* connector
=
1191 g_browser_process
->platform_part()->browser_policy_connector_chromeos();
1192 if (connector
->IsEnterpriseManaged()) {
1193 std::string policy_timezone
;
1194 if (CrosSettings::Get()->GetString(kSystemTimezonePolicy
,
1195 &policy_timezone
) &&
1196 !policy_timezone
.empty()) {
1197 VLOG(1) << "Resolve TimeZone: TimeZone settings are overridden"
1198 << " by DevicePolicy.";
1203 if (!timezone
->timeZoneId
.empty()) {
1204 VLOG(1) << "Resolve TimeZone: setting timezone to '" << timezone
->timeZoneId
1207 system::TimezoneSettings::GetInstance()->SetTimezoneFromID(
1208 base::UTF8ToUTF16(timezone
->timeZoneId
));
1212 TimeZoneProvider
* WizardController::GetTimezoneProvider() {
1213 if (!timezone_provider_
) {
1214 timezone_provider_
.reset(
1215 new TimeZoneProvider(g_browser_process
->system_request_context(),
1216 DefaultTimezoneProviderURL()));
1218 return timezone_provider_
.get();
1221 void WizardController::OnLocationResolved(const Geoposition
& position
,
1223 const base::TimeDelta elapsed
) {
1224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
1226 const base::TimeDelta timeout
=
1227 base::TimeDelta::FromSeconds(kResolveTimeZoneTimeoutSeconds
);
1228 // Ignore invalid position.
1229 if (!position
.Valid())
1232 if (elapsed
>= timeout
) {
1233 LOG(WARNING
) << "Resolve TimeZone: got location after timeout ("
1234 << elapsed
.InSecondsF() << " seconds elapsed). Ignored.";
1238 // WizardController owns TimezoneProvider, so timezone request is silently
1239 // cancelled on destruction.
1240 GetTimezoneProvider()->RequestTimezone(
1243 base::Bind(&WizardController::OnTimezoneResolved
,
1244 base::Unretained(this)));
1247 bool WizardController::SetOnTimeZoneResolvedForTesting(
1248 const base::Closure
& callback
) {
1249 if (timezone_resolved_
)
1252 on_timezone_resolved_for_testing_
= callback
;
1256 bool WizardController::IsHostPairingOobe() const {
1257 return IsRemoraRequisition() &&
1258 (base::CommandLine::ForCurrentProcess()->HasSwitch(
1259 switches::kHostPairingOobe
) ||
1260 shark_controller_detected_
);
1263 void WizardController::MaybeStartListeningForSharkConnection() {
1264 if (!IsRemoraRequisition())
1267 // We shouldn't be here if we are running pairing OOBE already.
1268 DCHECK(!IsHostPairingOobe());
1270 if (!shark_connection_listener_
) {
1271 shark_connection_listener_
.reset(
1272 new pairing_chromeos::SharkConnectionListener(
1273 base::Bind(&WizardController::OnSharkConnected
,
1274 weak_factory_
.GetWeakPtr())));
1278 void WizardController::OnSharkConnected(
1279 scoped_ptr
<pairing_chromeos::HostPairingController
> remora_controller
) {
1280 VLOG(1) << "OnSharkConnected";
1281 remora_controller_
= remora_controller
.Pass();
1282 base::MessageLoop::current()->DeleteSoon(
1283 FROM_HERE
, shark_connection_listener_
.release());
1284 shark_controller_detected_
= true;
1285 ShowHostPairingScreen();
1288 void WizardController::StartEnrollmentScreen() {
1289 VLOG(1) << "Showing enrollment screen.";
1291 // Determine the effective enrollment configuration. If there is a valid
1292 // prescribed configuration, use that. If not, figure out which variant of
1293 // manual enrollment is taking place.
1294 policy::EnrollmentConfig effective_config
= prescribed_enrollment_config_
;
1295 if (!effective_config
.should_enroll()) {
1296 effective_config
.mode
=
1297 prescribed_enrollment_config_
.management_domain
.empty()
1298 ? policy::EnrollmentConfig::MODE_MANUAL
1299 : policy::EnrollmentConfig::MODE_MANUAL_REENROLLMENT
;
1302 EnrollmentScreen
* screen
= EnrollmentScreen::Get(this);
1303 screen
->SetParameters(effective_config
, shark_controller_
.get(),
1304 remora_controller_
.get());
1305 SetStatusAreaVisible(true);
1306 SetCurrentScreen(screen
);
1309 } // namespace chromeos