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