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/ui/webui/chromeos/login/oobe_ui.h"
      6 
      7 #include <string>
      8 
      9 #include "ash/ash_switches.h"
     10 #include "base/command_line.h"
     11 #include "base/logging.h"
     12 #include "base/memory/ref_counted_memory.h"
     13 #include "base/values.h"
     14 #include "chrome/browser/browser_about_handler.h"
     15 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
     16 #include "chrome/browser/chromeos/login/enrollment/enrollment_screen_actor.h"
     17 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
     18 #include "chrome/browser/chromeos/login/screen_locker.h"
     19 #include "chrome/browser/chromeos/login/user_manager.h"
     20 #include "chrome/browser/chromeos/login/wizard_controller.h"
     21 #include "chrome/browser/chromeos/system/input_device_settings.h"
     22 #include "chrome/browser/profiles/profile.h"
     23 #include "chrome/browser/ui/webui/about_ui.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/kiosk_app_menu_handler.h"
     29 #include "chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.h"
     30 #include "chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.h"
     31 #include "chrome/browser/ui/webui/chromeos/login/locally_managed_user_creation_screen_handler.h"
     32 #include "chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.h"
     33 #include "chrome/browser/ui/webui/chromeos/login/network_screen_handler.h"
     34 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
     35 #include "chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h"
     36 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
     37 #include "chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h"
     38 #include "chrome/browser/ui/webui/chromeos/login/update_screen_handler.h"
     39 #include "chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.h"
     40 #include "chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h"
     41 #include "chrome/browser/ui/webui/options/chromeos/user_image_source.h"
     42 #include "chrome/browser/ui/webui/theme_source.h"
     43 #include "chrome/common/chrome_constants.h"
     44 #include "chrome/common/url_constants.h"
     45 #include "chromeos/chromeos_constants.h"
     46 #include "chromeos/chromeos_switches.h"
     47 #include "content/public/browser/web_ui.h"
     48 #include "content/public/browser/web_ui_data_source.h"
     49 #include "grit/browser_resources.h"
     50 #include "ui/base/resource/resource_bundle.h"
     51 #include "ui/webui/web_ui_util.h"
     52 
     53 namespace chromeos {
     54 
     55 namespace {
     56 
     57 // Path for a stripped down login page that does not have OOBE elements.
     58 const char kLoginPath[] = "login#login";
     59 
     60 const char kStringsJSPath[] = "strings.js";
     61 const char kLoginJSPath[] = "login.js";
     62 const char kOobeJSPath[] = "oobe.js";
     63 const char kKeyboardUtilsJSPath[] = "keyboard_utils.js";
     64 const char kDemoUserLoginJSPath[] = "demo_user_login.js";
     65 
     66 // Paths for deferred resource loading.
     67 const char kEnrollmentHTMLPath[] = "enrollment.html";
     68 const char kEnrollmentCSSPath[] = "enrollment.css";
     69 const char kEnrollmentJSPath[] = "enrollment.js";
     70 
     71 // Filter handler of chrome://oobe data source.
     72 bool HandleRequestCallback(
     73     const std::string& path,
     74     const content::WebUIDataSource::GotDataCallback& callback) {
     75   if (UserManager::Get()->IsUserLoggedIn() &&
     76       !UserManager::Get()->IsLoggedInAsStub() &&
     77       !ScreenLocker::default_screen_locker()) {
     78     scoped_refptr<base::RefCountedBytes> empty_bytes =
     79         new base::RefCountedBytes();
     80     callback.Run(empty_bytes.get());
     81     return true;
     82   }
     83 
     84   return false;
     85 }
     86 
     87 // Creates a WebUIDataSource for chrome://oobe
     88 content::WebUIDataSource* CreateOobeUIDataSource(
     89     const base::DictionaryValue& localized_strings) {
     90   content::WebUIDataSource* source =
     91       content::WebUIDataSource::Create(chrome::kChromeUIOobeHost);
     92   source->SetUseJsonJSFormatV2();
     93   source->AddLocalizedStrings(localized_strings);
     94   source->SetJsonPath(kStringsJSPath);
     95 
     96   if (chromeos::KioskModeSettings::Get()->IsKioskModeEnabled()) {
     97     source->SetDefaultResource(IDR_DEMO_USER_LOGIN_HTML);
     98     source->AddResourcePath(kDemoUserLoginJSPath,
     99                             IDR_DEMO_USER_LOGIN_JS);
    100     return source;
    101   }
    102 
    103   source->SetDefaultResource(IDR_OOBE_HTML);
    104   source->AddResourcePath(kOobeJSPath,
    105                           IDR_OOBE_JS);
    106   source->AddResourcePath(kLoginPath,
    107                           IDR_LOGIN_HTML);
    108   source->AddResourcePath(kLoginJSPath,
    109                           IDR_LOGIN_JS);
    110   source->AddResourcePath(kKeyboardUtilsJSPath,
    111                           IDR_KEYBOARD_UTILS_JS);
    112   source->OverrideContentSecurityPolicyFrameSrc(
    113       "frame-src chrome://terms/ "
    114       "chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik/;");
    115 
    116   // Serve deferred resources.
    117   source->AddResourcePath(kEnrollmentHTMLPath,
    118                           IDR_OOBE_ENROLLMENT_HTML);
    119   source->AddResourcePath(kEnrollmentCSSPath,
    120                           IDR_OOBE_ENROLLMENT_CSS);
    121   source->AddResourcePath(kEnrollmentJSPath,
    122                           IDR_OOBE_ENROLLMENT_JS);
    123 
    124   return source;
    125 }
    126 
    127 }  // namespace
    128 
    129 // static
    130 const char OobeUI::kScreenOobeNetwork[]     = "connect";
    131 const char OobeUI::kScreenOobeEula[]        = "eula";
    132 const char OobeUI::kScreenOobeUpdate[]      = "update";
    133 const char OobeUI::kScreenOobeEnrollment[]  = "oauth-enrollment";
    134 const char OobeUI::kScreenGaiaSignin[]      = "gaia-signin";
    135 const char OobeUI::kScreenAccountPicker[]   = "account-picker";
    136 const char OobeUI::kScreenKioskAutolaunch[] = "autolaunch";
    137 const char OobeUI::kScreenKioskEnable[]     = "kiosk-enable";
    138 const char OobeUI::kScreenErrorMessage[]    = "error-message";
    139 const char OobeUI::kScreenUserImagePicker[] = "user-image";
    140 const char OobeUI::kScreenTpmError[]        = "tpm-error-message";
    141 const char OobeUI::kScreenPasswordChanged[] = "password-changed";
    142 const char OobeUI::kScreenManagedUserCreationFlow[]
    143                                             = "managed-user-creation";
    144 const char OobeUI::kScreenTermsOfService[]  = "terms-of-service";
    145 const char OobeUI::kScreenWrongHWID[]       = "wrong-hwid";
    146 
    147 OobeUI::OobeUI(content::WebUI* web_ui)
    148     : WebUIController(web_ui),
    149       core_handler_(NULL),
    150       network_dropdown_handler_(NULL),
    151       update_screen_handler_(NULL),
    152       network_screen_actor_(NULL),
    153       eula_screen_actor_(NULL),
    154       reset_screen_actor_(NULL),
    155       autolaunch_screen_actor_(NULL),
    156       kiosk_enable_screen_actor_(NULL),
    157       wrong_hwid_screen_actor_(NULL),
    158       locally_managed_user_creation_screen_actor_(NULL),
    159       error_screen_handler_(NULL),
    160       signin_screen_handler_(NULL),
    161       terms_of_service_screen_actor_(NULL),
    162       user_image_screen_actor_(NULL),
    163       kiosk_app_menu_handler_(NULL),
    164       current_screen_(SCREEN_UNKNOWN),
    165       ready_(false) {
    166   InitializeScreenMaps();
    167 
    168   network_state_informer_ = new NetworkStateInformer();
    169   network_state_informer_->Init();
    170 
    171   core_handler_ = new CoreOobeHandler(this);
    172   AddScreenHandler(core_handler_);
    173   core_handler_->SetDelegate(this);
    174 
    175   network_dropdown_handler_ = new NetworkDropdownHandler();
    176   AddScreenHandler(network_dropdown_handler_);
    177 
    178   update_screen_handler_ = new UpdateScreenHandler();
    179   AddScreenHandler(update_screen_handler_);
    180   network_dropdown_handler_->AddObserver(update_screen_handler_);
    181 
    182   NetworkScreenHandler* network_screen_handler =
    183       new NetworkScreenHandler(core_handler_);
    184   network_screen_actor_ = network_screen_handler;
    185   AddScreenHandler(network_screen_handler);
    186 
    187   EulaScreenHandler* eula_screen_handler = new EulaScreenHandler(core_handler_);
    188   eula_screen_actor_ = eula_screen_handler;
    189   AddScreenHandler(eula_screen_handler);
    190 
    191   ResetScreenHandler* reset_screen_handler = new ResetScreenHandler();
    192   reset_screen_actor_ = reset_screen_handler;
    193   AddScreenHandler(reset_screen_handler);
    194 
    195   KioskAutolaunchScreenHandler* autolaunch_screen_handler =
    196       new KioskAutolaunchScreenHandler();
    197   autolaunch_screen_actor_ = autolaunch_screen_handler;
    198   AddScreenHandler(autolaunch_screen_handler);
    199 
    200   KioskEnableScreenHandler* kiosk_enable_screen_handler =
    201       new KioskEnableScreenHandler();
    202   kiosk_enable_screen_actor_ = kiosk_enable_screen_handler;
    203   AddScreenHandler(kiosk_enable_screen_handler);
    204 
    205   LocallyManagedUserCreationScreenHandler*
    206       locally_managed_user_creation_screen_handler =
    207           new LocallyManagedUserCreationScreenHandler();
    208   locally_managed_user_creation_screen_actor_ =
    209       locally_managed_user_creation_screen_handler;
    210   AddScreenHandler(locally_managed_user_creation_screen_handler);
    211 
    212   WrongHWIDScreenHandler* wrong_hwid_screen_handler =
    213       new WrongHWIDScreenHandler();
    214   wrong_hwid_screen_actor_ = wrong_hwid_screen_handler;
    215   AddScreenHandler(wrong_hwid_screen_handler);
    216 
    217   EnrollmentScreenHandler* enrollment_screen_handler =
    218       new EnrollmentScreenHandler();
    219   enrollment_screen_actor_ = enrollment_screen_handler;
    220   AddScreenHandler(enrollment_screen_handler);
    221 
    222   TermsOfServiceScreenHandler* terms_of_service_screen_handler =
    223       new TermsOfServiceScreenHandler;
    224   terms_of_service_screen_actor_ = terms_of_service_screen_handler;
    225   AddScreenHandler(terms_of_service_screen_handler);
    226 
    227   UserImageScreenHandler* user_image_screen_handler =
    228       new UserImageScreenHandler();
    229   user_image_screen_actor_ = user_image_screen_handler;
    230   AddScreenHandler(user_image_screen_handler);
    231 
    232   error_screen_handler_ = new ErrorScreenHandler(network_state_informer_);
    233   AddScreenHandler(error_screen_handler_);
    234 
    235   signin_screen_handler_ = new SigninScreenHandler(network_state_informer_,
    236                                                    error_screen_handler_,
    237                                                    core_handler_);
    238   AddScreenHandler(signin_screen_handler_);
    239 
    240   // Initialize KioskAppMenuHandler. Note that it is NOT a screen handler.
    241   kiosk_app_menu_handler_ = new KioskAppMenuHandler;
    242   web_ui->AddMessageHandler(kiosk_app_menu_handler_);
    243 
    244   base::DictionaryValue localized_strings;
    245   GetLocalizedStrings(&localized_strings);
    246 
    247   Profile* profile = Profile::FromWebUI(web_ui);
    248   // Set up the chrome://theme/ source, for Chrome logo.
    249   ThemeSource* theme = new ThemeSource(profile);
    250   content::URLDataSource::Add(profile, theme);
    251 
    252   // Set up the chrome://terms/ data source, for EULA content.
    253   AboutUIHTMLSource* about_source =
    254       new AboutUIHTMLSource(chrome::kChromeUITermsHost, profile);
    255   content::URLDataSource::Add(profile, about_source);
    256 
    257   // Set up the chrome://oobe/ source.
    258   content::WebUIDataSource::Add(profile,
    259                                 CreateOobeUIDataSource(localized_strings));
    260 
    261   // Set up the chrome://userimage/ source.
    262   options::UserImageSource* user_image_source =
    263       new options::UserImageSource();
    264   content::URLDataSource::Add(profile, user_image_source);
    265 }
    266 
    267 OobeUI::~OobeUI() {
    268   core_handler_->SetDelegate(NULL);
    269   network_dropdown_handler_->RemoveObserver(update_screen_handler_);
    270 }
    271 
    272 void OobeUI::ShowScreen(WizardScreen* screen) {
    273   screen->Show();
    274 }
    275 
    276 void OobeUI::HideScreen(WizardScreen* screen) {
    277   screen->Hide();
    278 }
    279 
    280 UpdateScreenActor* OobeUI::GetUpdateScreenActor() {
    281   return update_screen_handler_;
    282 }
    283 
    284 NetworkScreenActor* OobeUI::GetNetworkScreenActor() {
    285   return network_screen_actor_;
    286 }
    287 
    288 EulaScreenActor* OobeUI::GetEulaScreenActor() {
    289   return eula_screen_actor_;
    290 }
    291 
    292 EnrollmentScreenActor* OobeUI::GetEnrollmentScreenActor() {
    293   return enrollment_screen_actor_;
    294 }
    295 
    296 ResetScreenActor* OobeUI::GetResetScreenActor() {
    297   return reset_screen_actor_;
    298 }
    299 
    300 KioskAutolaunchScreenActor* OobeUI::GetKioskAutolaunchScreenActor() {
    301   return autolaunch_screen_actor_;
    302 }
    303 
    304 KioskEnableScreenActor* OobeUI::GetKioskEnableScreenActor() {
    305   return kiosk_enable_screen_actor_;
    306 }
    307 
    308 TermsOfServiceScreenActor* OobeUI::GetTermsOfServiceScreenActor() {
    309   return terms_of_service_screen_actor_;
    310 }
    311 
    312 WrongHWIDScreenActor* OobeUI::GetWrongHWIDScreenActor() {
    313   return wrong_hwid_screen_actor_;
    314 }
    315 
    316 UserImageScreenActor* OobeUI::GetUserImageScreenActor() {
    317   return user_image_screen_actor_;
    318 }
    319 
    320 ErrorScreenActor* OobeUI::GetErrorScreenActor() {
    321   return error_screen_handler_;
    322 }
    323 
    324 LocallyManagedUserCreationScreenHandler*
    325     OobeUI::GetLocallyManagedUserCreationScreenActor() {
    326   return locally_managed_user_creation_screen_actor_;
    327 }
    328 
    329 void OobeUI::GetLocalizedStrings(base::DictionaryValue* localized_strings) {
    330   // Note, handlers_[0] is a GenericHandler used by the WebUI.
    331   for (size_t i = 0; i < handlers_.size(); ++i)
    332     handlers_[i]->GetLocalizedStrings(localized_strings);
    333   webui::SetFontAndTextDirection(localized_strings);
    334   kiosk_app_menu_handler_->GetLocalizedStrings(localized_strings);
    335 
    336 #if defined(GOOGLE_CHROME_BUILD)
    337   localized_strings->SetString("buildType", "chrome");
    338 #else
    339   localized_strings->SetString("buildType", "chromium");
    340 #endif
    341 
    342   if (CommandLine::ForCurrentProcess()->
    343           HasSwitch(ash::switches::kAshDisableNewLockAnimations))
    344     localized_strings->SetString("lockAnimationsType", "old");
    345   else
    346     localized_strings->SetString("lockAnimationsType", "new");
    347 
    348   // If we're not doing boot animation then WebUI should trigger
    349   // wallpaper load on boot.
    350   if (CommandLine::ForCurrentProcess()->HasSwitch(
    351           switches::kDisableBootAnimation)) {
    352     localized_strings->SetString("bootIntoWallpaper", "on");
    353   } else {
    354     localized_strings->SetString("bootIntoWallpaper", "off");
    355   }
    356 
    357   bool keyboard_driven_oobe =
    358       system::keyboard_settings::ForceKeyboardDrivenUINavigation();
    359   localized_strings->SetString("highlightStrength",
    360                                keyboard_driven_oobe ? "strong" : "normal");
    361 }
    362 
    363 void OobeUI::InitializeScreenMaps() {
    364   screen_names_.resize(SCREEN_UNKNOWN);
    365   screen_names_[SCREEN_OOBE_NETWORK] = kScreenOobeNetwork;
    366   screen_names_[SCREEN_OOBE_EULA] = kScreenOobeEula;
    367   screen_names_[SCREEN_OOBE_UPDATE] = kScreenOobeUpdate;
    368   screen_names_[SCREEN_OOBE_ENROLLMENT] = kScreenOobeEnrollment;
    369   screen_names_[SCREEN_GAIA_SIGNIN] = kScreenGaiaSignin;
    370   screen_names_[SCREEN_ACCOUNT_PICKER] = kScreenAccountPicker;
    371   screen_names_[SCREEN_KIOSK_AUTOLAUNCH] = kScreenKioskAutolaunch;
    372   screen_names_[SCREEN_KIOSK_ENABLE] = kScreenKioskEnable;
    373   screen_names_[SCREEN_ERROR_MESSAGE] = kScreenErrorMessage;
    374   screen_names_[SCREEN_USER_IMAGE_PICKER] = kScreenUserImagePicker;
    375   screen_names_[SCREEN_TPM_ERROR] = kScreenTpmError;
    376   screen_names_[SCREEN_PASSWORD_CHANGED] = kScreenPasswordChanged;
    377   screen_names_[SCREEN_CREATE_MANAGED_USER_FLOW] =
    378       kScreenManagedUserCreationFlow;
    379   screen_names_[SCREEN_TERMS_OF_SERVICE] = kScreenTermsOfService;
    380   screen_names_[SCREEN_WRONG_HWID] = kScreenWrongHWID;
    381 
    382   screen_ids_.clear();
    383   for (size_t i = 0; i < screen_names_.size(); ++i)
    384     screen_ids_[screen_names_[i]] = static_cast<Screen>(i);
    385 }
    386 
    387 void OobeUI::AddScreenHandler(BaseScreenHandler* handler) {
    388   web_ui()->AddMessageHandler(handler);
    389   handlers_.push_back(handler);
    390 }
    391 
    392 void OobeUI::InitializeHandlers() {
    393   ready_ = true;
    394   for (size_t i = 0; i < ready_callbacks_.size(); ++i)
    395     ready_callbacks_[i].Run();
    396   ready_callbacks_.clear();
    397 
    398   for (size_t i = 0; i < handlers_.size(); ++i)
    399     handlers_[i]->InitializeBase();
    400 }
    401 
    402 bool OobeUI::IsJSReady(const base::Closure& display_is_ready_callback) {
    403   if (!ready_)
    404     ready_callbacks_.push_back(display_is_ready_callback);
    405   return ready_;
    406 }
    407 
    408 void OobeUI::ShowOobeUI(bool show) {
    409   core_handler_->ShowOobeUI(show);
    410 }
    411 
    412 void OobeUI::ShowRetailModeLoginSpinner() {
    413   signin_screen_handler_->ShowRetailModeLoginSpinner();
    414 }
    415 
    416 void OobeUI::ShowSigninScreen(SigninScreenHandlerDelegate* delegate,
    417                               NativeWindowDelegate* native_window_delegate) {
    418   signin_screen_handler_->SetDelegate(delegate);
    419   signin_screen_handler_->SetNativeWindowDelegate(native_window_delegate);
    420   signin_screen_handler_->Show(core_handler_->show_oobe_ui());
    421 }
    422 
    423 void OobeUI::ResetSigninScreenHandlerDelegate() {
    424   signin_screen_handler_->SetDelegate(NULL);
    425   signin_screen_handler_->SetNativeWindowDelegate(NULL);
    426 }
    427 
    428 const std::string& OobeUI::GetScreenName(Screen screen) const {
    429   DCHECK(screen >= 0 && screen < SCREEN_UNKNOWN);
    430   return screen_names_[static_cast<size_t>(screen)];
    431 }
    432 
    433 void OobeUI::OnCurrentScreenChanged(const std::string& screen) {
    434   if (screen_ids_.count(screen)) {
    435     current_screen_ = screen_ids_[screen];
    436   } else {
    437     NOTREACHED() << "Screen should be registered in InitializeScreenMaps()";
    438     current_screen_ = SCREEN_UNKNOWN;
    439   }
    440 }
    441 
    442 }  // namespace chromeos
    443