screen_error_message.js revision 5821806d5e7f356e8fa4b058a389a808ea183019
14e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// Copyright (c) 2012 The Chromium Authors. All rights reserved.
24e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// Use of this source code is governed by a BSD-style license that can be
34e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// found in the LICENSE file.
44e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
54e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis/**
64e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis * @fileoverview Offline message screen implementation.
74e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis */
84e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
94e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidiscr.define('login', function() {
104e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Screens that should have offline message overlay.
114e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /** @const */ var MANAGED_SCREENS = [SCREEN_GAIA_SIGNIN];
124e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
134e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Network state constants.
144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  var NET_STATE = {
154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    OFFLINE: 0,
164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    ONLINE: 1,
174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    PORTAL: 2,
18361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko    CONNECTING: 3
194e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  };
204e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
214e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Error reasons which are passed to updateState_() method.
224e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /** @const */ var ERROR_REASONS = {
234e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    PROXY_AUTH_CANCELLED: 'frame error:111',
244e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    PROXY_CONNECTION_FAILED: 'frame error:130',
251bc085aec3901e22b819bb6761d5ccc360194604Argyrios Kyrtzidis    PROXY_CONFIG_CHANGED: 'proxy changed',
261bc085aec3901e22b819bb6761d5ccc360194604Argyrios Kyrtzidis    LOADING_TIMEOUT: 'loading timeout',
271bc085aec3901e22b819bb6761d5ccc360194604Argyrios Kyrtzidis    PORTAL_DETECTED: 'portal detected',
281bc085aec3901e22b819bb6761d5ccc360194604Argyrios Kyrtzidis    NETWORK_CHANGED: 'network changed'
291bc085aec3901e22b819bb6761d5ccc360194604Argyrios Kyrtzidis  };
301bc085aec3901e22b819bb6761d5ccc360194604Argyrios Kyrtzidis
311bc085aec3901e22b819bb6761d5ccc360194604Argyrios Kyrtzidis  // Frame loading errors.
321bc085aec3901e22b819bb6761d5ccc360194604Argyrios Kyrtzidis  var NET_ERROR = {
331bc085aec3901e22b819bb6761d5ccc360194604Argyrios Kyrtzidis    ABORTED_BY_USER: 3
34ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  };
35ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
36e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  // Link which starts guest session for captive portal fixing.
37db4d7a5f47d13bf346260ac35eaafd2c92e5606eArgyrios Kyrtzidis  /** @const */ var FIX_CAPTIVE_PORTAL_ID = 'captive-portal-fix-link';
3858d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis
39db4d7a5f47d13bf346260ac35eaafd2c92e5606eArgyrios Kyrtzidis  /** @const */ var FIX_PROXY_SETTINGS_ID = 'proxy-settings-fix-link';
40db4d7a5f47d13bf346260ac35eaafd2c92e5606eArgyrios Kyrtzidis
41db4d7a5f47d13bf346260ac35eaafd2c92e5606eArgyrios Kyrtzidis  // Id of the element which holds current network name.
42361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko  /** @const */ var CURRENT_NETWORK_NAME_ID = 'captive-portal-network-name';
43db4d7a5f47d13bf346260ac35eaafd2c92e5606eArgyrios Kyrtzidis
44361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko  // Link which triggers frame reload.
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /** @const */ var RELOAD_PAGE_ID = 'proxy-error-retry-link';
46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
47db4d7a5f47d13bf346260ac35eaafd2c92e5606eArgyrios Kyrtzidis  // Timeout used to delay first offline notification from network
48db4d7a5f47d13bf346260ac35eaafd2c92e5606eArgyrios Kyrtzidis  // manager.
49db4d7a5f47d13bf346260ac35eaafd2c92e5606eArgyrios Kyrtzidis  /** @const */ var OFFLINE_TIMEOUT_SEC = 5;
50e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
51e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  // Timeout used to prevent infinite connecting to a flaky network.
52361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko  /** @const */ var CONNECTING_TIMEOUT_SEC = 60;
53d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis
54d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis  /**
55d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis   * Creates a new offline message screen div.
56d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis   * @constructor
57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @extends {HTMLDivElement}
58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   */
59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  var ErrorMessageScreen = cr.ui.define('div');
60d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis
61d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis  /**
62d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis   * Registers with Oobe.
63d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis   */
64d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis  ErrorMessageScreen.register = function() {
65d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis    var screen = $('error-message');
66d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis    ErrorMessageScreen.decorate(screen);
67d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis
68d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis    // Note that ErrorMessageScreen is not registered with Oobe because
69361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko    // it is shown on top of sign-in screen instead of as an independent screen.
704e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  };
71e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
728818d4570b916762513e2b5ec4ca7178b1e736a9Argyrios Kyrtzidis  ErrorMessageScreen.prototype = {
73361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko    __proto__: HTMLDivElement.prototype,
748818d4570b916762513e2b5ec4ca7178b1e736a9Argyrios Kyrtzidis
75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /** @inheritDoc */
768818d4570b916762513e2b5ec4ca7178b1e736a9Argyrios Kyrtzidis    decorate: function() {
778818d4570b916762513e2b5ec4ca7178b1e736a9Argyrios Kyrtzidis      cr.ui.DropDown.decorate($('offline-networks-list'));
788818d4570b916762513e2b5ec4ca7178b1e736a9Argyrios Kyrtzidis      this.updateLocalizedContent_();
798818d4570b916762513e2b5ec4ca7178b1e736a9Argyrios Kyrtzidis    },
808818d4570b916762513e2b5ec4ca7178b1e736a9Argyrios Kyrtzidis
818818d4570b916762513e2b5ec4ca7178b1e736a9Argyrios Kyrtzidis    /**
828818d4570b916762513e2b5ec4ca7178b1e736a9Argyrios Kyrtzidis     * Timer used to delay calls to updateState_ method.
838818d4570b916762513e2b5ec4ca7178b1e736a9Argyrios Kyrtzidis     */
848818d4570b916762513e2b5ec4ca7178b1e736a9Argyrios Kyrtzidis    updateStateTimer_: undefined,
854e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
864e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    /**
874e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis     * True if updateState_ method was not called.
88e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis     */
894e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    firstUpdateStateCall_: true,
904e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
914e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    /*
924e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis     * Timer which is started when network moves to the connecting
934e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis     * state. If it's triggered, then it's look like the network is
94361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko     * flaky and we must show offline message.
954e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis     */
96e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    connectingTimer_: undefined,
97e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
984e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    /**
994e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis     * Updates localized content of the screen that is not updated via template.
1004e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis     */
101361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko    updateLocalizedContent_: function() {
1024e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      $('captive-portal-message-text').innerHTML = localStrings.getStringF(
103e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis        'captivePortalMessage',
104e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis        '<b id="' + CURRENT_NETWORK_NAME_ID + '"></b>',
105e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis        '<a id="' + FIX_CAPTIVE_PORTAL_ID + '" class="signin-link" href="#">',
106e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis        '</a>');
107e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis      $(FIX_CAPTIVE_PORTAL_ID).onclick = function() {
1084e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        chrome.send('showCaptivePortal');
1094e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      };
110361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko
11176da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall      $('captive-portal-proxy-message-text').innerHTML =
11276da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall        localStrings.getStringF(
11376da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall          'captivePortalProxyMessage',
11476da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall          '<a id="' + FIX_PROXY_SETTINGS_ID + '" class="signin-link" href="#">',
11576da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall          '</a>');
116361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko      $(FIX_PROXY_SETTINGS_ID).onclick = function() {
1174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        chrome.send('openProxySettings');
118e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis      };
1194e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
1204e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      $('proxy-message-text').innerHTML = localStrings.getStringF(
1214e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis          'proxyMessageText',
122361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko          '<a id="' + RELOAD_PAGE_ID + '" class="signin-link" href="#">',
1232957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis          '</a>');
1244e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      $(RELOAD_PAGE_ID).onclick = function() {
1254e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        var currentScreen = Oobe.getInstance().currentScreen;
1264e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        // Schedules a immediate retry.
1274e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        currentScreen.doReload();
128361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko      };
1294e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
1304e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      $('error-guest-signin').innerHTML = localStrings.getStringF(
1314e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis          'guestSignin',
1324e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis          '<a id="error-guest-signin-link" class="signin-link" href="#">',
1334e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis          '</a>');
1344e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      $('error-guest-signin-link').onclick = function() {
135361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko        chrome.send('launchIncognito');
136dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis      };
1374e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
138375bb1413c041055262c8a416f20d10474a5eda9Douglas Gregor      $('error-offline-login').innerHTML = localStrings.getStringF(
139375bb1413c041055262c8a416f20d10474a5eda9Douglas Gregor          'offlineLogin',
140375bb1413c041055262c8a416f20d10474a5eda9Douglas Gregor          '<a id="error-offline-login-link" class="signin-link" href="#">',
141375bb1413c041055262c8a416f20d10474a5eda9Douglas Gregor          '</a>');
1424e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      $('error-offline-login-link').onclick = function() {
1434e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        chrome.send('offlineLogin');
1444e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      };
145361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko    },
146dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
1474e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    onBeforeShow: function(lastNetworkType) {
148bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor      var currentScreen = Oobe.getInstance().currentScreen;
149bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor
150bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor      cr.ui.DropDown.show('offline-networks-list', false, lastNetworkType);
151bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor
1524e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      $('error-guest-signin').hidden = $('guestSignin').hidden ||
1534e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis          !$('add-user-header-bar-item').hidden;
1544e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
155361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko      $('error-offline-login').hidden = !currentScreen.isOfflineAllowed;
156e7bbab91f5cc899104d0a1dee6059d8413c70eebArgyrios Kyrtzidis    },
15737f40572c4c78a8c57a7b45266f8b86db172a7c1Argyrios Kyrtzidis
15837f40572c4c78a8c57a7b45266f8b86db172a7c1Argyrios Kyrtzidis    onBeforeHide: function() {
15937f40572c4c78a8c57a7b45266f8b86db172a7c1Argyrios Kyrtzidis      cr.ui.DropDown.hide('offline-networks-list');
160e7bbab91f5cc899104d0a1dee6059d8413c70eebArgyrios Kyrtzidis    },
161e7bbab91f5cc899104d0a1dee6059d8413c70eebArgyrios Kyrtzidis
162e7bbab91f5cc899104d0a1dee6059d8413c70eebArgyrios Kyrtzidis    update: function() {
163dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis      chrome.send('loginRequestNetworkState',
1644e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                  ['login.ErrorMessageScreen.updateState',
1654e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                   'update']);
166390fff8e8b480fa146ffc14cbc63a1c2f9e2d206Argyrios Kyrtzidis    },
167390fff8e8b480fa146ffc14cbc63a1c2f9e2d206Argyrios Kyrtzidis
168390fff8e8b480fa146ffc14cbc63a1c2f9e2d206Argyrios Kyrtzidis    /**
169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines     * Clears |updateStateTimer_|.
170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines     * @private
171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines     */
172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    clearUpdateStateTimer_: function() {
173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (this.updateStateTimer_) {
174390fff8e8b480fa146ffc14cbc63a1c2f9e2d206Argyrios Kyrtzidis        window.clearTimeout(this.updateStateTimer_);
175390fff8e8b480fa146ffc14cbc63a1c2f9e2d206Argyrios Kyrtzidis        this.updateStateTimer_ = undefined;
1764e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      }
1774e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    },
1784e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
179361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko    /**
180dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis     * Clears |connectingTimer_|.
1814e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis     * @private
1824e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis     */
1834e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    clearConnectingTimer_: function() {
1844e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      if (this.connectingTimer_) {
1854e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        window.clearTimeout(this.connectingTimer_);
1864e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        this.connectingTimer_ = undefined;
187361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko      }
18837f40572c4c78a8c57a7b45266f8b86db172a7c1Argyrios Kyrtzidis    },
18937f40572c4c78a8c57a7b45266f8b86db172a7c1Argyrios Kyrtzidis
190dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis    /**
191dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis     * Prepares error screen to show proxy error.
192dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis     */
193dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis    showProxyError: function() {
1944e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      this.classList.remove('show-offline-message');
1954e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      this.classList.remove('show-captive-portal');
1964e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      this.classList.add('show-proxy-error');
1974e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    },
1984e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
199361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko    /**
200d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis     * Prepares error screen to show captive portal error.
201d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis     * @param {string} network Name of the current network
2021e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose     */
203d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis    showCaptivePortalError: function(network) {
2044e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      $(CURRENT_NETWORK_NAME_ID).textContent = network;
205d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis      this.classList.remove('show-offline-message');
2064e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      this.classList.remove('show-proxy-error');
2074e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      this.classList.add('show-captive-portal');
2084e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    },
209361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko
210d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis    /**
211d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis     * Prepares error screen to show offline error.
212d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis     */
213d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis    showOfflineError: function() {
214d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis      this.classList.remove('show-captive-portal');
215d7c15a64ba8ebdca0dd48dd1d2f233107d34494eArgyrios Kyrtzidis      this.classList.remove('show-proxy-error');
2164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      this.classList.add('show-offline-message');
2174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    },
2184e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
219b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis    /**
220b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis     * Shows screen.
221361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko     * @param {object} screen Screen that should be shown.
222b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis     */
223b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis    showScreen: function(screen) {
224b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis      screen.classList.remove('hidden');
225b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis      screen.classList.remove('faded');
226b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis
227b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis      if (Oobe.getInstance().isNewOobe())
228b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis        Oobe.getInstance().updateScreenSize(screen);
229b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis    },
230b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis
231ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    /**
232b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis     * Shows or hides offline message based on network on/offline state.
233b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis     * @param {number} state Current state of the network (see NET_STATE).
234b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis     * @param {string} network Name of the current network.
235b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis     * @param {string} reason Reason the callback was called.
2361bc085aec3901e22b819bb6761d5ccc360194604Argyrios Kyrtzidis     * @param {number} lastNetworkType Last active network type.
2371bc085aec3901e22b819bb6761d5ccc360194604Argyrios Kyrtzidis     * @param {boolean} opt_forceUpdate Are state should be updated in any case?
238f911242f43ae1b0a85c323631fe817df95c9cbe9Argyrios Kyrtzidis     */
239f911242f43ae1b0a85c323631fe817df95c9cbe9Argyrios Kyrtzidis    updateState_: function(state, network, reason, lastNetworkType,
240b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis                           opt_forceUpdate) {
241b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis      console.log('updateState_: state=' + state +
2421bc085aec3901e22b819bb6761d5ccc360194604Argyrios Kyrtzidis                  ', network=' + network + ', reason=' + reason +
2431bc085aec3901e22b819bb6761d5ccc360194604Argyrios Kyrtzidis                  ', lastNetworkType=' + lastNetworkType +
244f911242f43ae1b0a85c323631fe817df95c9cbe9Argyrios Kyrtzidis                  ', opt_forceUpdate=' + opt_forceUpdate);
245f911242f43ae1b0a85c323631fe817df95c9cbe9Argyrios Kyrtzidis
246b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis      this.clearUpdateStateTimer_();
2472957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
2482957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis      // Delay first notification about offline state.
2492957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis      if (state == NET_STATE.OFFLINE && this.firstUpdateStateCall_) {
250361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko        this.firstUpdateStateCall_ = false;
25168478b0cc1ff03c0d13ceca6800c5becf08791e7Argyrios Kyrtzidis        this.updateStateTimer_ = window.setTimeout(
25268478b0cc1ff03c0d13ceca6800c5becf08791e7Argyrios Kyrtzidis            this.updateState_.bind(
25368478b0cc1ff03c0d13ceca6800c5becf08791e7Argyrios Kyrtzidis                this, state, network, reason, lastNetworkType, opt_forceUpdate),
25468478b0cc1ff03c0d13ceca6800c5becf08791e7Argyrios Kyrtzidis            OFFLINE_TIMEOUT_SEC * 1000);
25568478b0cc1ff03c0d13ceca6800c5becf08791e7Argyrios Kyrtzidis        return;
256361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko      }
257911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis      this.firstUpdateStateCall_ = false;
258911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis
259911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis      // Don't show or hide error screen if we're in connecting state.
260911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis      if (state == NET_STATE.CONNECTING && !opt_forceUpdate) {
261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (!this.connectingTimer_) {
262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          // First notification about CONNECTING state.
263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          this.clearConnectingTimer_();
264911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis          this.connectingTimer_ = window.setTimeout(
265911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis              this.updateState_.bind(
266911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis                  this, state, network, reason, lastNetworkType, true),
267361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko              CONNECTING_TIMEOUT_SEC * 1000);
268911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis        }
269911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis        return;
270911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis      }
271911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis      this.clearConnectingTimer_();
272911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis
273911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis      var currentScreen = Oobe.getInstance().currentScreen;
274911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis      var offlineMessage = this;
275911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis      var isOnline = (state == NET_STATE.ONLINE);
276911d717307e0d90980699cf75204c22e4462b45dArgyrios Kyrtzidis      var isUnderCaptivePortal = (state == NET_STATE.PORTAL);
277361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko      var isProxyError = reason == ERROR_REASONS.PROXY_AUTH_CANCELLED ||
2782957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis          reason == ERROR_REASONS.PROXY_CONNECTION_FAILED;
2792957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis      var shouldOverlay = MANAGED_SCREENS.indexOf(currentScreen.id) != -1 &&
2802957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis          !currentScreen.isLocal;
2812957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis      var isTimeout = false;
2822957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis      var isShown = !offlineMessage.classList.contains('hidden') &&
2832957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis          !offlineMessage.classList.contains('faded');
284361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko      var isGaiaSignin = (currentScreen.id == SCREEN_GAIA_SIGNIN);
2856d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis      var gaiaSigninReloaded = false;
28658d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis
2876d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis      // Reload frame if network is changed.
28858d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis      if (reason == ERROR_REASONS.NETWORK_CHANGED) {
28958d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis        if (state == NET_STATE.ONLINE && isGaiaSignin && !gaiaSigninReloaded) {
29058d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis          currentScreen.doReload();
2916d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis          gaiaSigninReloaded = true;
2926d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis        }
2936d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis      }
2946d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis
295361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko      if (reason == ERROR_REASONS.PROXY_CONFIG_CHANGED && shouldOverlay &&
2962957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis          isGaiaSignin && !gaiaSigninReloaded) {
2972957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis        // Schedules a immediate retry.
298e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis        currentScreen.doReload();
2992957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis        gaiaSigninReloaded = true;
3002957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis        console.log('Retry page load since proxy settings has been changed');
3012957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis      }
302e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
3032957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis      // Fake portal state for loading timeout.
3042957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis      if (reason == ERROR_REASONS.LOADING_TIMEOUT) {
3052957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis        isOnline = false;
3062957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis        isUnderCaptivePortal = true;
307b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis        isTimeout = true;
308361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko      }
3092957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
3102957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis      // Portal was detected via generate_204 redirect on Chrome side.
311b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis      // Subsequent call to show dialog if it's already shown does nothing.
3124e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      if (reason == ERROR_REASONS.PORTAL_DETECTED) {
3132c3e05c266de0d4c465b58ffd129bd0b31604368Argyrios Kyrtzidis        isOnline = false;
314361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko        isUnderCaptivePortal = true;
31537f2f52fbc16b0d426d4d86c7e1662e5c6b9e3b8Argyrios Kyrtzidis      }
3162c3e05c266de0d4c465b58ffd129bd0b31604368Argyrios Kyrtzidis
3172c3e05c266de0d4c465b58ffd129bd0b31604368Argyrios Kyrtzidis      if (!isOnline && shouldOverlay) {
3184e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        console.log('Show offline message: state=' + state +
3194e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                    ', network=' + network + ', reason=' + reason +
3204e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                    ', isUnderCaptivePortal=' + isUnderCaptivePortal);
3214e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3224e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        // Clear any error messages that might still be around.
323d08900848307fdaea19d52249bdced94eefdb9bbArgyrios Kyrtzidis        Oobe.clearErrors();
324d08900848307fdaea19d52249bdced94eefdb9bbArgyrios Kyrtzidis
325d08900848307fdaea19d52249bdced94eefdb9bbArgyrios Kyrtzidis        offlineMessage.onBeforeShow(lastNetworkType);
326361d79ca6b9d185b5a71a46b01f1d6b25e3e7bb8Dmitri Gribenko
3274e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        if (isUnderCaptivePortal && !isProxyError) {
3284e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis          // Do not bother a user with obsessive captive portal showing. This
3294e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis          // check makes captive portal being shown only once: either when error
3304e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis          // screen is shown for the first time or when switching from another
3314e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis          // error screen (offline, proxy).
332651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          if (!isShown ||
333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              !offlineMessage.classList.contains('show-captive-portal')) {
3344e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis            // In case of timeout we're suspecting that network might be
3354e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis            // a captive portal but would like to check that first.
3363bed3d196dbb5ad2ea7442da4b6c2fbf6bb5fcc6Argyrios Kyrtzidis            // Otherwise (signal from shill / generate_204 got redirected)
33721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis            // show dialog right away.
33821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis            if (isTimeout)
3394e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis              chrome.send('fixCaptivePortal');
34021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis            else
34121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis              chrome.send('showCaptivePortal');
3424e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis          }
34321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis        } else {
34421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis          chrome.send('hideCaptivePortal');
34521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis        }
34621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
34721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis        if (isUnderCaptivePortal) {
34821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis          if (isProxyError)
3494e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis            offlineMessage.showProxyError();
3504e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis          else
3514e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis            offlineMessage.showCaptivePortalError(network);
35230a2805c2c85e6abfe3149293f83f60da018b2dfArgyrios Kyrtzidis        } else {
35330a2805c2c85e6abfe3149293f83f60da018b2dfArgyrios Kyrtzidis          offlineMessage.showOfflineError();
35430a2805c2c85e6abfe3149293f83f60da018b2dfArgyrios Kyrtzidis        }
35530a2805c2c85e6abfe3149293f83f60da018b2dfArgyrios Kyrtzidis
35630a2805c2c85e6abfe3149293f83f60da018b2dfArgyrios Kyrtzidis        offlineMessage.showScreen(offlineMessage);
3574e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
358        if (!currentScreen.classList.contains('faded')) {
359          currentScreen.classList.add('faded');
360          currentScreen.addEventListener('webkitTransitionEnd',
361            function f(e) {
362              currentScreen.removeEventListener('webkitTransitionEnd', f);
363              if (currentScreen.classList.contains('faded'))
364                currentScreen.classList.add('hidden');
365            });
366        }
367        chrome.send('networkErrorShown');
368        // Report back error screen UI being painted.
369        window.webkitRequestAnimationFrame(function() {
370          chrome.send('loginVisible', ['network-error']);
371        });
372      } else {
373        chrome.send('hideCaptivePortal');
374
375        if (!offlineMessage.classList.contains('faded')) {
376          console.log('Hide offline message. state=' + state +
377                      ', network=' + network + ', reason=' + reason);
378
379          offlineMessage.onBeforeHide();
380
381          offlineMessage.classList.add('faded');
382          if (offlineMessage.classList.contains('animated')) {
383            offlineMessage.addEventListener('webkitTransitionEnd',
384              function f(e) {
385                offlineMessage.removeEventListener('webkitTransitionEnd', f);
386                if (offlineMessage.classList.contains('faded'))
387                  offlineMessage.classList.add('hidden');
388              });
389          } else {
390            offlineMessage.classList.add('hidden');
391          }
392
393          offlineMessage.showScreen(currentScreen);
394
395          // Forces a reload for Gaia screen on hiding error message.
396          if (isGaiaSignin && !gaiaSigninReloaded) {
397            currentScreen.doReload();
398            gaiaSigninReloaded = true;
399          }
400        } else if (isGaiaSignin && currentScreen.loading) {
401          if (!gaiaSigninReloaded) {
402            currentScreen.doReload();
403            gaiaSigninReloaded = true;
404          }
405        }
406      }
407    },
408
409    // Request network state update with loading timeout as reason.
410    showLoadingTimeoutError: function() {
411      // Shows error message if it is not shown already.
412      if (this.classList.contains('hidden')) {
413        chrome.send('loginRequestNetworkState',
414                    ['login.ErrorMessageScreen.updateState',
415                     ERROR_REASONS.LOADING_TIMEOUT]);
416      }
417    }
418  };
419
420  /**
421   * Network state changed callback.
422   * @param {number} state Current state of the network (see NET_STATE).
423   * @param {string} network Name of the current network.
424   * @param {string} reason Reason the callback was called.
425   * @param {number} lastNetworkType Last active network type.
426   */
427  ErrorMessageScreen.updateState = function(
428      state, network, reason, lastNetworkType) {
429    $('error-message').updateState_(state, network, reason, lastNetworkType);
430  };
431
432  /**
433   * Handler for iframe's error notification coming from the outside.
434   * For more info see C++ class 'SnifferObserver' which calls this method.
435   * @param {number} error Error code.
436   */
437  ErrorMessageScreen.onFrameError = function(error) {
438    console.log('Gaia frame error = ' + error);
439    if (error == NET_ERROR.ABORTED_BY_USER) {
440      // Gaia frame was reloaded. Nothing to do here.
441      return;
442    }
443    $('gaia-signin').onFrameError(error);
444    // Check current network state if currentScreen is a managed one.
445    var currentScreen = Oobe.getInstance().currentScreen;
446    if (MANAGED_SCREENS.indexOf(currentScreen.id) != -1) {
447      chrome.send('loginRequestNetworkState',
448                  ['login.ErrorMessageScreen.maybeRetry',
449                   'frame error:' + error]);
450    }
451  };
452
453  /**
454   * Network state callback where we decide whether to schedule a retry.
455   */
456  ErrorMessageScreen.maybeRetry =
457      function(state, network, reason, lastNetworkType) {
458    console.log('ErrorMessageScreen.maybeRetry, state=' + state +
459                ', network=' + network +
460                ', lastNetworkType=' + lastNetworkType);
461
462    // No retry if we are not online.
463    if (state != NET_STATE.ONLINE)
464      return;
465
466    var currentScreen = Oobe.getInstance().currentScreen;
467    if (MANAGED_SCREENS.indexOf(currentScreen.id) != -1 &&
468        state != NET_STATE.CONNECTING) {
469      this.updateState(NET_STATE.PORTAL, network, reason, lastNetworkType);
470      // Schedules a retry.
471      currentScreen.scheduleRetry();
472    }
473  };
474
475  /**
476   * Updates screen localized content like links since they're not updated
477   * via template.
478   */
479  ErrorMessageScreen.updateLocalizedContent = function() {
480    $('error-message').updateLocalizedContent_();
481  };
482
483  return {
484    ErrorMessageScreen: ErrorMessageScreen
485  };
486});
487