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 'client screen' for Chromoting. | 7 * Functions related to the 'client screen' for Chromoting. |
8 */ | 8 */ |
9 | 9 |
10 'use strict'; | 10 'use strict'; |
11 | 11 |
12 /** @suppress {duplicate} */ | 12 /** @suppress {duplicate} */ |
13 var remoting = remoting || {}; | 13 var remoting = remoting || {}; |
14 | 14 |
15 /** | 15 /** |
16 * @type {remoting.SessionConnector} The connector object, set when a | |
17 * connection is initiated. | |
18 */ | |
19 remoting.connector = null; | |
20 | |
21 /** | |
22 * @type {remoting.ClientSession} The client session object, set once the | 16 * @type {remoting.ClientSession} The client session object, set once the |
23 * connector has invoked its onOk callback. | 17 * connector has invoked its onOk callback. |
24 */ | 18 */ |
25 remoting.clientSession = null; | 19 remoting.clientSession = null; |
26 | 20 |
27 /** | 21 /** |
28 * Initiate an IT2Me connection. | 22 * Initiate an IT2Me connection. |
29 */ | 23 */ |
30 remoting.connectIT2Me = function() { | 24 remoting.connectIT2Me = function() { |
31 remoting.ensureSessionConnector_(); | 25 var connector = remoting.app.getSessionConnector(); |
32 var accessCode = document.getElementById('access-code-entry').value; | 26 var accessCode = document.getElementById('access-code-entry').value; |
33 remoting.setMode(remoting.AppMode.CLIENT_CONNECTING); | 27 remoting.setMode(remoting.AppMode.CLIENT_CONNECTING); |
34 remoting.connector.connectIT2Me(accessCode); | 28 connector.connectIT2Me(accessCode); |
35 }; | 29 }; |
36 | 30 |
37 /** | 31 /** |
38 * Update the remoting client layout in response to a resize event. | 32 * Update the remoting client layout in response to a resize event. |
39 * | 33 * |
40 * @return {void} Nothing. | 34 * @return {void} Nothing. |
41 */ | 35 */ |
42 remoting.onResize = function() { | 36 remoting.onResize = function() { |
43 if (remoting.clientSession) { | 37 if (remoting.clientSession) { |
44 remoting.clientSession.onResize(); | 38 remoting.clientSession.onResize(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED_ME2ME); | 90 remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED_ME2ME); |
97 } | 91 } |
98 break; | 92 break; |
99 | 93 |
100 case remoting.ClientSession.State.FAILED: | 94 case remoting.ClientSession.State.FAILED: |
101 var error = remoting.clientSession.getError(); | 95 var error = remoting.clientSession.getError(); |
102 console.error('Client plugin reported connection failed: ' + error); | 96 console.error('Client plugin reported connection failed: ' + error); |
103 if (error == null) { | 97 if (error == null) { |
104 error = remoting.Error.UNEXPECTED; | 98 error = remoting.Error.UNEXPECTED; |
105 } | 99 } |
106 showConnectError_(error); | 100 remoting.app.onError(error); |
107 break; | 101 break; |
108 | 102 |
109 default: | 103 default: |
110 console.error('Unexpected client plugin state: ' + state.current); | 104 console.error('Unexpected client plugin state: ' + state.current); |
111 // This should only happen if the web-app and client plugin get out of | 105 // This should only happen if the web-app and client plugin get out of |
112 // sync, so MISSING_PLUGIN is a suitable error. | 106 // sync, so MISSING_PLUGIN is a suitable error. |
113 showConnectError_(remoting.Error.MISSING_PLUGIN); | 107 remoting.app.onError(remoting.Error.MISSING_PLUGIN); |
114 break; | 108 break; |
115 } | 109 } |
116 | 110 |
117 remoting.clientSession.removeEventListener('stateChanged', | 111 remoting.clientSession.removeEventListener('stateChanged', |
118 onClientStateChange_); | 112 onClientStateChange_); |
119 remoting.clientSession.cleanup(); | 113 remoting.clientSession.cleanup(); |
120 remoting.clientSession = null; | 114 remoting.clientSession = null; |
121 } | 115 } |
122 | 116 |
123 /** | 117 /** |
124 * Show a client-side error message. | |
125 * | |
126 * @param {remoting.Error} errorTag The error to be localized and | |
127 * displayed. | |
128 * @return {void} Nothing. | |
129 */ | |
130 function showConnectError_(errorTag) { | |
131 console.error('Connection failed: ' + errorTag); | |
132 var errorDiv = document.getElementById('connect-error-message'); | |
133 l10n.localizeElementFromTag(errorDiv, /** @type {string} */ (errorTag)); | |
134 remoting.accessCode = ''; | |
135 var mode = remoting.clientSession ? remoting.clientSession.getMode() | |
136 : remoting.connector.getConnectionMode(); | |
137 if (mode == remoting.ClientSession.Mode.IT2ME) { | |
138 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED_IT2ME); | |
139 remoting.hangoutSessionEvents.raiseEvent( | |
140 remoting.hangoutSessionEvents.sessionStateChanged, | |
141 remoting.ClientSession.State.FAILED | |
142 ); | |
143 } else { | |
144 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED_ME2ME); | |
145 } | |
146 } | |
147 | |
148 /** | |
149 * Set the text on the buttons shown under the error message so that they are | |
150 * easy to understand in the case where a successful connection failed, as | |
151 * opposed to the case where a connection never succeeded. | |
152 */ | |
153 function setConnectionInterruptedButtonsText_() { | |
154 var button1 = document.getElementById('client-reconnect-button'); | |
155 l10n.localizeElementFromTag(button1, /*i18n-content*/'RECONNECT'); | |
156 button1.removeAttribute('autofocus'); | |
157 var button2 = document.getElementById('client-finished-me2me-button'); | |
158 l10n.localizeElementFromTag(button2, /*i18n-content*/'OK'); | |
159 button2.setAttribute('autofocus', 'autofocus'); | |
160 } | |
161 | |
162 /** | |
163 * Timer callback to update the statistics panel. | 118 * Timer callback to update the statistics panel. |
164 */ | 119 */ |
165 function updateStatistics_() { | 120 function updateStatistics_() { |
166 if (!remoting.clientSession || | 121 if (!remoting.clientSession || |
167 remoting.clientSession.getState() != | 122 remoting.clientSession.getState() != |
168 remoting.ClientSession.State.CONNECTED) { | 123 remoting.ClientSession.State.CONNECTED) { |
169 return; | 124 return; |
170 } | 125 } |
171 var perfstats = remoting.clientSession.getPerfStats(); | 126 var perfstats = remoting.clientSession.getPerfStats(); |
172 remoting.stats.update(perfstats); | 127 remoting.stats.update(perfstats); |
173 remoting.clientSession.logStatistics(perfstats); | 128 remoting.clientSession.logStatistics(perfstats); |
174 // Update the stats once per second. | 129 // Update the stats once per second. |
175 window.setTimeout(updateStatistics_, 1000); | 130 window.setTimeout(updateStatistics_, 1000); |
176 } | 131 } |
177 | 132 |
178 /** | 133 /** |
179 * Entry-point for Me2Me connections, handling showing of the host-upgrade nag | 134 * Entry-point for Me2Me connections, handling showing of the host-upgrade nag |
180 * dialog if necessary. | 135 * dialog if necessary. |
181 * | 136 * |
182 * @param {string} hostId The unique id of the host. | 137 * @param {string} hostId The unique id of the host. |
183 * @return {void} Nothing. | 138 * @return {void} Nothing. |
184 */ | 139 */ |
185 remoting.connectMe2Me = function(hostId) { | 140 remoting.connectMe2Me = function(hostId) { |
186 var host = remoting.hostList.getHostForId(hostId); | 141 var host = remoting.hostList.getHostForId(hostId); |
187 if (!host) { | 142 if (!host) { |
188 showConnectError_(remoting.Error.HOST_IS_OFFLINE); | 143 remoting.app.onError(remoting.Error.HOST_IS_OFFLINE); |
189 return; | 144 return; |
190 } | 145 } |
191 var webappVersion = chrome.runtime.getManifest().version; | 146 var webappVersion = chrome.runtime.getManifest().version; |
192 if (remoting.Host.needsUpdate(host, webappVersion)) { | 147 if (remoting.Host.needsUpdate(host, webappVersion)) { |
193 var needsUpdateMessage = | 148 var needsUpdateMessage = |
194 document.getElementById('host-needs-update-message'); | 149 document.getElementById('host-needs-update-message'); |
195 l10n.localizeElementFromTag(needsUpdateMessage, | 150 l10n.localizeElementFromTag(needsUpdateMessage, |
196 /*i18n-content*/'HOST_NEEDS_UPDATE_TITLE', | 151 /*i18n-content*/'HOST_NEEDS_UPDATE_TITLE', |
197 host.hostName); | 152 host.hostName); |
198 /** @type {Element} */ | 153 /** @type {Element} */ |
(...skipping 19 matching lines...) Expand all Loading... |
218 }; | 173 }; |
219 | 174 |
220 /** | 175 /** |
221 * Shows PIN entry screen localized to include the host name, and registers | 176 * Shows PIN entry screen localized to include the host name, and registers |
222 * a host-specific one-shot event handler for the form submission. | 177 * a host-specific one-shot event handler for the form submission. |
223 * | 178 * |
224 * @param {remoting.Host} host The Me2Me host to which to connect. | 179 * @param {remoting.Host} host The Me2Me host to which to connect. |
225 * @return {void} Nothing. | 180 * @return {void} Nothing. |
226 */ | 181 */ |
227 remoting.connectMe2MeHostVersionAcknowledged_ = function(host) { | 182 remoting.connectMe2MeHostVersionAcknowledged_ = function(host) { |
228 remoting.ensureSessionConnector_(); | 183 /** @type {remoting.SessionConnector} */ |
| 184 var connector = remoting.app.getSessionConnector(); |
229 remoting.setMode(remoting.AppMode.CLIENT_CONNECTING); | 185 remoting.setMode(remoting.AppMode.CLIENT_CONNECTING); |
230 | 186 |
231 /** | 187 /** |
232 * @param {string} tokenUrl Token-issue URL received from the host. | 188 * @param {string} tokenUrl Token-issue URL received from the host. |
233 * @param {string} scope OAuth scope to request the token for. | 189 * @param {string} scope OAuth scope to request the token for. |
234 * @param {string} hostPublicKey Host public key (DER and Base64 encoded). | 190 * @param {string} hostPublicKey Host public key (DER and Base64 encoded). |
235 * @param {function(string, string):void} onThirdPartyTokenFetched Callback. | 191 * @param {function(string, string):void} onThirdPartyTokenFetched Callback. |
236 */ | 192 */ |
237 var fetchThirdPartyToken = function( | 193 var fetchThirdPartyToken = function( |
238 tokenUrl, hostPublicKey, scope, onThirdPartyTokenFetched) { | 194 tokenUrl, hostPublicKey, scope, onThirdPartyTokenFetched) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 var connectMe2MeHostSettingsRetrieved = function(settings) { | 256 var connectMe2MeHostSettingsRetrieved = function(settings) { |
301 /** @type {string} */ | 257 /** @type {string} */ |
302 var clientId = ''; | 258 var clientId = ''; |
303 /** @type {string} */ | 259 /** @type {string} */ |
304 var sharedSecret = ''; | 260 var sharedSecret = ''; |
305 var pairingInfo = /** @type {Object} */ (settings['pairingInfo']); | 261 var pairingInfo = /** @type {Object} */ (settings['pairingInfo']); |
306 if (pairingInfo) { | 262 if (pairingInfo) { |
307 clientId = /** @type {string} */ (pairingInfo['clientId']); | 263 clientId = /** @type {string} */ (pairingInfo['clientId']); |
308 sharedSecret = /** @type {string} */ (pairingInfo['sharedSecret']); | 264 sharedSecret = /** @type {string} */ (pairingInfo['sharedSecret']); |
309 } | 265 } |
310 remoting.connector.connectMe2Me(host, requestPin, fetchThirdPartyToken, | 266 connector.connectMe2Me(host, requestPin, fetchThirdPartyToken, |
311 clientId, sharedSecret); | 267 clientId, sharedSecret); |
312 } | 268 } |
313 | 269 |
314 remoting.HostSettings.load(host.hostId, connectMe2MeHostSettingsRetrieved); | 270 remoting.HostSettings.load(host.hostId, connectMe2MeHostSettingsRetrieved); |
315 }; | 271 }; |
316 | |
317 /** @param {remoting.ClientSession} clientSession */ | |
318 remoting.onConnected = function(clientSession) { | |
319 remoting.clientSession = clientSession; | |
320 remoting.clientSession.addEventListener('stateChanged', onClientStateChange_); | |
321 setConnectionInterruptedButtonsText_(); | |
322 document.getElementById('access-code-entry').value = ''; | |
323 remoting.setMode(remoting.AppMode.IN_SESSION); | |
324 if (!base.isAppsV2()) { | |
325 remoting.toolbar.center(); | |
326 remoting.toolbar.preview(); | |
327 } | |
328 remoting.clipboard.startSession(); | |
329 updateStatistics_(); | |
330 remoting.hangoutSessionEvents.raiseEvent( | |
331 remoting.hangoutSessionEvents.sessionStateChanged, | |
332 remoting.ClientSession.State.CONNECTED | |
333 ); | |
334 if (remoting.pairingRequested) { | |
335 /** | |
336 * @param {string} clientId | |
337 * @param {string} sharedSecret | |
338 */ | |
339 var onPairingComplete = function(clientId, sharedSecret) { | |
340 var pairingInfo = { | |
341 pairingInfo: { | |
342 clientId: clientId, | |
343 sharedSecret: sharedSecret | |
344 } | |
345 }; | |
346 remoting.HostSettings.save(remoting.connector.getHostId(), pairingInfo); | |
347 remoting.connector.updatePairingInfo(clientId, sharedSecret); | |
348 }; | |
349 // Use the platform name as a proxy for the local computer name. | |
350 // TODO(jamiewalch): Use a descriptive name for the local computer, for | |
351 // example, its Chrome Sync name. | |
352 var clientName = ''; | |
353 if (remoting.platformIsMac()) { | |
354 clientName = 'Mac'; | |
355 } else if (remoting.platformIsWindows()) { | |
356 clientName = 'Windows'; | |
357 } else if (remoting.platformIsChromeOS()) { | |
358 clientName = 'ChromeOS'; | |
359 } else if (remoting.platformIsLinux()) { | |
360 clientName = 'Linux'; | |
361 } else { | |
362 console.log('Unrecognized client platform. Using navigator.platform.'); | |
363 clientName = navigator.platform; | |
364 } | |
365 clientSession.requestPairing(clientName, onPairingComplete); | |
366 } | |
367 }; | |
368 | |
369 /** | |
370 * Extension message handler. | |
371 * | |
372 * @param {string} type The type of the extension message. | |
373 * @param {string} data The payload of the extension message. | |
374 * @return {boolean} Return true if the extension message was recognized. | |
375 */ | |
376 remoting.onExtensionMessage = function(type, data) { | |
377 if (remoting.clientSession) { | |
378 return remoting.clientSession.handleExtensionMessage(type, data); | |
379 } | |
380 return false; | |
381 }; | |
382 | |
383 /** | |
384 * Create a session connector if one doesn't already exist. | |
385 */ | |
386 remoting.ensureSessionConnector_ = function() { | |
387 if (!remoting.connector) { | |
388 remoting.connector = remoting.SessionConnector.factory.createConnector( | |
389 document.getElementById('video-container'), | |
390 remoting.onConnected, | |
391 showConnectError_, remoting.onExtensionMessage); | |
392 } | |
393 }; | |
OLD | NEW |