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/ui/webui/chromeos/login/oobe_ui.h"
7 #include "ash/ash_switches.h"
8 #include "base/command_line.h"
9 #include "base/logging.h"
10 #include "base/memory/ref_counted_memory.h"
11 #include "base/values.h"
12 #include "chrome/browser/browser_about_handler.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
15 #include "chrome/browser/chromeos/login/enrollment/enrollment_screen_actor.h"
16 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
17 #include "chrome/browser/chromeos/login/screen_locker.h"
18 #include "chrome/browser/chromeos/login/user_manager.h"
19 #include "chrome/browser/chromeos/login/wizard_controller.h"
20 #include "chrome/browser/chromeos/system/input_device_settings.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/ui/webui/about_ui.h"
23 #include "chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h"
24 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
25 #include "chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h"
26 #include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h"
27 #include "chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h"
28 #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
29 #include "chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.h"
30 #include "chrome/browser/ui/webui/chromeos/login/kiosk_app_menu_handler.h"
31 #include "chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.h"
32 #include "chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.h"
33 #include "chrome/browser/ui/webui/chromeos/login/locally_managed_user_creation_screen_handler.h"
34 #include "chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.h"
35 #include "chrome/browser/ui/webui/chromeos/login/network_screen_handler.h"
36 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
37 #include "chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h"
38 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
39 #include "chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h"
40 #include "chrome/browser/ui/webui/chromeos/login/update_screen_handler.h"
41 #include "chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.h"
42 #include "chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h"
43 #include "chrome/browser/ui/webui/options/chromeos/user_image_source.h"
44 #include "chrome/browser/ui/webui/theme_source.h"
45 #include "chrome/common/chrome_constants.h"
46 #include "chrome/common/url_constants.h"
47 #include "chromeos/chromeos_constants.h"
48 #include "chromeos/chromeos_switches.h"
49 #include "content/public/browser/web_ui.h"
50 #include "content/public/browser/web_ui_data_source.h"
51 #include "grit/browser_resources.h"
52 #include "ui/base/resource/resource_bundle.h"
53 #include "ui/base/webui/web_ui_util.h"
59 // List of known types of OobeUI. Type added as path in chrome://oobe url, for
60 // example chrome://oobe/user-adding.
61 const char kOobeDisplay
[] = "oobe";
62 const char kLoginDisplay
[] = "login";
63 const char kLockDisplay
[] = "lock";
64 const char kUserAddingDisplay
[] = "user-adding";
65 const char kAppLaunchSplashDisplay
[] = "app-launch-splash";
67 const char* kKnownDisplayTypes
[] = {
72 kAppLaunchSplashDisplay
75 const char kStringsJSPath
[] = "strings.js";
76 const char kLoginJSPath
[] = "login.js";
77 const char kOobeJSPath
[] = "oobe.js";
78 const char kKeyboardUtilsJSPath
[] = "keyboard_utils.js";
79 const char kDemoUserLoginJSPath
[] = "demo_user_login.js";
81 // Paths for deferred resource loading.
82 const char kEnrollmentHTMLPath
[] = "enrollment.html";
83 const char kEnrollmentCSSPath
[] = "enrollment.css";
84 const char kEnrollmentJSPath
[] = "enrollment.js";
86 // Creates a WebUIDataSource for chrome://oobe
87 content::WebUIDataSource
* CreateOobeUIDataSource(
88 const base::DictionaryValue
& localized_strings
,
89 const std::string
& display_type
) {
90 content::WebUIDataSource
* source
=
91 content::WebUIDataSource::Create(chrome::kChromeUIOobeHost
);
92 source
->SetUseJsonJSFormatV2();
93 source
->AddLocalizedStrings(localized_strings
);
94 source
->SetJsonPath(kStringsJSPath
);
96 if (chromeos::KioskModeSettings::Get()->IsKioskModeEnabled()) {
97 source
->SetDefaultResource(IDR_DEMO_USER_LOGIN_HTML
);
98 source
->AddResourcePath(kDemoUserLoginJSPath
, IDR_DEMO_USER_LOGIN_JS
);
101 if (display_type
== kOobeDisplay
) {
102 source
->SetDefaultResource(IDR_OOBE_HTML
);
103 source
->AddResourcePath(kOobeJSPath
, IDR_OOBE_JS
);
105 source
->SetDefaultResource(IDR_LOGIN_HTML
);
106 source
->AddResourcePath(kLoginJSPath
, IDR_LOGIN_JS
);
108 source
->AddResourcePath(kKeyboardUtilsJSPath
, IDR_KEYBOARD_UTILS_JS
);
109 source
->OverrideContentSecurityPolicyFrameSrc(
110 "frame-src chrome://terms/ "
111 "chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik/;");
113 // Serve deferred resources.
114 source
->AddResourcePath(kEnrollmentHTMLPath
, IDR_OOBE_ENROLLMENT_HTML
);
115 source
->AddResourcePath(kEnrollmentCSSPath
, IDR_OOBE_ENROLLMENT_CSS
);
116 source
->AddResourcePath(kEnrollmentJSPath
, IDR_OOBE_ENROLLMENT_JS
);
121 std::string
GetDisplayType(const GURL
& url
) {
122 std::string path
= url
.path().size() ? url
.path().substr(1) : "";
123 if (std::find(kKnownDisplayTypes
,
124 kKnownDisplayTypes
+ arraysize(kKnownDisplayTypes
),
125 path
) == kKnownDisplayTypes
+ arraysize(kKnownDisplayTypes
)) {
126 LOG(ERROR
) << "Unknown display type '" << path
<< "'. Setting default.";
127 return kLoginDisplay
;
135 const char OobeUI::kScreenOobeNetwork
[] = "connect";
136 const char OobeUI::kScreenOobeEula
[] = "eula";
137 const char OobeUI::kScreenOobeUpdate
[] = "update";
138 const char OobeUI::kScreenOobeEnrollment
[] = "oauth-enrollment";
139 const char OobeUI::kScreenOobeReset
[] = "reset";
140 const char OobeUI::kScreenGaiaSignin
[] = "gaia-signin";
141 const char OobeUI::kScreenAccountPicker
[] = "account-picker";
142 const char OobeUI::kScreenKioskAutolaunch
[] = "autolaunch";
143 const char OobeUI::kScreenKioskEnable
[] = "kiosk-enable";
144 const char OobeUI::kScreenErrorMessage
[] = "error-message";
145 const char OobeUI::kScreenUserImagePicker
[] = "user-image";
146 const char OobeUI::kScreenTpmError
[] = "tpm-error-message";
147 const char OobeUI::kScreenPasswordChanged
[] = "password-changed";
148 const char OobeUI::kScreenManagedUserCreationFlow
[]
149 = "managed-user-creation";
150 const char OobeUI::kScreenTermsOfService
[] = "terms-of-service";
151 const char OobeUI::kScreenWrongHWID
[] = "wrong-hwid";
152 const char OobeUI::kScreenHIDDetection
[] = "hid-detection";
153 const char OobeUI::kScreenAppLaunchSplash
[] = "app-launch-splash";
154 const char OobeUI::kScreenConfirmPassword
[] = "confirm-password";
155 const char OobeUI::kScreenFatalError
[] = "fatal-error";
157 OobeUI::OobeUI(content::WebUI
* web_ui
, const GURL
& url
)
158 : WebUIController(web_ui
),
160 network_dropdown_handler_(NULL
),
161 update_screen_handler_(NULL
),
162 network_screen_actor_(NULL
),
163 eula_screen_actor_(NULL
),
164 hid_detection_screen_actor_(NULL
),
165 reset_screen_actor_(NULL
),
166 autolaunch_screen_actor_(NULL
),
167 kiosk_enable_screen_actor_(NULL
),
168 wrong_hwid_screen_actor_(NULL
),
169 locally_managed_user_creation_screen_actor_(NULL
),
170 error_screen_handler_(NULL
),
171 signin_screen_handler_(NULL
),
172 terms_of_service_screen_actor_(NULL
),
173 user_image_screen_actor_(NULL
),
174 kiosk_app_menu_handler_(NULL
),
175 current_screen_(SCREEN_UNKNOWN
),
177 display_type_
= GetDisplayType(url
);
178 InitializeScreenMaps();
180 network_state_informer_
= new NetworkStateInformer();
181 network_state_informer_
->Init();
183 core_handler_
= new CoreOobeHandler(this);
184 AddScreenHandler(core_handler_
);
185 core_handler_
->SetDelegate(this);
187 network_dropdown_handler_
= new NetworkDropdownHandler();
188 AddScreenHandler(network_dropdown_handler_
);
190 update_screen_handler_
= new UpdateScreenHandler();
191 AddScreenHandler(update_screen_handler_
);
192 network_dropdown_handler_
->AddObserver(update_screen_handler_
);
194 if (display_type_
== kOobeDisplay
) {
195 NetworkScreenHandler
* network_screen_handler
=
196 new NetworkScreenHandler(core_handler_
);
197 network_screen_actor_
= network_screen_handler
;
198 AddScreenHandler(network_screen_handler
);
201 EulaScreenHandler
* eula_screen_handler
= new EulaScreenHandler(core_handler_
);
202 eula_screen_actor_
= eula_screen_handler
;
203 AddScreenHandler(eula_screen_handler
);
205 ResetScreenHandler
* reset_screen_handler
= new ResetScreenHandler();
206 reset_screen_actor_
= reset_screen_handler
;
207 AddScreenHandler(reset_screen_handler
);
209 KioskAutolaunchScreenHandler
* autolaunch_screen_handler
=
210 new KioskAutolaunchScreenHandler();
211 autolaunch_screen_actor_
= autolaunch_screen_handler
;
212 AddScreenHandler(autolaunch_screen_handler
);
214 KioskEnableScreenHandler
* kiosk_enable_screen_handler
=
215 new KioskEnableScreenHandler();
216 kiosk_enable_screen_actor_
= kiosk_enable_screen_handler
;
217 AddScreenHandler(kiosk_enable_screen_handler
);
219 LocallyManagedUserCreationScreenHandler
*
220 locally_managed_user_creation_screen_handler
=
221 new LocallyManagedUserCreationScreenHandler();
222 locally_managed_user_creation_screen_actor_
=
223 locally_managed_user_creation_screen_handler
;
224 AddScreenHandler(locally_managed_user_creation_screen_handler
);
226 WrongHWIDScreenHandler
* wrong_hwid_screen_handler
=
227 new WrongHWIDScreenHandler();
228 wrong_hwid_screen_actor_
= wrong_hwid_screen_handler
;
229 AddScreenHandler(wrong_hwid_screen_handler
);
231 HIDDetectionScreenHandler
* hid_detection_screen_handler
=
232 new HIDDetectionScreenHandler();
233 hid_detection_screen_actor_
= hid_detection_screen_handler
;
234 AddScreenHandler(hid_detection_screen_handler
);
236 EnrollmentScreenHandler
* enrollment_screen_handler
=
237 new EnrollmentScreenHandler();
238 enrollment_screen_actor_
= enrollment_screen_handler
;
239 AddScreenHandler(enrollment_screen_handler
);
241 TermsOfServiceScreenHandler
* terms_of_service_screen_handler
=
242 new TermsOfServiceScreenHandler
;
243 terms_of_service_screen_actor_
= terms_of_service_screen_handler
;
244 AddScreenHandler(terms_of_service_screen_handler
);
246 UserImageScreenHandler
* user_image_screen_handler
=
247 new UserImageScreenHandler();
248 user_image_screen_actor_
= user_image_screen_handler
;
249 AddScreenHandler(user_image_screen_handler
);
251 error_screen_handler_
= new ErrorScreenHandler(network_state_informer_
);
252 AddScreenHandler(error_screen_handler_
);
254 gaia_screen_handler_
= new GaiaScreenHandler(network_state_informer_
);
255 AddScreenHandler(gaia_screen_handler_
);
257 signin_screen_handler_
= new SigninScreenHandler(network_state_informer_
,
258 error_screen_handler_
,
260 gaia_screen_handler_
);
261 AddScreenHandler(signin_screen_handler_
);
263 AppLaunchSplashScreenHandler
* app_launch_splash_screen_handler
=
264 new AppLaunchSplashScreenHandler(network_state_informer_
,
265 error_screen_handler_
);
266 AddScreenHandler(app_launch_splash_screen_handler
);
267 app_launch_splash_screen_actor_
= app_launch_splash_screen_handler
;
269 // Initialize KioskAppMenuHandler. Note that it is NOT a screen handler.
270 kiosk_app_menu_handler_
= new KioskAppMenuHandler
;
271 web_ui
->AddMessageHandler(kiosk_app_menu_handler_
);
273 base::DictionaryValue localized_strings
;
274 GetLocalizedStrings(&localized_strings
);
276 Profile
* profile
= Profile::FromWebUI(web_ui
);
277 // Set up the chrome://theme/ source, for Chrome logo.
278 ThemeSource
* theme
= new ThemeSource(profile
);
279 content::URLDataSource::Add(profile
, theme
);
281 // Set up the chrome://terms/ data source, for EULA content.
282 AboutUIHTMLSource
* about_source
=
283 new AboutUIHTMLSource(chrome::kChromeUITermsHost
, profile
);
284 content::URLDataSource::Add(profile
, about_source
);
286 // Set up the chrome://oobe/ source.
287 content::WebUIDataSource::Add(profile
,
288 CreateOobeUIDataSource(localized_strings
,
291 // Set up the chrome://userimage/ source.
292 options::UserImageSource
* user_image_source
=
293 new options::UserImageSource();
294 content::URLDataSource::Add(profile
, user_image_source
);
298 core_handler_
->SetDelegate(NULL
);
299 network_dropdown_handler_
->RemoveObserver(update_screen_handler_
);
302 void OobeUI::ShowScreen(WizardScreen
* screen
) {
306 void OobeUI::HideScreen(WizardScreen
* screen
) {
310 UpdateScreenActor
* OobeUI::GetUpdateScreenActor() {
311 return update_screen_handler_
;
314 NetworkScreenActor
* OobeUI::GetNetworkScreenActor() {
315 return network_screen_actor_
;
318 EulaScreenActor
* OobeUI::GetEulaScreenActor() {
319 return eula_screen_actor_
;
322 EnrollmentScreenActor
* OobeUI::GetEnrollmentScreenActor() {
323 return enrollment_screen_actor_
;
326 ResetScreenActor
* OobeUI::GetResetScreenActor() {
327 return reset_screen_actor_
;
330 KioskAutolaunchScreenActor
* OobeUI::GetKioskAutolaunchScreenActor() {
331 return autolaunch_screen_actor_
;
334 KioskEnableScreenActor
* OobeUI::GetKioskEnableScreenActor() {
335 return kiosk_enable_screen_actor_
;
338 TermsOfServiceScreenActor
* OobeUI::GetTermsOfServiceScreenActor() {
339 return terms_of_service_screen_actor_
;
342 WrongHWIDScreenActor
* OobeUI::GetWrongHWIDScreenActor() {
343 return wrong_hwid_screen_actor_
;
346 HIDDetectionScreenActor
* OobeUI::GetHIDDetectionScreenActor() {
347 return hid_detection_screen_actor_
;
350 UserImageScreenActor
* OobeUI::GetUserImageScreenActor() {
351 return user_image_screen_actor_
;
354 ErrorScreenActor
* OobeUI::GetErrorScreenActor() {
355 return error_screen_handler_
;
358 LocallyManagedUserCreationScreenHandler
*
359 OobeUI::GetLocallyManagedUserCreationScreenActor() {
360 return locally_managed_user_creation_screen_actor_
;
363 AppLaunchSplashScreenActor
*
364 OobeUI::GetAppLaunchSplashScreenActor() {
365 return app_launch_splash_screen_actor_
;
368 void OobeUI::GetLocalizedStrings(base::DictionaryValue
* localized_strings
) {
369 // Note, handlers_[0] is a GenericHandler used by the WebUI.
370 for (size_t i
= 0; i
< handlers_
.size(); ++i
)
371 handlers_
[i
]->GetLocalizedStrings(localized_strings
);
372 webui::SetFontAndTextDirection(localized_strings
);
373 kiosk_app_menu_handler_
->GetLocalizedStrings(localized_strings
);
375 #if defined(GOOGLE_CHROME_BUILD)
376 localized_strings
->SetString("buildType", "chrome");
378 localized_strings
->SetString("buildType", "chromium");
381 // If we're not doing boot animation then WebUI should trigger
382 // wallpaper load on boot.
383 if (CommandLine::ForCurrentProcess()->HasSwitch(
384 switches::kDisableBootAnimation
)) {
385 localized_strings
->SetString("bootIntoWallpaper", "on");
387 localized_strings
->SetString("bootIntoWallpaper", "off");
390 bool keyboard_driven_oobe
=
391 system::InputDeviceSettings::Get()->ForceKeyboardDrivenUINavigation();
392 localized_strings
->SetString("highlightStrength",
393 keyboard_driven_oobe
? "strong" : "normal");
395 bool new_kiosk_ui
= KioskAppMenuHandler::EnableNewKioskUI();
396 localized_strings
->SetString("newKioskUI", new_kiosk_ui
? "on" : "off");
399 void OobeUI::InitializeScreenMaps() {
400 screen_names_
.resize(SCREEN_UNKNOWN
);
401 screen_names_
[SCREEN_OOBE_NETWORK
] = kScreenOobeNetwork
;
402 screen_names_
[SCREEN_OOBE_EULA
] = kScreenOobeEula
;
403 screen_names_
[SCREEN_OOBE_UPDATE
] = kScreenOobeUpdate
;
404 screen_names_
[SCREEN_OOBE_ENROLLMENT
] = kScreenOobeEnrollment
;
405 screen_names_
[SCREEN_OOBE_RESET
] = kScreenOobeReset
;
406 screen_names_
[SCREEN_GAIA_SIGNIN
] = kScreenGaiaSignin
;
407 screen_names_
[SCREEN_ACCOUNT_PICKER
] = kScreenAccountPicker
;
408 screen_names_
[SCREEN_KIOSK_AUTOLAUNCH
] = kScreenKioskAutolaunch
;
409 screen_names_
[SCREEN_KIOSK_ENABLE
] = kScreenKioskEnable
;
410 screen_names_
[SCREEN_ERROR_MESSAGE
] = kScreenErrorMessage
;
411 screen_names_
[SCREEN_USER_IMAGE_PICKER
] = kScreenUserImagePicker
;
412 screen_names_
[SCREEN_TPM_ERROR
] = kScreenTpmError
;
413 screen_names_
[SCREEN_PASSWORD_CHANGED
] = kScreenPasswordChanged
;
414 screen_names_
[SCREEN_CREATE_MANAGED_USER_FLOW
] =
415 kScreenManagedUserCreationFlow
;
416 screen_names_
[SCREEN_TERMS_OF_SERVICE
] = kScreenTermsOfService
;
417 screen_names_
[SCREEN_WRONG_HWID
] = kScreenWrongHWID
;
418 screen_names_
[SCREEN_APP_LAUNCH_SPLASH
] = kScreenAppLaunchSplash
;
419 screen_names_
[SCREEN_CONFIRM_PASSWORD
] = kScreenConfirmPassword
;
420 screen_names_
[SCREEN_FATAL_ERROR
] = kScreenFatalError
;
423 for (size_t i
= 0; i
< screen_names_
.size(); ++i
)
424 screen_ids_
[screen_names_
[i
]] = static_cast<Screen
>(i
);
427 void OobeUI::AddScreenHandler(BaseScreenHandler
* handler
) {
428 web_ui()->AddMessageHandler(handler
);
429 handlers_
.push_back(handler
);
432 void OobeUI::InitializeHandlers() {
434 for (size_t i
= 0; i
< ready_callbacks_
.size(); ++i
)
435 ready_callbacks_
[i
].Run();
436 ready_callbacks_
.clear();
438 // Notify 'initialize' for synchronously loaded screens.
439 for (size_t i
= 0; i
< handlers_
.size(); ++i
) {
440 if (handlers_
[i
]->async_assets_load_id().empty())
441 handlers_
[i
]->InitializeBase();
445 void OobeUI::OnScreenAssetsLoaded(const std::string
& async_assets_load_id
) {
446 DCHECK(!async_assets_load_id
.empty());
448 for (size_t i
= 0; i
< handlers_
.size(); ++i
) {
449 if (handlers_
[i
]->async_assets_load_id() == async_assets_load_id
)
450 handlers_
[i
]->InitializeBase();
454 bool OobeUI::IsJSReady(const base::Closure
& display_is_ready_callback
) {
456 ready_callbacks_
.push_back(display_is_ready_callback
);
460 void OobeUI::ShowOobeUI(bool show
) {
461 core_handler_
->ShowOobeUI(show
);
464 void OobeUI::ShowRetailModeLoginSpinner() {
465 signin_screen_handler_
->ShowRetailModeLoginSpinner();
468 void OobeUI::ShowSigninScreen(const LoginScreenContext
& context
,
469 SigninScreenHandlerDelegate
* delegate
,
470 NativeWindowDelegate
* native_window_delegate
) {
471 signin_screen_handler_
->SetDelegate(delegate
);
472 signin_screen_handler_
->SetNativeWindowDelegate(native_window_delegate
);
474 LoginScreenContext
actual_context(context
);
475 actual_context
.set_oobe_ui(core_handler_
->show_oobe_ui());
476 signin_screen_handler_
->Show(actual_context
);
479 void OobeUI::ResetSigninScreenHandlerDelegate() {
480 signin_screen_handler_
->SetDelegate(NULL
);
481 signin_screen_handler_
->SetNativeWindowDelegate(NULL
);
485 void OobeUI::AddObserver(Observer
* observer
) {
486 observer_list_
.AddObserver(observer
);
489 void OobeUI::RemoveObserver(Observer
* observer
) {
490 observer_list_
.RemoveObserver(observer
);
493 const std::string
& OobeUI::GetScreenName(Screen screen
) const {
494 DCHECK(screen
>= 0 && screen
< SCREEN_UNKNOWN
);
495 return screen_names_
[static_cast<size_t>(screen
)];
498 void OobeUI::OnCurrentScreenChanged(const std::string
& screen
) {
499 if (screen_ids_
.count(screen
)) {
500 Screen new_screen
= screen_ids_
[screen
];
501 FOR_EACH_OBSERVER(Observer
,
503 OnCurrentScreenChanged(current_screen_
, new_screen
));
504 current_screen_
= new_screen
;
506 NOTREACHED() << "Screen should be registered in InitializeScreenMaps()";
507 current_screen_
= SCREEN_UNKNOWN
;
511 } // namespace chromeos