OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 * Connect set-up state machine for Me2Me and IT2Me | 7 * Connect set-up state machine for Me2Me and IT2Me |
8 */ | 8 */ |
9 | 9 |
10 'use strict'; | 10 'use strict'; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 */ | 70 */ |
71 this.requiredCapabilities_ = requiredCapabilities; | 71 this.requiredCapabilities_ = requiredCapabilities; |
72 | 72 |
73 /** | 73 /** |
74 * @type {string} | 74 * @type {string} |
75 * @private | 75 * @private |
76 */ | 76 */ |
77 this.defaultRemapKeys_ = defaultRemapKeys; | 77 this.defaultRemapKeys_ = defaultRemapKeys; |
78 | 78 |
79 /** | 79 /** |
80 * @type {string} | |
81 * @private | |
82 */ | |
83 this.clientJid_ = ''; | |
84 | |
85 /** | |
86 * @type {remoting.DesktopConnectedView.Mode} | 80 * @type {remoting.DesktopConnectedView.Mode} |
87 * @private | 81 * @private |
88 */ | 82 */ |
89 this.connectionMode_ = remoting.DesktopConnectedView.Mode.ME2ME; | 83 this.connectionMode_ = remoting.DesktopConnectedView.Mode.ME2ME; |
90 | 84 |
91 /** | 85 /** |
92 * @type {remoting.SignalStrategy} | 86 * @type {remoting.SignalStrategy} |
93 * @private | 87 * @private |
94 */ | 88 */ |
95 this.signalStrategy_ = null; | 89 this.signalStrategy_ = null; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
128 */ | 122 */ |
129 this.logHostOfflineErrors_ = false; | 123 this.logHostOfflineErrors_ = false; |
130 | 124 |
131 /** | 125 /** |
132 * @type {remoting.ClientSession} | 126 * @type {remoting.ClientSession} |
133 * @private | 127 * @private |
134 */ | 128 */ |
135 this.clientSession_ = null; | 129 this.clientSession_ = null; |
136 | 130 |
137 /** | 131 /** |
138 * @type {XMLHttpRequest} | |
139 * @private | |
140 */ | |
141 this.pendingXhr_ = null; | |
142 | |
143 /** | |
144 * @type {remoting.CredentialsProvider} | 132 * @type {remoting.CredentialsProvider} |
145 * @private | 133 * @private |
146 */ | 134 */ |
147 this.credentialsProvider_ = null; | 135 this.credentialsProvider_ = null; |
148 }; | 136 }; |
149 | 137 |
150 /** | 138 /** |
151 * Initiate a Me2Me connection. | 139 * Initiate a Me2Me connection. |
152 * | 140 * |
153 * This doesn't report host-offline errors because the connection will | 141 * This doesn't report host-offline errors because the connection will |
154 * be retried and retryConnectMe2Me is responsible for reporting these errors. | 142 * be retried and retryConnectMe2Me is responsible for reporting these errors. |
155 * | 143 * |
156 * @param {remoting.Host} host The Me2Me host to which to connect. | 144 * @param {remoting.Host} host The Me2Me host to which to connect. |
157 * @param {function(boolean, function(string):void):void} fetchPin Function to | 145 * @param {function(boolean, function(string):void):void} fetchPin Function to |
158 * interactively obtain the PIN from the user. | 146 * interactively obtain the PIN from the user. |
159 * @param {string} clientPairingId The client id issued by the host when | 147 * @param {string} clientPairingId The client id issued by the host when |
160 * this device was paired, if it is already paired. | 148 * this device was paired, if it is already paired. |
161 * @param {string} clientPairedSecret The shared secret issued by the host when | 149 * @param {string} clientPairedSecret The shared secret issued by the host when |
162 * this device was paired, if it is already paired. | 150 * this device was paired, if it is already paired. |
163 * @return {void} Nothing. | 151 * @return {void} Nothing. |
164 */ | 152 */ |
165 remoting.SessionConnectorImpl.prototype.connectMe2Me = | 153 remoting.SessionConnectorImpl.prototype.connectMe2Me = |
166 function(host, fetchPin, fetchThirdPartyToken, | 154 function(host, fetchPin, fetchThirdPartyToken, |
167 clientPairingId, clientPairedSecret) { | 155 clientPairingId, clientPairedSecret) { |
168 this.connectionMode_ = remoting.DesktopConnectedView.Mode.ME2ME; | |
169 this.logHostOfflineErrors_ = false; | 156 this.logHostOfflineErrors_ = false; |
170 var credentialsProvider = new remoting.CredentialsProvider({ | 157 var credentialsProvider = new remoting.CredentialsProvider({ |
171 fetchPin: fetchPin, | 158 fetchPin: fetchPin, |
172 pairingInfo: { id: clientPairingId, secret: clientPairedSecret }, | 159 pairingInfo: { id: clientPairingId, secret: clientPairedSecret }, |
173 fetchThirdPartyToken: fetchThirdPartyToken | 160 fetchThirdPartyToken: fetchThirdPartyToken |
174 }); | 161 }); |
175 this.connectInternal_(host, credentialsProvider); | 162 this.connect( |
163 remoting.DesktopConnectedView.Mode.ME2ME, host, credentialsProvider); | |
176 }; | 164 }; |
177 | 165 |
178 /** | 166 /** |
179 * Retry connecting to a Me2Me host after a connection failure. | 167 * Retry connecting to a Me2Me host after a connection failure. |
180 * | 168 * |
181 * This is the same as connectMe2Me except that is will log errors if the | 169 * This is the same as connectMe2Me except that is will log errors if the |
182 * host is offline. | 170 * host is offline. |
183 * | 171 * |
184 * @param {remoting.Host} host The Me2Me host to refresh. | 172 * @param {remoting.Host} host The Me2Me host to refresh. |
185 * @return {void} Nothing. | 173 * @return {void} Nothing. |
186 */ | 174 */ |
187 remoting.SessionConnectorImpl.prototype.retryConnectMe2Me = function(host) { | 175 remoting.SessionConnectorImpl.prototype.retryConnectMe2Me = function(host) { |
188 this.connectionMode_ = remoting.DesktopConnectedView.Mode.ME2ME; | |
189 this.logHostOfflineErrors_ = true; | 176 this.logHostOfflineErrors_ = true; |
190 this.connectInternal_(host, this.credentialsProvider_); | 177 this.connect(remoting.DesktopConnectedView.Mode.ME2ME, host, |
178 this.credentialsProvider_); | |
191 }; | 179 }; |
192 | 180 |
193 /** | 181 /** |
194 * Initiate a Me2App connection. | 182 * Initiate a Me2App connection. |
195 * | 183 * |
196 * @param {remoting.Host} host The Me2Me host to which to connect. | 184 * @param {remoting.Host} host The Me2Me host to which to connect. |
197 * @param {function(string, string, string, | 185 * @param {function(string, string, string, |
198 * function(string, string): void): void} | 186 * function(string, string): void): void} |
199 * fetchThirdPartyToken Function to obtain a token from a third party | 187 * fetchThirdPartyToken Function to obtain a token from a third party |
200 * authenticaiton server. | 188 * authenticaiton server. |
201 * @return {void} Nothing. | 189 * @return {void} Nothing. |
202 */ | 190 */ |
203 remoting.SessionConnectorImpl.prototype.connectMe2App = | 191 remoting.SessionConnectorImpl.prototype.connectMe2App = |
204 function(host, fetchThirdPartyToken) { | 192 function(host, fetchThirdPartyToken) { |
205 this.connectionMode_ = remoting.DesktopConnectedView.Mode.APP_REMOTING; | |
206 this.logHostOfflineErrors_ = true; | 193 this.logHostOfflineErrors_ = true; |
207 var credentialsProvider = new remoting.CredentialsProvider({ | 194 var credentialsProvider = new remoting.CredentialsProvider({ |
208 fetchThirdPartyToken : fetchThirdPartyToken | 195 fetchThirdPartyToken : fetchThirdPartyToken |
209 }); | 196 }); |
210 this.connectInternal_(host, credentialsProvider); | 197 this.connect( |
198 remoting.DesktopConnectedView.Mode.APP_REMOTING, host, | |
199 credentialsProvider); | |
211 }; | 200 }; |
212 | 201 |
213 /** | 202 /** |
214 * Update the pairing info so that the reconnect function will work correctly. | 203 * Update the pairing info so that the reconnect function will work correctly. |
215 * | 204 * |
216 * @param {string} clientId The paired client id. | 205 * @param {string} clientId The paired client id. |
217 * @param {string} sharedSecret The shared secret. | 206 * @param {string} sharedSecret The shared secret. |
218 */ | 207 */ |
219 remoting.SessionConnectorImpl.prototype.updatePairingInfo = | 208 remoting.SessionConnectorImpl.prototype.updatePairingInfo = |
220 function(clientId, sharedSecret) { | 209 function(clientId, sharedSecret) { |
221 var pairingInfo = this.credentialsProvider_.getPairingInfo(); | 210 var pairingInfo = this.credentialsProvider_.getPairingInfo(); |
222 pairingInfo.id = clientId; | 211 pairingInfo.id = clientId; |
223 pairingInfo.secret = sharedSecret; | 212 pairingInfo.secret = sharedSecret; |
224 }; | 213 }; |
225 | 214 |
226 /** | 215 /** |
227 * Initiates a connection. | 216 * Initiates a connection. |
228 * | 217 * |
218 * @param {remoting.DesktopConnectedView.Mode} mode | |
229 * @param {remoting.Host} host the Host to connect to. | 219 * @param {remoting.Host} host the Host to connect to. |
230 * @param {remoting.CredentialsProvider} credentialsProvider | 220 * @param {remoting.CredentialsProvider} credentialsProvider |
231 * @return {void} Nothing. | 221 * @return {void} Nothing. |
232 * @private | 222 * @private |
233 */ | 223 */ |
234 remoting.SessionConnectorImpl.prototype.connectInternal_ = | 224 remoting.SessionConnectorImpl.prototype.connect = |
235 function(host, credentialsProvider) { | 225 function(mode, host, credentialsProvider) { |
236 // Cancel any existing connect operation. | 226 // Cancel any existing connect operation. |
237 this.cancel(); | 227 this.cancel(); |
238 | 228 this.connectionMode_ = mode; |
239 this.host_ = host; | 229 this.host_ = host; |
240 this.credentialsProvider_ = credentialsProvider; | 230 this.credentialsProvider_ = credentialsProvider; |
241 this.connectSignaling_(); | 231 this.connectSignaling_(); |
242 }; | 232 }; |
243 | 233 |
244 /** | 234 /** |
245 * Initiate an IT2Me connection. | |
246 * | |
247 * @param {string} accessCode The access code as entered by the user. | |
248 * @return {void} Nothing. | |
249 */ | |
250 remoting.SessionConnectorImpl.prototype.connectIT2Me = function(accessCode) { | |
kelvinp
2015/03/06 01:58:20
Moved to It2MeConnectFlow()
| |
251 var kSupportIdLen = 7; | |
252 var kHostSecretLen = 5; | |
253 var kAccessCodeLen = kSupportIdLen + kHostSecretLen; | |
254 | |
255 // Cancel any existing connect operation. | |
256 this.cancel(); | |
257 | |
258 var normalizedAccessCode = this.normalizeAccessCode_(accessCode); | |
259 if (normalizedAccessCode.length != kAccessCodeLen) { | |
260 this.onError_(remoting.Error.INVALID_ACCESS_CODE); | |
261 return; | |
262 } | |
263 var hostId = normalizedAccessCode.substring(0, kSupportIdLen); | |
264 this.credentialsProvider_ = new remoting.CredentialsProvider({ | |
265 accessCode: normalizedAccessCode | |
266 }); | |
267 this.connectionMode_ = remoting.DesktopConnectedView.Mode.IT2ME; | |
268 remoting.identity.getToken().then( | |
269 this.connectIT2MeWithToken_.bind(this, hostId), | |
270 remoting.Error.handler(this.onError_)); | |
271 }; | |
272 | |
273 /** | |
274 * Reconnect a closed connection. | 235 * Reconnect a closed connection. |
275 * | 236 * |
276 * @return {void} Nothing. | 237 * @return {void} Nothing. |
277 */ | 238 */ |
278 remoting.SessionConnectorImpl.prototype.reconnect = function() { | 239 remoting.SessionConnectorImpl.prototype.reconnect = function() { |
279 if (this.connectionMode_ == remoting.DesktopConnectedView.Mode.IT2ME) { | 240 if (this.connectionMode_ == remoting.DesktopConnectedView.Mode.IT2ME) { |
280 console.error('reconnect not supported for IT2Me.'); | 241 console.error('reconnect not supported for IT2Me.'); |
281 return; | 242 return; |
282 } | 243 } |
283 this.logHostOfflineErrors_ = false; | 244 this.logHostOfflineErrors_ = false; |
284 this.connectInternal_(this.host_, this.credentialsProvider_); | 245 this.connect(this.connectionMode_, this.host_, this.credentialsProvider_); |
285 }; | 246 }; |
286 | 247 |
287 /** | 248 /** |
288 * Cancel a connection-in-progress. | 249 * Cancel a connection-in-progress. |
289 */ | 250 */ |
290 remoting.SessionConnectorImpl.prototype.cancel = function() { | 251 remoting.SessionConnectorImpl.prototype.cancel = function() { |
291 if (this.clientSession_) { | 252 if (this.clientSession_) { |
292 this.clientSession_.removePlugin(); | 253 this.clientSession_.removePlugin(); |
293 this.clientSession_ = null; | 254 this.clientSession_ = null; |
294 } | 255 } |
295 if (this.pendingXhr_) { | |
296 this.pendingXhr_.abort(); | |
297 this.pendingXhr_ = null; | |
298 } | |
299 this.reset(); | 256 this.reset(); |
300 }; | 257 }; |
301 | 258 |
302 /** | 259 /** |
303 * Get the connection mode (Me2Me or IT2Me) | 260 * Get the connection mode (Me2Me or IT2Me) |
304 * | 261 * |
305 * @return {remoting.DesktopConnectedView.Mode} | 262 * @return {remoting.DesktopConnectedView.Mode} |
306 */ | 263 */ |
307 remoting.SessionConnectorImpl.prototype.getConnectionMode = function() { | 264 remoting.SessionConnectorImpl.prototype.getConnectionMode = function() { |
308 return this.connectionMode_; | 265 return this.connectionMode_; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
370 } | 327 } |
371 break; | 328 break; |
372 | 329 |
373 case remoting.SignalStrategy.State.FAILED: | 330 case remoting.SignalStrategy.State.FAILED: |
374 this.onError_(this.signalStrategy_.getError()); | 331 this.onError_(this.signalStrategy_.getError()); |
375 break; | 332 break; |
376 } | 333 } |
377 }; | 334 }; |
378 | 335 |
379 /** | 336 /** |
380 * Continue an IT2Me connection once an access token has been obtained. | |
381 * | |
382 * @param {string} hostId | |
383 * @param {string} token An OAuth2 access token. | |
384 * @return {void} Nothing. | |
385 * @private | |
386 */ | |
387 remoting.SessionConnectorImpl.prototype.connectIT2MeWithToken_ = | |
kelvinp
2015/03/06 01:58:20
Moved to It2MeConnectFlow()
| |
388 function(hostId, token) { | |
389 // Resolve the host id to get the host JID. | |
390 this.pendingXhr_ = remoting.xhr.start({ | |
391 method: 'GET', | |
392 url: remoting.settings.DIRECTORY_API_BASE_URL + '/support-hosts/' + | |
393 encodeURIComponent(hostId), | |
394 onDone: this.onIT2MeHostInfo_.bind(this, hostId), | |
395 oauthToken: token | |
396 }); | |
397 }; | |
398 | |
399 /** | |
400 * Continue an IT2Me connection once the host JID has been looked up. | |
401 * | |
402 * @param {string} hostId | |
403 * @param {XMLHttpRequest} xhr The server response to the support-hosts query. | |
404 * @return {void} Nothing. | |
405 * @private | |
406 */ | |
407 remoting.SessionConnectorImpl.prototype.onIT2MeHostInfo_ = | |
kelvinp
2015/03/06 01:58:19
Moved to It2MeConnectFlow()
| |
408 function(hostId, xhr) { | |
409 this.pendingXhr_ = null; | |
410 if (xhr.status == 200) { | |
411 var host = /** @type {{data: {jabberId: string, publicKey: string}}} */ | |
412 (base.jsonParseSafe(xhr.responseText)); | |
413 if (host && host.data && host.data.jabberId && host.data.publicKey) { | |
414 this.host_ = new remoting.Host(); | |
415 this.host_.hostId = hostId; | |
416 this.host_.jabberId = host.data.jabberId; | |
417 this.host_.publicKey = host.data.publicKey; | |
418 this.host_.hostName = host.data.jabberId.split('/')[0]; | |
419 this.connectSignaling_(); | |
420 return; | |
421 } else { | |
422 console.error('Invalid "support-hosts" response from server.'); | |
423 } | |
424 } else { | |
425 this.onError_(this.translateSupportHostsError_(xhr.status)); | |
426 } | |
427 }; | |
428 | |
429 /** | |
430 * Creates ClientSession object. | 337 * Creates ClientSession object. |
431 */ | 338 */ |
432 remoting.SessionConnectorImpl.prototype.createSession_ = function() { | 339 remoting.SessionConnectorImpl.prototype.createSession_ = function() { |
433 // In some circumstances, the WCS <iframe> can get reloaded, which results | 340 // In some circumstances, the WCS <iframe> can get reloaded, which results |
434 // in a new clientJid and a new callback. In this case, remove the old | 341 // in a new clientJid and a new callback. In this case, remove the old |
435 // client plugin before instantiating a new one. | 342 // client plugin before instantiating a new one. |
436 if (this.clientSession_) { | 343 if (this.clientSession_) { |
437 this.clientSession_.removePlugin(); | 344 this.clientSession_.removePlugin(); |
438 this.clientSession_ = null; | 345 this.clientSession_ = null; |
439 } | 346 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
515 | 422 |
516 default: | 423 default: |
517 console.error('Unexpected client plugin state: ' + event.current); | 424 console.error('Unexpected client plugin state: ' + event.current); |
518 // This should only happen if the web-app and client plugin get out of | 425 // This should only happen if the web-app and client plugin get out of |
519 // sync, and even then the version check should ensure compatibility. | 426 // sync, and even then the version check should ensure compatibility. |
520 this.onError_(remoting.Error.MISSING_PLUGIN); | 427 this.onError_(remoting.Error.MISSING_PLUGIN); |
521 } | 428 } |
522 }; | 429 }; |
523 | 430 |
524 /** | 431 /** |
525 * @param {number} error An HTTP error code returned by the support-hosts | |
526 * endpoint. | |
527 * @return {remoting.Error} The equivalent remoting.Error code. | |
528 * @private | |
529 */ | |
530 remoting.SessionConnectorImpl.prototype.translateSupportHostsError_ = | |
kelvinp
2015/03/06 01:58:20
Moved to It2MeConnectFlow()
| |
531 function(error) { | |
532 switch (error) { | |
533 case 0: return remoting.Error.NETWORK_FAILURE; | |
534 case 404: return remoting.Error.INVALID_ACCESS_CODE; | |
535 case 502: // No break | |
536 case 503: return remoting.Error.SERVICE_UNAVAILABLE; | |
537 default: return remoting.Error.UNEXPECTED; | |
538 } | |
539 }; | |
540 | |
541 /** | |
542 * Normalize the access code entered by the user. | |
543 * | |
544 * @param {string} accessCode The access code, as entered by the user. | |
545 * @return {string} The normalized form of the code (whitespace removed). | |
546 * @private | |
547 */ | |
548 remoting.SessionConnectorImpl.prototype.normalizeAccessCode_ = | |
549 function(accessCode) { | |
550 // Trim whitespace. | |
551 return accessCode.replace(/\s/g, ''); | |
552 }; | |
553 | |
554 | |
555 /** | |
556 * @constructor | 432 * @constructor |
557 * @implements {remoting.SessionConnectorFactory} | 433 * @implements {remoting.SessionConnectorFactory} |
558 */ | 434 */ |
559 remoting.DefaultSessionConnectorFactory = function() { | 435 remoting.DefaultSessionConnectorFactory = function() {}; |
560 }; | |
561 | 436 |
562 /** | 437 /** |
563 * @param {HTMLElement} clientContainer Container element for the client view. | 438 * @param {HTMLElement} clientContainer Container element for the client view. |
564 * @param {function(remoting.ClientSession):void} onConnected Callback on | 439 * @param {function(remoting.ClientSession):void} onConnected Callback on |
565 * success. | 440 * success. |
566 * @param {function(remoting.Error):void} onError Callback on error. | 441 * @param {function(remoting.Error):void} onError Callback on error. |
567 * @param {function(string, string):boolean} onExtensionMessage The handler for | 442 * @param {function(string, string):boolean} onExtensionMessage The handler for |
568 * protocol extension messages. Returns true if a message is recognized; | 443 * protocol extension messages. Returns true if a message is recognized; |
569 * false otherwise. | 444 * false otherwise. |
570 * @param {function(remoting.Error):void} onConnectionFailed Callback for when | 445 * @param {function(remoting.Error):void} onConnectionFailed Callback for when |
571 * the connection fails. | 446 * the connection fails. |
572 * @param {Array<string>} requiredCapabilities Connector capabilities | 447 * @param {Array<string>} requiredCapabilities Connector capabilities |
573 * required by this application. | 448 * required by this application. |
574 * @param {string} defaultRemapKeys The default set of key mappings to use | 449 * @param {string} defaultRemapKeys The default set of key mappings to use |
575 * in the client session. | 450 * in the client session. |
576 * @return {remoting.SessionConnector} | 451 * @return {remoting.SessionConnector} |
577 */ | 452 */ |
578 remoting.DefaultSessionConnectorFactory.prototype.createConnector = | 453 remoting.DefaultSessionConnectorFactory.prototype.createConnector = |
579 function(clientContainer, onConnected, onError, onExtensionMessage, | 454 function(clientContainer, onConnected, onError, onExtensionMessage, |
580 onConnectionFailed, requiredCapabilities, defaultRemapKeys) { | 455 onConnectionFailed, requiredCapabilities, defaultRemapKeys) { |
581 return new remoting.SessionConnectorImpl(clientContainer, onConnected, | 456 return new remoting.SessionConnectorImpl(clientContainer, onConnected, |
582 onError, onExtensionMessage, | 457 onError, onExtensionMessage, |
583 onConnectionFailed, | 458 onConnectionFailed, |
584 requiredCapabilities, | 459 requiredCapabilities, |
585 defaultRemapKeys); | 460 defaultRemapKeys); |
586 }; | 461 }; |
OLD | NEW |