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 * Class handling creation and teardown of a remoting client session. | 7 * Class handling creation and teardown of a remoting client session. |
8 * | 8 * |
9 * The ClientSession class controls lifetime of the client plugin | 9 * The ClientSession class controls lifetime of the client plugin |
10 * object and provides the plugin with the functionality it needs to | 10 * object and provides the plugin with the functionality it needs to |
(...skipping 18 matching lines...) Expand all Loading... | |
29 * @const | 29 * @const |
30 * @type {number} | 30 * @type {number} |
31 */ | 31 */ |
32 remoting.ACCESS_TOKEN_RESEND_INTERVAL_MS = 15 * 60 * 1000; | 32 remoting.ACCESS_TOKEN_RESEND_INTERVAL_MS = 15 * 60 * 1000; |
33 | 33 |
34 /** | 34 /** |
35 * @param {remoting.Host} host The host to connect to. | 35 * @param {remoting.Host} host The host to connect to. |
36 * @param {remoting.SignalStrategy} signalStrategy Signal strategy. | 36 * @param {remoting.SignalStrategy} signalStrategy Signal strategy. |
37 * @param {remoting.CredentialsProvider} credentialsProvider | 37 * @param {remoting.CredentialsProvider} credentialsProvider |
38 * The credentialsProvider to authenticate the client with the host. | 38 * The credentialsProvider to authenticate the client with the host. |
39 * @param {HTMLElement} container Container element for the client view. | |
40 * @param {remoting.DesktopConnectedView.Mode} mode The mode of this connection. | 39 * @param {remoting.DesktopConnectedView.Mode} mode The mode of this connection. |
41 * @param {string} defaultRemapKeys The default set of remap keys, to use | |
42 * when the client doesn't define any. | |
43 * @constructor | 40 * @constructor |
44 * @extends {base.EventSourceImpl} | 41 * @extends {base.EventSourceImpl} |
45 * @implements {base.Disposable} | 42 * @implements {base.Disposable} |
46 */ | 43 */ |
47 remoting.ClientSession = function(host, signalStrategy, credentialsProvider, | 44 remoting.ClientSession = function(host, signalStrategy, credentialsProvider, |
kelvinp
2015/03/06 02:58:37
I think we should create the clientSession only af
| |
48 container, mode, defaultRemapKeys) { | 45 mode) { |
49 /** @private */ | 46 /** @private */ |
50 this.state_ = remoting.ClientSession.State.CREATED; | 47 this.state_ = remoting.ClientSession.State.CREATED; |
51 | 48 |
52 /** @private */ | 49 /** @private */ |
53 this.error_ = remoting.Error.NONE; | 50 this.error_ = remoting.Error.NONE; |
54 | 51 |
55 /** @private */ | 52 /** @private */ |
56 this.host_ = host; | 53 this.host_ = host; |
57 | 54 |
58 /** @private */ | 55 /** @private */ |
59 this.credentialsProvider_ = credentialsProvider; | 56 this.credentialsProvider_ = credentialsProvider; |
60 | 57 |
61 /** @private */ | 58 /** @private */ |
62 this.uiHandler_ = new remoting.DesktopConnectedView( | |
63 this, container, this.host_, mode, defaultRemapKeys, | |
64 this.onPluginInitialized_.bind(this)); | |
65 remoting.desktopConnectedView = this.uiHandler_; | |
66 | |
67 /** @private */ | |
68 this.sessionId_ = ''; | 59 this.sessionId_ = ''; |
69 /** @type {remoting.ClientPlugin} | 60 /** @type {remoting.ClientPlugin} |
70 * @private */ | 61 * @private */ |
71 this.plugin_ = null; | 62 this.plugin_ = null; |
72 /** @private */ | 63 /** @private */ |
73 this.hasReceivedFrame_ = false; | 64 this.hasReceivedFrame_ = false; |
74 this.logToServer = new remoting.LogToServer(signalStrategy, mode); | 65 this.logToServer = new remoting.LogToServer(signalStrategy, mode); |
75 | 66 |
76 /** @private */ | 67 /** @private */ |
77 this.signalStrategy_ = signalStrategy; | 68 this.signalStrategy_ = signalStrategy; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
243 * the client and host. | 234 * the client and host. |
244 */ | 235 */ |
245 remoting.ClientSession.prototype.hasCapability = function(capability) { | 236 remoting.ClientSession.prototype.hasCapability = function(capability) { |
246 if (this.capabilities_ == null) | 237 if (this.capabilities_ == null) |
247 return false; | 238 return false; |
248 | 239 |
249 return this.capabilities_.indexOf(capability) > -1; | 240 return this.capabilities_.indexOf(capability) > -1; |
250 }; | 241 }; |
251 | 242 |
252 /** | 243 /** |
253 * Adds <embed> element to the UI container and readies the session object. | |
254 * | |
255 * @param {function(string, string):boolean} onExtensionMessage The handler for | |
256 * protocol extension messages. Returns true if a message is recognized; | |
257 * false otherwise. | |
258 * @param {Array<string>} requiredCapabilities A list of capabilities | |
259 * required by this application. | |
260 */ | |
261 remoting.ClientSession.prototype.createPluginAndConnect = | |
262 function(onExtensionMessage, requiredCapabilities) { | |
263 this.uiHandler_.createPluginAndConnect(onExtensionMessage, | |
264 requiredCapabilities); | |
265 }; | |
266 | |
267 /** | |
268 * @param {remoting.Error} error | |
269 * @param {remoting.ClientPlugin} plugin | 244 * @param {remoting.ClientPlugin} plugin |
270 */ | 245 */ |
271 remoting.ClientSession.prototype.onPluginInitialized_ = function( | 246 remoting.ClientSession.prototype.onPluginInitialized = function(plugin) { |
272 error, plugin) { | |
273 if (error != remoting.Error.NONE) { | |
274 this.resetWithError_(error); | |
275 } | |
276 | |
277 this.plugin_ = plugin; | 247 this.plugin_ = plugin; |
278 plugin.setOnOutgoingIqHandler(this.sendIq_.bind(this)); | 248 plugin.setOnOutgoingIqHandler(this.sendIq_.bind(this)); |
279 plugin.setOnDebugMessageHandler(this.onDebugMessage_.bind(this)); | 249 plugin.setOnDebugMessageHandler(this.onDebugMessage_.bind(this)); |
280 | 250 |
281 plugin.setConnectionStatusUpdateHandler( | 251 plugin.setConnectionStatusUpdateHandler( |
282 this.onConnectionStatusUpdate_.bind(this)); | 252 this.onConnectionStatusUpdate_.bind(this)); |
283 plugin.setRouteChangedHandler(this.onRouteChanged_.bind(this)); | 253 plugin.setRouteChangedHandler(this.onRouteChanged_.bind(this)); |
284 plugin.setConnectionReadyHandler(this.onConnectionReady_.bind(this)); | 254 plugin.setConnectionReadyHandler(this.onConnectionReady_.bind(this)); |
285 plugin.setCapabilitiesHandler(this.onSetCapabilities_.bind(this)); | 255 plugin.setCapabilitiesHandler(this.onSetCapabilities_.bind(this)); |
286 plugin.setGnubbyAuthHandler( | 256 plugin.setGnubbyAuthHandler( |
287 this.processGnubbyAuthMessage_.bind(this)); | 257 this.processGnubbyAuthMessage_.bind(this)); |
288 plugin.setCastExtensionHandler( | 258 plugin.setCastExtensionHandler( |
289 this.processCastExtensionMessage_.bind(this)); | 259 this.processCastExtensionMessage_.bind(this)); |
290 | 260 |
291 this.plugin_.connect( | 261 this.plugin_.connect( |
292 this.host_, this.signalStrategy_.getJid(), this.credentialsProvider_); | 262 this.host_, this.signalStrategy_.getJid(), this.credentialsProvider_); |
293 }; | 263 }; |
294 | 264 |
295 /** | 265 /** |
296 * @param {remoting.Error} error | |
297 */ | |
298 remoting.ClientSession.prototype.resetWithError_ = function(error) { | |
299 this.signalStrategy_.setIncomingStanzaCallback(null); | |
300 this.removePlugin(); | |
301 this.error_ = error; | |
302 this.setState_(remoting.ClientSession.State.FAILED); | |
303 }; | |
304 | |
305 /** | |
306 * Deletes the <embed> element from the container, without sending a | 266 * Deletes the <embed> element from the container, without sending a |
kelvinp
2015/03/06 02:58:37
This comment needs to be updated.
garykac
2015/03/06 23:38:33
Done.
| |
307 * session_terminate request. This is to be called when the session was | 267 * session_terminate request. This is to be called when the session was |
308 * disconnected by the Host. | 268 * disconnected by the Host. |
309 * | 269 * |
310 * @return {void} Nothing. | 270 * @return {void} Nothing. |
311 */ | 271 */ |
312 remoting.ClientSession.prototype.removePlugin = function() { | 272 remoting.ClientSession.prototype.removePlugin = function() { |
313 this.uiHandler_.removePlugin(); | |
kelvinp
2015/03/06 02:58:37
I think after all, it may still make sense for the
garykac
2015/03/06 23:38:33
ClientPlugin and ClientSession have similar lifeti
| |
314 this.plugin_ = null; | 273 this.plugin_ = null; |
315 remoting.desktopConnectedView = null; | |
316 }; | 274 }; |
317 | 275 |
318 /** | 276 /** |
319 * Disconnect the current session with a particular |error|. The session will | 277 * Disconnect the current session with a particular |error|. The session will |
320 * raise a |stateChanged| event in response to it. The caller should then call | 278 * raise a |stateChanged| event in response to it. The caller should then call |
321 * dispose() to remove and destroy the <embed> element. | 279 * dispose() to remove and destroy the <embed> element. |
322 * | 280 * |
323 * @param {remoting.Error} error The reason for the disconnection. Use | 281 * @param {remoting.Error} error The reason for the disconnection. Use |
324 * remoting.Error.NONE if there is no error. | 282 * remoting.Error.NONE if there is no error. |
325 * @return {void} Nothing. | 283 * @return {void} Nothing. |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
443 * Callback that the plugin invokes to indicate that the connection | 401 * Callback that the plugin invokes to indicate that the connection |
444 * status has changed. | 402 * status has changed. |
445 * | 403 * |
446 * @param {number} status The plugin's status. | 404 * @param {number} status The plugin's status. |
447 * @param {number} error The plugin's error state, if any. | 405 * @param {number} error The plugin's error state, if any. |
448 * @private | 406 * @private |
449 */ | 407 */ |
450 remoting.ClientSession.prototype.onConnectionStatusUpdate_ = | 408 remoting.ClientSession.prototype.onConnectionStatusUpdate_ = |
451 function(status, error) { | 409 function(status, error) { |
452 if (status == remoting.ClientSession.State.CONNECTED) { | 410 if (status == remoting.ClientSession.State.CONNECTED) { |
453 this.uiHandler_.updateClientSessionUi_(this); | 411 remoting.desktopConnectedView.updateClientSessionUi_(this); |
454 | 412 |
455 } else if (status == remoting.ClientSession.State.FAILED) { | 413 } else if (status == remoting.ClientSession.State.FAILED) { |
456 switch (error) { | 414 switch (error) { |
457 case remoting.ClientSession.ConnectionError.HOST_IS_OFFLINE: | 415 case remoting.ClientSession.ConnectionError.HOST_IS_OFFLINE: |
458 this.error_ = remoting.Error.HOST_IS_OFFLINE; | 416 this.error_ = remoting.Error.HOST_IS_OFFLINE; |
459 break; | 417 break; |
460 case remoting.ClientSession.ConnectionError.SESSION_REJECTED: | 418 case remoting.ClientSession.ConnectionError.SESSION_REJECTED: |
461 this.error_ = remoting.Error.INVALID_ACCESS_CODE; | 419 this.error_ = remoting.Error.INVALID_ACCESS_CODE; |
462 break; | 420 break; |
463 case remoting.ClientSession.ConnectionError.INCOMPATIBLE_PROTOCOL: | 421 case remoting.ClientSession.ConnectionError.INCOMPATIBLE_PROTOCOL: |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
502 // TODO(jamiewalch): Currently, the logic for determining whether or not the | 460 // TODO(jamiewalch): Currently, the logic for determining whether or not the |
503 // connection is available is based solely on whether or not any video frames | 461 // connection is available is based solely on whether or not any video frames |
504 // have been received recently. which leads to poor UX on slow connections. | 462 // have been received recently. which leads to poor UX on slow connections. |
505 // Re-enable this once crbug.com/435315 has been fixed. | 463 // Re-enable this once crbug.com/435315 has been fixed. |
506 var ignoreVideoChannelState = true; | 464 var ignoreVideoChannelState = true; |
507 if (ignoreVideoChannelState) { | 465 if (ignoreVideoChannelState) { |
508 console.log('Video channel ' + (ready ? '' : 'not ') + 'ready.'); | 466 console.log('Video channel ' + (ready ? '' : 'not ') + 'ready.'); |
509 return; | 467 return; |
510 } | 468 } |
511 | 469 |
512 this.uiHandler_.onConnectionReady(ready); | 470 remoting.desktopConnectedView.onConnectionReady(ready); |
513 | 471 |
514 this.raiseEvent(remoting.ClientSession.Events.videoChannelStateChanged, | 472 this.raiseEvent(remoting.ClientSession.Events.videoChannelStateChanged, |
515 ready); | 473 ready); |
516 }; | 474 }; |
517 | 475 |
518 /** | 476 /** |
519 * Called when the client-host capabilities negotiation is complete. | 477 * Called when the client-host capabilities negotiation is complete. |
520 * TODO(kelvinp): Move this function out of ClientSession. | 478 * TODO(kelvinp): Move this function out of ClientSession. |
521 * | 479 * |
522 * @param {!Array<string>} capabilities The set of capabilities negotiated | 480 * @param {!Array<string>} capabilities The set of capabilities negotiated |
523 * between the client and host. | 481 * between the client and host. |
524 * @return {void} Nothing. | 482 * @return {void} Nothing. |
525 * @private | 483 * @private |
526 */ | 484 */ |
527 remoting.ClientSession.prototype.onSetCapabilities_ = function(capabilities) { | 485 remoting.ClientSession.prototype.onSetCapabilities_ = function(capabilities) { |
528 if (this.capabilities_ != null) { | 486 if (this.capabilities_ != null) { |
529 console.error('onSetCapabilities_() is called more than once'); | 487 console.error('onSetCapabilities_() is called more than once'); |
530 return; | 488 return; |
531 } | 489 } |
532 | 490 |
533 this.capabilities_ = capabilities; | 491 this.capabilities_ = capabilities; |
534 if (this.hasCapability(remoting.ClientSession.Capability.GOOGLE_DRIVE)) { | 492 if (this.hasCapability(remoting.ClientSession.Capability.GOOGLE_DRIVE)) { |
535 this.sendGoogleDriveAccessToken_(); | 493 this.sendGoogleDriveAccessToken_(); |
536 } | 494 } |
537 if (this.hasCapability( | 495 if (this.hasCapability( |
538 remoting.ClientSession.Capability.VIDEO_RECORDER)) { | 496 remoting.ClientSession.Capability.VIDEO_RECORDER)) { |
539 this.uiHandler_.initVideoFrameRecorder(); | 497 remoting.desktopConnectedView.initVideoFrameRecorder(); |
540 } | 498 } |
541 }; | 499 }; |
542 | 500 |
543 /** | 501 /** |
544 * @param {remoting.ClientSession.State} newState The new state for the session. | 502 * @param {remoting.ClientSession.State} newState The new state for the session. |
545 * @return {void} Nothing. | 503 * @return {void} Nothing. |
546 * @private | 504 * @private |
547 */ | 505 */ |
548 remoting.ClientSession.prototype.setState_ = function(newState) { | 506 remoting.ClientSession.prototype.setState_ = function(newState) { |
549 var oldState = this.state_; | 507 var oldState = this.state_; |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
668 console.error('Received unexpected gnubby message'); | 626 console.error('Received unexpected gnubby message'); |
669 } | 627 } |
670 }; | 628 }; |
671 | 629 |
672 /** | 630 /** |
673 * Create a gnubby auth handler and inform the host that gnubby auth is | 631 * Create a gnubby auth handler and inform the host that gnubby auth is |
674 * supported. | 632 * supported. |
675 * @private | 633 * @private |
676 */ | 634 */ |
677 remoting.ClientSession.prototype.createGnubbyAuthHandler_ = function() { | 635 remoting.ClientSession.prototype.createGnubbyAuthHandler_ = function() { |
678 if (this.uiHandler_.getMode() == remoting.DesktopConnectedView.Mode.ME2ME) { | 636 if (remoting.desktopConnectedView.getMode() == |
637 remoting.DesktopConnectedView.Mode.ME2ME) { | |
679 this.gnubbyAuthHandler_ = new remoting.GnubbyAuthHandler(this); | 638 this.gnubbyAuthHandler_ = new remoting.GnubbyAuthHandler(this); |
680 // TODO(psj): Move to more generic capabilities mechanism. | 639 // TODO(psj): Move to more generic capabilities mechanism. |
681 this.sendGnubbyAuthMessage({'type': 'control', 'option': 'auth-v1'}); | 640 this.sendGnubbyAuthMessage({'type': 'control', 'option': 'auth-v1'}); |
682 } | 641 } |
683 }; | 642 }; |
684 | 643 |
685 /** | 644 /** |
686 * Timer callback to send the access token to the host. | 645 * Timer callback to send the access token to the host. |
687 * @private | 646 * @private |
688 */ | 647 */ |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
735 } | 694 } |
736 }; | 695 }; |
737 | 696 |
738 /** | 697 /** |
739 * Create a CastExtensionHandler and inform the host that cast extension | 698 * Create a CastExtensionHandler and inform the host that cast extension |
740 * is supported. | 699 * is supported. |
741 * @private | 700 * @private |
742 */ | 701 */ |
743 remoting.ClientSession.prototype.createCastExtensionHandler_ = function() { | 702 remoting.ClientSession.prototype.createCastExtensionHandler_ = function() { |
744 if (remoting.app.hasCapability(remoting.ClientSession.Capability.CAST) && | 703 if (remoting.app.hasCapability(remoting.ClientSession.Capability.CAST) && |
745 this.uiHandler_.getMode() == remoting.DesktopConnectedView.Mode.ME2ME) { | 704 remoting.desktopConnectedView.getMode() == |
705 remoting.DesktopConnectedView.Mode.ME2ME) { | |
746 this.castExtensionHandler_ = new remoting.CastExtensionHandler(this); | 706 this.castExtensionHandler_ = new remoting.CastExtensionHandler(this); |
747 } | 707 } |
748 }; | 708 }; |
749 | 709 |
750 /** | 710 /** |
751 * Handles protocol extension messages. | 711 * Handles protocol extension messages. |
752 * @param {string} type Type of extension message. | 712 * @param {string} type Type of extension message. |
753 * @param {Object} message The parsed extension message data. | 713 * @param {Object} message The parsed extension message data. |
754 * @return {boolean} True if the message was recognized, false otherwise. | 714 * @return {boolean} True if the message was recognized, false otherwise. |
755 */ | 715 */ |
756 remoting.ClientSession.prototype.handleExtensionMessage = | 716 remoting.ClientSession.prototype.handleExtensionMessage = |
757 function(type, message) { | 717 function(type, message) { |
758 if (this.uiHandler_.handleExtensionMessage(type, message)) { | 718 if (remoting.desktopConnectedView.handleExtensionMessage(type, message)) { |
759 return true; | 719 return true; |
760 } | 720 } |
761 return false; | 721 return false; |
762 }; | 722 }; |
763 | 723 |
764 /** | 724 /** |
765 * Enables or disables rendering of dirty regions for debugging. | 725 * Enables or disables rendering of dirty regions for debugging. |
766 * @param {boolean} enable True to enable rendering. | 726 * @param {boolean} enable True to enable rendering. |
767 */ | 727 */ |
768 remoting.ClientSession.prototype.enableDebugRegion = function(enable) { | 728 remoting.ClientSession.prototype.enableDebugRegion = function(enable) { |
769 if (enable) { | 729 if (enable) { |
770 this.plugin_.setDebugDirtyRegionHandler( | 730 this.plugin_.setDebugDirtyRegionHandler( |
771 this.uiHandler_.handleDebugRegion.bind(this.uiHandler_)); | 731 remoting.desktopConnectedView.handleDebugRegion.bind( |
732 remoting.desktopConnectedView)); | |
772 } else { | 733 } else { |
773 this.plugin_.setDebugDirtyRegionHandler(null); | 734 this.plugin_.setDebugDirtyRegionHandler(null); |
774 } | 735 } |
775 } | 736 } |
OLD | NEW |