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 |
11 * client plugins versions when it is necessary. | 11 * client plugins versions when it is necessary. |
12 */ | 12 */ |
13 | 13 |
14 'use strict'; | 14 'use strict'; |
15 | 15 |
16 /** @suppress {duplicate} */ | 16 /** @suppress {duplicate} */ |
17 var remoting = remoting || {}; | 17 var remoting = remoting || {}; |
18 | 18 |
19 /** @constructor */ | 19 /** @constructor */ |
20 remoting.ClientPluginMessage = function() { | 20 remoting.ClientPluginMessage = function() { |
21 /** @type {string} */ | 21 /** @type {string} */ |
22 this.method = ''; | 22 this.method = ''; |
23 | 23 |
24 /** @type {Object.<string,*>} */ | 24 /** @type {Object<string,*>} */ |
25 this.data = {}; | 25 this.data = {}; |
26 }; | 26 }; |
27 | 27 |
28 /** | 28 /** |
29 * @param {Element} container The container for the embed element. | 29 * @param {Element} container The container for the embed element. |
30 * @param {function(string, string):boolean} onExtensionMessage The handler for | 30 * @param {function(string, string):boolean} onExtensionMessage The handler for |
31 * protocol extension messages. Returns true if a message is recognized; | 31 * protocol extension messages. Returns true if a message is recognized; |
32 * false otherwise. | 32 * false otherwise. |
33 * @param {Array.<string>} requiredCapabilities The set of capabilties that the | 33 * @param {Array<string>} requiredCapabilities The set of capabilties that the |
34 * session must support for this application. | 34 * session must support for this application. |
35 * @constructor | 35 * @constructor |
36 * @implements {remoting.ClientPlugin} | 36 * @implements {remoting.ClientPlugin} |
37 */ | 37 */ |
38 remoting.ClientPluginImpl = function(container, onExtensionMessage, | 38 remoting.ClientPluginImpl = function(container, onExtensionMessage, |
39 requiredCapabilities) { | 39 requiredCapabilities) { |
40 this.plugin_ = remoting.ClientPluginImpl.createPluginElement_(); | 40 this.plugin_ = remoting.ClientPluginImpl.createPluginElement_(); |
41 this.plugin_.id = 'session-client-plugin'; | 41 this.plugin_.id = 'session-client-plugin'; |
42 container.appendChild(this.plugin_); | 42 container.appendChild(this.plugin_); |
43 | 43 |
44 this.onExtensionMessage_ = onExtensionMessage; | 44 this.onExtensionMessage_ = onExtensionMessage; |
45 /** | 45 /** |
46 * @type {Array.<string>} | 46 * @type {Array<string>} |
47 * @private | 47 * @private |
48 */ | 48 */ |
49 this.requiredCapabilities_ = requiredCapabilities; | 49 this.requiredCapabilities_ = requiredCapabilities; |
50 | 50 |
51 /** @private */ | 51 /** @private */ |
52 this.desktopWidth_ = 0; | 52 this.desktopWidth_ = 0; |
53 /** @private */ | 53 /** @private */ |
54 this.desktopHeight_ = 0; | 54 this.desktopHeight_ = 0; |
55 /** @private */ | 55 /** @private */ |
56 this.desktopXDpi_ = 96; | 56 this.desktopXDpi_ = 96; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 * @param {string} tokenUrl Token-request URL, received from the host. | 91 * @param {string} tokenUrl Token-request URL, received from the host. |
92 * @param {string} hostPublicKey Public key for the host. | 92 * @param {string} hostPublicKey Public key for the host. |
93 * @param {string} scope OAuth scope to request the token for. | 93 * @param {string} scope OAuth scope to request the token for. |
94 * @private | 94 * @private |
95 */ | 95 */ |
96 this.fetchThirdPartyTokenHandler_ = function( | 96 this.fetchThirdPartyTokenHandler_ = function( |
97 tokenUrl, hostPublicKey, scope) {}; | 97 tokenUrl, hostPublicKey, scope) {}; |
98 /** @private */ | 98 /** @private */ |
99 this.onDesktopSizeUpdateHandler_ = function () {}; | 99 this.onDesktopSizeUpdateHandler_ = function () {}; |
100 /** | 100 /** |
101 * @param {Array.<Array.<number>>} rects | 101 * @param {Array<Array<number>>} rects |
102 * @private | 102 * @private |
103 */ | 103 */ |
104 this.onDesktopShapeUpdateHandler_ = function (rects) {}; | 104 this.onDesktopShapeUpdateHandler_ = function (rects) {}; |
105 /** | 105 /** |
106 * @param {!Array.<string>} capabilities The negotiated capabilities. | 106 * @param {!Array<string>} capabilities The negotiated capabilities. |
107 * @private | 107 * @private |
108 */ | 108 */ |
109 this.onSetCapabilitiesHandler_ = function (capabilities) {}; | 109 this.onSetCapabilitiesHandler_ = function (capabilities) {}; |
110 /** @private */ | 110 /** @private */ |
111 this.fetchPinHandler_ = function (supportsPairing) {}; | 111 this.fetchPinHandler_ = function (supportsPairing) {}; |
112 /** | 112 /** |
113 * @param {string} data Remote gnubbyd data. | 113 * @param {string} data Remote gnubbyd data. |
114 * @private | 114 * @private |
115 */ | 115 */ |
116 this.onGnubbyAuthHandler_ = function(data) {}; | 116 this.onGnubbyAuthHandler_ = function(data) {}; |
(...skipping 10 matching lines...) Expand all Loading... |
127 * @private | 127 * @private |
128 */ | 128 */ |
129 this.onCastExtensionHandler_ = function(data) {}; | 129 this.onCastExtensionHandler_ = function(data) {}; |
130 | 130 |
131 /** | 131 /** |
132 * @type {number} | 132 * @type {number} |
133 * @private | 133 * @private |
134 */ | 134 */ |
135 this.pluginApiVersion_ = -1; | 135 this.pluginApiVersion_ = -1; |
136 /** | 136 /** |
137 * @type {Array.<string>} | 137 * @type {Array<string>} |
138 * @private | 138 * @private |
139 */ | 139 */ |
140 this.pluginApiFeatures_ = []; | 140 this.pluginApiFeatures_ = []; |
141 /** | 141 /** |
142 * @type {number} | 142 * @type {number} |
143 * @private | 143 * @private |
144 */ | 144 */ |
145 this.pluginApiMinVersion_ = -1; | 145 this.pluginApiMinVersion_ = -1; |
146 /** | 146 /** |
147 * @type {!Array.<string>} | 147 * @type {!Array<string>} |
148 * @private | 148 * @private |
149 */ | 149 */ |
150 this.capabilities_ = []; | 150 this.capabilities_ = []; |
151 /** | 151 /** |
152 * @type {boolean} | 152 * @type {boolean} |
153 * @private | 153 * @private |
154 */ | 154 */ |
155 this.helloReceived_ = false; | 155 this.helloReceived_ = false; |
156 /** | 156 /** |
157 * @type {function(boolean)|null} | 157 * @type {function(boolean)|null} |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 | 266 |
267 /** | 267 /** |
268 * @param {function():void} handler | 268 * @param {function():void} handler |
269 */ | 269 */ |
270 remoting.ClientPluginImpl.prototype.setDesktopSizeUpdateHandler = | 270 remoting.ClientPluginImpl.prototype.setDesktopSizeUpdateHandler = |
271 function(handler) { | 271 function(handler) { |
272 this.onDesktopSizeUpdateHandler_ = handler; | 272 this.onDesktopSizeUpdateHandler_ = handler; |
273 }; | 273 }; |
274 | 274 |
275 /** | 275 /** |
276 * @param {function(Array.<Array.<number>>):void} handler | 276 * @param {function(Array<Array<number>>):void} handler |
277 */ | 277 */ |
278 remoting.ClientPluginImpl.prototype.setDesktopShapeUpdateHandler = | 278 remoting.ClientPluginImpl.prototype.setDesktopShapeUpdateHandler = |
279 function(handler) { | 279 function(handler) { |
280 this.onDesktopShapeUpdateHandler_ = handler; | 280 this.onDesktopShapeUpdateHandler_ = handler; |
281 }; | 281 }; |
282 | 282 |
283 /** | 283 /** |
284 * @param {function(!Array.<string>):void} handler | 284 * @param {function(!Array<string>):void} handler |
285 */ | 285 */ |
286 remoting.ClientPluginImpl.prototype.setCapabilitiesHandler = function(handler) { | 286 remoting.ClientPluginImpl.prototype.setCapabilitiesHandler = function(handler) { |
287 this.onSetCapabilitiesHandler_ = handler; | 287 this.onSetCapabilitiesHandler_ = handler; |
288 }; | 288 }; |
289 | 289 |
290 /** | 290 /** |
291 * @param {function(string):void} handler | 291 * @param {function(string):void} handler |
292 */ | 292 */ |
293 remoting.ClientPluginImpl.prototype.setGnubbyAuthHandler = function(handler) { | 293 remoting.ClientPluginImpl.prototype.setGnubbyAuthHandler = function(handler) { |
294 this.onGnubbyAuthHandler_ = handler; | 294 this.onGnubbyAuthHandler_ = handler; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 | 348 |
349 /** | 349 /** |
350 * @param {remoting.ClientPluginMessage} | 350 * @param {remoting.ClientPluginMessage} |
351 * message Parsed message from the plugin. | 351 * message Parsed message from the plugin. |
352 * @private | 352 * @private |
353 */ | 353 */ |
354 remoting.ClientPluginImpl.prototype.handleMessageMethod_ = function(message) { | 354 remoting.ClientPluginImpl.prototype.handleMessageMethod_ = function(message) { |
355 /** | 355 /** |
356 * Splits a string into a list of words delimited by spaces. | 356 * Splits a string into a list of words delimited by spaces. |
357 * @param {string} str String that should be split. | 357 * @param {string} str String that should be split. |
358 * @return {!Array.<string>} List of words. | 358 * @return {!Array<string>} List of words. |
359 */ | 359 */ |
360 var tokenize = function(str) { | 360 var tokenize = function(str) { |
361 /** @type {Array.<string>} */ | 361 /** @type {Array<string>} */ |
362 var tokens = str.match(/\S+/g); | 362 var tokens = str.match(/\S+/g); |
363 return tokens ? tokens : []; | 363 return tokens ? tokens : []; |
364 }; | 364 }; |
365 | 365 |
366 if (message.method == 'hello') { | 366 if (message.method == 'hello') { |
367 // Resize in case we had to enlarge it to support click-to-play. | 367 // Resize in case we had to enlarge it to support click-to-play. |
368 this.hidePluginForClickToPlay_(); | 368 this.hidePluginForClickToPlay_(); |
369 this.pluginApiVersion_ = getNumberAttr(message.data, 'apiVersion'); | 369 this.pluginApiVersion_ = getNumberAttr(message.data, 'apiVersion'); |
370 this.pluginApiMinVersion_ = getNumberAttr(message.data, 'apiMinVersion'); | 370 this.pluginApiMinVersion_ = getNumberAttr(message.data, 'apiMinVersion'); |
371 | 371 |
372 if (this.pluginApiVersion_ >= 7) { | 372 if (this.pluginApiVersion_ >= 7) { |
373 this.pluginApiFeatures_ = | 373 this.pluginApiFeatures_ = |
374 tokenize(getStringAttr(message.data, 'apiFeatures')); | 374 tokenize(getStringAttr(message.data, 'apiFeatures')); |
375 | 375 |
376 // Negotiate capabilities. | 376 // Negotiate capabilities. |
377 | 377 |
378 /** @type {!Array.<string>} */ | 378 /** @type {!Array<string>} */ |
379 var requestedCapabilities = []; | 379 var requestedCapabilities = []; |
380 if ('requestedCapabilities' in message.data) { | 380 if ('requestedCapabilities' in message.data) { |
381 requestedCapabilities = | 381 requestedCapabilities = |
382 tokenize(getStringAttr(message.data, 'requestedCapabilities')); | 382 tokenize(getStringAttr(message.data, 'requestedCapabilities')); |
383 } | 383 } |
384 | 384 |
385 /** @type {!Array.<string>} */ | 385 /** @type {!Array<string>} */ |
386 var supportedCapabilities = []; | 386 var supportedCapabilities = []; |
387 if ('supportedCapabilities' in message.data) { | 387 if ('supportedCapabilities' in message.data) { |
388 supportedCapabilities = | 388 supportedCapabilities = |
389 tokenize(getStringAttr(message.data, 'supportedCapabilities')); | 389 tokenize(getStringAttr(message.data, 'supportedCapabilities')); |
390 } | 390 } |
391 // At the moment the webapp does not recognize any of | 391 // At the moment the webapp does not recognize any of |
392 // 'requestedCapabilities' capabilities (so they all should be disabled) | 392 // 'requestedCapabilities' capabilities (so they all should be disabled) |
393 // and do not care about any of 'supportedCapabilities' capabilities (so | 393 // and do not care about any of 'supportedCapabilities' capabilities (so |
394 // they all can be enabled). | 394 // they all can be enabled). |
395 // All the required capabilities (specified by the app) are added to this. | 395 // All the required capabilities (specified by the app) are added to this. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 } else if (message.method == 'onDesktopSize') { | 427 } else if (message.method == 'onDesktopSize') { |
428 this.desktopWidth_ = getNumberAttr(message.data, 'width'); | 428 this.desktopWidth_ = getNumberAttr(message.data, 'width'); |
429 this.desktopHeight_ = getNumberAttr(message.data, 'height'); | 429 this.desktopHeight_ = getNumberAttr(message.data, 'height'); |
430 this.desktopXDpi_ = getNumberAttr(message.data, 'x_dpi', 96); | 430 this.desktopXDpi_ = getNumberAttr(message.data, 'x_dpi', 96); |
431 this.desktopYDpi_ = getNumberAttr(message.data, 'y_dpi', 96); | 431 this.desktopYDpi_ = getNumberAttr(message.data, 'y_dpi', 96); |
432 this.onDesktopSizeUpdateHandler_(); | 432 this.onDesktopSizeUpdateHandler_(); |
433 | 433 |
434 } else if (message.method == 'onDesktopShape') { | 434 } else if (message.method == 'onDesktopShape') { |
435 var rects = getArrayAttr(message.data, 'rects'); | 435 var rects = getArrayAttr(message.data, 'rects'); |
436 for (var i = 0; i < rects.length; ++i) { | 436 for (var i = 0; i < rects.length; ++i) { |
437 /** @type {Array.<number>} */ | 437 /** @type {Array<number>} */ |
438 var rect = rects[i]; | 438 var rect = rects[i]; |
439 if (typeof rect != 'object' || rect.length != 4) { | 439 if (typeof rect != 'object' || rect.length != 4) { |
440 throw 'Received invalid onDesktopShape message'; | 440 throw 'Received invalid onDesktopShape message'; |
441 } | 441 } |
442 } | 442 } |
443 this.onDesktopShapeUpdateHandler_(rects); | 443 this.onDesktopShapeUpdateHandler_(rects); |
444 | 444 |
445 } else if (message.method == 'onPerfStats') { | 445 } else if (message.method == 'onPerfStats') { |
446 // Return value is ignored. These calls will throw an error if the value | 446 // Return value is ignored. These calls will throw an error if the value |
447 // is not a number. | 447 // is not a number. |
(...skipping 25 matching lines...) Expand all Loading... |
473 | 473 |
474 } else if (message.method == 'fetchPin') { | 474 } else if (message.method == 'fetchPin') { |
475 // The pairingSupported value in the dictionary indicates whether both | 475 // The pairingSupported value in the dictionary indicates whether both |
476 // client and host support pairing. If the client doesn't support pairing, | 476 // client and host support pairing. If the client doesn't support pairing, |
477 // then the value won't be there at all, so give it a default of false. | 477 // then the value won't be there at all, so give it a default of false. |
478 var pairingSupported = getBooleanAttr(message.data, 'pairingSupported', | 478 var pairingSupported = getBooleanAttr(message.data, 'pairingSupported', |
479 false) | 479 false) |
480 this.fetchPinHandler_(pairingSupported); | 480 this.fetchPinHandler_(pairingSupported); |
481 | 481 |
482 } else if (message.method == 'setCapabilities') { | 482 } else if (message.method == 'setCapabilities') { |
483 /** @type {!Array.<string>} */ | 483 /** @type {!Array<string>} */ |
484 var capabilities = tokenize(getStringAttr(message.data, 'capabilities')); | 484 var capabilities = tokenize(getStringAttr(message.data, 'capabilities')); |
485 this.onSetCapabilitiesHandler_(capabilities); | 485 this.onSetCapabilitiesHandler_(capabilities); |
486 | 486 |
487 } else if (message.method == 'fetchThirdPartyToken') { | 487 } else if (message.method == 'fetchThirdPartyToken') { |
488 var tokenUrl = getStringAttr(message.data, 'tokenUrl'); | 488 var tokenUrl = getStringAttr(message.data, 'tokenUrl'); |
489 var hostPublicKey = getStringAttr(message.data, 'hostPublicKey'); | 489 var hostPublicKey = getStringAttr(message.data, 'hostPublicKey'); |
490 var scope = getStringAttr(message.data, 'scope'); | 490 var scope = getStringAttr(message.data, 'scope'); |
491 this.fetchThirdPartyTokenHandler_(tokenUrl, hostPublicKey, scope); | 491 this.fetchThirdPartyTokenHandler_(tokenUrl, hostPublicKey, scope); |
492 | 492 |
493 } else if (message.method == 'pairingResponse') { | 493 } else if (message.method == 'pairingResponse') { |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
959 | 959 |
960 /** | 960 /** |
961 * @constructor | 961 * @constructor |
962 * @implements {remoting.ClientPluginFactory} | 962 * @implements {remoting.ClientPluginFactory} |
963 */ | 963 */ |
964 remoting.DefaultClientPluginFactory = function() {}; | 964 remoting.DefaultClientPluginFactory = function() {}; |
965 | 965 |
966 /** | 966 /** |
967 * @param {Element} container | 967 * @param {Element} container |
968 * @param {function(string, string):boolean} onExtensionMessage | 968 * @param {function(string, string):boolean} onExtensionMessage |
969 * @param {Array.<string>} requiredCapabilities | 969 * @param {Array<string>} requiredCapabilities |
970 * @return {remoting.ClientPlugin} | 970 * @return {remoting.ClientPlugin} |
971 */ | 971 */ |
972 remoting.DefaultClientPluginFactory.prototype.createPlugin = | 972 remoting.DefaultClientPluginFactory.prototype.createPlugin = |
973 function(container, onExtensionMessage, requiredCapabilities) { | 973 function(container, onExtensionMessage, requiredCapabilities) { |
974 return new remoting.ClientPluginImpl(container, onExtensionMessage, | 974 return new remoting.ClientPluginImpl(container, onExtensionMessage, |
975 requiredCapabilities); | 975 requiredCapabilities); |
976 }; | 976 }; |
977 | 977 |
978 remoting.DefaultClientPluginFactory.prototype.preloadPlugin = function() { | 978 remoting.DefaultClientPluginFactory.prototype.preloadPlugin = function() { |
979 if (remoting.settings.CLIENT_PLUGIN_TYPE != 'pnacl') { | 979 if (remoting.settings.CLIENT_PLUGIN_TYPE != 'pnacl') { |
980 return; | 980 return; |
981 } | 981 } |
982 | 982 |
983 var plugin = remoting.ClientPluginImpl.createPluginElement_(); | 983 var plugin = remoting.ClientPluginImpl.createPluginElement_(); |
984 plugin.addEventListener( | 984 plugin.addEventListener( |
985 'loadend', function() { document.body.removeChild(plugin); }, false); | 985 'loadend', function() { document.body.removeChild(plugin); }, false); |
986 document.body.appendChild(plugin); | 986 document.body.appendChild(plugin); |
987 }; | 987 }; |
OLD | NEW |