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.
6 * @fileoverview Offline message screen implementation.
9 login.createScreen('ErrorMessageScreen', 'error-message', function() {
10 var CONTEXT_KEY_ERROR_STATE_CODE = 'error-state-code';
11 var CONTEXT_KEY_ERROR_STATE_NETWORK = 'error-state-network';
12 var CONTEXT_KEY_GUEST_SIGNIN_ALLOWED = 'guest-signin-allowed';
13 var CONTEXT_KEY_OFFLINE_SIGNIN_ALLOWED = 'offline-signin-allowed';
14 var CONTEXT_KEY_SHOW_CONNECTING_INDICATOR = 'show-connecting-indicator';
15 var CONTEXT_KEY_UI_STATE = 'ui-state';
17 var USER_ACTION_CONFIGURE_CERTS = 'configure-certs';
18 var USER_ACTION_DIAGNOSE = 'diagnose';
19 var USER_ACTION_LAUNCH_OOBE_GUEST = 'launch-oobe-guest';
20 var USER_ACTION_LOCAL_STATE_POWERWASH = 'local-state-error-powerwash';
21 var USER_ACTION_REBOOT = 'reboot';
22 var USER_ACTION_SHOW_CAPTIVE_PORTAL = 'show-captive-portal';
24 // Link which starts guest session for captive portal fixing.
25 /** @const */ var FIX_CAPTIVE_PORTAL_ID = 'captive-portal-fix-link';
27 /** @const */ var FIX_PROXY_SETTINGS_ID = 'proxy-settings-fix-link';
29 // Class of the elements which hold current network name.
30 /** @const */ var CURRENT_NETWORK_NAME_CLASS =
31 'portal-network-name';
33 // Link which triggers frame reload.
34 /** @const */ var RELOAD_PAGE_ID = 'proxy-error-signin-retry-link';
36 // Array of the possible UI states of the screen. Must be in the
37 // same order as ErrorScreen::UIState enum values.
38 /** @const */ var UI_STATES = [
39 ERROR_SCREEN_UI_STATE.UNKNOWN,
40 ERROR_SCREEN_UI_STATE.UPDATE,
41 ERROR_SCREEN_UI_STATE.SIGNIN,
42 ERROR_SCREEN_UI_STATE.SUPERVISED_USER_CREATION_FLOW,
43 ERROR_SCREEN_UI_STATE.KIOSK_MODE,
44 ERROR_SCREEN_UI_STATE.LOCAL_STATE_ERROR,
45 ERROR_SCREEN_UI_STATE.AUTO_ENROLLMENT_ERROR,
46 ERROR_SCREEN_UI_STATE.ROLLBACK_ERROR,
49 // The help topic linked from the auto enrollment error message.
50 /** @const */ var HELP_TOPIC_AUTO_ENROLLMENT = 4632009;
52 // Possible error states of the screen.
53 /** @const */ var ERROR_STATE = {
54 UNKNOWN: 'error-state-unknown',
55 PORTAL: 'error-state-portal',
56 OFFLINE: 'error-state-offline',
57 PROXY: 'error-state-proxy',
58 AUTH_EXT_TIMEOUT: 'error-state-auth-ext-timeout',
59 KIOSK_ONLINE: 'error-state-kiosk-online'
62 // Possible error states of the screen. Must be in the same order as
63 // ErrorScreen::ErrorState enum values.
64 /** @const */ var ERROR_STATES = [
69 ERROR_STATE.AUTH_EXT_TIMEOUT,
71 ERROR_STATE.KIOSK_ONLINE,
76 'updateLocalizedContent',
83 'showConnectingIndicator'
86 // Error screen initial UI state.
87 ui_state_: ERROR_SCREEN_UI_STATE.UNKNOWN,
89 // Error screen initial error state.
90 error_state_: ERROR_STATE.UNKNOWN,
93 decorate: function() {
94 cr.ui.DropDown.decorate($('offline-networks-list'));
95 this.updateLocalizedContent();
98 this.context.addObserver(CONTEXT_KEY_ERROR_STATE_CODE,
99 function(error_state) {
100 self.setErrorState(error_state);
102 this.context.addObserver(CONTEXT_KEY_ERROR_STATE_NETWORK,
104 self.setNetwork_(network);
106 this.context.addObserver(CONTEXT_KEY_GUEST_SIGNIN_ALLOWED,
108 self.allowGuestSignin(allowed);
110 this.context.addObserver(CONTEXT_KEY_OFFLINE_SIGNIN_ALLOWED,
112 self.allowOfflineLogin(allowed);
114 this.context.addObserver(CONTEXT_KEY_SHOW_CONNECTING_INDICATOR,
116 self.showConnectingIndicator(show);
118 this.context.addObserver(CONTEXT_KEY_UI_STATE, function(ui_state) {
119 self.setUIState(ui_state);
121 $('error-close-button').addEventListener('click', this.cancel.bind(this));
125 * Updates localized content of the screen that is not updated via template.
127 updateLocalizedContent: function() {
129 $('auto-enrollment-offline-message-text').innerHTML =
130 loadTimeData.getStringF(
131 'autoEnrollmentOfflineMessageBody',
132 loadTimeData.getString('deviceType'),
133 '<b class="' + CURRENT_NETWORK_NAME_CLASS + '"></b>',
134 '<a id="auto-enrollment-learn-more" class="signin-link" ' +
137 $('auto-enrollment-learn-more').onclick = function() {
138 chrome.send('launchHelpApp', [HELP_TOPIC_AUTO_ENROLLMENT]);
141 $('captive-portal-message-text').innerHTML = loadTimeData.getStringF(
142 'captivePortalMessage',
143 '<b class="' + CURRENT_NETWORK_NAME_CLASS + '"></b>',
144 '<a id="' + FIX_CAPTIVE_PORTAL_ID + '" class="signin-link" href="#">',
146 $(FIX_CAPTIVE_PORTAL_ID).onclick = function() {
147 self.send(login.Screen.CALLBACK_USER_ACTED,
148 USER_ACTION_SHOW_CAPTIVE_PORTAL);
151 $('captive-portal-proxy-message-text').innerHTML =
152 loadTimeData.getStringF(
153 'captivePortalProxyMessage',
154 '<a id="' + FIX_PROXY_SETTINGS_ID + '" class="signin-link" href="#">',
156 $(FIX_PROXY_SETTINGS_ID).onclick = function() {
157 chrome.send('openProxySettings');
159 $('update-proxy-message-text').innerHTML = loadTimeData.getStringF(
160 'updateProxyMessageText',
161 '<a id="update-proxy-error-fix-proxy" class="signin-link" href="#">',
163 $('update-proxy-error-fix-proxy').onclick = function() {
164 chrome.send('openProxySettings');
166 $('signin-proxy-message-text').innerHTML = loadTimeData.getStringF(
167 'signinProxyMessageText',
168 '<a id="' + RELOAD_PAGE_ID + '" class="signin-link" href="#">',
170 '<a id="signin-proxy-error-fix-proxy" class="signin-link" href="#">',
172 $(RELOAD_PAGE_ID).onclick = function() {
173 var gaiaScreen = $(SCREEN_GAIA_SIGNIN);
174 // Schedules an immediate retry.
175 gaiaScreen.doReload();
177 $('signin-proxy-error-fix-proxy').onclick = function() {
178 chrome.send('openProxySettings');
181 $('error-guest-signin').innerHTML = loadTimeData.getStringF(
183 '<a id="error-guest-signin-link" class="signin-link" href="#">',
185 $('error-guest-signin-link').addEventListener(
187 this.launchGuestSession_.bind(this));
189 $('error-guest-signin-fix-network').innerHTML = loadTimeData.getStringF(
190 'guestSigninFixNetwork',
191 '<a id="error-guest-fix-network-signin-link" class="signin-link" ' +
194 $('error-guest-fix-network-signin-link').addEventListener(
196 this.launchGuestSession_.bind(this));
198 $('error-offline-login').innerHTML = loadTimeData.getStringF(
200 '<a id="error-offline-login-link" class="signin-link" href="#">',
202 $('error-offline-login-link').onclick = function() {
203 chrome.send('offlineLogin');
207 for (var i = 1; i <= 3; ++i) {
209 '<span id="connecting-indicator-ellipsis-' + i + '"></span>';
211 $('connecting-indicator').innerHTML =
212 loadTimeData.getStringF('connectingIndicatorText', ellipsis);
214 this.onContentChange_();
218 * Event handler that is invoked just before the screen in shown.
219 * @param {Object} data Screen init payload.
221 onBeforeShow: function(data) {
222 cr.ui.Oobe.clearErrors();
223 cr.ui.DropDown.show('offline-networks-list', false);
224 $('login-header-bar').signinUIState = SIGNIN_UI_STATE.ERROR;
225 $('error-close-button').hidden =
226 !(Oobe.isNewGaiaFlow() && $('login-header-bar').allowCancel);
230 * Event handler that is invoked just before the screen is hidden.
232 onBeforeHide: function() {
233 cr.ui.DropDown.hide('offline-networks-list');
234 $('login-header-bar').signinUIState = SIGNIN_UI_STATE.HIDDEN;
238 * Buttons in oobe wizard's button strip.
239 * @type {array} Array of Buttons.
245 var rebootButton = this.ownerDocument.createElement('button');
246 rebootButton.textContent = loadTimeData.getString('rebootButton');
247 rebootButton.classList.add('show-with-ui-state-kiosk-mode');
248 rebootButton.addEventListener('click', function(e) {
249 self.send(login.Screen.CALLBACK_USER_ACTED, USER_ACTION_REBOOT);
252 buttons.push(rebootButton);
254 var diagnoseButton = this.ownerDocument.createElement('button');
255 diagnoseButton.textContent = loadTimeData.getString('diagnoseButton');
256 diagnoseButton.classList.add('show-with-ui-state-kiosk-mode');
257 diagnoseButton.addEventListener('click', function(e) {
258 self.send(login.Screen.CALLBACK_USER_ACTED, USER_ACTION_DIAGNOSE);
261 buttons.push(diagnoseButton);
263 var certsButton = this.ownerDocument.createElement('button');
264 certsButton.textContent = loadTimeData.getString('configureCertsButton');
265 certsButton.classList.add('show-with-ui-state-kiosk-mode');
266 certsButton.addEventListener('click', function(e) {
267 self.send(login.Screen.CALLBACK_USER_ACTED,
268 USER_ACTION_CONFIGURE_CERTS);
271 buttons.push(certsButton);
273 var continueButton = this.ownerDocument.createElement('button');
274 continueButton.id = 'continue-network-config-btn';
275 continueButton.textContent = loadTimeData.getString('continueButton');
276 continueButton.classList.add('show-with-error-state-kiosk-online');
277 continueButton.addEventListener('click', function(e) {
278 chrome.send('continueAppLaunch');
281 buttons.push(continueButton);
283 var okButton = this.ownerDocument.createElement('button');
284 okButton.id = 'ok-error-screen-btn';
285 okButton.textContent = loadTimeData.getString('okButton');
286 okButton.classList.add('show-with-ui-state-rollback-error');
287 okButton.addEventListener('click', function(e) {
288 chrome.send('cancelOnReset');
291 buttons.push(okButton);
293 var spacer = this.ownerDocument.createElement('div');
294 spacer.classList.add('button-spacer');
295 spacer.classList.add('show-with-ui-state-kiosk-mode');
296 buttons.push(spacer);
298 var powerwashButton = this.ownerDocument.createElement('button');
299 powerwashButton.id = 'error-message-restart-and-powerwash-button';
300 powerwashButton.textContent =
301 loadTimeData.getString('localStateErrorPowerwashButton');
302 powerwashButton.classList.add('show-with-ui-state-local-state-error');
303 powerwashButton.addEventListener('click', function(e) {
304 self.send(login.Screen.CALLBACK_USER_ACTED,
305 USER_ACTION_LOCAL_STATE_POWERWASH);
308 buttons.push(powerwashButton);
314 * Sets current UI state of the screen.
315 * @param {string} ui_state New UI state of the screen.
318 setUIState_: function(ui_state) {
319 this.classList.remove(this.ui_state);
320 this.ui_state = ui_state;
321 this.classList.add(this.ui_state);
323 if (ui_state == ERROR_SCREEN_UI_STATE.LOCAL_STATE_ERROR) {
324 // Hide header bar and progress dots, because there are no way
325 // from the error screen about broken local state.
326 Oobe.getInstance().headerHidden = true;
327 $('progress-dots').hidden = true;
329 this.onContentChange_();
333 * Sets current error state of the screen.
334 * @param {string} error_state New error state of the screen.
337 setErrorState_: function(error_state) {
338 this.classList.remove(this.error_state);
339 this.error_state = error_state;
340 this.classList.add(this.error_state);
341 this.onContentChange_();
346 * @param {string} network Name of the current network
349 setNetwork_: function(network) {
350 var networkNameElems =
351 document.getElementsByClassName(CURRENT_NETWORK_NAME_CLASS);
352 for (var i = 0; i < networkNameElems.length; ++i)
353 networkNameElems[i].textContent = network;
354 this.onContentChange_();
357 /* Method called after content of the screen changed.
360 onContentChange_: function() {
361 if (Oobe.getInstance().currentScreen === this)
362 Oobe.getInstance().updateScreenSize(this);
366 * Event handler for guest session launch.
369 launchGuestSession_: function() {
370 if (Oobe.getInstance().isOobeUI()) {
371 this.send(login.Screen.CALLBACK_USER_ACTED,
372 USER_ACTION_LAUNCH_OOBE_GUEST);
374 chrome.send('launchIncognito');
379 * Prepares error screen to show guest signin link.
382 allowGuestSignin: function(allowed) {
383 this.classList.toggle('allow-guest-signin', allowed);
384 this.onContentChange_();
388 * Prepares error screen to show offline login link.
391 allowOfflineLogin: function(allowed) {
392 this.classList.toggle('allow-offline-login', allowed);
393 this.onContentChange_();
397 * Sets current UI state of the screen.
398 * @param {number} ui_state New UI state of the screen.
401 setUIState: function(ui_state) {
402 this.setUIState_(UI_STATES[ui_state]);
406 * Sets current error state of the screen.
407 * @param {number} error_state New error state of the screen.
410 setErrorState: function(error_state) {
411 this.setErrorState_(ERROR_STATES[error_state]);
415 * Updates visibility of the label indicating we're reconnecting.
416 * @param {boolean} show Whether the label should be shown.
418 showConnectingIndicator: function(show) {
419 this.classList.toggle('show-connecting-indicator', show);
420 this.onContentChange_();
424 * Cancels error screen and drops to user pods.
427 if ($('login-header-bar').allowCancel)