| 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 /** | 19 /** |
| 20 * @param {remoting.ViewerPlugin} plugin The plugin embed element. | 20 * @param {Element} container The container for the embed element. |
| 21 * @param {function(string, string):boolean} onExtensionMessage The handler for | 21 * @param {function(string, string):boolean} onExtensionMessage The handler for |
| 22 * protocol extension messages. Returns true if a message is recognized; | 22 * protocol extension messages. Returns true if a message is recognized; |
| 23 * false otherwise. | 23 * false otherwise. |
| 24 * @constructor | 24 * @constructor |
| 25 */ | 25 */ |
| 26 remoting.ClientPlugin = function(plugin, onExtensionMessage) { | 26 remoting.ClientPlugin = function(container, onExtensionMessage) { |
| 27 this.plugin = plugin; | 27 this.plugin_ = /** @type {remoting.ViewerPlugin} */ |
| 28 document.createElement('embed'); |
| 29 |
| 30 this.plugin_.id = 'session-client-plugin'; |
| 31 if (remoting.settings.CLIENT_PLUGIN_TYPE == 'pnacl') { |
| 32 this.plugin_.src = 'remoting_client_pnacl.nmf'; |
| 33 this.plugin_.type = 'application/x-pnacl'; |
| 34 } else if (remoting.settings.CLIENT_PLUGIN_TYPE == 'nacl') { |
| 35 this.plugin_.src = 'remoting_client_nacl.nmf'; |
| 36 this.plugin_.type = 'application/x-nacl'; |
| 37 } else { |
| 38 this.plugin_.src = 'about://none'; |
| 39 this.plugin_.type = 'application/vnd.chromium.remoting-viewer'; |
| 40 } |
| 41 |
| 42 this.plugin_.width = 0; |
| 43 this.plugin_.height = 0; |
| 44 this.plugin_.tabIndex = 0; // Required, otherwise focus() doesn't work. |
| 45 container.appendChild(this.plugin_); |
| 46 |
| 28 this.onExtensionMessage_ = onExtensionMessage; | 47 this.onExtensionMessage_ = onExtensionMessage; |
| 29 | 48 |
| 30 this.desktopWidth = 0; | 49 this.desktopWidth = 0; |
| 31 this.desktopHeight = 0; | 50 this.desktopHeight = 0; |
| 32 this.desktopXDpi = 96; | 51 this.desktopXDpi = 96; |
| 33 this.desktopYDpi = 96; | 52 this.desktopYDpi = 96; |
| 34 | 53 |
| 35 /** @param {string} iq The Iq stanza received from the host. */ | 54 /** @param {string} iq The Iq stanza received from the host. */ |
| 36 this.onOutgoingIqHandler = function (iq) {}; | 55 this.onOutgoingIqHandler = function (iq) {}; |
| 37 /** @param {string} message Log message. */ | 56 /** @param {string} message Log message. */ |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 /** @type {function(boolean)|null} */ | 99 /** @type {function(boolean)|null} */ |
| 81 this.onInitializedCallback_ = null; | 100 this.onInitializedCallback_ = null; |
| 82 /** @type {function(string, string):void} */ | 101 /** @type {function(string, string):void} */ |
| 83 this.onPairingComplete_ = function(clientId, sharedSecret) {}; | 102 this.onPairingComplete_ = function(clientId, sharedSecret) {}; |
| 84 /** @type {remoting.ClientSession.PerfStats} */ | 103 /** @type {remoting.ClientSession.PerfStats} */ |
| 85 this.perfStats_ = new remoting.ClientSession.PerfStats(); | 104 this.perfStats_ = new remoting.ClientSession.PerfStats(); |
| 86 | 105 |
| 87 /** @type {remoting.ClientPlugin} */ | 106 /** @type {remoting.ClientPlugin} */ |
| 88 var that = this; | 107 var that = this; |
| 89 /** @param {Event} event Message event from the plugin. */ | 108 /** @param {Event} event Message event from the plugin. */ |
| 90 this.plugin.addEventListener('message', function(event) { | 109 this.plugin_.addEventListener('message', function(event) { |
| 91 that.handleMessage_(event.data); | 110 that.handleMessage_(event.data); |
| 92 }, false); | 111 }, false); |
| 93 | 112 |
| 94 if (remoting.settings.CLIENT_PLUGIN_TYPE == 'native') { | 113 if (remoting.settings.CLIENT_PLUGIN_TYPE == 'native') { |
| 95 window.setTimeout(this.showPluginForClickToPlay_.bind(this), 500); | 114 window.setTimeout(this.showPluginForClickToPlay_.bind(this), 500); |
| 96 } | 115 } |
| 97 }; | 116 }; |
| 98 | 117 |
| 99 /** | 118 /** |
| 100 * Set of features for which hasFeature() can be used to test. | 119 * Set of features for which hasFeature() can be used to test. |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 | 392 |
| 374 context.putImageData(imageData, 0, 0); | 393 context.putImageData(imageData, 0, 0); |
| 375 this.updateMouseCursorImage(canvas.toDataURL(), hotspotX, hotspotY); | 394 this.updateMouseCursorImage(canvas.toDataURL(), hotspotX, hotspotY); |
| 376 } | 395 } |
| 377 }; | 396 }; |
| 378 | 397 |
| 379 /** | 398 /** |
| 380 * Deletes the plugin. | 399 * Deletes the plugin. |
| 381 */ | 400 */ |
| 382 remoting.ClientPlugin.prototype.cleanup = function() { | 401 remoting.ClientPlugin.prototype.cleanup = function() { |
| 383 this.plugin.parentNode.removeChild(this.plugin); | 402 if (this.plugin_) { |
| 403 this.plugin_.parentNode.removeChild(this.plugin_); |
| 404 this.plugin_ = null; |
| 405 } |
| 384 }; | 406 }; |
| 385 | 407 |
| 386 /** | 408 /** |
| 387 * @return {HTMLEmbedElement} HTML element that correspods to the plugin. | 409 * @return {HTMLEmbedElement} HTML element that corresponds to the plugin. |
| 388 */ | 410 */ |
| 389 remoting.ClientPlugin.prototype.element = function() { | 411 remoting.ClientPlugin.prototype.element = function() { |
| 390 return this.plugin; | 412 return this.plugin_; |
| 391 }; | 413 }; |
| 392 | 414 |
| 393 /** | 415 /** |
| 394 * @param {function(boolean): void} onDone | 416 * @param {function(boolean): void} onDone |
| 395 */ | 417 */ |
| 396 remoting.ClientPlugin.prototype.initialize = function(onDone) { | 418 remoting.ClientPlugin.prototype.initialize = function(onDone) { |
| 397 if (this.helloReceived_) { | 419 if (this.helloReceived_) { |
| 398 onDone(true); | 420 onDone(true); |
| 399 } else { | 421 } else { |
| 400 this.onInitializedCallback_ = onDone; | 422 this.onInitializedCallback_ = onDone; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 431 * @return {boolean} True if the plugin supports the injectKeyEvent API. | 453 * @return {boolean} True if the plugin supports the injectKeyEvent API. |
| 432 */ | 454 */ |
| 433 remoting.ClientPlugin.prototype.isInjectKeyEventSupported = function() { | 455 remoting.ClientPlugin.prototype.isInjectKeyEventSupported = function() { |
| 434 return this.pluginApiVersion_ >= 6; | 456 return this.pluginApiVersion_ >= 6; |
| 435 }; | 457 }; |
| 436 | 458 |
| 437 /** | 459 /** |
| 438 * @param {string} iq Incoming IQ stanza. | 460 * @param {string} iq Incoming IQ stanza. |
| 439 */ | 461 */ |
| 440 remoting.ClientPlugin.prototype.onIncomingIq = function(iq) { | 462 remoting.ClientPlugin.prototype.onIncomingIq = function(iq) { |
| 441 if (this.plugin && this.plugin.postMessage) { | 463 if (this.plugin_ && this.plugin_.postMessage) { |
| 442 this.plugin.postMessage(JSON.stringify( | 464 this.plugin_.postMessage(JSON.stringify( |
| 443 { method: 'incomingIq', data: { iq: iq } })); | 465 { method: 'incomingIq', data: { iq: iq } })); |
| 444 } else { | 466 } else { |
| 445 // plugin.onIq may not be set after the plugin has been shut | 467 // plugin.onIq may not be set after the plugin has been shut |
| 446 // down. Particularly this happens when we receive response to | 468 // down. Particularly this happens when we receive response to |
| 447 // session-terminate stanza. | 469 // session-terminate stanza. |
| 448 console.warn('plugin.onIq is not set so dropping incoming message.'); | 470 console.warn('plugin.onIq is not set so dropping incoming message.'); |
| 449 } | 471 } |
| 450 }; | 472 }; |
| 451 | 473 |
| 452 /** | 474 /** |
| (...skipping 15 matching lines...) Expand all Loading... |
| 468 remoting.ClientPlugin.prototype.connect = function( | 490 remoting.ClientPlugin.prototype.connect = function( |
| 469 hostJid, hostPublicKey, localJid, sharedSecret, | 491 hostJid, hostPublicKey, localJid, sharedSecret, |
| 470 authenticationMethods, authenticationTag, | 492 authenticationMethods, authenticationTag, |
| 471 clientPairingId, clientPairedSecret) { | 493 clientPairingId, clientPairedSecret) { |
| 472 var keyFilter = ''; | 494 var keyFilter = ''; |
| 473 if (remoting.platformIsMac()) { | 495 if (remoting.platformIsMac()) { |
| 474 keyFilter = 'mac'; | 496 keyFilter = 'mac'; |
| 475 } else if (remoting.platformIsChromeOS()) { | 497 } else if (remoting.platformIsChromeOS()) { |
| 476 keyFilter = 'cros'; | 498 keyFilter = 'cros'; |
| 477 } | 499 } |
| 478 this.plugin.postMessage(JSON.stringify( | 500 this.plugin_.postMessage(JSON.stringify( |
| 479 { method: 'delegateLargeCursors', data: {} })); | 501 { method: 'delegateLargeCursors', data: {} })); |
| 480 this.plugin.postMessage(JSON.stringify( | 502 this.plugin_.postMessage(JSON.stringify( |
| 481 { method: 'connect', data: { | 503 { method: 'connect', data: { |
| 482 hostJid: hostJid, | 504 hostJid: hostJid, |
| 483 hostPublicKey: hostPublicKey, | 505 hostPublicKey: hostPublicKey, |
| 484 localJid: localJid, | 506 localJid: localJid, |
| 485 sharedSecret: sharedSecret, | 507 sharedSecret: sharedSecret, |
| 486 authenticationMethods: authenticationMethods, | 508 authenticationMethods: authenticationMethods, |
| 487 authenticationTag: authenticationTag, | 509 authenticationTag: authenticationTag, |
| 488 capabilities: this.capabilities_.join(" "), | 510 capabilities: this.capabilities_.join(" "), |
| 489 clientPairingId: clientPairingId, | 511 clientPairingId: clientPairingId, |
| 490 clientPairedSecret: clientPairedSecret, | 512 clientPairedSecret: clientPairedSecret, |
| 491 keyFilter: keyFilter | 513 keyFilter: keyFilter |
| 492 } | 514 } |
| 493 })); | 515 })); |
| 494 }; | 516 }; |
| 495 | 517 |
| 496 /** | 518 /** |
| 497 * Release all currently pressed keys. | 519 * Release all currently pressed keys. |
| 498 */ | 520 */ |
| 499 remoting.ClientPlugin.prototype.releaseAllKeys = function() { | 521 remoting.ClientPlugin.prototype.releaseAllKeys = function() { |
| 500 this.plugin.postMessage(JSON.stringify( | 522 this.plugin_.postMessage(JSON.stringify( |
| 501 { method: 'releaseAllKeys', data: {} })); | 523 { method: 'releaseAllKeys', data: {} })); |
| 502 }; | 524 }; |
| 503 | 525 |
| 504 /** | 526 /** |
| 505 * Send a key event to the host. | 527 * Send a key event to the host. |
| 506 * | 528 * |
| 507 * @param {number} usbKeycode The USB-style code of the key to inject. | 529 * @param {number} usbKeycode The USB-style code of the key to inject. |
| 508 * @param {boolean} pressed True to inject a key press, False for a release. | 530 * @param {boolean} pressed True to inject a key press, False for a release. |
| 509 */ | 531 */ |
| 510 remoting.ClientPlugin.prototype.injectKeyEvent = | 532 remoting.ClientPlugin.prototype.injectKeyEvent = |
| 511 function(usbKeycode, pressed) { | 533 function(usbKeycode, pressed) { |
| 512 this.plugin.postMessage(JSON.stringify( | 534 this.plugin_.postMessage(JSON.stringify( |
| 513 { method: 'injectKeyEvent', data: { | 535 { method: 'injectKeyEvent', data: { |
| 514 'usbKeycode': usbKeycode, | 536 'usbKeycode': usbKeycode, |
| 515 'pressed': pressed} | 537 'pressed': pressed} |
| 516 })); | 538 })); |
| 517 }; | 539 }; |
| 518 | 540 |
| 519 /** | 541 /** |
| 520 * Remap one USB keycode to another in all subsequent key events. | 542 * Remap one USB keycode to another in all subsequent key events. |
| 521 * | 543 * |
| 522 * @param {number} fromKeycode The USB-style code of the key to remap. | 544 * @param {number} fromKeycode The USB-style code of the key to remap. |
| 523 * @param {number} toKeycode The USB-style code to remap the key to. | 545 * @param {number} toKeycode The USB-style code to remap the key to. |
| 524 */ | 546 */ |
| 525 remoting.ClientPlugin.prototype.remapKey = | 547 remoting.ClientPlugin.prototype.remapKey = |
| 526 function(fromKeycode, toKeycode) { | 548 function(fromKeycode, toKeycode) { |
| 527 this.plugin.postMessage(JSON.stringify( | 549 this.plugin_.postMessage(JSON.stringify( |
| 528 { method: 'remapKey', data: { | 550 { method: 'remapKey', data: { |
| 529 'fromKeycode': fromKeycode, | 551 'fromKeycode': fromKeycode, |
| 530 'toKeycode': toKeycode} | 552 'toKeycode': toKeycode} |
| 531 })); | 553 })); |
| 532 }; | 554 }; |
| 533 | 555 |
| 534 /** | 556 /** |
| 535 * Enable/disable redirection of the specified key to the web-app. | 557 * Enable/disable redirection of the specified key to the web-app. |
| 536 * | 558 * |
| 537 * @param {number} keycode The USB-style code of the key. | 559 * @param {number} keycode The USB-style code of the key. |
| 538 * @param {Boolean} trap True to enable trapping, False to disable. | 560 * @param {Boolean} trap True to enable trapping, False to disable. |
| 539 */ | 561 */ |
| 540 remoting.ClientPlugin.prototype.trapKey = function(keycode, trap) { | 562 remoting.ClientPlugin.prototype.trapKey = function(keycode, trap) { |
| 541 this.plugin.postMessage(JSON.stringify( | 563 this.plugin_.postMessage(JSON.stringify( |
| 542 { method: 'trapKey', data: { | 564 { method: 'trapKey', data: { |
| 543 'keycode': keycode, | 565 'keycode': keycode, |
| 544 'trap': trap} | 566 'trap': trap} |
| 545 })); | 567 })); |
| 546 }; | 568 }; |
| 547 | 569 |
| 548 /** | 570 /** |
| 549 * Returns an associative array with a set of stats for this connecton. | 571 * Returns an associative array with a set of stats for this connecton. |
| 550 * | 572 * |
| 551 * @return {remoting.ClientSession.PerfStats} The connection statistics. | 573 * @return {remoting.ClientSession.PerfStats} The connection statistics. |
| 552 */ | 574 */ |
| 553 remoting.ClientPlugin.prototype.getPerfStats = function() { | 575 remoting.ClientPlugin.prototype.getPerfStats = function() { |
| 554 return this.perfStats_; | 576 return this.perfStats_; |
| 555 }; | 577 }; |
| 556 | 578 |
| 557 /** | 579 /** |
| 558 * Sends a clipboard item to the host. | 580 * Sends a clipboard item to the host. |
| 559 * | 581 * |
| 560 * @param {string} mimeType The MIME type of the clipboard item. | 582 * @param {string} mimeType The MIME type of the clipboard item. |
| 561 * @param {string} item The clipboard item. | 583 * @param {string} item The clipboard item. |
| 562 */ | 584 */ |
| 563 remoting.ClientPlugin.prototype.sendClipboardItem = | 585 remoting.ClientPlugin.prototype.sendClipboardItem = |
| 564 function(mimeType, item) { | 586 function(mimeType, item) { |
| 565 if (!this.hasFeature(remoting.ClientPlugin.Feature.SEND_CLIPBOARD_ITEM)) | 587 if (!this.hasFeature(remoting.ClientPlugin.Feature.SEND_CLIPBOARD_ITEM)) |
| 566 return; | 588 return; |
| 567 this.plugin.postMessage(JSON.stringify( | 589 this.plugin_.postMessage(JSON.stringify( |
| 568 { method: 'sendClipboardItem', | 590 { method: 'sendClipboardItem', |
| 569 data: { mimeType: mimeType, item: item }})); | 591 data: { mimeType: mimeType, item: item }})); |
| 570 }; | 592 }; |
| 571 | 593 |
| 572 /** | 594 /** |
| 573 * Notifies the host that the client has the specified size and pixel density. | 595 * Notifies the host that the client has the specified size and pixel density. |
| 574 * | 596 * |
| 575 * @param {number} width The available client width in DIPs. | 597 * @param {number} width The available client width in DIPs. |
| 576 * @param {number} height The available client height in DIPs. | 598 * @param {number} height The available client height in DIPs. |
| 577 * @param {number} device_scale The number of device pixels per DIP. | 599 * @param {number} device_scale The number of device pixels per DIP. |
| 578 */ | 600 */ |
| 579 remoting.ClientPlugin.prototype.notifyClientResolution = | 601 remoting.ClientPlugin.prototype.notifyClientResolution = |
| 580 function(width, height, device_scale) { | 602 function(width, height, device_scale) { |
| 581 if (this.hasFeature(remoting.ClientPlugin.Feature.NOTIFY_CLIENT_RESOLUTION)) { | 603 if (this.hasFeature(remoting.ClientPlugin.Feature.NOTIFY_CLIENT_RESOLUTION)) { |
| 582 var dpi = Math.floor(device_scale * 96); | 604 var dpi = Math.floor(device_scale * 96); |
| 583 this.plugin.postMessage(JSON.stringify( | 605 this.plugin_.postMessage(JSON.stringify( |
| 584 { method: 'notifyClientResolution', | 606 { method: 'notifyClientResolution', |
| 585 data: { width: Math.floor(width * device_scale), | 607 data: { width: Math.floor(width * device_scale), |
| 586 height: Math.floor(height * device_scale), | 608 height: Math.floor(height * device_scale), |
| 587 x_dpi: dpi, y_dpi: dpi }})); | 609 x_dpi: dpi, y_dpi: dpi }})); |
| 588 } | 610 } |
| 589 }; | 611 }; |
| 590 | 612 |
| 591 /** | 613 /** |
| 592 * Requests that the host pause or resume sending video updates. | 614 * Requests that the host pause or resume sending video updates. |
| 593 * | 615 * |
| 594 * @param {boolean} pause True to suspend video updates, false otherwise. | 616 * @param {boolean} pause True to suspend video updates, false otherwise. |
| 595 */ | 617 */ |
| 596 remoting.ClientPlugin.prototype.pauseVideo = | 618 remoting.ClientPlugin.prototype.pauseVideo = |
| 597 function(pause) { | 619 function(pause) { |
| 598 if (this.hasFeature(remoting.ClientPlugin.Feature.VIDEO_CONTROL)) { | 620 if (this.hasFeature(remoting.ClientPlugin.Feature.VIDEO_CONTROL)) { |
| 599 this.plugin.postMessage(JSON.stringify( | 621 this.plugin_.postMessage(JSON.stringify( |
| 600 { method: 'videoControl', data: { pause: pause }})); | 622 { method: 'videoControl', data: { pause: pause }})); |
| 601 } else if (this.hasFeature(remoting.ClientPlugin.Feature.PAUSE_VIDEO)) { | 623 } else if (this.hasFeature(remoting.ClientPlugin.Feature.PAUSE_VIDEO)) { |
| 602 this.plugin.postMessage(JSON.stringify( | 624 this.plugin_.postMessage(JSON.stringify( |
| 603 { method: 'pauseVideo', data: { pause: pause }})); | 625 { method: 'pauseVideo', data: { pause: pause }})); |
| 604 } | 626 } |
| 605 }; | 627 }; |
| 606 | 628 |
| 607 /** | 629 /** |
| 608 * Requests that the host pause or resume sending audio updates. | 630 * Requests that the host pause or resume sending audio updates. |
| 609 * | 631 * |
| 610 * @param {boolean} pause True to suspend audio updates, false otherwise. | 632 * @param {boolean} pause True to suspend audio updates, false otherwise. |
| 611 */ | 633 */ |
| 612 remoting.ClientPlugin.prototype.pauseAudio = | 634 remoting.ClientPlugin.prototype.pauseAudio = |
| 613 function(pause) { | 635 function(pause) { |
| 614 if (!this.hasFeature(remoting.ClientPlugin.Feature.PAUSE_AUDIO)) { | 636 if (!this.hasFeature(remoting.ClientPlugin.Feature.PAUSE_AUDIO)) { |
| 615 return; | 637 return; |
| 616 } | 638 } |
| 617 this.plugin.postMessage(JSON.stringify( | 639 this.plugin_.postMessage(JSON.stringify( |
| 618 { method: 'pauseAudio', data: { pause: pause }})); | 640 { method: 'pauseAudio', data: { pause: pause }})); |
| 619 }; | 641 }; |
| 620 | 642 |
| 621 /** | 643 /** |
| 622 * Requests that the host configure the video codec for lossless encode. | 644 * Requests that the host configure the video codec for lossless encode. |
| 623 * | 645 * |
| 624 * @param {boolean} wantLossless True to request lossless encoding. | 646 * @param {boolean} wantLossless True to request lossless encoding. |
| 625 */ | 647 */ |
| 626 remoting.ClientPlugin.prototype.setLosslessEncode = | 648 remoting.ClientPlugin.prototype.setLosslessEncode = |
| 627 function(wantLossless) { | 649 function(wantLossless) { |
| 628 if (!this.hasFeature(remoting.ClientPlugin.Feature.VIDEO_CONTROL)) { | 650 if (!this.hasFeature(remoting.ClientPlugin.Feature.VIDEO_CONTROL)) { |
| 629 return; | 651 return; |
| 630 } | 652 } |
| 631 this.plugin.postMessage(JSON.stringify( | 653 this.plugin_.postMessage(JSON.stringify( |
| 632 { method: 'videoControl', data: { losslessEncode: wantLossless }})); | 654 { method: 'videoControl', data: { losslessEncode: wantLossless }})); |
| 633 }; | 655 }; |
| 634 | 656 |
| 635 /** | 657 /** |
| 636 * Requests that the host configure the video codec for lossless color. | 658 * Requests that the host configure the video codec for lossless color. |
| 637 * | 659 * |
| 638 * @param {boolean} wantLossless True to request lossless color. | 660 * @param {boolean} wantLossless True to request lossless color. |
| 639 */ | 661 */ |
| 640 remoting.ClientPlugin.prototype.setLosslessColor = | 662 remoting.ClientPlugin.prototype.setLosslessColor = |
| 641 function(wantLossless) { | 663 function(wantLossless) { |
| 642 if (!this.hasFeature(remoting.ClientPlugin.Feature.VIDEO_CONTROL)) { | 664 if (!this.hasFeature(remoting.ClientPlugin.Feature.VIDEO_CONTROL)) { |
| 643 return; | 665 return; |
| 644 } | 666 } |
| 645 this.plugin.postMessage(JSON.stringify( | 667 this.plugin_.postMessage(JSON.stringify( |
| 646 { method: 'videoControl', data: { losslessColor: wantLossless }})); | 668 { method: 'videoControl', data: { losslessColor: wantLossless }})); |
| 647 }; | 669 }; |
| 648 | 670 |
| 649 /** | 671 /** |
| 650 * Called when a PIN is obtained from the user. | 672 * Called when a PIN is obtained from the user. |
| 651 * | 673 * |
| 652 * @param {string} pin The PIN. | 674 * @param {string} pin The PIN. |
| 653 */ | 675 */ |
| 654 remoting.ClientPlugin.prototype.onPinFetched = | 676 remoting.ClientPlugin.prototype.onPinFetched = |
| 655 function(pin) { | 677 function(pin) { |
| 656 if (!this.hasFeature(remoting.ClientPlugin.Feature.ASYNC_PIN)) { | 678 if (!this.hasFeature(remoting.ClientPlugin.Feature.ASYNC_PIN)) { |
| 657 return; | 679 return; |
| 658 } | 680 } |
| 659 this.plugin.postMessage(JSON.stringify( | 681 this.plugin_.postMessage(JSON.stringify( |
| 660 { method: 'onPinFetched', data: { pin: pin }})); | 682 { method: 'onPinFetched', data: { pin: pin }})); |
| 661 }; | 683 }; |
| 662 | 684 |
| 663 /** | 685 /** |
| 664 * Tells the plugin to ask for the PIN asynchronously. | 686 * Tells the plugin to ask for the PIN asynchronously. |
| 665 */ | 687 */ |
| 666 remoting.ClientPlugin.prototype.useAsyncPinDialog = | 688 remoting.ClientPlugin.prototype.useAsyncPinDialog = |
| 667 function() { | 689 function() { |
| 668 if (!this.hasFeature(remoting.ClientPlugin.Feature.ASYNC_PIN)) { | 690 if (!this.hasFeature(remoting.ClientPlugin.Feature.ASYNC_PIN)) { |
| 669 return; | 691 return; |
| 670 } | 692 } |
| 671 this.plugin.postMessage(JSON.stringify( | 693 this.plugin_.postMessage(JSON.stringify( |
| 672 { method: 'useAsyncPinDialog', data: {} })); | 694 { method: 'useAsyncPinDialog', data: {} })); |
| 673 }; | 695 }; |
| 674 | 696 |
| 675 /** | 697 /** |
| 676 * Sets the third party authentication token and shared secret. | 698 * Sets the third party authentication token and shared secret. |
| 677 * | 699 * |
| 678 * @param {string} token The token received from the token URL. | 700 * @param {string} token The token received from the token URL. |
| 679 * @param {string} sharedSecret Shared secret received from the token URL. | 701 * @param {string} sharedSecret Shared secret received from the token URL. |
| 680 */ | 702 */ |
| 681 remoting.ClientPlugin.prototype.onThirdPartyTokenFetched = function( | 703 remoting.ClientPlugin.prototype.onThirdPartyTokenFetched = function( |
| 682 token, sharedSecret) { | 704 token, sharedSecret) { |
| 683 this.plugin.postMessage(JSON.stringify( | 705 this.plugin_.postMessage(JSON.stringify( |
| 684 { method: 'onThirdPartyTokenFetched', | 706 { method: 'onThirdPartyTokenFetched', |
| 685 data: { token: token, sharedSecret: sharedSecret}})); | 707 data: { token: token, sharedSecret: sharedSecret}})); |
| 686 }; | 708 }; |
| 687 | 709 |
| 688 /** | 710 /** |
| 689 * Request pairing with the host for PIN-less authentication. | 711 * Request pairing with the host for PIN-less authentication. |
| 690 * | 712 * |
| 691 * @param {string} clientName The human-readable name of the client. | 713 * @param {string} clientName The human-readable name of the client. |
| 692 * @param {function(string, string):void} onDone, Callback to receive the | 714 * @param {function(string, string):void} onDone, Callback to receive the |
| 693 * client id and shared secret when they are available. | 715 * client id and shared secret when they are available. |
| 694 */ | 716 */ |
| 695 remoting.ClientPlugin.prototype.requestPairing = | 717 remoting.ClientPlugin.prototype.requestPairing = |
| 696 function(clientName, onDone) { | 718 function(clientName, onDone) { |
| 697 if (!this.hasFeature(remoting.ClientPlugin.Feature.PINLESS_AUTH)) { | 719 if (!this.hasFeature(remoting.ClientPlugin.Feature.PINLESS_AUTH)) { |
| 698 return; | 720 return; |
| 699 } | 721 } |
| 700 this.onPairingComplete_ = onDone; | 722 this.onPairingComplete_ = onDone; |
| 701 this.plugin.postMessage(JSON.stringify( | 723 this.plugin_.postMessage(JSON.stringify( |
| 702 { method: 'requestPairing', data: { clientName: clientName } })); | 724 { method: 'requestPairing', data: { clientName: clientName } })); |
| 703 }; | 725 }; |
| 704 | 726 |
| 705 /** | 727 /** |
| 706 * Send an extension message to the host. | 728 * Send an extension message to the host. |
| 707 * | 729 * |
| 708 * @param {string} type The message type. | 730 * @param {string} type The message type. |
| 709 * @param {string} message The message payload. | 731 * @param {string} message The message payload. |
| 710 */ | 732 */ |
| 711 remoting.ClientPlugin.prototype.sendClientMessage = | 733 remoting.ClientPlugin.prototype.sendClientMessage = |
| 712 function(type, message) { | 734 function(type, message) { |
| 713 if (!this.hasFeature(remoting.ClientPlugin.Feature.EXTENSION_MESSAGE)) { | 735 if (!this.hasFeature(remoting.ClientPlugin.Feature.EXTENSION_MESSAGE)) { |
| 714 return; | 736 return; |
| 715 } | 737 } |
| 716 this.plugin.postMessage(JSON.stringify( | 738 this.plugin_.postMessage(JSON.stringify( |
| 717 { method: 'extensionMessage', | 739 { method: 'extensionMessage', |
| 718 data: { type: type, data: message } })); | 740 data: { type: type, data: message } })); |
| 719 | 741 |
| 720 }; | 742 }; |
| 721 | 743 |
| 722 /** | 744 /** |
| 723 * Request MediaStream-based rendering. | 745 * Request MediaStream-based rendering. |
| 724 * | 746 * |
| 725 * @param {remoting.MediaSourceRenderer} mediaSourceRenderer | 747 * @param {remoting.MediaSourceRenderer} mediaSourceRenderer |
| 726 */ | 748 */ |
| 727 remoting.ClientPlugin.prototype.enableMediaSourceRendering = | 749 remoting.ClientPlugin.prototype.enableMediaSourceRendering = |
| 728 function(mediaSourceRenderer) { | 750 function(mediaSourceRenderer) { |
| 729 if (!this.hasFeature(remoting.ClientPlugin.Feature.MEDIA_SOURCE_RENDERING)) { | 751 if (!this.hasFeature(remoting.ClientPlugin.Feature.MEDIA_SOURCE_RENDERING)) { |
| 730 return; | 752 return; |
| 731 } | 753 } |
| 732 this.mediaSourceRenderer_ = mediaSourceRenderer; | 754 this.mediaSourceRenderer_ = mediaSourceRenderer; |
| 733 this.plugin.postMessage(JSON.stringify( | 755 this.plugin_.postMessage(JSON.stringify( |
| 734 { method: 'enableMediaSourceRendering', data: {} })); | 756 { method: 'enableMediaSourceRendering', data: {} })); |
| 735 }; | 757 }; |
| 736 | 758 |
| 737 /** | 759 /** |
| 738 * If we haven't yet received a "hello" message from the plugin, change its | 760 * If we haven't yet received a "hello" message from the plugin, change its |
| 739 * size so that the user can confirm it if click-to-play is enabled, or can | 761 * size so that the user can confirm it if click-to-play is enabled, or can |
| 740 * see the "this plugin is disabled" message if it is actually disabled. | 762 * see the "this plugin is disabled" message if it is actually disabled. |
| 741 * @private | 763 * @private |
| 742 */ | 764 */ |
| 743 remoting.ClientPlugin.prototype.showPluginForClickToPlay_ = function() { | 765 remoting.ClientPlugin.prototype.showPluginForClickToPlay_ = function() { |
| 744 if (!this.helloReceived_) { | 766 if (!this.helloReceived_) { |
| 745 var width = 200; | 767 var width = 200; |
| 746 var height = 200; | 768 var height = 200; |
| 747 this.plugin.style.width = width + 'px'; | 769 this.plugin_.style.width = width + 'px'; |
| 748 this.plugin.style.height = height + 'px'; | 770 this.plugin_.style.height = height + 'px'; |
| 749 // Center the plugin just underneath the "Connnecting..." dialog. | 771 // Center the plugin just underneath the "Connnecting..." dialog. |
| 750 var dialog = document.getElementById('client-dialog'); | 772 var dialog = document.getElementById('client-dialog'); |
| 751 var dialogRect = dialog.getBoundingClientRect(); | 773 var dialogRect = dialog.getBoundingClientRect(); |
| 752 this.plugin.style.top = (dialogRect.bottom + 16) + 'px'; | 774 this.plugin_.style.top = (dialogRect.bottom + 16) + 'px'; |
| 753 this.plugin.style.left = (window.innerWidth - width) / 2 + 'px'; | 775 this.plugin_.style.left = (window.innerWidth - width) / 2 + 'px'; |
| 754 this.plugin.style.position = 'fixed'; | 776 this.plugin_.style.position = 'fixed'; |
| 755 } | 777 } |
| 756 }; | 778 }; |
| 757 | 779 |
| 758 /** | 780 /** |
| 759 * Undo the CSS rules needed to make the plugin clickable for click-to-play. | 781 * Undo the CSS rules needed to make the plugin clickable for click-to-play. |
| 760 * @private | 782 * @private |
| 761 */ | 783 */ |
| 762 remoting.ClientPlugin.prototype.hidePluginForClickToPlay_ = function() { | 784 remoting.ClientPlugin.prototype.hidePluginForClickToPlay_ = function() { |
| 763 this.plugin.style.width = ''; | 785 this.plugin_.style.width = ''; |
| 764 this.plugin.style.height = ''; | 786 this.plugin_.style.height = ''; |
| 765 this.plugin.style.top = ''; | 787 this.plugin_.style.top = ''; |
| 766 this.plugin.style.left = ''; | 788 this.plugin_.style.left = ''; |
| 767 this.plugin.style.position = ''; | 789 this.plugin_.style.position = ''; |
| 768 }; | 790 }; |
| OLD | NEW |