Chromium Code Reviews| 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 that wraps low-level details of interacting with the client plugin. | 7 * Class that wraps low-level details of interacting with the client plugin. |
| 8 * | 8 * |
| 9 * This abstracts a <embed> element and controls the plugin which does | 9 * This abstracts a <embed> element and controls the plugin which does |
| 10 * the actual remoting work. It also handles differences between | 10 * the actual remoting work. It also handles differences between |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 * @param {string} connectionType The connection type. | 70 * @param {string} connectionType The connection type. |
| 71 * @private | 71 * @private |
| 72 */ | 72 */ |
| 73 this.onRouteChangedHandler_ = function(channel, connectionType) {}; | 73 this.onRouteChangedHandler_ = function(channel, connectionType) {}; |
| 74 | 74 |
| 75 /** | 75 /** |
| 76 * @param {boolean} ready Connection ready state. | 76 * @param {boolean} ready Connection ready state. |
| 77 * @private | 77 * @private |
| 78 */ | 78 */ |
| 79 this.onConnectionReadyHandler_ = function(ready) {}; | 79 this.onConnectionReadyHandler_ = function(ready) {}; |
| 80 | |
| 81 /** | |
| 82 * @param {string} tokenUrl Token-request URL, received from the host. | |
| 83 * @param {string} hostPublicKey Public key for the host. | |
| 84 * @param {string} scope OAuth scope to request the token for. | |
| 85 * @private | |
| 86 */ | |
| 87 this.fetchThirdPartyTokenHandler_ = function( | |
| 88 tokenUrl, hostPublicKey, scope) {}; | |
| 89 /** | 80 /** |
| 90 * @param {!Array<string>} capabilities The negotiated capabilities. | 81 * @param {!Array<string>} capabilities The negotiated capabilities. |
| 91 * @private | 82 * @private |
| 92 */ | 83 */ |
| 93 this.onSetCapabilitiesHandler_ = function (capabilities) {}; | 84 this.onSetCapabilitiesHandler_ = function (capabilities) {}; |
| 94 /** @private */ | |
| 95 this.fetchPinHandler_ = function (supportsPairing) {}; | |
| 96 /** | 85 /** |
| 97 * @param {string} data Remote gnubbyd data. | 86 * @param {string} data Remote gnubbyd data. |
| 98 * @private | 87 * @private |
| 99 */ | 88 */ |
| 100 this.onGnubbyAuthHandler_ = function(data) {}; | 89 this.onGnubbyAuthHandler_ = function(data) {}; |
| 101 /** | 90 /** |
| 102 * @param {string} url | 91 * @param {string} url |
| 103 * @param {number} hotspotX | 92 * @param {number} hotspotX |
| 104 * @param {number} hotspotY | 93 * @param {number} hotspotY |
| 105 * @private | 94 * @private |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 161 that.handleMessage_( | 150 that.handleMessage_( |
| 162 /** @type {remoting.ClientPluginMessage} */ (event.data)); | 151 /** @type {remoting.ClientPluginMessage} */ (event.data)); |
| 163 }, false); | 152 }, false); |
| 164 | 153 |
| 165 if (remoting.settings.CLIENT_PLUGIN_TYPE == 'native') { | 154 if (remoting.settings.CLIENT_PLUGIN_TYPE == 'native') { |
| 166 window.setTimeout(this.showPluginForClickToPlay_.bind(this), 500); | 155 window.setTimeout(this.showPluginForClickToPlay_.bind(this), 500); |
| 167 } | 156 } |
| 168 | 157 |
| 169 this.hostDesktop_ = new remoting.ClientPlugin.HostDesktopImpl( | 158 this.hostDesktop_ = new remoting.ClientPlugin.HostDesktopImpl( |
| 170 this, this.postMessage_.bind(this)); | 159 this, this.postMessage_.bind(this)); |
| 160 | |
| 161 /** @private {remoting.CredentialsProvider} */ | |
| 162 this.credentials_ = null; | |
| 171 }; | 163 }; |
| 172 | 164 |
| 173 /** | 165 /** |
| 174 * Creates plugin element without adding it to a container. | 166 * Creates plugin element without adding it to a container. |
| 175 * | 167 * |
| 176 * @return {HTMLEmbedElement} Plugin element | 168 * @return {HTMLEmbedElement} Plugin element |
| 177 */ | 169 */ |
| 178 remoting.ClientPluginImpl.createPluginElement_ = function() { | 170 remoting.ClientPluginImpl.createPluginElement_ = function() { |
| 179 var plugin = | 171 var plugin = |
| 180 /** @type {HTMLEmbedElement} */ (document.createElement('embed')); | 172 /** @type {HTMLEmbedElement} */ (document.createElement('embed')); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 275 }; | 267 }; |
| 276 | 268 |
| 277 /** | 269 /** |
| 278 * @param {function(string, number, number):void} handler | 270 * @param {function(string, number, number):void} handler |
| 279 */ | 271 */ |
| 280 remoting.ClientPluginImpl.prototype.setMouseCursorHandler = function(handler) { | 272 remoting.ClientPluginImpl.prototype.setMouseCursorHandler = function(handler) { |
| 281 this.updateMouseCursorImage_ = handler; | 273 this.updateMouseCursorImage_ = handler; |
| 282 }; | 274 }; |
| 283 | 275 |
| 284 /** | 276 /** |
| 285 * @param {function(string, string, string):void} handler | |
| 286 */ | |
| 287 remoting.ClientPluginImpl.prototype.setFetchThirdPartyTokenHandler = | |
| 288 function(handler) { | |
| 289 this.fetchThirdPartyTokenHandler_ = handler; | |
| 290 }; | |
| 291 | |
| 292 /** | |
| 293 * @param {function(boolean):void} handler | |
| 294 */ | |
| 295 remoting.ClientPluginImpl.prototype.setFetchPinHandler = function(handler) { | |
| 296 this.fetchPinHandler_ = handler; | |
| 297 }; | |
| 298 | |
| 299 /** | |
| 300 * @param {?function({rects:Array<Array<number>>}):void} handler | 277 * @param {?function({rects:Array<Array<number>>}):void} handler |
| 301 */ | 278 */ |
| 302 remoting.ClientPluginImpl.prototype.setDebugDirtyRegionHandler = | 279 remoting.ClientPluginImpl.prototype.setDebugDirtyRegionHandler = |
| 303 function(handler) { | 280 function(handler) { |
| 304 this.debugRegionHandler_ = handler; | 281 this.debugRegionHandler_ = handler; |
| 305 this.plugin_.postMessage(JSON.stringify( | 282 this.plugin_.postMessage(JSON.stringify( |
| 306 { method: 'enableDebugRegion', data: { enable: handler != null } })); | 283 { method: 'enableDebugRegion', data: { enable: handler != null } })); |
| 307 }; | 284 }; |
| 308 | 285 |
| 309 /** | 286 /** |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 429 | 406 |
| 430 } else if (message.method == 'onConnectionReady') { | 407 } else if (message.method == 'onConnectionReady') { |
| 431 var ready = getBooleanAttr(message.data, 'ready'); | 408 var ready = getBooleanAttr(message.data, 'ready'); |
| 432 this.onConnectionReadyHandler_(ready); | 409 this.onConnectionReadyHandler_(ready); |
| 433 | 410 |
| 434 } else if (message.method == 'fetchPin') { | 411 } else if (message.method == 'fetchPin') { |
| 435 // The pairingSupported value in the dictionary indicates whether both | 412 // The pairingSupported value in the dictionary indicates whether both |
| 436 // client and host support pairing. If the client doesn't support pairing, | 413 // client and host support pairing. If the client doesn't support pairing, |
| 437 // then the value won't be there at all, so give it a default of false. | 414 // then the value won't be there at all, so give it a default of false. |
| 438 var pairingSupported = getBooleanAttr(message.data, 'pairingSupported', | 415 var pairingSupported = getBooleanAttr(message.data, 'pairingSupported', |
| 439 false) | 416 false); |
| 440 this.fetchPinHandler_(pairingSupported); | 417 this.credentials_.getPIN(pairingSupported).then( |
| 441 | 418 this.onPinFetched_.bind(this) |
| 419 ); | |
| 442 } else if (message.method == 'setCapabilities') { | 420 } else if (message.method == 'setCapabilities') { |
| 443 /** @type {!Array<string>} */ | 421 /** @type {!Array<string>} */ |
| 444 var capabilities = tokenize(getStringAttr(message.data, 'capabilities')); | 422 var capabilities = tokenize(getStringAttr(message.data, 'capabilities')); |
| 445 this.onSetCapabilitiesHandler_(capabilities); | 423 this.onSetCapabilitiesHandler_(capabilities); |
| 446 | 424 |
| 447 } else if (message.method == 'fetchThirdPartyToken') { | 425 } else if (message.method == 'fetchThirdPartyToken') { |
| 448 var tokenUrl = getStringAttr(message.data, 'tokenUrl'); | 426 var tokenUrl = getStringAttr(message.data, 'tokenUrl'); |
| 449 var hostPublicKey = getStringAttr(message.data, 'hostPublicKey'); | 427 var hostPublicKey = getStringAttr(message.data, 'hostPublicKey'); |
| 450 var scope = getStringAttr(message.data, 'scope'); | 428 var scope = getStringAttr(message.data, 'scope'); |
| 451 this.fetchThirdPartyTokenHandler_(tokenUrl, hostPublicKey, scope); | 429 this.credentials_.getThirdPartyToken(tokenUrl, hostPublicKey, scope).then( |
| 452 | 430 this.onThirdPartyTokenFetched_.bind(this) |
| 431 ); | |
| 453 } else if (message.method == 'pairingResponse') { | 432 } else if (message.method == 'pairingResponse') { |
| 454 var clientId = getStringAttr(message.data, 'clientId'); | 433 var clientId = getStringAttr(message.data, 'clientId'); |
| 455 var sharedSecret = getStringAttr(message.data, 'sharedSecret'); | 434 var sharedSecret = getStringAttr(message.data, 'sharedSecret'); |
| 456 this.onPairingComplete_(clientId, sharedSecret); | 435 this.onPairingComplete_(clientId, sharedSecret); |
| 457 | 436 |
| 458 } else if (message.method == 'extensionMessage') { | 437 } else if (message.method == 'extensionMessage') { |
| 459 var extMsgType = getStringAttr(message.data, 'type'); | 438 var extMsgType = getStringAttr(message.data, 'type'); |
| 460 var extMsgData = getStringAttr(message.data, 'data'); | 439 var extMsgData = getStringAttr(message.data, 'data'); |
| 461 switch (extMsgType) { | 440 switch (extMsgType) { |
| 462 case 'gnubby-auth': | 441 case 'gnubby-auth': |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 583 { method: 'incomingIq', data: { iq: iq } })); | 562 { method: 'incomingIq', data: { iq: iq } })); |
| 584 } else { | 563 } else { |
| 585 // plugin.onIq may not be set after the plugin has been shut | 564 // plugin.onIq may not be set after the plugin has been shut |
| 586 // down. Particularly this happens when we receive response to | 565 // down. Particularly this happens when we receive response to |
| 587 // session-terminate stanza. | 566 // session-terminate stanza. |
| 588 console.warn('plugin.onIq is not set so dropping incoming message.'); | 567 console.warn('plugin.onIq is not set so dropping incoming message.'); |
| 589 } | 568 } |
| 590 }; | 569 }; |
| 591 | 570 |
| 592 /** | 571 /** |
| 593 * @param {string} hostJid The jid of the host to connect to. | 572 * @param {remoting.Host} host The host to connect to. |
| 594 * @param {string} hostPublicKey The base64 encoded version of the host's | |
| 595 * public key. | |
| 596 * @param {string} localJid Local jid. | 573 * @param {string} localJid Local jid. |
| 597 * @param {string} sharedSecret The access code for IT2Me or the PIN | 574 * @param {remoting.CredentialsProvider} credentials The credentials |
| 598 * for Me2Me. | 575 * provider. |
| 599 * @param {string} authenticationMethods Comma-separated list of | |
| 600 * authentication methods the client should attempt to use. | |
| 601 * @param {string} authenticationTag A host-specific tag to mix into | |
| 602 * authentication hashes. | |
| 603 * @param {string} clientPairingId For paired Me2Me connections, the | |
| 604 * pairing id for this client, as issued by the host. | |
| 605 * @param {string} clientPairedSecret For paired Me2Me connections, the | |
| 606 * paired secret for this client, as issued by the host. | |
| 607 */ | 576 */ |
| 608 remoting.ClientPluginImpl.prototype.connect = function( | 577 remoting.ClientPluginImpl.prototype.connect = |
| 609 hostJid, hostPublicKey, localJid, sharedSecret, | 578 function(host, localJid, credentials) { |
| 610 authenticationMethods, authenticationTag, | |
| 611 clientPairingId, clientPairedSecret) { | |
| 612 var keyFilter = ''; | 579 var keyFilter = ''; |
| 613 if (remoting.platformIsMac()) { | 580 if (remoting.platformIsMac()) { |
| 614 keyFilter = 'mac'; | 581 keyFilter = 'mac'; |
| 615 } else if (remoting.platformIsChromeOS()) { | 582 } else if (remoting.platformIsChromeOS()) { |
| 616 keyFilter = 'cros'; | 583 keyFilter = 'cros'; |
| 617 } | 584 } |
| 618 // Use PPB_VideoDecoder API only in Chrome 42 and above. It is broken in | 585 // Use PPB_VideoDecoder API only in Chrome 42 and above. It is broken in |
| 619 // previous versions of Chrome, see http://crbug.com/447403 . | 586 // previous versions of Chrome, see http://crbug.com/447403 . |
| 620 // Currently PPAPI doesn't provide a way for plugins to check the Chrome | 587 // Currently PPAPI doesn't provide a way for plugins to check the Chrome |
| 621 // version, so this check needs to be in the webapp. | 588 // version, so this check needs to be in the webapp. |
| 622 var enableVideoDecodeRenderer = | 589 var enableVideoDecodeRenderer = |
| 623 parseInt((remoting.getChromeVersion() || '0').split('.')[0], 10) >= 42; | 590 parseInt((remoting.getChromeVersion() || '0').split('.')[0], 10) >= 42; |
| 624 this.plugin_.postMessage(JSON.stringify( | 591 this.plugin_.postMessage(JSON.stringify( |
| 625 { method: 'delegateLargeCursors', data: {} })); | 592 { method: 'delegateLargeCursors', data: {} })); |
| 593 var methods = 'third_party,spake2_pair,spake2_hmac,spake2_plain'; | |
| 594 this.credentials_ = credentials; | |
| 595 if (credentials.supports(remoting.CredentialsProvider.Methods.PIN)) { | |
| 596 this.useAsyncPinDialog_(); | |
| 597 } | |
| 626 this.plugin_.postMessage(JSON.stringify( | 598 this.plugin_.postMessage(JSON.stringify( |
| 627 { method: 'connect', data: { | 599 { method: 'connect', data: { |
| 628 hostJid: hostJid, | 600 hostJid: host.jabberId, |
| 629 hostPublicKey: hostPublicKey, | 601 hostPublicKey: host.publicKey, |
| 630 localJid: localJid, | 602 localJid: localJid, |
| 631 sharedSecret: sharedSecret, | 603 sharedSecret: credentials.getSharedSecret(), |
| 632 authenticationMethods: authenticationMethods, | 604 authenticationMethods: methods, |
| 633 authenticationTag: authenticationTag, | 605 authenticationTag: host.hostId, |
| 634 capabilities: this.capabilities_.join(" "), | 606 capabilities: this.capabilities_.join(" "), |
| 635 clientPairingId: clientPairingId, | 607 clientPairingId: credentials.getPairingInfo().id, |
| 636 clientPairedSecret: clientPairedSecret, | 608 clientPairedSecret: credentials.getPairingInfo().secret, |
| 637 keyFilter: keyFilter, | 609 keyFilter: keyFilter, |
| 638 enableVideoDecodeRenderer: enableVideoDecodeRenderer | 610 enableVideoDecodeRenderer: enableVideoDecodeRenderer |
| 639 } | 611 } |
| 640 })); | 612 })); |
| 641 }; | 613 }; |
| 642 | 614 |
| 643 /** | 615 /** |
| 644 * Release all currently pressed keys. | 616 * Release all currently pressed keys. |
| 645 */ | 617 */ |
| 646 remoting.ClientPluginImpl.prototype.releaseAllKeys = function() { | 618 remoting.ClientPluginImpl.prototype.releaseAllKeys = function() { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 783 return; | 755 return; |
| 784 } | 756 } |
| 785 this.plugin_.postMessage(JSON.stringify( | 757 this.plugin_.postMessage(JSON.stringify( |
| 786 { method: 'videoControl', data: { losslessColor: wantLossless }})); | 758 { method: 'videoControl', data: { losslessColor: wantLossless }})); |
| 787 }; | 759 }; |
| 788 | 760 |
| 789 /** | 761 /** |
| 790 * Called when a PIN is obtained from the user. | 762 * Called when a PIN is obtained from the user. |
| 791 * | 763 * |
| 792 * @param {string} pin The PIN. | 764 * @param {string} pin The PIN. |
| 765 * @private | |
| 793 */ | 766 */ |
| 794 remoting.ClientPluginImpl.prototype.onPinFetched = | 767 remoting.ClientPluginImpl.prototype.onPinFetched_ = |
| 795 function(pin) { | 768 function(pin) { |
| 796 if (!this.hasFeature(remoting.ClientPlugin.Feature.ASYNC_PIN)) { | 769 if (!this.hasFeature(remoting.ClientPlugin.Feature.ASYNC_PIN)) { |
| 797 return; | 770 return; |
| 798 } | 771 } |
| 799 this.plugin_.postMessage(JSON.stringify( | 772 this.plugin_.postMessage(JSON.stringify( |
| 800 { method: 'onPinFetched', data: { pin: pin }})); | 773 { method: 'onPinFetched', data: { pin: pin }})); |
| 801 }; | 774 }; |
| 802 | 775 |
| 803 /** | 776 /** |
| 804 * Tells the plugin to ask for the PIN asynchronously. | 777 * Tells the plugin to ask for the PIN asynchronously. |
| 778 * @private | |
| 805 */ | 779 */ |
| 806 remoting.ClientPluginImpl.prototype.useAsyncPinDialog = | 780 remoting.ClientPluginImpl.prototype.useAsyncPinDialog_ = |
| 807 function() { | 781 function() { |
| 808 if (!this.hasFeature(remoting.ClientPlugin.Feature.ASYNC_PIN)) { | 782 if (!this.hasFeature(remoting.ClientPlugin.Feature.ASYNC_PIN)) { |
| 809 return; | 783 return; |
| 810 } | 784 } |
| 811 this.plugin_.postMessage(JSON.stringify( | 785 this.plugin_.postMessage(JSON.stringify( |
| 812 { method: 'useAsyncPinDialog', data: {} })); | 786 { method: 'useAsyncPinDialog', data: {} })); |
| 813 }; | 787 }; |
| 814 | 788 |
| 815 /** | 789 /** |
| 816 * Allows automatic mouse-lock. | 790 * Allows automatic mouse-lock. |
| 817 */ | 791 */ |
| 818 remoting.ClientPluginImpl.prototype.allowMouseLock = function() { | 792 remoting.ClientPluginImpl.prototype.allowMouseLock = function() { |
| 819 this.plugin_.postMessage(JSON.stringify( | 793 this.plugin_.postMessage(JSON.stringify( |
| 820 { method: 'allowMouseLock', data: {} })); | 794 { method: 'allowMouseLock', data: {} })); |
| 821 }; | 795 }; |
| 822 | 796 |
| 823 /** | 797 /** |
| 824 * Sets the third party authentication token and shared secret. | 798 * Sets the third party authentication token and shared secret. |
| 825 * | 799 * |
| 826 * @param {string} token The token received from the token URL. | 800 * @param {remoting.ThirdPartyToken} credentials |
|
Jamie
2015/02/26 23:20:14
I think |token| was a better name here. If you pre
kelvinp
2015/02/27 01:03:21
Done.
| |
| 827 * @param {string} sharedSecret Shared secret received from the token URL. | 801 * @private |
| 828 */ | 802 */ |
| 829 remoting.ClientPluginImpl.prototype.onThirdPartyTokenFetched = function( | 803 remoting.ClientPluginImpl.prototype.onThirdPartyTokenFetched_ = function( |
| 830 token, sharedSecret) { | 804 credentials) { |
| 831 this.plugin_.postMessage(JSON.stringify( | 805 this.plugin_.postMessage(JSON.stringify( |
| 832 { method: 'onThirdPartyTokenFetched', | 806 { method: 'onThirdPartyTokenFetched', |
| 833 data: { token: token, sharedSecret: sharedSecret}})); | 807 data: { token: credentials.token, sharedSecret: credentials.secret}})); |
| 834 }; | 808 }; |
| 835 | 809 |
| 836 /** | 810 /** |
| 837 * Request pairing with the host for PIN-less authentication. | 811 * Request pairing with the host for PIN-less authentication. |
| 838 * | 812 * |
| 839 * @param {string} clientName The human-readable name of the client. | 813 * @param {string} clientName The human-readable name of the client. |
| 840 * @param {function(string, string):void} onDone, Callback to receive the | 814 * @param {function(string, string):void} onDone, Callback to receive the |
| 841 * client id and shared secret when they are available. | 815 * client id and shared secret when they are available. |
| 842 */ | 816 */ |
| 843 remoting.ClientPluginImpl.prototype.requestPairing = | 817 remoting.ClientPluginImpl.prototype.requestPairing = |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 937 remoting.DefaultClientPluginFactory.prototype.preloadPlugin = function() { | 911 remoting.DefaultClientPluginFactory.prototype.preloadPlugin = function() { |
| 938 if (remoting.settings.CLIENT_PLUGIN_TYPE != 'pnacl') { | 912 if (remoting.settings.CLIENT_PLUGIN_TYPE != 'pnacl') { |
| 939 return; | 913 return; |
| 940 } | 914 } |
| 941 | 915 |
| 942 var plugin = remoting.ClientPluginImpl.createPluginElement_(); | 916 var plugin = remoting.ClientPluginImpl.createPluginElement_(); |
| 943 plugin.addEventListener( | 917 plugin.addEventListener( |
| 944 'loadend', function() { document.body.removeChild(plugin); }, false); | 918 'loadend', function() { document.body.removeChild(plugin); }, false); |
| 945 document.body.appendChild(plugin); | 919 document.body.appendChild(plugin); |
| 946 }; | 920 }; |
| OLD | NEW |