summaryrefslogtreecommitdiffstats
path: root/remoting/webapp
diff options
context:
space:
mode:
authorlambroslambrou@chromium.org <lambroslambrou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-30 20:02:23 +0000
committerlambroslambrou@chromium.org <lambroslambrou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-30 20:02:23 +0000
commit63157e7efd57c3b7bd89af64607eea1a8f460bb6 (patch)
tree6dffd9eeee4d2a09d91cab086e03f40981fd2cc9 /remoting/webapp
parent2a5c8be4bd97e396000cfe767820c31da6ebbd84 (diff)
downloadchromium_src-63157e7efd57c3b7bd89af64607eea1a8f460bb6.zip
chromium_src-63157e7efd57c3b7bd89af64607eea1a8f460bb6.tar.gz
chromium_src-63157e7efd57c3b7bd89af64607eea1a8f460bb6.tar.bz2
Implement hello exchange with Chromoting Native Messaging host
The webapp initializes Native Messaging, sends a 'hello' message to the host and waits for a response. If this fails, the webapp gets a disconnect notification on the port (if it was successfully created) and falls back to using the NPAPI plugin. BUG=173509 TEST=manual Review URL: https://chromiumcodereview.appspot.com/13284002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191544 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/webapp')
-rw-r--r--remoting/webapp/host_controller.js58
-rw-r--r--remoting/webapp/host_native_messaging.js92
2 files changed, 104 insertions, 46 deletions
diff --git a/remoting/webapp/host_controller.js b/remoting/webapp/host_controller.js
index c35d63c..fd54442 100644
--- a/remoting/webapp/host_controller.js
+++ b/remoting/webapp/host_controller.js
@@ -9,34 +9,46 @@ var remoting = remoting || {};
/** @constructor */
remoting.HostController = function() {
+ /** @type {remoting.HostController} */
+ var that = this;
+
+ /** @type {boolean} @private */
+ this.pluginSupported_ = true;
+
/** @type {remoting.HostPlugin} @private */
- this.plugin_ = null;
- if (remoting.HostNativeMessaging.isSupported()) {
- this.plugin_ = new remoting.HostNativeMessaging();
- } else {
- this.plugin_ = remoting.HostSession.createPlugin();
- /** @type {HTMLElement} @private */
- var container = document.getElementById('daemon-plugin-container');
- container.appendChild(this.plugin_);
- }
+ this.plugin_ = new remoting.HostNativeMessaging();
- /** @param {string} version */
- var printVersion = function(version) {
- if (version == '') {
- console.log('Host not installed.');
+ /** @param {boolean} success */
+ var onNativeMessagingInit = function(success) {
+ if (success) {
+ console.log('Native Messaging supported.');
} else {
- console.log('Host version: ' + version);
+ console.log('Native Messaging unsupported, falling back to NPAPI.');
+ that.plugin_ = remoting.HostSession.createPlugin();
+ /** @type {HTMLElement} @private */
+ var container = document.getElementById('daemon-plugin-container');
+ container.appendChild(that.plugin_);
+ }
+
+ /** @param {string} version */
+ var printVersion = function(version) {
+ if (version == '') {
+ console.log('Host not installed.');
+ } else {
+ console.log('Host version: ' + version);
+ }
+ };
+ that.pluginSupported_ = true;
+ try {
+ that.plugin_.getDaemonVersion(printVersion);
+ } catch (err) {
+ console.log('Host version not available.');
+ that.pluginSupported_ = false;
}
- };
- /** @type {boolean} @private */
- this.pluginSupported_ = true;
- try {
- this.plugin_.getDaemonVersion(printVersion);
- } catch (err) {
- console.log('Host version not available.');
- this.pluginSupported_ = false;
}
-};
+
+ this.plugin_.initialize(onNativeMessagingInit);
+}
// Note that the values in the enums below are copied from
// daemon_controller.h and must be kept in sync.
diff --git a/remoting/webapp/host_native_messaging.js b/remoting/webapp/host_native_messaging.js
index 64576a5..b1e58f0 100644
--- a/remoting/webapp/host_native_messaging.js
+++ b/remoting/webapp/host_native_messaging.js
@@ -24,26 +24,51 @@ remoting.HostNativeMessaging = function() {
this.nextId_ = 0;
/**
- * @type {Object.<number, {callback:function(...):void, type:string}>}
+ * @type {Object.<number, {callback:?function(...):void, type:string}>}
* @private
*/
this.pendingReplies_ = {};
- /** @private */
- this.port_ = chrome.runtime.connectNative(
- 'chrome-remote-desktop-native-host');
- this.port_.onMessage.addListener(this.onIncomingMessage_.bind(this));
+ /** @type {?chrome.extension.Port} @private */
+ this.port_ = null;
+
+ /** @type {?function(boolean):void} @private */
+ this.onInitializedCallback_ = null;
+
+ /** @type {string} @private */
+ this.version_ = ''
};
/**
- * @return {boolean} True if native messaging is supported.
+ * Sets up connection to the Native Messaging host process and exchanges
+ * 'hello' messages. If Native Messaging is not available or the host
+ * process is not installed, this returns false to the callback.
+ *
+ * @param {function(boolean): void} onDone Called with the result of
+ * initialization.
+ * @return {void} Nothing.
*/
-remoting.HostNativeMessaging.isSupported = function() {
- // TODO(lambroslambrou): This needs to perform an asynchronous "hello"
- // exchange with the native host component (possibly getting its version
- // number at the same time), and report the result via a regular callback or
- // an error callback. For now, simply return false here.
- return false;
+remoting.HostNativeMessaging.prototype.initialize = function(onDone) {
+ if (!chrome.runtime.connectNative) {
+ console.log('Native Messaging API not available');
+ onDone(false);
+ return;
+ }
+
+ try {
+ this.port_ = chrome.runtime.connectNative(
+ 'com.google.chrome.remote_desktop');
+ this.port_.onMessage.addListener(this.onIncomingMessage_.bind(this));
+ this.port_.onDisconnect.addListener(this.onDisconnect_.bind(this));
+ this.postMessage_({type: 'hello'}, null);
+ } catch (err) {
+ console.log('Native Messaging initialization failed: ',
+ /** @type {*} */ (err));
+ onDone(false);
+ return;
+ }
+
+ this.onInitializedCallback_ = onDone;
};
/**
@@ -90,8 +115,8 @@ function asAsyncResult_(result) {
* depending on the message type.
*
* @param {{type: string}} message The message to post.
- * @param {function(...):void} callback The callback to be triggered on
- * response.
+ * @param {?function(...):void} callback The callback, if any, to be triggered
+ * on response.
* @return {void} Nothing.
* @private
*/
@@ -143,6 +168,20 @@ remoting.HostNativeMessaging.prototype.onIncomingMessage_ = function(message) {
// TODO(lambroslambrou): Errors here should be passed to an error-callback
// supplied by the caller of this interface.
switch (type) {
+ case 'helloResponse':
+ /** @type {string} */
+ var version = message['version'];
+ if (checkType_('version', version, 'string')) {
+ this.version_ = version;
+ if (this.onInitializedCallback_) {
+ this.onInitializedCallback_(true);
+ this.onInitializedCallback_ = null;
+ } else {
+ console.error('Unexpected helloResponse received.');
+ }
+ }
+ break;
+
case 'getHostNameResponse':
/** @type {*} */
var hostname = message['hostname'];
@@ -185,14 +224,6 @@ remoting.HostNativeMessaging.prototype.onIncomingMessage_ = function(message) {
}
break;
- case 'getDaemonVersionResponse':
- /** @type {*} */
- var version = message['version'];
- if (checkType_('version', version, 'string')) {
- callback(version);
- }
- break;
-
case 'getUsageStatsConsentResponse':
/** @type {*} */
var supported = message['supported'];
@@ -221,6 +252,18 @@ remoting.HostNativeMessaging.prototype.onIncomingMessage_ = function(message) {
};
/**
+ * @return {void} Nothing.
+ * @private
+ */
+remoting.HostNativeMessaging.prototype.onDisconnect_ = function() {
+ console.log('Native Message port disconnected');
+ if (this.onInitializedCallback_) {
+ this.onInitializedCallback_(false);
+ this.onInitializedCallback_ = null;
+ }
+}
+
+/**
* @param {string} email The email address of the connector.
* @param {string} token The access token for the connector.
* @return {void} Nothing.
@@ -321,7 +364,10 @@ remoting.HostNativeMessaging.prototype.getDaemonConfig = function(callback) {
* @return {void} Nothing.
*/
remoting.HostNativeMessaging.prototype.getDaemonVersion = function(callback) {
- this.postMessage_({type: 'getDaemonVersion'}, callback);
+ // Return the cached version from the 'hello' exchange. This interface needs
+ // to be asynchronous because the NPAPI version is, and this implements the
+ // same interface.
+ callback(this.version_);
};
/**