Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(566)

Side by Side Diff: remoting/webapp/client_session.js

Issue 530213004: Use XMPP in V2 webapp (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « remoting/remoting_webapp_files.gypi ('k') | remoting/webapp/session_connector.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 12 matching lines...) Expand all
23 var remoting = remoting || {}; 23 var remoting = remoting || {};
24 24
25 /** 25 /**
26 * True if Cast capability is supported. 26 * True if Cast capability is supported.
27 * 27 *
28 * @type {boolean} 28 * @type {boolean}
29 */ 29 */
30 remoting.enableCast = false; 30 remoting.enableCast = false;
31 31
32 /** 32 /**
33 * @param {remoting.SignalStrategy} signalStrategy Signal strategy.
33 * @param {HTMLElement} container Container element for the client view. 34 * @param {HTMLElement} container Container element for the client view.
34 * @param {string} hostDisplayName A human-readable name for the host. 35 * @param {string} hostDisplayName A human-readable name for the host.
35 * @param {string} accessCode The IT2Me access code. Blank for Me2Me. 36 * @param {string} accessCode The IT2Me access code. Blank for Me2Me.
36 * @param {function(boolean, function(string): void): void} fetchPin 37 * @param {function(boolean, function(string): void): void} fetchPin
37 * Called by Me2Me connections when a PIN needs to be obtained 38 * Called by Me2Me connections when a PIN needs to be obtained
38 * interactively. 39 * interactively.
39 * @param {function(string, string, string, 40 * @param {function(string, string, string,
40 * function(string, string): void): void} 41 * function(string, string): void): void}
41 * fetchThirdPartyToken Called by Me2Me connections when a third party 42 * fetchThirdPartyToken Called by Me2Me connections when a third party
42 * authentication token must be obtained. 43 * authentication token must be obtained.
43 * @param {string} authenticationMethods Comma-separated list of 44 * @param {string} authenticationMethods Comma-separated list of
44 * authentication methods the client should attempt to use. 45 * authentication methods the client should attempt to use.
45 * @param {string} hostId The host identifier for Me2Me, or empty for IT2Me. 46 * @param {string} hostId The host identifier for Me2Me, or empty for IT2Me.
46 * Mixed into authentication hashes for some authentication methods. 47 * Mixed into authentication hashes for some authentication methods.
47 * @param {string} hostJid The jid of the host to connect to. 48 * @param {string} hostJid The jid of the host to connect to.
48 * @param {string} hostPublicKey The base64 encoded version of the host's 49 * @param {string} hostPublicKey The base64 encoded version of the host's
49 * public key. 50 * public key.
50 * @param {remoting.ClientSession.Mode} mode The mode of this connection. 51 * @param {remoting.ClientSession.Mode} mode The mode of this connection.
51 * @param {string} clientPairingId For paired Me2Me connections, the 52 * @param {string} clientPairingId For paired Me2Me connections, the
52 * pairing id for this client, as issued by the host. 53 * pairing id for this client, as issued by the host.
53 * @param {string} clientPairedSecret For paired Me2Me connections, the 54 * @param {string} clientPairedSecret For paired Me2Me connections, the
54 * paired secret for this client, as issued by the host. 55 * paired secret for this client, as issued by the host.
55 * @constructor 56 * @constructor
56 * @extends {base.EventSource} 57 * @extends {base.EventSource}
57 */ 58 */
58 remoting.ClientSession = function(container, hostDisplayName, accessCode, 59 remoting.ClientSession = function(signalStrategy, container, hostDisplayName,
59 fetchPin, fetchThirdPartyToken, 60 accessCode, fetchPin, fetchThirdPartyToken,
60 authenticationMethods, hostId, hostJid, 61 authenticationMethods, hostId, hostJid,
61 hostPublicKey, mode, clientPairingId, 62 hostPublicKey, mode, clientPairingId,
62 clientPairedSecret) { 63 clientPairedSecret) {
63 /** @private */ 64 /** @private */
64 this.state_ = remoting.ClientSession.State.CREATED; 65 this.state_ = remoting.ClientSession.State.CREATED;
65 66
66 /** @private */ 67 /** @private */
67 this.error_ = remoting.Error.NONE; 68 this.error_ = remoting.Error.NONE;
68 69
69 /** @type {HTMLElement} 70 /** @type {HTMLElement}
(...skipping 30 matching lines...) Expand all
100 /** @private */ 101 /** @private */
101 this.shrinkToFit_ = true; 102 this.shrinkToFit_ = true;
102 /** @private */ 103 /** @private */
103 this.resizeToClient_ = true; 104 this.resizeToClient_ = true;
104 /** @private */ 105 /** @private */
105 this.remapKeys_ = ''; 106 this.remapKeys_ = '';
106 /** @private */ 107 /** @private */
107 this.hasReceivedFrame_ = false; 108 this.hasReceivedFrame_ = false;
108 this.logToServer = new remoting.LogToServer(); 109 this.logToServer = new remoting.LogToServer();
109 110
111 /** @private */
112 this.signalStrategy_ = signalStrategy;
113 base.debug.assert(this.signalStrategy_.getState() ==
114 remoting.SignalStrategy.State.CONNECTED);
115 this.signalStrategy_.setIncomingStanzaCallback(
116 this.onIncomingMessage_.bind(this));
117 remoting.formatIq.setJids(this.signalStrategy_.getJid(), hostJid);
118
110 /** @type {number?} @private */ 119 /** @type {number?} @private */
111 this.notifyClientResolutionTimer_ = null; 120 this.notifyClientResolutionTimer_ = null;
112 /** @type {number?} @private */ 121 /** @type {number?} @private */
113 this.bumpScrollTimer_ = null; 122 this.bumpScrollTimer_ = null;
114 123
115 // Bump-scroll test variables. Override to use a fake value for the width 124 // Bump-scroll test variables. Override to use a fake value for the width
116 // and height of the client plugin so that bump-scrolling can be tested 125 // and height of the client plugin so that bump-scrolling can be tested
117 // without relying on the actual size of the host desktop. 126 // without relying on the actual size of the host desktop.
118 /** @type {number} @private */ 127 /** @type {number} @private */
119 this.pluginWidthForBumpScrollTesting = 0; 128 this.pluginWidthForBumpScrollTesting = 0;
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 'focus', this.callPluginGotFocus_, false); 492 'focus', this.callPluginGotFocus_, false);
484 this.plugin_.element().addEventListener( 493 this.plugin_.element().addEventListener(
485 'blur', this.callPluginLostFocus_, false); 494 'blur', this.callPluginLostFocus_, false);
486 this.plugin_.element().focus(); 495 this.plugin_.element().focus();
487 }; 496 };
488 497
489 /** 498 /**
490 * @param {remoting.Error} error 499 * @param {remoting.Error} error
491 */ 500 */
492 remoting.ClientSession.prototype.resetWithError_ = function(error) { 501 remoting.ClientSession.prototype.resetWithError_ = function(error) {
502 this.signalStrategy_.setIncomingStanzaCallback(null);
493 this.plugin_.cleanup(); 503 this.plugin_.cleanup();
494 this.plugin_ = null; 504 this.plugin_ = null;
495 this.error_ = error; 505 this.error_ = error;
496 this.setState_(remoting.ClientSession.State.FAILED); 506 this.setState_(remoting.ClientSession.State.FAILED);
497 } 507 }
498 508
499 /** 509 /**
500 * @param {boolean} initialized 510 * @param {boolean} initialized
501 */ 511 */
502 remoting.ClientSession.prototype.onPluginInitialized_ = function(initialized) { 512 remoting.ClientSession.prototype.onPluginInitialized_ = function(initialized) {
(...skipping 17 matching lines...) Expand all
520 } else if (this.mode_ != remoting.ClientSession.Mode.ME2ME) { 530 } else if (this.mode_ != remoting.ClientSession.Mode.ME2ME) {
521 var sendCadElement = document.getElementById('send-ctrl-alt-del'); 531 var sendCadElement = document.getElementById('send-ctrl-alt-del');
522 sendCadElement.hidden = true; 532 sendCadElement.hidden = true;
523 } 533 }
524 534
525 // Apply customized key remappings if the plugin supports remapKeys. 535 // Apply customized key remappings if the plugin supports remapKeys.
526 if (this.plugin_.hasFeature(remoting.ClientPlugin.Feature.REMAP_KEY)) { 536 if (this.plugin_.hasFeature(remoting.ClientPlugin.Feature.REMAP_KEY)) {
527 this.applyRemapKeys_(true); 537 this.applyRemapKeys_(true);
528 } 538 }
529 539
530
531 // Enable MediaSource-based rendering on Chrome 37 and above. 540 // Enable MediaSource-based rendering on Chrome 37 and above.
532 var chromeVersionMajor = 541 var chromeVersionMajor =
533 parseInt((remoting.getChromeVersion() || '0').split('.')[0], 10); 542 parseInt((remoting.getChromeVersion() || '0').split('.')[0], 10);
534 if (chromeVersionMajor >= 37 && 543 if (chromeVersionMajor >= 37 &&
535 this.plugin_.hasFeature( 544 this.plugin_.hasFeature(
536 remoting.ClientPlugin.Feature.MEDIA_SOURCE_RENDERING)) { 545 remoting.ClientPlugin.Feature.MEDIA_SOURCE_RENDERING)) {
537 this.video_ = /** @type {HTMLMediaElement} */( 546 this.video_ = /** @type {HTMLMediaElement} */(
538 this.container_.querySelector('video')); 547 this.container_.querySelector('video'));
539 // Make sure that the <video> element is hidden until we get the first 548 // Make sure that the <video> element is hidden until we get the first
540 // frame. 549 // frame.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 this.error_ = error; 641 this.error_ = error;
633 this.setState_(state); 642 this.setState_(state);
634 }; 643 };
635 644
636 /** 645 /**
637 * Deletes the <embed> element from the container and disconnects. 646 * Deletes the <embed> element from the container and disconnects.
638 * 647 *
639 * @return {void} Nothing. 648 * @return {void} Nothing.
640 */ 649 */
641 remoting.ClientSession.prototype.cleanup = function() { 650 remoting.ClientSession.prototype.cleanup = function() {
642 remoting.wcsSandbox.setOnIq(null);
643 this.sendIq_( 651 this.sendIq_(
644 '<cli:iq ' + 652 '<cli:iq ' +
645 'to="' + this.hostJid_ + '" ' + 653 'to="' + this.hostJid_ + '" ' +
646 'type="set" ' + 654 'type="set" ' +
647 'id="session-terminate" ' + 655 'id="session-terminate" ' +
648 'xmlns:cli="jabber:client">' + 656 'xmlns:cli="jabber:client">' +
649 '<jingle ' + 657 '<jingle ' +
650 'xmlns="urn:xmpp:jingle:1" ' + 658 'xmlns="urn:xmpp:jingle:1" ' +
651 'action="session-terminate" ' + 659 'action="session-terminate" ' +
652 'sid="' + this.sessionId_ + '">' + 660 'sid="' + this.sessionId_ + '">' +
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 }; 833 };
826 834
827 /** 835 /**
828 * @return {boolean} Whether the client has received a video buffer. 836 * @return {boolean} Whether the client has received a video buffer.
829 */ 837 */
830 remoting.ClientSession.prototype.hasReceivedFrame = function() { 838 remoting.ClientSession.prototype.hasReceivedFrame = function() {
831 return this.hasReceivedFrame_; 839 return this.hasReceivedFrame_;
832 }; 840 };
833 841
834 /** 842 /**
835 * Sends an IQ stanza via the http xmpp proxy. 843 * Sends a signaling message.
836 * 844 *
837 * @private 845 * @private
838 * @param {string} msg XML string of IQ stanza to send to server. 846 * @param {string} message XML string of IQ stanza to send to server.
839 * @return {void} Nothing. 847 * @return {void} Nothing.
840 */ 848 */
841 remoting.ClientSession.prototype.sendIq_ = function(msg) { 849 remoting.ClientSession.prototype.sendIq_ = function(message) {
842 // Extract the session id, so we can close the session later. 850 // Extract the session id, so we can close the session later.
843 var parser = new DOMParser(); 851 var parser = new DOMParser();
844 var iqNode = parser.parseFromString(msg, 'text/xml').firstChild; 852 var iqNode = parser.parseFromString(message, 'text/xml').firstChild;
845 var jingleNode = iqNode.firstChild; 853 var jingleNode = iqNode.firstChild;
846 if (jingleNode) { 854 if (jingleNode) {
847 var action = jingleNode.getAttribute('action'); 855 var action = jingleNode.getAttribute('action');
848 if (jingleNode.nodeName == 'jingle' && action == 'session-initiate') { 856 if (jingleNode.nodeName == 'jingle' && action == 'session-initiate') {
849 this.sessionId_ = jingleNode.getAttribute('sid'); 857 this.sessionId_ = jingleNode.getAttribute('sid');
850 } 858 }
851 } 859 }
852 860
853 // HACK: Add 'x' prefix to the IDs of the outgoing messages to make sure that 861 console.log(remoting.timestamp(), remoting.formatIq.prettifySendIq(message));
854 // stanza IDs used by host and client do not match. This is necessary to 862 if (this.signalStrategy_.getState() !=
855 // workaround bug in the signaling endpoint used by chromoting. 863 remoting.SignalStrategy.State.CONNECTED) {
856 // TODO(sergeyu): Remove this hack once the server-side bug is fixed. 864 console.log("Message above is dropped because signaling is not connected.");
857 var type = iqNode.getAttribute('type'); 865 return;
858 if (type == 'set') {
859 var id = iqNode.getAttribute('id');
860 iqNode.setAttribute('id', 'x' + id);
861 msg = (new XMLSerializer()).serializeToString(iqNode);
862 } 866 }
863 867
864 console.log(remoting.timestamp(), remoting.formatIq.prettifySendIq(msg)); 868 this.signalStrategy_.sendMessage(message);
865
866 // Send the stanza.
867 remoting.wcsSandbox.sendIq(msg);
868 }; 869 };
869 870
871 /**
872 * @private
873 * @param {Element} message
874 */
875 remoting.ClientSession.prototype.onIncomingMessage_ = function(message) {
876 if (!this.plugin_) {
877 return;
878 }
879 var formatted = new XMLSerializer().serializeToString(message);
880 console.log(remoting.timestamp(),
881 remoting.formatIq.prettifyReceiveIq(formatted));
882 this.plugin_.onIncomingIq(formatted);
883 }
884
885 /**
886 * @private
887 */
870 remoting.ClientSession.prototype.initiateConnection_ = function() { 888 remoting.ClientSession.prototype.initiateConnection_ = function() {
871 /** @type {remoting.ClientSession} */ 889 /** @type {remoting.ClientSession} */
872 var that = this; 890 var that = this;
873 891
874 remoting.wcsSandbox.connect(onWcsConnected, this.resetWithError_.bind(this)); 892 /** @param {string} sharedSecret Shared secret. */
893 function onSharedSecretReceived(sharedSecret) {
894 that.plugin_.connect(
895 that.hostJid_, that.hostPublicKey_, that.signalStrategy_.getJid(),
896 sharedSecret, that.authenticationMethods_, that.hostId_,
897 that.clientPairingId_, that.clientPairedSecret_);
898 };
875 899
876 /** @param {string} localJid Local JID. */ 900 this.getSharedSecret_(onSharedSecretReceived);
877 function onWcsConnected(localJid) {
878 that.connectPluginToWcs_(localJid);
879 that.getSharedSecret_(onSharedSecretReceived.bind(null, localJid));
880 }
881
882 /** @param {string} localJid Local JID.
883 * @param {string} sharedSecret Shared secret. */
884 function onSharedSecretReceived(localJid, sharedSecret) {
885 that.plugin_.connect(
886 that.hostJid_, that.hostPublicKey_, localJid, sharedSecret,
887 that.authenticationMethods_, that.hostId_, that.clientPairingId_,
888 that.clientPairedSecret_);
889 };
890 } 901 }
891 902
892 /** 903 /**
893 * Connects the plugin to WCS.
894 *
895 * @private
896 * @param {string} localJid Local JID.
897 * @return {void} Nothing.
898 */
899 remoting.ClientSession.prototype.connectPluginToWcs_ = function(localJid) {
900 remoting.formatIq.setJids(localJid, this.hostJid_);
901 var forwardIq = this.plugin_.onIncomingIq.bind(this.plugin_);
902 /** @param {string} stanza The IQ stanza received. */
903 var onIncomingIq = function(stanza) {
904 // HACK: Remove 'x' prefix added to the id in sendIq_().
905 try {
906 var parser = new DOMParser();
907 var iqNode = parser.parseFromString(stanza, 'text/xml').firstChild;
908 var type = iqNode.getAttribute('type');
909 var id = iqNode.getAttribute('id');
910 if (type != 'set' && id.charAt(0) == 'x') {
911 iqNode.setAttribute('id', id.substr(1));
912 stanza = (new XMLSerializer()).serializeToString(iqNode);
913 }
914 } catch (err) {
915 // Pass message as is when it is malformed.
916 }
917
918 console.log(remoting.timestamp(),
919 remoting.formatIq.prettifyReceiveIq(stanza));
920 forwardIq(stanza);
921 };
922 remoting.wcsSandbox.setOnIq(onIncomingIq);
923 }
924
925 /**
926 * Gets shared secret to be used for connection. 904 * Gets shared secret to be used for connection.
927 * 905 *
928 * @param {function(string)} callback Callback called with the shared secret. 906 * @param {function(string)} callback Callback called with the shared secret.
929 * @return {void} Nothing. 907 * @return {void} Nothing.
930 * @private 908 * @private
931 */ 909 */
932 remoting.ClientSession.prototype.getSharedSecret_ = function(callback) { 910 remoting.ClientSession.prototype.getSharedSecret_ = function(callback) {
933 /** @type remoting.ClientSession */ 911 /** @type remoting.ClientSession */
934 var that = this; 912 var that = this;
935 if (this.plugin_.hasFeature(remoting.ClientPlugin.Feature.THIRD_PARTY_AUTH)) { 913 if (this.plugin_.hasFeature(remoting.ClientPlugin.Feature.THIRD_PARTY_AUTH)) {
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
1635 * @param {string} data Contents of the extension message. 1613 * @param {string} data Contents of the extension message.
1636 * @return {boolean} True if the message was recognized, false otherwise. 1614 * @return {boolean} True if the message was recognized, false otherwise.
1637 */ 1615 */
1638 remoting.ClientSession.prototype.handleExtensionMessage = 1616 remoting.ClientSession.prototype.handleExtensionMessage =
1639 function(type, data) { 1617 function(type, data) {
1640 if (this.videoFrameRecorder_) { 1618 if (this.videoFrameRecorder_) {
1641 return this.videoFrameRecorder_.handleMessage(type, data); 1619 return this.videoFrameRecorder_.handleMessage(type, data);
1642 } 1620 }
1643 return false; 1621 return false;
1644 } 1622 }
OLDNEW
« no previous file with comments | « remoting/remoting_webapp_files.gypi ('k') | remoting/webapp/session_connector.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698