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 */ |
| 20 remoting.ClientPluginMessage = function() { |
| 21 /** @type {string} */ |
| 22 this.method = ''; |
| 23 |
| 24 /** @type {Object.<string,*>} */ |
| 25 this.data = {}; |
| 26 }; |
| 27 |
19 /** | 28 /** |
20 * @param {Element} container The container for the embed element. | 29 * @param {Element} container The container for the embed element. |
21 * @param {function(string, string):boolean} onExtensionMessage The handler for | 30 * @param {function(string, string):boolean} onExtensionMessage The handler for |
22 * protocol extension messages. Returns true if a message is recognized; | 31 * protocol extension messages. Returns true if a message is recognized; |
23 * false otherwise. | 32 * false otherwise. |
24 * @param {Array.<string>} requiredCapabilities The set of capabilties that the | 33 * @param {Array.<string>} requiredCapabilities The set of capabilties that the |
25 * session must support for this application. | 34 * session must support for this application. |
26 * @constructor | 35 * @constructor |
27 * @implements {remoting.ClientPlugin} | 36 * @implements {remoting.ClientPlugin} |
28 */ | 37 */ |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 /** | 166 /** |
158 * @type {remoting.ClientSession.PerfStats} | 167 * @type {remoting.ClientSession.PerfStats} |
159 * @private | 168 * @private |
160 */ | 169 */ |
161 this.perfStats_ = new remoting.ClientSession.PerfStats(); | 170 this.perfStats_ = new remoting.ClientSession.PerfStats(); |
162 | 171 |
163 /** @type {remoting.ClientPluginImpl} */ | 172 /** @type {remoting.ClientPluginImpl} */ |
164 var that = this; | 173 var that = this; |
165 /** @param {Event} event Message event from the plugin. */ | 174 /** @param {Event} event Message event from the plugin. */ |
166 this.plugin_.addEventListener('message', function(event) { | 175 this.plugin_.addEventListener('message', function(event) { |
167 that.handleMessage_(event.data); | 176 that.handleMessage_( |
| 177 /** @type {remoting.ClientPluginMessage} */ (event.data)); |
168 }, false); | 178 }, false); |
169 | 179 |
170 if (remoting.settings.CLIENT_PLUGIN_TYPE == 'native') { | 180 if (remoting.settings.CLIENT_PLUGIN_TYPE == 'native') { |
171 window.setTimeout(this.showPluginForClickToPlay_.bind(this), 500); | 181 window.setTimeout(this.showPluginForClickToPlay_.bind(this), 500); |
172 } | 182 } |
173 }; | 183 }; |
174 | 184 |
175 /** | 185 /** |
176 * Creates plugin element without adding it to a container. | 186 * Creates plugin element without adding it to a container. |
177 * | 187 * |
178 * @return {remoting.ViewerPlugin} Plugin element | 188 * @return {HTMLEmbedElement} Plugin element |
179 */ | 189 */ |
180 remoting.ClientPluginImpl.createPluginElement_ = function() { | 190 remoting.ClientPluginImpl.createPluginElement_ = function() { |
181 var plugin = /** @type {remoting.ViewerPlugin} */ | 191 var plugin = |
182 document.createElement('embed'); | 192 /** @type {HTMLEmbedElement} */ (document.createElement('embed')); |
183 if (remoting.settings.CLIENT_PLUGIN_TYPE == 'pnacl') { | 193 if (remoting.settings.CLIENT_PLUGIN_TYPE == 'pnacl') { |
184 plugin.src = 'remoting_client_pnacl.nmf'; | 194 plugin.src = 'remoting_client_pnacl.nmf'; |
185 plugin.type = 'application/x-pnacl'; | 195 plugin.type = 'application/x-pnacl'; |
186 } else if (remoting.settings.CLIENT_PLUGIN_TYPE == 'nacl') { | 196 } else if (remoting.settings.CLIENT_PLUGIN_TYPE == 'nacl') { |
187 plugin.src = 'remoting_client_nacl.nmf'; | 197 plugin.src = 'remoting_client_nacl.nmf'; |
188 plugin.type = 'application/x-nacl'; | 198 plugin.type = 'application/x-nacl'; |
189 } else { | 199 } else { |
190 plugin.src = 'about://none'; | 200 plugin.src = 'about://none'; |
191 plugin.type = 'application/vnd.chromium.remoting-viewer'; | 201 plugin.type = 'application/vnd.chromium.remoting-viewer'; |
192 } | 202 } |
193 plugin.width = 0; | 203 plugin.width = '0'; |
194 plugin.height = 0; | 204 plugin.height = '0'; |
195 plugin.tabIndex = 0; // Required, otherwise focus() doesn't work. | 205 plugin.tabIndex = 0; // Required, otherwise focus() doesn't work. |
196 return plugin; | 206 return plugin; |
197 } | 207 } |
198 | 208 |
199 /** | 209 /** |
200 * Chromoting session API version (for this javascript). | 210 * Chromoting session API version (for this javascript). |
201 * This is compared with the plugin API version to verify that they are | 211 * This is compared with the plugin API version to verify that they are |
202 * compatible. | 212 * compatible. |
203 * | 213 * |
204 * @const | 214 * @const |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 | 266 |
257 /** | 267 /** |
258 * @param {function():void} handler | 268 * @param {function():void} handler |
259 */ | 269 */ |
260 remoting.ClientPluginImpl.prototype.setDesktopSizeUpdateHandler = | 270 remoting.ClientPluginImpl.prototype.setDesktopSizeUpdateHandler = |
261 function(handler) { | 271 function(handler) { |
262 this.onDesktopSizeUpdateHandler_ = handler; | 272 this.onDesktopSizeUpdateHandler_ = handler; |
263 }; | 273 }; |
264 | 274 |
265 /** | 275 /** |
266 * @param {function():void} handler | 276 * @param {function(Array.<Array.<number>>):void} handler |
267 */ | 277 */ |
268 remoting.ClientPluginImpl.prototype.setDesktopShapeUpdateHandler = | 278 remoting.ClientPluginImpl.prototype.setDesktopShapeUpdateHandler = |
269 function(handler) { | 279 function(handler) { |
270 this.onDesktopShapeUpdateHandler_ = handler; | 280 this.onDesktopShapeUpdateHandler_ = handler; |
271 }; | 281 }; |
272 | 282 |
273 /** | 283 /** |
274 * @param {function(!Array.<string>):void} handler | 284 * @param {function(!Array.<string>):void} handler |
275 */ | 285 */ |
276 remoting.ClientPluginImpl.prototype.setCapabilitiesHandler = function(handler) { | 286 remoting.ClientPluginImpl.prototype.setCapabilitiesHandler = function(handler) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 }; | 318 }; |
309 | 319 |
310 /** | 320 /** |
311 * @param {function(boolean):void} handler | 321 * @param {function(boolean):void} handler |
312 */ | 322 */ |
313 remoting.ClientPluginImpl.prototype.setFetchPinHandler = function(handler) { | 323 remoting.ClientPluginImpl.prototype.setFetchPinHandler = function(handler) { |
314 this.fetchPinHandler_ = handler; | 324 this.fetchPinHandler_ = handler; |
315 }; | 325 }; |
316 | 326 |
317 /** | 327 /** |
318 * @param {string|{method:string, data:Object.<string,*>}} | 328 * @param {string|remoting.ClientPluginMessage} |
319 * rawMessage Message from the plugin. | 329 * rawMessage Message from the plugin. |
320 * @private | 330 * @private |
321 */ | 331 */ |
322 remoting.ClientPluginImpl.prototype.handleMessage_ = function(rawMessage) { | 332 remoting.ClientPluginImpl.prototype.handleMessage_ = function(rawMessage) { |
323 var message = | 333 var message = |
324 /** @type {{method:string, data:Object.<string,*>}} */ | 334 /** @type {remoting.ClientPluginMessage} */ |
325 ((typeof(rawMessage) == 'string') ? base.jsonParseSafe(rawMessage) | 335 ((typeof(rawMessage) == 'string') ? base.jsonParseSafe(rawMessage) |
326 : rawMessage); | 336 : rawMessage); |
327 if (!message || !('method' in message) || !('data' in message)) { | 337 if (!message || !('method' in message) || !('data' in message)) { |
328 console.error('Received invalid message from the plugin:', rawMessage); | 338 console.error('Received invalid message from the plugin:', rawMessage); |
329 return; | 339 return; |
330 } | 340 } |
331 | 341 |
332 try { | 342 try { |
333 this.handleMessageMethod_(message); | 343 this.handleMessageMethod_(message); |
334 } catch(e) { | 344 } catch(/** @type {*} */ e) { |
335 console.error(/** @type {*} */ (e)); | 345 console.error(e); |
336 } | 346 } |
337 } | 347 } |
338 | 348 |
339 /** | 349 /** |
340 * @param {{method:string, data:Object.<string,*>}} | 350 * @param {remoting.ClientPluginMessage} |
341 * message Parsed message from the plugin. | 351 * message Parsed message from the plugin. |
342 * @private | 352 * @private |
343 */ | 353 */ |
344 remoting.ClientPluginImpl.prototype.handleMessageMethod_ = function(message) { | 354 remoting.ClientPluginImpl.prototype.handleMessageMethod_ = function(message) { |
345 /** | 355 /** |
346 * Splits a string into a list of words delimited by spaces. | 356 * Splits a string into a list of words delimited by spaces. |
347 * @param {string} str String that should be split. | 357 * @param {string} str String that should be split. |
348 * @return {!Array.<string>} List of words. | 358 * @return {!Array.<string>} List of words. |
349 */ | 359 */ |
350 var tokenize = function(str) { | 360 var tokenize = function(str) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 // 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 |
437 // is not a number. | 447 // is not a number. |
438 getNumberAttr(message.data, 'videoBandwidth'); | 448 getNumberAttr(message.data, 'videoBandwidth'); |
439 getNumberAttr(message.data, 'videoFrameRate'); | 449 getNumberAttr(message.data, 'videoFrameRate'); |
440 getNumberAttr(message.data, 'captureLatency'); | 450 getNumberAttr(message.data, 'captureLatency'); |
441 getNumberAttr(message.data, 'encodeLatency'); | 451 getNumberAttr(message.data, 'encodeLatency'); |
442 getNumberAttr(message.data, 'decodeLatency'); | 452 getNumberAttr(message.data, 'decodeLatency'); |
443 getNumberAttr(message.data, 'renderLatency'); | 453 getNumberAttr(message.data, 'renderLatency'); |
444 getNumberAttr(message.data, 'roundtripLatency'); | 454 getNumberAttr(message.data, 'roundtripLatency'); |
445 this.perfStats_ = | 455 this.perfStats_ = |
446 /** @type {remoting.ClientSession.PerfStats} */ message.data; | 456 /** @type {remoting.ClientSession.PerfStats} */ (message.data); |
447 | 457 |
448 } else if (message.method == 'injectClipboardItem') { | 458 } else if (message.method == 'injectClipboardItem') { |
449 var mimetype = getStringAttr(message.data, 'mimeType'); | 459 var mimetype = getStringAttr(message.data, 'mimeType'); |
450 var item = getStringAttr(message.data, 'item'); | 460 var item = getStringAttr(message.data, 'item'); |
451 if (remoting.clipboard) { | 461 if (remoting.clipboard) { |
452 remoting.clipboard.fromHost(mimetype, item); | 462 remoting.clipboard.fromHost(mimetype, item); |
453 } | 463 } |
454 | 464 |
455 } else if (message.method == 'onFirstFrameReceived') { | 465 } else if (message.method == 'onFirstFrameReceived') { |
456 if (remoting.clientSession) { | 466 if (remoting.clientSession) { |
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 remoting.DefaultClientPluginFactory.prototype.preloadPlugin = function() { | 971 remoting.DefaultClientPluginFactory.prototype.preloadPlugin = function() { |
962 if (remoting.settings.CLIENT_PLUGIN_TYPE != 'pnacl') { | 972 if (remoting.settings.CLIENT_PLUGIN_TYPE != 'pnacl') { |
963 return; | 973 return; |
964 } | 974 } |
965 | 975 |
966 var plugin = remoting.ClientPluginImpl.createPluginElement_(); | 976 var plugin = remoting.ClientPluginImpl.createPluginElement_(); |
967 plugin.addEventListener( | 977 plugin.addEventListener( |
968 'loadend', function() { document.body.removeChild(plugin); }, false); | 978 'loadend', function() { document.body.removeChild(plugin); }, false); |
969 document.body.appendChild(plugin); | 979 document.body.appendChild(plugin); |
970 }; | 980 }; |
OLD | NEW |