OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview | 6 * @fileoverview |
7 * Functions related to the 'host screen' for Chromoting. | 7 * Functions related to the 'host screen' for Chromoting. |
8 */ | 8 */ |
9 | 9 |
10 'use strict'; | |
11 | |
12 /** @suppress {duplicate} */ | 10 /** @suppress {duplicate} */ |
13 var remoting = remoting || {}; | 11 var remoting = remoting || {}; |
14 | 12 |
| 13 (function(){ |
| 14 |
| 15 'use strict'; |
| 16 |
15 /** @type {remoting.HostSession} */ | 17 /** @type {remoting.HostSession} */ |
16 remoting.hostSession = null; | 18 var hostSession_ = null; |
17 | 19 |
18 /** | 20 /** |
19 * @type {boolean} Whether or not the last share was cancelled by the user. | 21 * @type {boolean} Whether or not the last share was cancelled by the user. |
20 * This controls what screen is shown when the host signals completion. | 22 * This controls what screen is shown when the host signals completion. |
21 * @private | |
22 */ | 23 */ |
23 var lastShareWasCancelled_ = false; | 24 var lastShareWasCancelled_ = false; |
24 | 25 |
25 /** | 26 /** |
26 * Start a host session. This is the main entry point for the host screen, | 27 * Start a host session. This is the main entry point for the host screen, |
27 * called directly from the onclick action of a button on the home screen. | 28 * called directly from the onclick action of a button on the home screen. |
28 * It first verifies that the native host components are installed and asks | 29 * It first verifies that the native host components are installed and asks |
29 * to install them if necessary. | 30 * to install them if necessary. |
30 */ | 31 */ |
31 remoting.tryShare = function() { | 32 remoting.tryShare = function() { |
32 /** @type {remoting.It2MeHostFacade} */ | 33 /** @type {remoting.It2MeHostFacade} */ |
33 var hostFacade = new remoting.It2MeHostFacade(); | 34 var hostFacade = new remoting.It2MeHostFacade(); |
34 | 35 |
35 /** @type {remoting.HostInstallDialog} */ | 36 /** @type {remoting.HostInstallDialog} */ |
36 var hostInstallDialog = null; | 37 var hostInstallDialog = null; |
37 | 38 |
38 var tryInitializeFacade = function() { | 39 var tryInitializeFacade = function() { |
39 hostFacade.initialize(onFacadeInitialized, onFacadeInitializationFailed); | 40 hostFacade.initialize(onFacadeInitialized, onFacadeInitializationFailed); |
40 } | 41 }; |
41 | 42 |
42 var onFacadeInitialized = function () { | 43 var onFacadeInitialized = function () { |
43 // Host already installed. | 44 // Host already installed. |
44 remoting.startHostUsingFacade_(hostFacade); | 45 remoting.startHostUsingFacade_(hostFacade); |
45 }; | 46 }; |
46 | 47 |
47 var onFacadeInitializationFailed = function() { | 48 var onFacadeInitializationFailed = function() { |
48 // If we failed to initialize the dispatcher then prompt the user to install | 49 // If we failed to initialize the dispatcher then prompt the user to install |
49 // the host manually. | 50 // the host manually. |
50 var hasHostDialog = (hostInstallDialog != null); /** jscompile hack */ | 51 var hasHostDialog = (hostInstallDialog !== null); /** jscompile hack */ |
51 if (!hasHostDialog) { | 52 if (!hasHostDialog) { |
52 hostInstallDialog = new remoting.HostInstallDialog(); | 53 hostInstallDialog = new remoting.HostInstallDialog(); |
53 hostInstallDialog.show(tryInitializeFacade, onInstallError); | 54 hostInstallDialog.show(tryInitializeFacade, onInstallError); |
54 } else { | 55 } else { |
55 hostInstallDialog.tryAgain(); | 56 hostInstallDialog.tryAgain(); |
56 } | 57 } |
57 }; | 58 }; |
58 | 59 |
59 /** @param {remoting.Error} error */ | 60 /** @param {remoting.Error} error */ |
60 var onInstallError = function(error) { | 61 var onInstallError = function(error) { |
61 if (error == remoting.Error.CANCELLED) { | 62 if (error == remoting.Error.CANCELLED) { |
62 remoting.setMode(remoting.AppMode.HOME); | 63 remoting.setMode(remoting.AppMode.HOME); |
63 } else { | 64 } else { |
64 showShareError_(error); | 65 showShareError_(error); |
65 } | 66 } |
66 } | 67 }; |
67 | 68 |
68 tryInitializeFacade(); | 69 tryInitializeFacade(); |
69 }; | 70 }; |
70 | 71 |
71 /** | 72 /** |
72 * @param {remoting.It2MeHostFacade} hostFacade An initialized It2MeHostFacade. | 73 * @param {remoting.It2MeHostFacade} hostFacade An initialized It2MeHostFacade. |
73 */ | 74 */ |
74 remoting.startHostUsingFacade_ = function(hostFacade) { | 75 remoting.startHostUsingFacade_ = function(hostFacade) { |
75 console.log('Attempting to share...'); | 76 console.log('Attempting to share...'); |
76 remoting.identity.callWithToken( | 77 remoting.identity.callWithToken( |
77 remoting.tryShareWithToken_.bind(null, hostFacade), | 78 remoting.tryShareWithToken_.bind(null, hostFacade), |
78 remoting.showErrorMessage); | 79 remoting.showErrorMessage); |
79 } | 80 } |
80 | 81 |
81 /** | 82 /** |
82 * @param {remoting.It2MeHostFacade} hostFacade An initialized | 83 * @param {remoting.It2MeHostFacade} hostFacade An initialized |
83 * It2MeHostFacade. | 84 * It2MeHostFacade. |
84 * @param {string} token The OAuth access token. | 85 * @param {string} token The OAuth access token. |
85 * @private | 86 * @private |
86 */ | 87 */ |
87 remoting.tryShareWithToken_ = function(hostFacade, token) { | 88 remoting.tryShareWithToken_ = function(hostFacade, token) { |
88 lastShareWasCancelled_ = false; | 89 lastShareWasCancelled_ = false; |
89 onNatTraversalPolicyChanged_(true); // Hide warning by default. | 90 onNatTraversalPolicyChanged_(true); // Hide warning by default. |
90 remoting.setMode(remoting.AppMode.HOST_WAITING_FOR_CODE); | 91 remoting.setMode(remoting.AppMode.HOST_WAITING_FOR_CODE); |
91 document.getElementById('cancel-share-button').disabled = false; | 92 document.getElementById('cancel-share-button').disabled = false; |
92 disableTimeoutCountdown_(); | 93 disableTimeoutCountdown_(); |
93 | 94 |
94 remoting.hostSession = new remoting.HostSession(); | 95 base.debug.assert(hostSession_ === null); |
| 96 hostSession_ = new remoting.HostSession(); |
95 var email = /** @type {string} */ (remoting.identity.getCachedEmail()); | 97 var email = /** @type {string} */ (remoting.identity.getCachedEmail()); |
96 remoting.hostSession.connect( | 98 hostSession_.connect( |
97 hostFacade, email, token, onHostStateChanged_, | 99 hostFacade, email, token, onHostStateChanged_, |
98 onNatTraversalPolicyChanged_, logDebugInfo_, it2meConnectFailed_); | 100 onNatTraversalPolicyChanged_, logDebugInfo_, it2meConnectFailed_); |
99 }; | 101 }; |
100 | 102 |
101 /** | 103 /** |
102 * Callback for the host plugin to notify the web app of state changes. | 104 * Callback for the host plugin to notify the web app of state changes. |
103 * @param {remoting.HostSession.State} state The new state of the plugin. | 105 * @param {remoting.HostSession.State} state The new state of the plugin. |
104 * @return {void} Nothing. | 106 * @return {void} Nothing. |
105 * @private | |
106 */ | 107 */ |
107 function onHostStateChanged_(state) { | 108 function onHostStateChanged_(state) { |
108 if (state == remoting.HostSession.State.STARTING) { | 109 if (state == remoting.HostSession.State.STARTING) { |
109 // Nothing to do here. | 110 // Nothing to do here. |
110 console.log('Host state: STARTING'); | 111 console.log('Host state: STARTING'); |
111 | 112 |
112 } else if (state == remoting.HostSession.State.REQUESTED_ACCESS_CODE) { | 113 } else if (state == remoting.HostSession.State.REQUESTED_ACCESS_CODE) { |
113 // Nothing to do here. | 114 // Nothing to do here. |
114 console.log('Host state: REQUESTED_ACCESS_CODE'); | 115 console.log('Host state: REQUESTED_ACCESS_CODE'); |
115 | 116 |
116 } else if (state == remoting.HostSession.State.RECEIVED_ACCESS_CODE) { | 117 } else if (state == remoting.HostSession.State.RECEIVED_ACCESS_CODE) { |
117 console.log('Host state: RECEIVED_ACCESS_CODE'); | 118 console.log('Host state: RECEIVED_ACCESS_CODE'); |
118 var accessCode = remoting.hostSession.getAccessCode(); | 119 var accessCode = hostSession_.getAccessCode(); |
119 var accessCodeDisplay = document.getElementById('access-code-display'); | 120 var accessCodeDisplay = document.getElementById('access-code-display'); |
120 accessCodeDisplay.innerText = ''; | 121 accessCodeDisplay.innerText = ''; |
121 // Display the access code in groups of four digits for readability. | 122 // Display the access code in groups of four digits for readability. |
122 var kDigitsPerGroup = 4; | 123 var kDigitsPerGroup = 4; |
123 for (var i = 0; i < accessCode.length; i += kDigitsPerGroup) { | 124 for (var i = 0; i < accessCode.length; i += kDigitsPerGroup) { |
124 var nextFourDigits = document.createElement('span'); | 125 var nextFourDigits = document.createElement('span'); |
125 nextFourDigits.className = 'access-code-digit-group'; | 126 nextFourDigits.className = 'access-code-digit-group'; |
126 nextFourDigits.innerText = accessCode.substring(i, i + kDigitsPerGroup); | 127 nextFourDigits.innerText = accessCode.substring(i, i + kDigitsPerGroup); |
127 accessCodeDisplay.appendChild(nextFourDigits); | 128 accessCodeDisplay.appendChild(nextFourDigits); |
128 } | 129 } |
129 accessCodeExpiresIn_ = remoting.hostSession.getAccessCodeLifetime(); | 130 accessCodeExpiresIn_ = hostSession_.getAccessCodeLifetime(); |
130 if (accessCodeExpiresIn_ > 0) { // Check it hasn't expired. | 131 if (accessCodeExpiresIn_ > 0) { // Check it hasn't expired. |
131 accessCodeTimerId_ = setInterval(decrementAccessCodeTimeout_, 1000); | 132 accessCodeTimerId_ = setInterval(decrementAccessCodeTimeout_, 1000); |
132 timerRunning_ = true; | 133 timerRunning_ = true; |
133 updateAccessCodeTimeoutElement_(); | 134 updateAccessCodeTimeoutElement_(); |
134 updateTimeoutStyles_(); | 135 updateTimeoutStyles_(); |
135 remoting.setMode(remoting.AppMode.HOST_WAITING_FOR_CONNECTION); | 136 remoting.setMode(remoting.AppMode.HOST_WAITING_FOR_CONNECTION); |
136 } else { | 137 } else { |
137 // This can only happen if the cloud tells us that the code lifetime is | 138 // This can only happen if the cloud tells us that the code lifetime is |
138 // <= 0s, which shouldn't happen so we don't care how clean this UX is. | 139 // <= 0s, which shouldn't happen so we don't care how clean this UX is. |
139 console.error('Access code already invalid on receipt!'); | 140 console.error('Access code already invalid on receipt!'); |
140 remoting.cancelShare(); | 141 remoting.cancelShare(); |
141 } | 142 } |
142 | 143 |
143 } else if (state == remoting.HostSession.State.CONNECTED) { | 144 } else if (state == remoting.HostSession.State.CONNECTED) { |
144 console.log('Host state: CONNECTED'); | 145 console.log('Host state: CONNECTED'); |
145 var element = document.getElementById('host-shared-message'); | 146 var element = document.getElementById('host-shared-message'); |
146 var client = remoting.hostSession.getClient(); | 147 var client = hostSession_.getClient(); |
147 l10n.localizeElement(element, client); | 148 l10n.localizeElement(element, client); |
148 remoting.setMode(remoting.AppMode.HOST_SHARED); | 149 remoting.setMode(remoting.AppMode.HOST_SHARED); |
149 disableTimeoutCountdown_(); | 150 disableTimeoutCountdown_(); |
150 | 151 |
151 } else if (state == remoting.HostSession.State.DISCONNECTING) { | 152 } else if (state == remoting.HostSession.State.DISCONNECTING) { |
152 console.log('Host state: DISCONNECTING'); | 153 console.log('Host state: DISCONNECTING'); |
153 | 154 |
154 } else if (state == remoting.HostSession.State.DISCONNECTED) { | 155 } else if (state == remoting.HostSession.State.DISCONNECTED) { |
155 console.log('Host state: DISCONNECTED'); | 156 console.log('Host state: DISCONNECTED'); |
156 if (remoting.currentMode != remoting.AppMode.HOST_SHARE_FAILED) { | 157 if (remoting.currentMode != remoting.AppMode.HOST_SHARE_FAILED) { |
157 // If an error is being displayed, then the plugin should not be able to | 158 // If an error is being displayed, then the plugin should not be able to |
158 // hide it by setting the state. Errors must be dismissed by the user | 159 // hide it by setting the state. Errors must be dismissed by the user |
159 // clicking OK, which puts the app into mode HOME. | 160 // clicking OK, which puts the app into mode HOME. |
160 if (lastShareWasCancelled_) { | 161 if (lastShareWasCancelled_) { |
161 remoting.setMode(remoting.AppMode.HOME); | 162 remoting.setMode(remoting.AppMode.HOME); |
162 } else { | 163 } else { |
163 remoting.setMode(remoting.AppMode.HOST_SHARE_FINISHED); | 164 remoting.setMode(remoting.AppMode.HOST_SHARE_FINISHED); |
164 } | 165 } |
165 } | 166 } |
| 167 cleanUp(); |
166 } else if (state == remoting.HostSession.State.ERROR) { | 168 } else if (state == remoting.HostSession.State.ERROR) { |
167 console.error('Host state: ERROR'); | 169 console.error('Host state: ERROR'); |
168 showShareError_(remoting.Error.UNEXPECTED); | 170 showShareError_(remoting.Error.UNEXPECTED); |
169 } else if (state == remoting.HostSession.State.INVALID_DOMAIN_ERROR) { | 171 } else if (state == remoting.HostSession.State.INVALID_DOMAIN_ERROR) { |
170 console.error('Host state: INVALID_DOMAIN_ERROR'); | 172 console.error('Host state: INVALID_DOMAIN_ERROR'); |
171 showShareError_(remoting.Error.INVALID_HOST_DOMAIN); | 173 showShareError_(remoting.Error.INVALID_HOST_DOMAIN); |
172 } else { | 174 } else { |
173 console.error('Unknown state -> ' + state); | 175 console.error('Unknown state -> ' + state); |
174 } | 176 } |
175 } | 177 } |
176 | 178 |
177 /** | 179 /** |
178 * This is the callback that the host plugin invokes to indicate that there | 180 * This is the callback that the host plugin invokes to indicate that there |
179 * is additional debug log info to display. | 181 * is additional debug log info to display. |
180 * @param {string} msg The message (which will not be localized) to be logged. | 182 * @param {string} msg The message (which will not be localized) to be logged. |
181 * @private | |
182 */ | 183 */ |
183 function logDebugInfo_(msg) { | 184 function logDebugInfo_(msg) { |
184 console.log('plugin: ' + msg); | 185 console.log('plugin: ' + msg); |
185 } | 186 } |
186 | 187 |
187 /** | 188 /** |
188 * Show a host-side error message. | 189 * Show a host-side error message. |
189 * | 190 * |
190 * @param {string} errorTag The error message to be localized and displayed. | 191 * @param {string} errorTag The error message to be localized and displayed. |
191 * @return {void} Nothing. | 192 * @return {void} Nothing. |
192 * @private | |
193 */ | 193 */ |
194 function showShareError_(errorTag) { | 194 function showShareError_(errorTag) { |
195 var errorDiv = document.getElementById('host-plugin-error'); | 195 var errorDiv = document.getElementById('host-plugin-error'); |
196 l10n.localizeElementFromTag(errorDiv, errorTag); | 196 l10n.localizeElementFromTag(errorDiv, errorTag); |
197 console.error('Sharing error: ' + errorTag); | 197 console.error('Sharing error: ' + errorTag); |
198 remoting.setMode(remoting.AppMode.HOST_SHARE_FAILED); | 198 remoting.setMode(remoting.AppMode.HOST_SHARE_FAILED); |
| 199 cleanUp(); |
199 } | 200 } |
200 | 201 |
201 /** | 202 /** |
202 * Show a sharing error with error code UNEXPECTED . | 203 * Show a sharing error with error code UNEXPECTED . |
203 * | 204 * |
204 * @return {void} Nothing. | 205 * @return {void} Nothing. |
205 * @private | |
206 */ | 206 */ |
207 function it2meConnectFailed_() { | 207 function it2meConnectFailed_() { |
208 // TODO (weitaosu): Instruct the user to install the native messaging host. | 208 // TODO (weitaosu): Instruct the user to install the native messaging host. |
209 // We probably want to add a new error code (with the corresponding error | 209 // We probably want to add a new error code (with the corresponding error |
210 // message for sharing error. | 210 // message for sharing error. |
211 console.error('Cannot share desktop.'); | 211 console.error('Cannot share desktop.'); |
212 showShareError_(remoting.Error.UNEXPECTED); | 212 showShareError_(remoting.Error.UNEXPECTED); |
213 } | 213 } |
214 | 214 |
| 215 function cleanUp() { |
| 216 base.dispose(hostSession_); |
| 217 hostSession_ = null; |
| 218 } |
| 219 |
215 /** | 220 /** |
216 * Cancel an active or pending it2me share operation. | 221 * Cancel an active or pending it2me share operation. |
217 * | 222 * |
218 * @return {void} Nothing. | 223 * @return {void} Nothing. |
219 */ | 224 */ |
220 remoting.cancelShare = function() { | 225 remoting.cancelShare = function() { |
221 document.getElementById('cancel-share-button').disabled = true; | 226 document.getElementById('cancel-share-button').disabled = true; |
222 console.log('Canceling share...'); | 227 console.log('Canceling share...'); |
223 remoting.lastShareWasCancelled = true; | 228 remoting.lastShareWasCancelled = true; |
224 try { | 229 try { |
225 remoting.hostSession.disconnect(); | 230 hostSession_.disconnect(); |
226 } catch (/** @type {*} */ error) { | 231 } catch (/** @type {*} */ error) { |
227 console.error('Error disconnecting: ' + error + | 232 console.error('Error disconnecting: ' + error + |
228 '. The host probably crashed.'); | 233 '. The host probably crashed.'); |
229 // TODO(jamiewalch): Clean this up. We should have a class representing | 234 // TODO(jamiewalch): Clean this up. We should have a class representing |
230 // the host plugin, like we do for the client, which should handle crash | 235 // the host plugin, like we do for the client, which should handle crash |
231 // reporting and it should use a more detailed error message than the | 236 // reporting and it should use a more detailed error message than the |
232 // default 'generic' one. See crbug.com/94624 | 237 // default 'generic' one. See crbug.com/94624 |
233 showShareError_(remoting.Error.UNEXPECTED); | 238 showShareError_(remoting.Error.UNEXPECTED); |
234 } | 239 } |
235 disableTimeoutCountdown_(); | 240 disableTimeoutCountdown_(); |
236 }; | 241 }; |
237 | 242 |
238 /** | 243 /** |
239 * @type {boolean} Whether or not the access code timeout countdown is running. | 244 * @type {boolean} Whether or not the access code timeout countdown is running. |
240 * @private | |
241 */ | 245 */ |
242 var timerRunning_ = false; | 246 var timerRunning_ = false; |
243 | 247 |
244 /** | 248 /** |
245 * @type {number} The id of the access code expiry countdown timer. | 249 * @type {number} The id of the access code expiry countdown timer. |
246 * @private | |
247 */ | 250 */ |
248 var accessCodeTimerId_ = 0; | 251 var accessCodeTimerId_ = 0; |
249 | 252 |
250 /** | 253 /** |
251 * @type {number} The number of seconds until the access code expires. | 254 * @type {number} The number of seconds until the access code expires. |
252 * @private | |
253 */ | 255 */ |
254 var accessCodeExpiresIn_ = 0; | 256 var accessCodeExpiresIn_ = 0; |
255 | 257 |
256 /** | 258 /** |
257 * The timer callback function | 259 * The timer callback function |
258 * @return {void} Nothing. | 260 * @return {void} Nothing. |
259 * @private | |
260 */ | 261 */ |
261 function decrementAccessCodeTimeout_() { | 262 function decrementAccessCodeTimeout_() { |
262 --accessCodeExpiresIn_; | 263 --accessCodeExpiresIn_; |
263 updateAccessCodeTimeoutElement_(); | 264 updateAccessCodeTimeoutElement_(); |
264 }; | 265 } |
265 | 266 |
266 /** | 267 /** |
267 * Stop the access code timeout countdown if it is running. | 268 * Stop the access code timeout countdown if it is running. |
268 * @return {void} Nothing. | 269 * @return {void} Nothing. |
269 * @private | |
270 */ | 270 */ |
271 function disableTimeoutCountdown_() { | 271 function disableTimeoutCountdown_() { |
272 if (timerRunning_) { | 272 if (timerRunning_) { |
273 clearInterval(accessCodeTimerId_); | 273 clearInterval(accessCodeTimerId_); |
274 timerRunning_ = false; | 274 timerRunning_ = false; |
275 updateTimeoutStyles_(); | 275 updateTimeoutStyles_(); |
276 } | 276 } |
277 } | 277 } |
278 | 278 |
279 /** | 279 /** |
280 * Constants controlling the access code timer countdown display. | 280 * Constants controlling the access code timer countdown display. |
281 * @private | |
282 */ | 281 */ |
283 var ACCESS_CODE_TIMER_DISPLAY_THRESHOLD_ = 30; | 282 var ACCESS_CODE_TIMER_DISPLAY_THRESHOLD_ = 30; |
284 var ACCESS_CODE_RED_THRESHOLD_ = 10; | 283 var ACCESS_CODE_RED_THRESHOLD_ = 10; |
285 | 284 |
286 /** | 285 /** |
287 * Show/hide or restyle various elements, depending on the remaining countdown | 286 * Show/hide or restyle various elements, depending on the remaining countdown |
288 * and timer state. | 287 * and timer state. |
289 * | 288 * |
290 * @return {boolean} True if the timeout is in progress, false if it has | 289 * @return {boolean} True if the timeout is in progress, false if it has |
291 * expired. | 290 * expired. |
292 * @private | |
293 */ | 291 */ |
294 function updateTimeoutStyles_() { | 292 function updateTimeoutStyles_() { |
295 if (timerRunning_) { | 293 if (timerRunning_) { |
296 if (accessCodeExpiresIn_ <= 0) { | 294 if (accessCodeExpiresIn_ <= 0) { |
297 remoting.cancelShare(); | 295 remoting.cancelShare(); |
298 return false; | 296 return false; |
299 } | 297 } |
300 var accessCode = document.getElementById('access-code-display'); | 298 var accessCode = document.getElementById('access-code-display'); |
301 if (accessCodeExpiresIn_ <= ACCESS_CODE_RED_THRESHOLD_) { | 299 if (accessCodeExpiresIn_ <= ACCESS_CODE_RED_THRESHOLD_) { |
302 accessCode.classList.add('expiring'); | 300 accessCode.classList.add('expiring'); |
303 } else { | 301 } else { |
304 accessCode.classList.remove('expiring'); | 302 accessCode.classList.remove('expiring'); |
305 } | 303 } |
306 } | 304 } |
307 document.getElementById('access-code-countdown').hidden = | 305 document.getElementById('access-code-countdown').hidden = |
308 (accessCodeExpiresIn_ > ACCESS_CODE_TIMER_DISPLAY_THRESHOLD_) || | 306 (accessCodeExpiresIn_ > ACCESS_CODE_TIMER_DISPLAY_THRESHOLD_) || |
309 !timerRunning_; | 307 !timerRunning_; |
310 return true; | 308 return true; |
311 } | 309 } |
312 | 310 |
313 /** | 311 /** |
314 * Update the text and appearance of the access code timeout element to | 312 * Update the text and appearance of the access code timeout element to |
315 * reflect the time remaining. | 313 * reflect the time remaining. |
316 * @return {void} Nothing. | 314 * @return {void} Nothing. |
317 * @private | |
318 */ | 315 */ |
319 function updateAccessCodeTimeoutElement_() { | 316 function updateAccessCodeTimeoutElement_() { |
320 var pad = (accessCodeExpiresIn_ < 10) ? '0:0' : '0:'; | 317 var pad = (accessCodeExpiresIn_ < 10) ? '0:0' : '0:'; |
321 l10n.localizeElement(document.getElementById('seconds-remaining'), | 318 l10n.localizeElement(document.getElementById('seconds-remaining'), |
322 pad + accessCodeExpiresIn_); | 319 pad + accessCodeExpiresIn_); |
323 if (!updateTimeoutStyles_()) { | 320 if (!updateTimeoutStyles_()) { |
324 disableTimeoutCountdown_(); | 321 disableTimeoutCountdown_(); |
325 } | 322 } |
326 } | 323 } |
327 | 324 |
328 /** | 325 /** |
329 * Callback to show or hide the NAT traversal warning when the policy changes. | 326 * Callback to show or hide the NAT traversal warning when the policy changes. |
330 * @param {boolean} enabled True if NAT traversal is enabled. | 327 * @param {boolean} enabled True if NAT traversal is enabled. |
331 * @return {void} Nothing. | 328 * @return {void} Nothing. |
332 * @private | |
333 */ | 329 */ |
334 function onNatTraversalPolicyChanged_(enabled) { | 330 function onNatTraversalPolicyChanged_(enabled) { |
335 var natBox = document.getElementById('nat-box'); | 331 var natBox = document.getElementById('nat-box'); |
336 if (enabled) { | 332 if (enabled) { |
337 natBox.classList.add('traversal-enabled'); | 333 natBox.classList.add('traversal-enabled'); |
338 } else { | 334 } else { |
339 natBox.classList.remove('traversal-enabled'); | 335 natBox.classList.remove('traversal-enabled'); |
340 } | 336 } |
341 } | 337 } |
| 338 |
| 339 })(); |
OLD | NEW |