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

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
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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 this.error_ = error; 642 this.error_ = error;
634 this.setState_(state); 643 this.setState_(state);
635 }; 644 };
636 645
637 /** 646 /**
638 * Deletes the <embed> element from the container and disconnects. 647 * Deletes the <embed> element from the container and disconnects.
639 * 648 *
640 * @return {void} Nothing. 649 * @return {void} Nothing.
641 */ 650 */
642 remoting.ClientSession.prototype.cleanup = function() { 651 remoting.ClientSession.prototype.cleanup = function() {
643 remoting.wcsSandbox.setOnIq(null);
644 this.sendIq_( 652 this.sendIq_(
645 '<cli:iq ' + 653 '<cli:iq ' +
646 'to="' + this.hostJid_ + '" ' + 654 'to="' + this.hostJid_ + '" ' +
647 'type="set" ' + 655 'type="set" ' +
648 'id="session-terminate" ' + 656 'id="session-terminate" ' +
649 'xmlns:cli="jabber:client">' + 657 'xmlns:cli="jabber:client">' +
650 '<jingle ' + 658 '<jingle ' +
651 'xmlns="urn:xmpp:jingle:1" ' + 659 'xmlns="urn:xmpp:jingle:1" ' +
652 'action="session-terminate" ' + 660 'action="session-terminate" ' +
653 'sid="' + this.sessionId_ + '">' + 661 'sid="' + this.sessionId_ + '">' +
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 }; 834 };
827 835
828 /** 836 /**
829 * @return {boolean} Whether the client has received a video buffer. 837 * @return {boolean} Whether the client has received a video buffer.
830 */ 838 */
831 remoting.ClientSession.prototype.hasReceivedFrame = function() { 839 remoting.ClientSession.prototype.hasReceivedFrame = function() {
832 return this.hasReceivedFrame_; 840 return this.hasReceivedFrame_;
833 }; 841 };
834 842
835 /** 843 /**
836 * Sends an IQ stanza via the http xmpp proxy. 844 * Sends a signaling message.
837 * 845 *
838 * @private 846 * @private
839 * @param {string} msg XML string of IQ stanza to send to server. 847 * @param {string} message XML string of IQ stanza to send to server.
840 * @return {void} Nothing. 848 * @return {void} Nothing.
841 */ 849 */
842 remoting.ClientSession.prototype.sendIq_ = function(msg) { 850 remoting.ClientSession.prototype.sendIq_ = function(message) {
843 // Extract the session id, so we can close the session later. 851 // Extract the session id, so we can close the session later.
844 var parser = new DOMParser(); 852 var parser = new DOMParser();
845 var iqNode = parser.parseFromString(msg, 'text/xml').firstChild; 853 var iqNode = parser.parseFromString(message, 'text/xml').firstChild;
846 var jingleNode = iqNode.firstChild; 854 var jingleNode = iqNode.firstChild;
847 if (jingleNode) { 855 if (jingleNode) {
848 var action = jingleNode.getAttribute('action'); 856 var action = jingleNode.getAttribute('action');
849 if (jingleNode.nodeName == 'jingle' && action == 'session-initiate') { 857 if (jingleNode.nodeName == 'jingle' && action == 'session-initiate') {
850 this.sessionId_ = jingleNode.getAttribute('sid'); 858 this.sessionId_ = jingleNode.getAttribute('sid');
851 } 859 }
852 } 860 }
853 861
854 // HACK: Add 'x' prefix to the IDs of the outgoing messages to make sure that 862 console.log(remoting.timestamp(), remoting.formatIq.prettifySendIq(message));
855 // stanza IDs used by host and client do not match. This is necessary to 863 if (this.signalStrategy_.getState() !=
856 // workaround bug in the signaling endpoint used by chromoting. 864 remoting.SignalStrategy.State.CONNECTED) {
857 // TODO(sergeyu): Remove this hack once the server-side bug is fixed. 865 console.log("Message above is dropped because signaling is not connected.");
858 var type = iqNode.getAttribute('type'); 866 return;
859 if (type == 'set') {
860 var id = iqNode.getAttribute('id');
861 iqNode.setAttribute('id', 'x' + id);
862 msg = (new XMLSerializer()).serializeToString(iqNode);
863 } 867 }
864 868
865 console.log(remoting.timestamp(), remoting.formatIq.prettifySendIq(msg)); 869 this.signalStrategy_.sendMessage(message);
870 };
866 871
867 // Send the stanza. 872 /** @param{Element} message */
kelvinp 2014/09/03 18:53:29 Nit space between @param and {Element} Add private
Sergey Ulanov 2014/09/03 23:25:12 Done.
868 remoting.wcsSandbox.sendIq(msg); 873 remoting.ClientSession.prototype.onIncomingMessage_ = function(message) {
869 }; 874 if (!this.plugin_) {
875 return;
876 }
877 var formatted = new XMLSerializer().serializeToString(message);
878 console.log(remoting.timestamp(),
879 remoting.formatIq.prettifyReceiveIq(formatted));
880 this.plugin_.onIncomingIq(formatted);
881 }
870 882
871 remoting.ClientSession.prototype.initiateConnection_ = function() { 883 remoting.ClientSession.prototype.initiateConnection_ = function() {
872 /** @type {remoting.ClientSession} */ 884 /** @type {remoting.ClientSession} */
873 var that = this; 885 var that = this;
874 886
875 remoting.wcsSandbox.connect(onWcsConnected, this.resetWithError_.bind(this)); 887 /** @param {string} sharedSecret Shared secret. */
888 function onSharedSecretReceived(sharedSecret) {
889 that.plugin_.connect(
890 that.hostJid_, that.hostPublicKey_, that.signalStrategy_.getJid(),
891 sharedSecret, that.authenticationMethods_, that.hostId_,
892 that.clientPairingId_, that.clientPairedSecret_);
893 };
876 894
877 /** @param {string} localJid Local JID. */ 895 this.getSharedSecret_(onSharedSecretReceived);
878 function onWcsConnected(localJid) {
879 that.connectPluginToWcs_(localJid);
880 that.getSharedSecret_(onSharedSecretReceived.bind(null, localJid));
881 }
882
883 /** @param {string} localJid Local JID.
884 * @param {string} sharedSecret Shared secret. */
885 function onSharedSecretReceived(localJid, sharedSecret) {
886 that.plugin_.connect(
887 that.hostJid_, that.hostPublicKey_, localJid, sharedSecret,
888 that.authenticationMethods_, that.hostId_, that.clientPairingId_,
889 that.clientPairedSecret_);
890 };
891 } 896 }
892 897
893 /** 898 /**
894 * Connects the plugin to WCS.
895 *
896 * @private
897 * @param {string} localJid Local JID.
898 * @return {void} Nothing.
899 */
900 remoting.ClientSession.prototype.connectPluginToWcs_ = function(localJid) {
901 remoting.formatIq.setJids(localJid, this.hostJid_);
902 var forwardIq = this.plugin_.onIncomingIq.bind(this.plugin_);
903 /** @param {string} stanza The IQ stanza received. */
904 var onIncomingIq = function(stanza) {
905 // HACK: Remove 'x' prefix added to the id in sendIq_().
906 try {
907 var parser = new DOMParser();
908 var iqNode = parser.parseFromString(stanza, 'text/xml').firstChild;
909 var type = iqNode.getAttribute('type');
910 var id = iqNode.getAttribute('id');
911 if (type != 'set' && id.charAt(0) == 'x') {
912 iqNode.setAttribute('id', id.substr(1));
913 stanza = (new XMLSerializer()).serializeToString(iqNode);
914 }
915 } catch (err) {
916 // Pass message as is when it is malformed.
917 }
918
919 console.log(remoting.timestamp(),
920 remoting.formatIq.prettifyReceiveIq(stanza));
921 forwardIq(stanza);
922 };
923 remoting.wcsSandbox.setOnIq(onIncomingIq);
924 }
925
926 /**
927 * Gets shared secret to be used for connection. 899 * Gets shared secret to be used for connection.
928 * 900 *
929 * @param {function(string)} callback Callback called with the shared secret. 901 * @param {function(string)} callback Callback called with the shared secret.
930 * @return {void} Nothing. 902 * @return {void} Nothing.
931 * @private 903 * @private
932 */ 904 */
933 remoting.ClientSession.prototype.getSharedSecret_ = function(callback) { 905 remoting.ClientSession.prototype.getSharedSecret_ = function(callback) {
934 /** @type remoting.ClientSession */ 906 /** @type remoting.ClientSession */
935 var that = this; 907 var that = this;
936 if (this.plugin_.hasFeature(remoting.ClientPlugin.Feature.THIRD_PARTY_AUTH)) { 908 if (this.plugin_.hasFeature(remoting.ClientPlugin.Feature.THIRD_PARTY_AUTH)) {
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after
1637 * @param {string} data Contents of the extension message. 1609 * @param {string} data Contents of the extension message.
1638 * @return {boolean} True if the message was recognized, false otherwise. 1610 * @return {boolean} True if the message was recognized, false otherwise.
1639 */ 1611 */
1640 remoting.ClientSession.prototype.handleExtensionMessage = 1612 remoting.ClientSession.prototype.handleExtensionMessage =
1641 function(type, data) { 1613 function(type, data) {
1642 if (this.videoFrameRecorder_) { 1614 if (this.videoFrameRecorder_) {
1643 return this.videoFrameRecorder_.handleMessage(type, data); 1615 return this.videoFrameRecorder_.handleMessage(type, data);
1644 } 1616 }
1645 return false; 1617 return false;
1646 } 1618 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698