Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / login / screen_error_message.js
blob5efe9d6b35732009bbee130a127e6ea1b3de9ee8
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.
5 /**
6  * @fileoverview Offline message screen implementation.
7  */
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,
47   ];
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'
60   };
62   // Possible error states of the screen. Must be in the same order as
63   // ErrorScreen::ErrorState enum values.
64   /** @const */ var ERROR_STATES = [
65     ERROR_STATE.UNKNOWN,
66     ERROR_STATE.PORTAL,
67     ERROR_STATE.OFFLINE,
68     ERROR_STATE.PROXY,
69     ERROR_STATE.AUTH_EXT_TIMEOUT,
70     ERROR_STATE.NONE,
71     ERROR_STATE.KIOSK_ONLINE,
72   ];
74   return {
75     EXTERNAL_API: [
76       'updateLocalizedContent',
77       'onBeforeShow',
78       'onBeforeHide',
79       'allowGuestSignin',
80       'allowOfflineLogin',
81       'setUIState',
82       'setErrorState',
83       'showConnectingIndicator'
84     ],
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,
92     /** @override */
93     decorate: function() {
94       cr.ui.DropDown.decorate($('offline-networks-list'));
95       this.updateLocalizedContent();
97       var self = this;
98       this.context.addObserver(CONTEXT_KEY_ERROR_STATE_CODE,
99                                function(error_state) {
100         self.setErrorState(error_state);
101       });
102       this.context.addObserver(CONTEXT_KEY_ERROR_STATE_NETWORK,
103                                function(network) {
104         self.setNetwork_(network);
105       });
106       this.context.addObserver(CONTEXT_KEY_GUEST_SIGNIN_ALLOWED,
107                                function(allowed) {
108         self.allowGuestSignin(allowed);
109       });
110       this.context.addObserver(CONTEXT_KEY_OFFLINE_SIGNIN_ALLOWED,
111                                function(allowed) {
112         self.allowOfflineLogin(allowed);
113       });
114       this.context.addObserver(CONTEXT_KEY_SHOW_CONNECTING_INDICATOR,
115                                function(show) {
116         self.showConnectingIndicator(show);
117       });
118       this.context.addObserver(CONTEXT_KEY_UI_STATE, function(ui_state) {
119         self.setUIState(ui_state);
120       });
121       $('error-close-button').addEventListener('click', this.cancel.bind(this));
122     },
124     /**
125      * Updates localized content of the screen that is not updated via template.
126      */
127     updateLocalizedContent: function() {
128       var self = this;
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" ' +
135                   '"href="#">',
136               '</a>');
137       $('auto-enrollment-learn-more').onclick = function() {
138         chrome.send('launchHelpApp', [HELP_TOPIC_AUTO_ENROLLMENT]);
139       };
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="#">',
145         '</a>');
146       $(FIX_CAPTIVE_PORTAL_ID).onclick = function() {
147         self.send(login.Screen.CALLBACK_USER_ACTED,
148                   USER_ACTION_SHOW_CAPTIVE_PORTAL);
149       };
151       $('captive-portal-proxy-message-text').innerHTML =
152         loadTimeData.getStringF(
153           'captivePortalProxyMessage',
154           '<a id="' + FIX_PROXY_SETTINGS_ID + '" class="signin-link" href="#">',
155           '</a>');
156       $(FIX_PROXY_SETTINGS_ID).onclick = function() {
157         chrome.send('openProxySettings');
158       };
159       $('update-proxy-message-text').innerHTML = loadTimeData.getStringF(
160           'updateProxyMessageText',
161           '<a id="update-proxy-error-fix-proxy" class="signin-link" href="#">',
162           '</a>');
163       $('update-proxy-error-fix-proxy').onclick = function() {
164         chrome.send('openProxySettings');
165       };
166       $('signin-proxy-message-text').innerHTML = loadTimeData.getStringF(
167           'signinProxyMessageText',
168           '<a id="' + RELOAD_PAGE_ID + '" class="signin-link" href="#">',
169           '</a>',
170           '<a id="signin-proxy-error-fix-proxy" class="signin-link" href="#">',
171           '</a>');
172       $(RELOAD_PAGE_ID).onclick = function() {
173         var gaiaScreen = $(SCREEN_GAIA_SIGNIN);
174         // Schedules an immediate retry.
175         gaiaScreen.doReload();
176       };
177       $('signin-proxy-error-fix-proxy').onclick = function() {
178         chrome.send('openProxySettings');
179       };
181       $('error-guest-signin').innerHTML = loadTimeData.getStringF(
182           'guestSignin',
183           '<a id="error-guest-signin-link" class="signin-link" href="#">',
184           '</a>');
185       $('error-guest-signin-link').addEventListener(
186           'click',
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" ' +
192               'href="#">',
193           '</a>');
194       $('error-guest-fix-network-signin-link').addEventListener(
195           'click',
196           this.launchGuestSession_.bind(this));
198       $('error-offline-login').innerHTML = loadTimeData.getStringF(
199           'offlineLogin',
200           '<a id="error-offline-login-link" class="signin-link" href="#">',
201           '</a>');
202       $('error-offline-login-link').onclick = function() {
203         chrome.send('offlineLogin');
204       };
206       var ellipsis = '';
207       for (var i = 1; i <= 3; ++i) {
208         ellipsis +=
209             '<span id="connecting-indicator-ellipsis-' + i + '"></span>';
210       }
211       $('connecting-indicator').innerHTML =
212           loadTimeData.getStringF('connectingIndicatorText', ellipsis);
214       this.onContentChange_();
215     },
217     /**
218      * Event handler that is invoked just before the screen in shown.
219      * @param {Object} data Screen init payload.
220      */
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);
227     },
229     /**
230      * Event handler that is invoked just before the screen is hidden.
231      */
232     onBeforeHide: function() {
233       cr.ui.DropDown.hide('offline-networks-list');
234       $('login-header-bar').signinUIState = SIGNIN_UI_STATE.HIDDEN;
235     },
237     /**
238      * Buttons in oobe wizard's button strip.
239      * @type {array} Array of Buttons.
240      */
241     get buttons() {
242       var buttons = [];
243       var self = this;
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);
250         e.stopPropagation();
251       });
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);
259         e.stopPropagation();
260       });
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);
269         e.stopPropagation();
270       });
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');
279         e.stopPropagation();
280       });
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');
289         e.stopPropagation();
290       });
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);
306         e.stopPropagation();
307       });
308       buttons.push(powerwashButton);
310       return buttons;
311     },
313     /**
314       * Sets current UI state of the screen.
315       * @param {string} ui_state New UI state of the screen.
316       * @private
317       */
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;
328       }
329       this.onContentChange_();
330     },
332     /**
333       * Sets current error state of the screen.
334       * @param {string} error_state New error state of the screen.
335       * @private
336       */
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_();
342     },
344     /**
345      * Sets network.
346      * @param {string} network Name of the current network
347      * @private
348      */
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_();
355     },
357     /* Method called after content of the screen changed.
358      * @private
359      */
360     onContentChange_: function() {
361       if (Oobe.getInstance().currentScreen === this)
362         Oobe.getInstance().updateScreenSize(this);
363     },
365     /**
366      * Event handler for guest session launch.
367      * @private
368      */
369     launchGuestSession_: function() {
370       if (Oobe.getInstance().isOobeUI()) {
371         this.send(login.Screen.CALLBACK_USER_ACTED,
372                   USER_ACTION_LAUNCH_OOBE_GUEST);
373       } else {
374         chrome.send('launchIncognito');
375       }
376     },
378     /**
379      * Prepares error screen to show guest signin link.
380      * @private
381      */
382     allowGuestSignin: function(allowed) {
383       this.classList.toggle('allow-guest-signin', allowed);
384       this.onContentChange_();
385     },
387     /**
388      * Prepares error screen to show offline login link.
389      * @private
390      */
391     allowOfflineLogin: function(allowed) {
392       this.classList.toggle('allow-offline-login', allowed);
393       this.onContentChange_();
394     },
396     /**
397       * Sets current UI state of the screen.
398       * @param {number} ui_state New UI state of the screen.
399       * @private
400       */
401     setUIState: function(ui_state) {
402       this.setUIState_(UI_STATES[ui_state]);
403     },
405     /**
406       * Sets current error state of the screen.
407       * @param {number} error_state New error state of the screen.
408       * @private
409       */
410     setErrorState: function(error_state) {
411       this.setErrorState_(ERROR_STATES[error_state]);
412     },
414     /**
415      * Updates visibility of the label indicating we're reconnecting.
416      * @param {boolean} show Whether the label should be shown.
417      */
418     showConnectingIndicator: function(show) {
419       this.classList.toggle('show-connecting-indicator', show);
420       this.onContentChange_();
421     },
423     /**
424      * Cancels error screen and drops to user pods.
425      */
426     cancel: function() {
427       if ($('login-header-bar').allowCancel)
428         Oobe.showUserPods();
429     }
430   };