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_, ¶ms); 294 show_on_init_ = false; 295 } 296 } 297 298 } // namespace chromeos 299