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 |