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/error_screen_handler.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/time/time.h"
     10 #include "chrome/browser/chrome_notification_types.h"
     11 #include "chrome/browser/chromeos/app_mode/app_session_lifetime.h"
     12 #include "chrome/browser/chromeos/app_mode/certificate_manager_dialog.h"
     13 #include "chrome/browser/chromeos/login/ui/captive_portal_window_proxy.h"
     14 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
     15 #include "chrome/browser/chromeos/login/ui/webui_login_view.h"
     16 #include "chrome/browser/extensions/component_loader.h"
     17 #include "chrome/browser/extensions/extension_service.h"
     18 #include "chrome/browser/profiles/profile_manager.h"
     19 #include "chrome/browser/ui/extensions/application_launch.h"
     20 #include "chrome/browser/ui/webui/chromeos/login/native_window_delegate.h"
     21 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
     22 #include "chrome/grit/chromium_strings.h"
     23 #include "chrome/grit/generated_resources.h"
     24 #include "chromeos/dbus/dbus_thread_manager.h"
     25 #include "chromeos/dbus/power_manager_client.h"
     26 #include "chromeos/dbus/session_manager_client.h"
     27 #include "chromeos/network/portal_detector/network_portal_detector.h"
     28 #include "chromeos/network/portal_detector/network_portal_detector_strategy.h"
     29 #include "components/user_manager/user_manager.h"
     30 #include "extensions/browser/extension_system.h"
     31 #include "grit/browser_resources.h"
     32 #include "ui/strings/grit/ui_strings.h"
     33 
     34 namespace {
     35 
     36 const char kJsScreenPath[] = "login.ErrorMessageScreen";
     37 
     38 }  // namespace
     39 
     40 namespace chromeos {
     41 
     42 ErrorScreenHandler::ErrorScreenHandler(
     43     const scoped_refptr<NetworkStateInformer>& network_state_informer)
     44     : BaseScreenHandler(kJsScreenPath),
     45       delegate_(NULL),
     46       network_state_informer_(network_state_informer),
     47       show_on_init_(false),
     48       weak_ptr_factory_(this) {
     49   DCHECK(network_state_informer_.get());
     50 }
     51 
     52 ErrorScreenHandler::~ErrorScreenHandler() {}
     53 
     54 void ErrorScreenHandler::SetDelegate(ErrorScreenActorDelegate* delegate) {
     55   delegate_ = delegate;
     56 }
     57 
     58 void ErrorScreenHandler::Show(OobeDisplay::Screen parent_screen,
     59                               base::DictionaryValue* params,
     60                               const base::Closure& on_hide) {
     61   if (!page_is_ready()) {
     62     show_on_init_ = true;
     63     return;
     64   }
     65   parent_screen_ = parent_screen;
     66   on_hide_.reset(new base::Closure(on_hide));
     67   ShowScreen(OobeUI::kScreenErrorMessage, params);
     68   NetworkErrorShown();
     69   NetworkPortalDetector::Get()->SetStrategy(
     70       PortalDetectorStrategy::STRATEGY_ID_ERROR_SCREEN);
     71   if (delegate_)
     72     delegate_->OnErrorShow();
     73   LOG(WARNING) << "Offline message is displayed";
     74 }
     75 
     76 void ErrorScreenHandler::CheckAndShowScreen() {
     77   std::string screen_name;
     78   if (GetScreenName(parent_screen(), &screen_name))
     79     ShowScreen(screen_name.c_str(), NULL);
     80 }
     81 
     82 void ErrorScreenHandler::Show(OobeDisplay::Screen parent_screen,
     83                               base::DictionaryValue* params) {
     84   Show(parent_screen,
     85        params,
     86        base::Bind(&ErrorScreenHandler::CheckAndShowScreen,
     87                   weak_ptr_factory_.GetWeakPtr()));
     88 }
     89 
     90 void ErrorScreenHandler::Hide() {
     91   if (parent_screen_ == OobeUI::SCREEN_UNKNOWN)
     92     return;
     93   if (on_hide_)
     94     on_hide_->Run();
     95   NetworkPortalDetector::Get()->SetStrategy(
     96       PortalDetectorStrategy::STRATEGY_ID_LOGIN_SCREEN);
     97   if (delegate_)
     98     delegate_->OnErrorHide();
     99   LOG(WARNING) << "Offline message is hidden";
    100 }
    101 
    102 void ErrorScreenHandler::FixCaptivePortal() {
    103   if (!captive_portal_window_proxy_.get()) {
    104     content::WebContents* web_contents =
    105         LoginDisplayHostImpl::default_host()->GetWebUILoginView()->
    106             GetWebContents();
    107     captive_portal_window_proxy_.reset(
    108         new CaptivePortalWindowProxy(network_state_informer_.get(),
    109                                      web_contents));
    110   }
    111   captive_portal_window_proxy_->ShowIfRedirected();
    112 }
    113 
    114 void ErrorScreenHandler::ShowCaptivePortal() {
    115   // This call is an explicit user action
    116   // i.e. clicking on link so force dialog show.
    117   FixCaptivePortal();
    118   captive_portal_window_proxy_->Show();
    119 }
    120 
    121 void ErrorScreenHandler::HideCaptivePortal() {
    122   if (captive_portal_window_proxy_.get())
    123     captive_portal_window_proxy_->Close();
    124 }
    125 
    126 void ErrorScreenHandler::SetUIState(ErrorScreen::UIState ui_state) {
    127   show_connecting_indicator_ = false;
    128   ui_state_ = ui_state;
    129   if (page_is_ready())
    130     CallJS("setUIState", static_cast<int>(ui_state_));
    131 }
    132 
    133 void ErrorScreenHandler::SetErrorState(ErrorScreen::ErrorState error_state,
    134                                        const std::string& network) {
    135   error_state_ = error_state;
    136   network_ = network;
    137   if (page_is_ready())
    138     CallJS("setErrorState", static_cast<int>(error_state_), network);
    139 }
    140 
    141 void ErrorScreenHandler::AllowGuestSignin(bool allowed) {
    142   guest_signin_allowed_ = allowed;
    143   if (page_is_ready())
    144     CallJS("allowGuestSignin", allowed);
    145 }
    146 
    147 void ErrorScreenHandler::AllowOfflineLogin(bool allowed) {
    148   offline_login_allowed_ = allowed;
    149   if (page_is_ready())
    150     CallJS("allowOfflineLogin", allowed);
    151 }
    152 
    153 void ErrorScreenHandler::ShowConnectingIndicator(bool show) {
    154   show_connecting_indicator_ = show;
    155   if (page_is_ready())
    156     CallJS("showConnectingIndicator", show);
    157 }
    158 
    159 void ErrorScreenHandler::NetworkErrorShown() {
    160   content::NotificationService::current()->Notify(
    161       chrome::NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN,
    162       content::NotificationService::AllSources(),
    163       content::NotificationService::NoDetails());
    164 }
    165 
    166 bool ErrorScreenHandler::GetScreenName(OobeUI::Screen screen,
    167                                        std::string* name) const {
    168   OobeUI* oobe_ui = static_cast<OobeUI*>(web_ui()->GetController());
    169   if (!oobe_ui)
    170     return false;
    171   *name = oobe_ui->GetScreenName(screen);
    172   return true;
    173 }
    174 
    175 void ErrorScreenHandler::HandleShowCaptivePortal() {
    176   ShowCaptivePortal();
    177 }
    178 
    179 void ErrorScreenHandler::HandleHideCaptivePortal() {
    180   HideCaptivePortal();
    181 }
    182 
    183 void ErrorScreenHandler::HandleLocalStateErrorPowerwashButtonClicked() {
    184   chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->
    185       StartDeviceWipe();
    186 }
    187 
    188 void ErrorScreenHandler::HandleRebootButtonClicked() {
    189   chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
    190 }
    191 
    192 void ErrorScreenHandler::HandleDiagnoseButtonClicked() {
    193   Profile* profile = ProfileManager::GetActiveUserProfile();
    194   ExtensionService* extension_service =
    195       extensions::ExtensionSystem::Get(profile)->extension_service();
    196 
    197   std::string extension_id =
    198       extension_service->component_loader()->Add(
    199           IDR_CONNECTIVITY_DIAGNOSTICS_MANIFEST,
    200           base::FilePath(extension_misc::kConnectivityDiagnosticsKioskPath));
    201 
    202   const extensions::Extension* extension = extension_service->
    203       GetExtensionById(extension_id, true);
    204   OpenApplication(AppLaunchParams(profile, extension,
    205                                   extensions::LAUNCH_CONTAINER_WINDOW,
    206                                   NEW_WINDOW));
    207   InitAppSession(profile, extension_id);
    208 
    209   user_manager::UserManager::Get()->SessionStarted();
    210 
    211   LoginDisplayHostImpl::default_host()->Finalize();
    212 }
    213 
    214 void ErrorScreenHandler::HandleConfigureCerts() {
    215   CertificateManagerDialog* dialog =
    216       new CertificateManagerDialog(ProfileManager::GetActiveUserProfile(),
    217                                    NULL,
    218                                    GetNativeWindow());
    219   dialog->Show();
    220 }
    221 
    222 void ErrorScreenHandler::HandleLaunchOobeGuestSession() {
    223   if (delegate_)
    224     delegate_->OnLaunchOobeGuestSession();
    225 }
    226 
    227 void ErrorScreenHandler::RegisterMessages() {
    228   AddCallback("showCaptivePortal",
    229               &ErrorScreenHandler::HandleShowCaptivePortal);
    230   AddCallback("hideCaptivePortal",
    231               &ErrorScreenHandler::HandleHideCaptivePortal);
    232   AddCallback("localStateErrorPowerwashButtonClicked",
    233               &ErrorScreenHandler::HandleLocalStateErrorPowerwashButtonClicked);
    234   AddCallback("rebootButtonClicked",
    235               &ErrorScreenHandler::HandleRebootButtonClicked);
    236   AddCallback("diagnoseButtonClicked",
    237               &ErrorScreenHandler::HandleDiagnoseButtonClicked);
    238   AddCallback("configureCertsClicked",
    239               &ErrorScreenHandler::HandleConfigureCerts);
    240   AddCallback("launchOobeGuestSession",
    241               &ErrorScreenHandler::HandleLaunchOobeGuestSession);
    242   AddCallback("rollbackOkButtonClicked",
    243               &ErrorScreenHandler::HandleRebootButtonClicked);
    244 }
    245 
    246 void ErrorScreenHandler::DeclareLocalizedValues(
    247     LocalizedValuesBuilder* builder) {
    248   builder->Add("loginErrorTitle", IDS_LOGIN_ERROR_TITLE);
    249   builder->Add("rollbackErrorTitle", IDS_RESET_SCREEN_REVERT_ERROR);
    250   builder->Add("signinOfflineMessageBody", IDS_LOGIN_OFFLINE_MESSAGE);
    251   builder->Add("kioskOfflineMessageBody", IDS_KIOSK_OFFLINE_MESSAGE);
    252   builder->Add("kioskOnlineTitle", IDS_LOGIN_NETWORK_RESTORED_TITLE);
    253   builder->Add("kioskOnlineMessageBody", IDS_KIOSK_ONLINE_MESSAGE);
    254   builder->Add("autoEnrollmentOfflineMessageBody",
    255                IDS_LOGIN_AUTO_ENROLLMENT_OFFLINE_MESSAGE);
    256   builder->AddF("rollbackErrorMessageBody",
    257                IDS_RESET_SCREEN_REVERT_ERROR_EXPLANATION,
    258                IDS_SHORT_PRODUCT_NAME);
    259   builder->Add("captivePortalTitle", IDS_LOGIN_MAYBE_CAPTIVE_PORTAL_TITLE);
    260   builder->Add("captivePortalMessage", IDS_LOGIN_MAYBE_CAPTIVE_PORTAL);
    261   builder->Add("captivePortalProxyMessage",
    262                IDS_LOGIN_MAYBE_CAPTIVE_PORTAL_PROXY);
    263   builder->Add("captivePortalNetworkSelect",
    264                IDS_LOGIN_MAYBE_CAPTIVE_PORTAL_NETWORK_SELECT);
    265   builder->Add("signinProxyMessageText", IDS_LOGIN_PROXY_ERROR_MESSAGE);
    266   builder->Add("updateOfflineMessageBody", IDS_UPDATE_OFFLINE_MESSAGE);
    267   builder->Add("updateProxyMessageText", IDS_UPDATE_PROXY_ERROR_MESSAGE);
    268   builder->AddF("localStateErrorText0", IDS_LOCAL_STATE_ERROR_TEXT_0,
    269                 IDS_SHORT_PRODUCT_NAME);
    270   builder->Add("localStateErrorText1", IDS_LOCAL_STATE_ERROR_TEXT_1);
    271   builder->Add("localStateErrorPowerwashButton",
    272                IDS_LOCAL_STATE_ERROR_POWERWASH_BUTTON);
    273   builder->Add("connectingIndicatorText", IDS_LOGIN_CONNECTING_INDICATOR_TEXT);
    274   builder->Add("guestSigninFixNetwork", IDS_LOGIN_GUEST_SIGNIN_FIX_NETWORK);
    275   builder->Add("rebootButton", IDS_RELAUNCH_BUTTON);
    276   builder->Add("diagnoseButton", IDS_DIAGNOSE_BUTTON);
    277   builder->Add("configureCertsButton", IDS_MANAGE_CERTIFICATES);
    278   builder->Add("continueButton", IDS_NETWORK_SELECTION_CONTINUE_BUTTON);
    279   builder->Add("okButton", IDS_APP_OK);
    280 }
    281 
    282 void ErrorScreenHandler::Initialize() {
    283   if (!page_is_ready())
    284     return;
    285   if (show_on_init_) {
    286     base::DictionaryValue params;
    287     params.SetInteger("uiState", static_cast<int>(ui_state_));
    288     params.SetInteger("errorState", static_cast<int>(error_state_));
    289     params.SetString("network", network_);
    290     params.SetBoolean("guestSigninAllowed", guest_signin_allowed_);
    291     params.SetBoolean("offlineLoginAllowed", offline_login_allowed_);
    292     params.SetBoolean("showConnectingIndicator", show_connecting_indicator_);
    293     Show(parent_screen_, &params);
    294     show_on_init_ = false;
    295   }
    296 }
    297 
    298 }  // namespace chromeos
    299