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/kiosk_app_menu_handler.h"
30 #include "chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.h"
31 #include "chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.h"
32 #include "chrome/browser/ui/webui/chromeos/login/locally_managed_user_creation_screen_handler.h"
33 #include "chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.h"
34 #include "chrome/browser/ui/webui/chromeos/login/network_screen_handler.h"
35 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
36 #include "chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h"
37 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
38 #include "chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h"
39 #include "chrome/browser/ui/webui/chromeos/login/update_screen_handler.h"
40 #include "chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.h"
41 #include "chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h"
42 #include "chrome/browser/ui/webui/options/chromeos/user_image_source.h"
43 #include "chrome/browser/ui/webui/theme_source.h"
44 #include "chrome/common/chrome_constants.h"
45 #include "chrome/common/url_constants.h"
46 #include "chromeos/chromeos_constants.h"
47 #include "chromeos/chromeos_switches.h"
48 #include "content/public/browser/web_ui.h"
49 #include "content/public/browser/web_ui_data_source.h"
50 #include "grit/browser_resources.h"
51 #include "ui/base/resource/resource_bundle.h"
52 #include "ui/base/webui/web_ui_util.h"
58 // List of known types of OobeUI. Type added as path in chrome://oobe url, for
59 // example chrome://oobe/user-adding.
60 const char kOobeDisplay
[] = "oobe";
61 const char kLoginDisplay
[] = "login";
62 const char kLockDisplay
[] = "lock";
63 const char kUserAddingDisplay
[] = "user-adding";
64 const char kAppLaunchSplashDisplay
[] = "app-launch-splash";
66 const char* kKnownDisplayTypes
[] = {
71 kAppLaunchSplashDisplay
74 const char kStringsJSPath
[] = "strings.js";
75 const char kLoginJSPath
[] = "login.js";
76 const char kOobeJSPath
[] = "oobe.js";
77 const char kKeyboardUtilsJSPath
[] = "keyboard_utils.js";
78 const char kDemoUserLoginJSPath
[] = "demo_user_login.js";
80 // Paths for deferred resource loading.
81 const char kEnrollmentHTMLPath
[] = "enrollment.html";
82 const char kEnrollmentCSSPath
[] = "enrollment.css";
83 const char kEnrollmentJSPath
[] = "enrollment.js";
85 // Creates a WebUIDataSource for chrome://oobe
86 content::WebUIDataSource
* CreateOobeUIDataSource(
87 const base::DictionaryValue
& localized_strings
,
88 const std::string
& display_type
) {
89 content::WebUIDataSource
* source
=
90 content::WebUIDataSource::Create(chrome::kChromeUIOobeHost
);
91 source
->SetUseJsonJSFormatV2();
92 source
->AddLocalizedStrings(localized_strings
);
93 source
->SetJsonPath(kStringsJSPath
);
95 if (chromeos::KioskModeSettings::Get()->IsKioskModeEnabled()) {
96 source
->SetDefaultResource(IDR_DEMO_USER_LOGIN_HTML
);
97 source
->AddResourcePath(kDemoUserLoginJSPath
, IDR_DEMO_USER_LOGIN_JS
);
100 if (display_type
== kOobeDisplay
) {
101 source
->SetDefaultResource(IDR_OOBE_HTML
);
102 source
->AddResourcePath(kOobeJSPath
, IDR_OOBE_JS
);
104 source
->SetDefaultResource(IDR_LOGIN_HTML
);
105 source
->AddResourcePath(kLoginJSPath
, IDR_LOGIN_JS
);
107 source
->AddResourcePath(kKeyboardUtilsJSPath
, IDR_KEYBOARD_UTILS_JS
);
108 source
->OverrideContentSecurityPolicyFrameSrc(
109 "frame-src chrome://terms/ "
110 "chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik/;");
112 // Serve deferred resources.
113 source
->AddResourcePath(kEnrollmentHTMLPath
, IDR_OOBE_ENROLLMENT_HTML
);
114 source
->AddResourcePath(kEnrollmentCSSPath
, IDR_OOBE_ENROLLMENT_CSS
);
115 source
->AddResourcePath(kEnrollmentJSPath
, IDR_OOBE_ENROLLMENT_JS
);
120 std::string
GetDisplayType(const GURL
& url
) {
121 std::string path
= url
.path().size() ? url
.path().substr(1) : "";
122 if (std::find(kKnownDisplayTypes
,
123 kKnownDisplayTypes
+ arraysize(kKnownDisplayTypes
),
124 path
) == kKnownDisplayTypes
+ arraysize(kKnownDisplayTypes
)) {
125 LOG(ERROR
) << "Unknown display type '" << path
<< "'. Setting default.";
126 return kLoginDisplay
;
134 const char OobeUI::kScreenOobeNetwork
[] = "connect";
135 const char OobeUI::kScreenOobeEula
[] = "eula";
136 const char OobeUI::kScreenOobeUpdate
[] = "update";
137 const char OobeUI::kScreenOobeEnrollment
[] = "oauth-enrollment";
138 const char OobeUI::kScreenGaiaSignin
[] = "gaia-signin";
139 const char OobeUI::kScreenAccountPicker
[] = "account-picker";
140 const char OobeUI::kScreenKioskAutolaunch
[] = "autolaunch";
141 const char OobeUI::kScreenKioskEnable
[] = "kiosk-enable";
142 const char OobeUI::kScreenErrorMessage
[] = "error-message";
143 const char OobeUI::kScreenUserImagePicker
[] = "user-image";
144 const char OobeUI::kScreenTpmError
[] = "tpm-error-message";
145 const char OobeUI::kScreenPasswordChanged
[] = "password-changed";
146 const char OobeUI::kScreenManagedUserCreationFlow
[]
147 = "managed-user-creation";
148 const char OobeUI::kScreenTermsOfService
[] = "terms-of-service";
149 const char OobeUI::kScreenWrongHWID
[] = "wrong-hwid";
150 const char OobeUI::kScreenAppLaunchSplash
[] = "app-launch-splash";
151 const char OobeUI::kScreenConfirmPassword
[] = "confirm-password";
152 const char OobeUI::kScreenMessageBox
[] = "message-box";
154 OobeUI::OobeUI(content::WebUI
* web_ui
, const GURL
& url
)
155 : WebUIController(web_ui
),
157 network_dropdown_handler_(NULL
),
158 update_screen_handler_(NULL
),
159 network_screen_actor_(NULL
),
160 eula_screen_actor_(NULL
),
161 reset_screen_actor_(NULL
),
162 autolaunch_screen_actor_(NULL
),
163 kiosk_enable_screen_actor_(NULL
),
164 wrong_hwid_screen_actor_(NULL
),
165 locally_managed_user_creation_screen_actor_(NULL
),
166 error_screen_handler_(NULL
),
167 signin_screen_handler_(NULL
),
168 terms_of_service_screen_actor_(NULL
),
169 user_image_screen_actor_(NULL
),
170 kiosk_app_menu_handler_(NULL
),
171 current_screen_(SCREEN_UNKNOWN
),
173 display_type_
= GetDisplayType(url
);
174 InitializeScreenMaps();
176 network_state_informer_
= new NetworkStateInformer();
177 network_state_informer_
->Init();
179 core_handler_
= new CoreOobeHandler(this);
180 AddScreenHandler(core_handler_
);
181 core_handler_
->SetDelegate(this);
183 network_dropdown_handler_
= new NetworkDropdownHandler();
184 AddScreenHandler(network_dropdown_handler_
);
186 update_screen_handler_
= new UpdateScreenHandler();
187 AddScreenHandler(update_screen_handler_
);
188 network_dropdown_handler_
->AddObserver(update_screen_handler_
);
190 if (display_type_
== kOobeDisplay
) {
191 NetworkScreenHandler
* network_screen_handler
=
192 new NetworkScreenHandler(core_handler_
);
193 network_screen_actor_
= network_screen_handler
;
194 AddScreenHandler(network_screen_handler
);
197 EulaScreenHandler
* eula_screen_handler
= new EulaScreenHandler(core_handler_
);
198 eula_screen_actor_
= eula_screen_handler
;
199 AddScreenHandler(eula_screen_handler
);
201 ResetScreenHandler
* reset_screen_handler
= new ResetScreenHandler();
202 reset_screen_actor_
= reset_screen_handler
;
203 AddScreenHandler(reset_screen_handler
);
205 KioskAutolaunchScreenHandler
* autolaunch_screen_handler
=
206 new KioskAutolaunchScreenHandler();
207 autolaunch_screen_actor_
= autolaunch_screen_handler
;
208 AddScreenHandler(autolaunch_screen_handler
);
210 KioskEnableScreenHandler
* kiosk_enable_screen_handler
=
211 new KioskEnableScreenHandler();
212 kiosk_enable_screen_actor_
= kiosk_enable_screen_handler
;
213 AddScreenHandler(kiosk_enable_screen_handler
);
215 LocallyManagedUserCreationScreenHandler
*
216 locally_managed_user_creation_screen_handler
=
217 new LocallyManagedUserCreationScreenHandler();
218 locally_managed_user_creation_screen_actor_
=
219 locally_managed_user_creation_screen_handler
;
220 AddScreenHandler(locally_managed_user_creation_screen_handler
);
222 WrongHWIDScreenHandler
* wrong_hwid_screen_handler
=
223 new WrongHWIDScreenHandler();
224 wrong_hwid_screen_actor_
= wrong_hwid_screen_handler
;
225 AddScreenHandler(wrong_hwid_screen_handler
);
227 EnrollmentScreenHandler
* enrollment_screen_handler
=
228 new EnrollmentScreenHandler();
229 enrollment_screen_actor_
= enrollment_screen_handler
;
230 AddScreenHandler(enrollment_screen_handler
);
232 TermsOfServiceScreenHandler
* terms_of_service_screen_handler
=
233 new TermsOfServiceScreenHandler
;
234 terms_of_service_screen_actor_
= terms_of_service_screen_handler
;
235 AddScreenHandler(terms_of_service_screen_handler
);
237 UserImageScreenHandler
* user_image_screen_handler
=
238 new UserImageScreenHandler();
239 user_image_screen_actor_
= user_image_screen_handler
;
240 AddScreenHandler(user_image_screen_handler
);
242 error_screen_handler_
= new ErrorScreenHandler(network_state_informer_
);
243 AddScreenHandler(error_screen_handler_
);
245 gaia_screen_handler_
= new GaiaScreenHandler(network_state_informer_
);
246 AddScreenHandler(gaia_screen_handler_
);
248 signin_screen_handler_
= new SigninScreenHandler(network_state_informer_
,
249 error_screen_handler_
,
251 gaia_screen_handler_
);
252 AddScreenHandler(signin_screen_handler_
);
254 AppLaunchSplashScreenHandler
* app_launch_splash_screen_handler
=
255 new AppLaunchSplashScreenHandler(network_state_informer_
,
256 error_screen_handler_
);
257 AddScreenHandler(app_launch_splash_screen_handler
);
258 app_launch_splash_screen_actor_
= app_launch_splash_screen_handler
;
260 // Initialize KioskAppMenuHandler. Note that it is NOT a screen handler.
261 kiosk_app_menu_handler_
= new KioskAppMenuHandler
;
262 web_ui
->AddMessageHandler(kiosk_app_menu_handler_
);
264 base::DictionaryValue localized_strings
;
265 GetLocalizedStrings(&localized_strings
);
267 Profile
* profile
= Profile::FromWebUI(web_ui
);
268 // Set up the chrome://theme/ source, for Chrome logo.
269 ThemeSource
* theme
= new ThemeSource(profile
);
270 content::URLDataSource::Add(profile
, theme
);
272 // Set up the chrome://terms/ data source, for EULA content.
273 AboutUIHTMLSource
* about_source
=
274 new AboutUIHTMLSource(chrome::kChromeUITermsHost
, profile
);
275 content::URLDataSource::Add(profile
, about_source
);
277 // Set up the chrome://oobe/ source.
278 content::WebUIDataSource::Add(profile
,
279 CreateOobeUIDataSource(localized_strings
,
282 // Set up the chrome://userimage/ source.
283 options::UserImageSource
* user_image_source
=
284 new options::UserImageSource();
285 content::URLDataSource::Add(profile
, user_image_source
);
289 core_handler_
->SetDelegate(NULL
);
290 network_dropdown_handler_
->RemoveObserver(update_screen_handler_
);
293 void OobeUI::ShowScreen(WizardScreen
* screen
) {
297 void OobeUI::HideScreen(WizardScreen
* screen
) {
301 UpdateScreenActor
* OobeUI::GetUpdateScreenActor() {
302 return update_screen_handler_
;
305 NetworkScreenActor
* OobeUI::GetNetworkScreenActor() {
306 return network_screen_actor_
;
309 EulaScreenActor
* OobeUI::GetEulaScreenActor() {
310 return eula_screen_actor_
;
313 EnrollmentScreenActor
* OobeUI::GetEnrollmentScreenActor() {
314 return enrollment_screen_actor_
;
317 ResetScreenActor
* OobeUI::GetResetScreenActor() {
318 return reset_screen_actor_
;
321 KioskAutolaunchScreenActor
* OobeUI::GetKioskAutolaunchScreenActor() {
322 return autolaunch_screen_actor_
;
325 KioskEnableScreenActor
* OobeUI::GetKioskEnableScreenActor() {
326 return kiosk_enable_screen_actor_
;
329 TermsOfServiceScreenActor
* OobeUI::GetTermsOfServiceScreenActor() {
330 return terms_of_service_screen_actor_
;
333 WrongHWIDScreenActor
* OobeUI::GetWrongHWIDScreenActor() {
334 return wrong_hwid_screen_actor_
;
337 UserImageScreenActor
* OobeUI::GetUserImageScreenActor() {
338 return user_image_screen_actor_
;
341 ErrorScreenActor
* OobeUI::GetErrorScreenActor() {
342 return error_screen_handler_
;
345 LocallyManagedUserCreationScreenHandler
*
346 OobeUI::GetLocallyManagedUserCreationScreenActor() {
347 return locally_managed_user_creation_screen_actor_
;
350 AppLaunchSplashScreenActor
*
351 OobeUI::GetAppLaunchSplashScreenActor() {
352 return app_launch_splash_screen_actor_
;
355 void OobeUI::GetLocalizedStrings(base::DictionaryValue
* localized_strings
) {
356 // Note, handlers_[0] is a GenericHandler used by the WebUI.
357 for (size_t i
= 0; i
< handlers_
.size(); ++i
)
358 handlers_
[i
]->GetLocalizedStrings(localized_strings
);
359 webui::SetFontAndTextDirection(localized_strings
);
360 kiosk_app_menu_handler_
->GetLocalizedStrings(localized_strings
);
362 #if defined(GOOGLE_CHROME_BUILD)
363 localized_strings
->SetString("buildType", "chrome");
365 localized_strings
->SetString("buildType", "chromium");
368 // If we're not doing boot animation then WebUI should trigger
369 // wallpaper load on boot.
370 if (CommandLine::ForCurrentProcess()->HasSwitch(
371 switches::kDisableBootAnimation
)) {
372 localized_strings
->SetString("bootIntoWallpaper", "on");
374 localized_strings
->SetString("bootIntoWallpaper", "off");
377 bool keyboard_driven_oobe
=
378 system::keyboard_settings::ForceKeyboardDrivenUINavigation();
379 localized_strings
->SetString("highlightStrength",
380 keyboard_driven_oobe
? "strong" : "normal");
383 void OobeUI::InitializeScreenMaps() {
384 screen_names_
.resize(SCREEN_UNKNOWN
);
385 screen_names_
[SCREEN_OOBE_NETWORK
] = kScreenOobeNetwork
;
386 screen_names_
[SCREEN_OOBE_EULA
] = kScreenOobeEula
;
387 screen_names_
[SCREEN_OOBE_UPDATE
] = kScreenOobeUpdate
;
388 screen_names_
[SCREEN_OOBE_ENROLLMENT
] = kScreenOobeEnrollment
;
389 screen_names_
[SCREEN_GAIA_SIGNIN
] = kScreenGaiaSignin
;
390 screen_names_
[SCREEN_ACCOUNT_PICKER
] = kScreenAccountPicker
;
391 screen_names_
[SCREEN_KIOSK_AUTOLAUNCH
] = kScreenKioskAutolaunch
;
392 screen_names_
[SCREEN_KIOSK_ENABLE
] = kScreenKioskEnable
;
393 screen_names_
[SCREEN_ERROR_MESSAGE
] = kScreenErrorMessage
;
394 screen_names_
[SCREEN_USER_IMAGE_PICKER
] = kScreenUserImagePicker
;
395 screen_names_
[SCREEN_TPM_ERROR
] = kScreenTpmError
;
396 screen_names_
[SCREEN_PASSWORD_CHANGED
] = kScreenPasswordChanged
;
397 screen_names_
[SCREEN_CREATE_MANAGED_USER_FLOW
] =
398 kScreenManagedUserCreationFlow
;
399 screen_names_
[SCREEN_TERMS_OF_SERVICE
] = kScreenTermsOfService
;
400 screen_names_
[SCREEN_WRONG_HWID
] = kScreenWrongHWID
;
401 screen_names_
[SCREEN_APP_LAUNCH_SPLASH
] = kScreenAppLaunchSplash
;
402 screen_names_
[SCREEN_CONFIRM_PASSWORD
] = kScreenConfirmPassword
;
403 screen_names_
[SCREEN_MESSAGE_BOX
] = kScreenMessageBox
;
406 for (size_t i
= 0; i
< screen_names_
.size(); ++i
)
407 screen_ids_
[screen_names_
[i
]] = static_cast<Screen
>(i
);
410 void OobeUI::AddScreenHandler(BaseScreenHandler
* handler
) {
411 web_ui()->AddMessageHandler(handler
);
412 handlers_
.push_back(handler
);
415 void OobeUI::InitializeHandlers() {
417 for (size_t i
= 0; i
< ready_callbacks_
.size(); ++i
)
418 ready_callbacks_
[i
].Run();
419 ready_callbacks_
.clear();
421 // Notify 'initialize' for synchronously loaded screens.
422 for (size_t i
= 0; i
< handlers_
.size(); ++i
) {
423 if (handlers_
[i
]->async_assets_load_id().empty())
424 handlers_
[i
]->InitializeBase();
428 void OobeUI::OnScreenAssetsLoaded(const std::string
& async_assets_load_id
) {
429 DCHECK(!async_assets_load_id
.empty());
431 for (size_t i
= 0; i
< handlers_
.size(); ++i
) {
432 if (handlers_
[i
]->async_assets_load_id() == async_assets_load_id
)
433 handlers_
[i
]->InitializeBase();
437 bool OobeUI::IsJSReady(const base::Closure
& display_is_ready_callback
) {
439 ready_callbacks_
.push_back(display_is_ready_callback
);
443 void OobeUI::ShowOobeUI(bool show
) {
444 core_handler_
->ShowOobeUI(show
);
447 void OobeUI::ShowRetailModeLoginSpinner() {
448 signin_screen_handler_
->ShowRetailModeLoginSpinner();
451 void OobeUI::ShowSigninScreen(const LoginScreenContext
& context
,
452 SigninScreenHandlerDelegate
* delegate
,
453 NativeWindowDelegate
* native_window_delegate
) {
454 signin_screen_handler_
->SetDelegate(delegate
);
455 signin_screen_handler_
->SetNativeWindowDelegate(native_window_delegate
);
457 LoginScreenContext
actual_context(context
);
458 actual_context
.set_oobe_ui(core_handler_
->show_oobe_ui());
459 signin_screen_handler_
->Show(actual_context
);
462 void OobeUI::ResetSigninScreenHandlerDelegate() {
463 signin_screen_handler_
->SetDelegate(NULL
);
464 signin_screen_handler_
->SetNativeWindowDelegate(NULL
);
468 void OobeUI::AddObserver(Observer
* observer
) {
469 observer_list_
.AddObserver(observer
);
472 void OobeUI::RemoveObserver(Observer
* observer
) {
473 observer_list_
.RemoveObserver(observer
);
476 const std::string
& OobeUI::GetScreenName(Screen screen
) const {
477 DCHECK(screen
>= 0 && screen
< SCREEN_UNKNOWN
);
478 return screen_names_
[static_cast<size_t>(screen
)];
481 void OobeUI::OnCurrentScreenChanged(const std::string
& screen
) {
482 if (screen_ids_
.count(screen
)) {
483 Screen new_screen
= screen_ids_
[screen
];
484 FOR_EACH_OBSERVER(Observer
,
486 OnCurrentScreenChanged(current_screen_
, new_screen
));
487 current_screen_
= new_screen
;
489 NOTREACHED() << "Screen should be registered in InitializeScreenMaps()";
490 current_screen_
= SCREEN_UNKNOWN
;
494 } // namespace chromeos