diff options
author | lambroslambrou@chromium.org <lambroslambrou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-18 20:05:58 +0000 |
---|---|---|
committer | lambroslambrou@chromium.org <lambroslambrou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-18 20:05:58 +0000 |
commit | dd02ed22bb3c38209bd70ecb3637231e279a7c02 (patch) | |
tree | 9fcbc97b8aaa15e2918c71baee03afb7aac12cd8 /remoting | |
parent | 205ffcd8dfc396363866e1d3f5ce995f19a3393e (diff) | |
download | chromium_src-dd02ed22bb3c38209bd70ecb3637231e279a7c02.zip chromium_src-dd02ed22bb3c38209bd70ecb3637231e279a7c02.tar.gz chromium_src-dd02ed22bb3c38209bd70ecb3637231e279a7c02.tar.bz2 |
Add error-handling to host_dispatcher.js interface
Each method of HostDispatcher, and HostNativeMessaging, now takes an
additional onError callback parameter.
BUG=249970
TEST=Test host setup, with NPAPI enabled/disabled, also test with
Native Messaging
Review URL: https://chromiumcodereview.appspot.com/17115007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@207071 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/webapp/appsv2.patch | 13 | ||||
-rw-r--r-- | remoting/webapp/host_controller.js | 42 | ||||
-rw-r--r-- | remoting/webapp/host_dispatcher.js | 160 | ||||
-rw-r--r-- | remoting/webapp/host_native_messaging.js | 182 |
4 files changed, 236 insertions, 161 deletions
diff --git a/remoting/webapp/appsv2.patch b/remoting/webapp/appsv2.patch index 4b2aed2..505cb12 100644 --- a/remoting/webapp/appsv2.patch +++ b/remoting/webapp/appsv2.patch @@ -17,19 +17,6 @@ index 5dfc368..f69d984 100644 -window.addEventListener('beforeunload', onBeforeUnload, false); window.addEventListener('resize', remoting.onResize, false); -window.addEventListener('unload', remoting.disconnect, false); -diff --git a/remoting/webapp/host_controller.js b/remoting/webapp/host_controller.js -index 83c9844..98f63c3 100644 ---- a/host_controller.js -+++ b/host_controller.js -@@ -31,7 +31,7 @@ remoting.HostController.prototype.getLocalHostStateAndId = function(onDone) { - }; - - try { -- this.hostDispatcher_.getDaemonVersion(printVersion); -+ onConfig('{}'); - } catch (err) { - console.log('Host version not available.'); - } diff --git a/remoting/webapp/main.html b/remoting/webapp/main.html index 061caeb..f61e532 100644 --- a/main.html diff --git a/remoting/webapp/host_controller.js b/remoting/webapp/host_controller.js index a92aec7..1529e3c 100644 --- a/remoting/webapp/host_controller.js +++ b/remoting/webapp/host_controller.js @@ -30,11 +30,9 @@ remoting.HostController = function() { } }; - try { - this.hostDispatcher_.getDaemonVersion(printVersion); - } catch (err) { + this.hostDispatcher_.getDaemonVersion(printVersion, function() { console.log('Host version not available.'); - } + }); } // Note that the values in the enums below are copied from @@ -64,7 +62,8 @@ remoting.HostController.AsyncResult = { * called when done. */ remoting.HostController.prototype.getConsent = function(callback) { - this.hostDispatcher_.getUsageStatsConsent(callback); + this.hostDispatcher_.getUsageStatsConsent(callback, + remoting.showErrorMessage); }; /** @@ -121,7 +120,8 @@ remoting.HostController.prototype.start = function(hostPin, consent, callback) { if (success) { that.hostDispatcher_.getPinHash(newHostId, hostPin, - startHostWithHash.bind(null, hostName, publicKey, privateKey, xhr)); + startHostWithHash.bind(null, hostName, publicKey, privateKey, xhr), + remoting.showErrorMessage); } else { console.log('Failed to register the host. Status: ' + xhr.status + ' response: ' + xhr.responseText); @@ -150,7 +150,8 @@ remoting.HostController.prototype.start = function(hostPin, consent, callback) { var onStartDaemon = function(result) { onStarted(callback, result, hostName, publicKey); }; - that.hostDispatcher_.startDaemon(hostConfig, consent, onStartDaemon); + that.hostDispatcher_.startDaemon(hostConfig, consent, onStartDaemon, + remoting.showErrorMessage); } /** @@ -201,10 +202,12 @@ remoting.HostController.prototype.start = function(hostPin, consent, callback) { * @return {void} Nothing. */ function startWithHostname(hostName) { - that.hostDispatcher_.generateKeyPair(onKeyGenerated.bind(null, hostName)); + that.hostDispatcher_.generateKeyPair(onKeyGenerated.bind(null, hostName), + remoting.showErrorMessage); } - this.hostDispatcher_.getHostName(startWithHostname); + this.hostDispatcher_.getHostName(startWithHostname, + remoting.showErrorMessage); }; /** @@ -241,7 +244,7 @@ remoting.HostController.prototype.stop = function(callback) { that.getLocalHostId(unregisterHost.bind(null, result)); }; - this.hostDispatcher_.stopDaemon(onStopped); + this.hostDispatcher_.stopDaemon(onStopped, remoting.showErrorMessage); }; /** @@ -273,7 +276,8 @@ remoting.HostController.prototype.updatePin = function(newPin, callback) { } /** @type {string} */ var hostId = config['host_id']; - that.hostDispatcher_.getPinHash(hostId, newPin, updateDaemonConfigWithHash); + that.hostDispatcher_.getPinHash(hostId, newPin, updateDaemonConfigWithHash, + remoting.showErrorMessage); } /** @param {string} pinHash */ @@ -281,12 +285,13 @@ remoting.HostController.prototype.updatePin = function(newPin, callback) { var newConfig = { host_secret_hash: pinHash }; - that.hostDispatcher_.updateDaemonConfig(newConfig, callback); + that.hostDispatcher_.updateDaemonConfig(newConfig, callback, + remoting.showErrorMessage); } // TODO(sergeyu): When crbug.com/121518 is fixed: replace this call // with an unprivileged version if that is necessary. - this.hostDispatcher_.getDaemonConfig(onConfig); + this.hostDispatcher_.getDaemonConfig(onConfig, remoting.showErrorMessage); }; /** @@ -296,7 +301,9 @@ remoting.HostController.prototype.updatePin = function(newPin, callback) { * Completion callback. */ remoting.HostController.prototype.getLocalHostState = function(onDone) { - this.hostDispatcher_.getDaemonState(onDone); + this.hostDispatcher_.getDaemonState(onDone, function() { + onDone(remoting.HostController.State.NOT_IMPLEMENTED); + }); }; /** @@ -315,11 +322,10 @@ remoting.HostController.prototype.getLocalHostId = function(onDone) { } onDone(hostId); }; - try { - this.hostDispatcher_.getDaemonConfig(onConfig); - } catch (err) { + + this.hostDispatcher_.getDaemonConfig(onConfig, function(error) { onDone(null); - } + }); }; /** @type {remoting.HostController} */ diff --git a/remoting/webapp/host_dispatcher.js b/remoting/webapp/host_dispatcher.js index 41ed241..7ac0d93 100644 --- a/remoting/webapp/host_dispatcher.js +++ b/remoting/webapp/host_dispatcher.js @@ -72,18 +72,24 @@ remoting.HostDispatcher.State = { /** * @param {function(string):void} callback + * @param {function(remoting.Error):void} onError * @return {void} */ -remoting.HostDispatcher.prototype.getHostName = function(callback) { +remoting.HostDispatcher.prototype.getHostName = function(callback, onError) { switch (this.state_) { case remoting.HostDispatcher.State.UNKNOWN: - this.pendingRequests_.push(this.getHostName.bind(this, callback)); + this.pendingRequests_.push( + this.getHostName.bind(this, callback, onError)); break; case remoting.HostDispatcher.State.NATIVE_MESSAGING: - this.nativeMessagingHost_.getHostName(callback); + this.nativeMessagingHost_.getHostName(callback, onError); break; case remoting.HostDispatcher.State.NPAPI: - this.npapiHost_.getHostName(callback); + try { + this.npapiHost_.getHostName(callback); + } catch (err) { + onError(remoting.Error.MISSING_PLUGIN); + } break; } }; @@ -92,37 +98,50 @@ remoting.HostDispatcher.prototype.getHostName = function(callback) { * @param {string} hostId * @param {string} pin * @param {function(string):void} callback + * @param {function(remoting.Error):void} onError * @return {void} */ -remoting.HostDispatcher.prototype.getPinHash = function(hostId, pin, callback) { +remoting.HostDispatcher.prototype.getPinHash = function(hostId, pin, callback, + onError) { switch (this.state_) { case remoting.HostDispatcher.State.UNKNOWN: - this.pendingRequests_.push(this.getPinHash.bind(this, hostId, pin, - callback)); + this.pendingRequests_.push( + this.getPinHash.bind(this, hostId, pin, callback, onError)); break; case remoting.HostDispatcher.State.NATIVE_MESSAGING: - this.nativeMessagingHost_.getPinHash(hostId, pin, callback); + this.nativeMessagingHost_.getPinHash(hostId, pin, callback, onError); break; case remoting.HostDispatcher.State.NPAPI: - this.npapiHost_.getPinHash(hostId, pin, callback); + try { + this.npapiHost_.getPinHash(hostId, pin, callback); + } catch (err) { + onError(remoting.Error.MISSING_PLUGIN); + } break; } }; /** * @param {function(string, string):void} callback + * @param {function(remoting.Error):void} onError * @return {void} */ -remoting.HostDispatcher.prototype.generateKeyPair = function(callback) { +remoting.HostDispatcher.prototype.generateKeyPair = function(callback, + onError) { switch (this.state_) { case remoting.HostDispatcher.State.UNKNOWN: - this.pendingRequests_.push(this.generateKeyPair.bind(this, callback)); + this.pendingRequests_.push( + this.generateKeyPair.bind(this, callback, onError)); break; case remoting.HostDispatcher.State.NATIVE_MESSAGING: - this.nativeMessagingHost_.generateKeyPair(callback); + this.nativeMessagingHost_.generateKeyPair(callback, onError); break; case remoting.HostDispatcher.State.NPAPI: - this.npapiHost_.generateKeyPair(callback); + try { + this.npapiHost_.generateKeyPair(callback); + } catch (err) { + onError(remoting.Error.MISSING_PLUGIN); + } break; } }; @@ -130,28 +149,37 @@ remoting.HostDispatcher.prototype.generateKeyPair = function(callback) { /** * @param {Object} config * @param {function(remoting.HostController.AsyncResult):void} callback + * @param {function(remoting.Error):void} onError * @return {void} */ remoting.HostDispatcher.prototype.updateDaemonConfig = function(config, - callback) { + callback, + onError) { switch (this.state_) { case remoting.HostDispatcher.State.UNKNOWN: - this.pendingRequests_.push(this.updateDaemonConfig.bind(this, callback)); + this.pendingRequests_.push( + this.updateDaemonConfig.bind(this, config, callback, onError)); break; case remoting.HostDispatcher.State.NATIVE_MESSAGING: - this.nativeMessagingHost_.updateDaemonConfig(config, callback); + this.nativeMessagingHost_.updateDaemonConfig(config, callback, onError); break; case remoting.HostDispatcher.State.NPAPI: - this.npapiHost_.updateDaemonConfig(JSON.stringify(config), callback); + try { + this.npapiHost_.updateDaemonConfig(JSON.stringify(config), callback); + } catch (err) { + onError(remoting.Error.MISSING_PLUGIN); + } break; } }; /** * @param {function(Object):void} callback + * @param {function(remoting.Error):void} onError * @return {void} */ -remoting.HostDispatcher.prototype.getDaemonConfig = function(callback) { +remoting.HostDispatcher.prototype.getDaemonConfig = function(callback, + onError) { /** * Converts the config string from the NPAPI plugin to an Object, to pass to * |callback|. @@ -159,63 +187,78 @@ remoting.HostDispatcher.prototype.getDaemonConfig = function(callback) { * @return {void} */ function callbackForNpapi(configStr) { - var config = null; - try { - config = JSON.parse(configStr); - } catch (err) {} + var config = jsonParseSafe(configStr); if (typeof(config) != 'object') { - // TODO(lambroslambrou): Call error handler here when that's implemented. - config = null; + onError(remoting.Error.UNEXPECTED); + } else { + callback(/** @type {Object} */ (config)); } - callback(/** @type {Object} */ (config)); } switch (this.state_) { case remoting.HostDispatcher.State.UNKNOWN: - this.pendingRequests_.push(this.getDaemonConfig.bind(this, callback)); + this.pendingRequests_.push( + this.getDaemonConfig.bind(this, callback, onError)); break; case remoting.HostDispatcher.State.NATIVE_MESSAGING: - this.nativeMessagingHost_.getDaemonConfig(callback); + this.nativeMessagingHost_.getDaemonConfig(callback, onError); break; case remoting.HostDispatcher.State.NPAPI: - this.npapiHost_.getDaemonConfig(callbackForNpapi); + try { + this.npapiHost_.getDaemonConfig(callbackForNpapi); + } catch (err) { + onError(remoting.Error.MISSING_PLUGIN); + } break; } }; /** * @param {function(string):void} callback + * @param {function(remoting.Error):void} onError * @return {void} */ -remoting.HostDispatcher.prototype.getDaemonVersion = function(callback) { +remoting.HostDispatcher.prototype.getDaemonVersion = function(callback, + onError) { switch (this.state_) { case remoting.HostDispatcher.State.UNKNOWN: - this.pendingRequests_.push(this.getDaemonVersion.bind(this, callback)); + this.pendingRequests_.push( + this.getDaemonVersion.bind(this, callback, onError)); break; case remoting.HostDispatcher.State.NATIVE_MESSAGING: - this.nativeMessagingHost_.getDaemonVersion(callback); + callback(this.nativeMessagingHost_.getDaemonVersion()); break; case remoting.HostDispatcher.State.NPAPI: - this.npapiHost_.getDaemonVersion(callback); + try { + this.npapiHost_.getDaemonVersion(callback); + } catch (err) { + onError(remoting.Error.MISSING_PLUGIN); + } break; } }; /** * @param {function(boolean, boolean, boolean):void} callback + * @param {function(remoting.Error):void} onError * @return {void} */ -remoting.HostDispatcher.prototype.getUsageStatsConsent = function(callback) { +remoting.HostDispatcher.prototype.getUsageStatsConsent = function(callback, + onError) { switch (this.state_) { case remoting.HostDispatcher.State.UNKNOWN: - this.pendingRequests_.push(this.getUsageStatsConsent.bind(this, - callback)); + this.pendingRequests_.push( + this.getUsageStatsConsent.bind(this, callback, onError)); break; case remoting.HostDispatcher.State.NATIVE_MESSAGING: - this.nativeMessagingHost_.getUsageStatsConsent(callback); + this.nativeMessagingHost_.getUsageStatsConsent(callback, onError); break; case remoting.HostDispatcher.State.NPAPI: - this.npapiHost_.getUsageStatsConsent(callback); + try { + this.npapiHost_.getUsageStatsConsent(callback); + } catch (err) { + onError(remoting.Error.MISSING_PLUGIN); + } break; } }; @@ -224,64 +267,75 @@ remoting.HostDispatcher.prototype.getUsageStatsConsent = function(callback) { * @param {Object} config * @param {boolean} consent * @param {function(remoting.HostController.AsyncResult):void} callback + * @param {function(remoting.Error):void} onError * @return {void} */ remoting.HostDispatcher.prototype.startDaemon = function(config, consent, - callback) { + callback, onError) { switch (this.state_) { case remoting.HostDispatcher.State.UNKNOWN: - this.pendingRequests_.push(this.startDaemon.bind(this, config, consent, - callback)); + this.pendingRequests_.push( + this.startDaemon.bind(this, config, consent, callback, onError)); break; case remoting.HostDispatcher.State.NATIVE_MESSAGING: - this.nativeMessagingHost_.startDaemon(config, consent, callback); + this.nativeMessagingHost_.startDaemon(config, consent, callback, onError); break; case remoting.HostDispatcher.State.NPAPI: - this.npapiHost_.startDaemon(JSON.stringify(config), consent, callback); + try { + this.npapiHost_.startDaemon(JSON.stringify(config), consent, callback); + } catch (err) { + onError(remoting.Error.MISSING_PLUGIN); + } break; } }; /** * @param {function(remoting.HostController.AsyncResult):void} callback + * @param {function(remoting.Error):void} onError * @return {void} */ -remoting.HostDispatcher.prototype.stopDaemon = function(callback) { +remoting.HostDispatcher.prototype.stopDaemon = function(callback, onError) { switch (this.state_) { case remoting.HostDispatcher.State.UNKNOWN: - this.pendingRequests_.push(this.stopDaemon.bind(this, callback)); + this.pendingRequests_.push(this.stopDaemon.bind(this, callback, onError)); break; case remoting.HostDispatcher.State.NATIVE_MESSAGING: - this.nativeMessagingHost_.stopDaemon(callback); + this.nativeMessagingHost_.stopDaemon(callback, onError); break; case remoting.HostDispatcher.State.NPAPI: - this.npapiHost_.stopDaemon(callback); + try { + this.npapiHost_.stopDaemon(callback); + } catch (err) { + onError(remoting.Error.MISSING_PLUGIN); + } break; } }; /** * @param {function(remoting.HostController.State):void} callback + * @param {function(remoting.Error):void} onError * @return {void} */ -remoting.HostDispatcher.prototype.getDaemonState = function(callback) { +remoting.HostDispatcher.prototype.getDaemonState = function(callback, onError) { switch (this.state_) { case remoting.HostDispatcher.State.UNKNOWN: - this.pendingRequests_.push(this.getDaemonState.bind(this, callback)); + this.pendingRequests_.push( + this.getDaemonState.bind(this, callback, onError)); break; case remoting.HostDispatcher.State.NATIVE_MESSAGING: - this.nativeMessagingHost_.getDaemonState(callback); + this.nativeMessagingHost_.getDaemonState(callback, onError); break; case remoting.HostDispatcher.State.NPAPI: // Call the callback directly, since NPAPI exposes the state directly as // a field member, rather than an asynchronous method. var state = this.npapiHost_.daemonState; if (state === undefined) { - // If the plug-in can't be instantiated, for example on ChromeOS, then - // return something sensible. - state = remoting.HostController.State.NOT_IMPLEMENTED; + onError(remoting.Error.MISSING_PLUGIN); + } else { + callback(state); } - callback(state); break; } } diff --git a/remoting/webapp/host_native_messaging.js b/remoting/webapp/host_native_messaging.js index 5a35617..f9d5ba7 100644 --- a/remoting/webapp/host_native_messaging.js +++ b/remoting/webapp/host_native_messaging.js @@ -14,7 +14,6 @@ var remoting = remoting || {}; /** * @constructor - * @extends {remoting.HostPlugin} */ remoting.HostNativeMessaging = function() { /** @@ -24,7 +23,7 @@ remoting.HostNativeMessaging = function() { this.nextId_ = 0; /** - * @type {Object.<number, {callback:?function(...):void, type:string}>} + * @type {Object.<number, remoting.HostNativeMessaging.PendingReply>} * @private */ this.pendingReplies_ = {}; @@ -32,14 +31,27 @@ remoting.HostNativeMessaging = function() { /** @type {?chrome.extension.Port} @private */ this.port_ = null; - /** @type {?function(boolean):void} @private */ - this.onInitializedCallback_ = null; - /** @type {string} @private */ this.version_ = '' }; /** + * Type used for entries of |pendingReplies_| list. + * + * @param {string} type Type of the originating request. + * @param {?function(...):void} callback The callback, if any, to be triggered + * on response. The actual parameters depend on the original request type. + * @param {function(remoting.Error):void} onError The callback to be triggered + * on error. + * @constructor + */ +remoting.HostNativeMessaging.PendingReply = function(type, callback, onError) { + this.type = type; + this.callback = callback; + this.onError = onError; +}; + +/** * 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. @@ -73,15 +85,14 @@ remoting.HostNativeMessaging.prototype.initialize = function(onDone) { '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); + this.postMessage_({type: 'hello'}, onDone.bind(null, true), + onDone.bind(null, false)); } catch (err) { console.log('Native Messaging initialization failed: ', /** @type {*} */ (err)); onDone(false); return; } - - this.onInitializedCallback_ = onDone; }; /** @@ -146,17 +157,18 @@ function asHostState_(result) { * @param {{type: string}} message The message to post. * @param {?function(...):void} callback The callback, if any, to be triggered * on response. + * @param {function(remoting.Error):void} onError The callback to be triggered + * on error. * @return {void} Nothing. * @private */ remoting.HostNativeMessaging.prototype.postMessage_ = function(message, - callback) { + callback, + onError) { var id = this.nextId_++; message['id'] = id; - this.pendingReplies_[id] = { - callback: callback, - type: message.type + 'Response' - } + this.pendingReplies_[id] = new remoting.HostNativeMessaging.PendingReply( + message.type + 'Response', callback, onError); this.port_.postMessage(message); }; @@ -181,33 +193,31 @@ remoting.HostNativeMessaging.prototype.onIncomingMessage_ = function(message) { } delete this.pendingReplies_[id]; + var callback = reply.callback; + var onError = reply.onError; + /** @type {string} */ var type = message['type']; if (!checkType_('type', type, 'string')) { + onError(remoting.Error.UNEXPECTED); return; } if (type != reply.type) { console.error('NativeMessaging: expected reply type: ', reply.type, ', got: ', type); + onError(remoting.Error.UNEXPECTED); return; } - var callback = reply.callback; - - // 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.'); - } + callback(); + } else { + onError(remoting.Error.UNEXPECTED); } break; @@ -216,6 +226,8 @@ remoting.HostNativeMessaging.prototype.onIncomingMessage_ = function(message) { var hostname = message['hostname']; if (checkType_('hostname', hostname, 'string')) { callback(hostname); + } else { + onError(remoting.Error.UNEXPECTED); } break; @@ -224,6 +236,8 @@ remoting.HostNativeMessaging.prototype.onIncomingMessage_ = function(message) { var hash = message['hash']; if (checkType_('hash', hash, 'string')) { callback(hash); + } else { + onError(remoting.Error.UNEXPECTED); } break; @@ -235,6 +249,8 @@ remoting.HostNativeMessaging.prototype.onIncomingMessage_ = function(message) { if (checkType_('privateKey', privateKey, 'string') && checkType_('publicKey', publicKey, 'string')) { callback(privateKey, publicKey); + } else { + onError(remoting.Error.UNEXPECTED); } break; @@ -242,6 +258,8 @@ remoting.HostNativeMessaging.prototype.onIncomingMessage_ = function(message) { var result = asAsyncResult_(message['result']); if (result != null) { callback(result); + } else { + onError(remoting.Error.UNEXPECTED); } break; @@ -250,6 +268,8 @@ remoting.HostNativeMessaging.prototype.onIncomingMessage_ = function(message) { var config = message['config']; if (checkType_('config', config, 'object')) { callback(config); + } else { + onError(remoting.Error.UNEXPECTED); } break; @@ -264,6 +284,8 @@ remoting.HostNativeMessaging.prototype.onIncomingMessage_ = function(message) { checkType_('allowed', allowed, 'boolean') && checkType_('setByPolicy', setByPolicy, 'boolean')) { callback(supported, allowed, setByPolicy); + } else { + onError(remoting.Error.UNEXPECTED); } break; @@ -272,6 +294,8 @@ remoting.HostNativeMessaging.prototype.onIncomingMessage_ = function(message) { var result = asAsyncResult_(message['result']); if (result != null) { callback(result); + } else { + onError(remoting.Error.UNEXPECTED); } break; @@ -279,11 +303,14 @@ remoting.HostNativeMessaging.prototype.onIncomingMessage_ = function(message) { var state = asHostState_(message['state']); if (state != null) { callback(state); + } else { + onError(remoting.Error.UNEXPECTED); } break; default: console.error('Unexpected native message: ', message); + onError(remoting.Error.UNEXPECTED); } }; @@ -292,42 +319,26 @@ remoting.HostNativeMessaging.prototype.onIncomingMessage_ = function(message) { * @private */ remoting.HostNativeMessaging.prototype.onDisconnect_ = function() { - console.log('Native Message port disconnected'); - if (this.onInitializedCallback_) { - this.onInitializedCallback_(false); - this.onInitializedCallback_ = null; + console.error('Native Message port disconnected'); + + // Notify the error-handlers of any requests that are still outstanding. + for (var id in this.pendingReplies_) { + this.pendingReplies_[/** @type {number} */(id)].onError( + remoting.Error.UNEXPECTED); } + this.pendingReplies_ = {}; } /** - * @param {string} email The email address of the connector. - * @param {string} token The access token for the connector. - * @return {void} Nothing. - */ -remoting.HostNativeMessaging.prototype.connect = function(email, token) { - console.error('NativeMessaging: connect() not implemented.'); -}; - -/** @return {void} Nothing. */ -remoting.HostNativeMessaging.prototype.disconnect = function() { - console.error('NativeMessaging: disconnect() not implemented.'); -}; - -/** - * @param {function(string):string} callback Pointer to chrome.i18n.getMessage. - * @return {void} Nothing. - */ -remoting.HostNativeMessaging.prototype.localize = function(callback) { - console.error('NativeMessaging: localize() not implemented.'); -}; - -/** * @param {function(string):void} callback Callback to be called with the * local hostname. + * @param {function(remoting.Error):void} onError The callback to be triggered + * on error. * @return {void} Nothing. */ -remoting.HostNativeMessaging.prototype.getHostName = function(callback) { - this.postMessage_({type: 'getHostName'}, callback); +remoting.HostNativeMessaging.prototype.getHostName = function(callback, + onError) { + this.postMessage_({type: 'getHostName'}, callback, onError); }; /** @@ -337,15 +348,18 @@ remoting.HostNativeMessaging.prototype.getHostName = function(callback) { * @param {string} hostId The host ID. * @param {string} pin The PIN. * @param {function(string):void} callback Callback. + * @param {function(remoting.Error):void} onError The callback to be triggered + * on error. * @return {void} Nothing. */ remoting.HostNativeMessaging.prototype.getPinHash = function(hostId, pin, - callback) { + callback, + onError) { this.postMessage_({ type: 'getPinHash', hostId: hostId, pin: pin - }, callback); + }, callback, onError); }; /** @@ -354,10 +368,13 @@ remoting.HostNativeMessaging.prototype.getPinHash = function(hostId, pin, * host (PublicKeyInfo structure encoded with ASN.1 DER, and then BASE64). * * @param {function(string, string):void} callback Callback. + * @param {function(remoting.Error):void} onError The callback to be triggered + * on error. * @return {void} Nothing. */ -remoting.HostNativeMessaging.prototype.generateKeyPair = function(callback) { - this.postMessage_({type: 'generateKeyPair'}, callback); +remoting.HostNativeMessaging.prototype.generateKeyPair = function(callback, + onError) { + this.postMessage_({type: 'generateKeyPair'}, callback, onError); }; /** @@ -371,14 +388,16 @@ remoting.HostNativeMessaging.prototype.generateKeyPair = function(callback) { * @param {Object} config The new config parameters. * @param {function(remoting.HostController.AsyncResult):void} callback * Callback to be called when finished. + * @param {function(remoting.Error):void} onError The callback to be triggered + * on error. * @return {void} Nothing. */ remoting.HostNativeMessaging.prototype.updateDaemonConfig = - function(config, callback) { + function(config, callback, onError) { this.postMessage_({ type: 'updateDaemonConfig', config: config - }, callback); + }, callback, onError); }; /** @@ -386,24 +405,23 @@ remoting.HostNativeMessaging.prototype.updateDaemonConfig = * callback. * * @param {function(Object):void} callback Callback. + * @param {function(remoting.Error):void} onError The callback to be triggered + * on error. * @return {void} Nothing. */ -remoting.HostNativeMessaging.prototype.getDaemonConfig = function(callback) { - this.postMessage_({type: 'getDaemonConfig'}, callback); +remoting.HostNativeMessaging.prototype.getDaemonConfig = function(callback, + onError) { + this.postMessage_({type: 'getDaemonConfig'}, callback, onError); }; /** - * Retrieves daemon version. The version is passed to the callback as a dotted - * decimal string of the form major.minor.build.patch. - * - * @param {function(string):void} callback Callback. - * @return {void} Nothing. + * Retrieves daemon version. The version is returned as a dotted decimal string + * of the form major.minor.build.patch. + * @return {string} The daemon version, or the empty string if not available. */ -remoting.HostNativeMessaging.prototype.getDaemonVersion = function(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_); +remoting.HostNativeMessaging.prototype.getDaemonVersion = function() { + // Return the cached version from the 'hello' exchange. + return this.version_; }; /** @@ -411,11 +429,13 @@ remoting.HostNativeMessaging.prototype.getDaemonVersion = function(callback) { * the callback as booleans: supported, allowed, set-by-policy. * * @param {function(boolean, boolean, boolean):void} callback Callback. + * @param {function(remoting.Error):void} onError The callback to be triggered + * on error. * @return {void} Nothing. */ remoting.HostNativeMessaging.prototype.getUsageStatsConsent = - function(callback) { - this.postMessage_({type: 'getUsageStatsConsent'}, callback); + function(callback, onError) { + this.postMessage_({type: 'getUsageStatsConsent'}, callback, onError); }; /** @@ -425,15 +445,17 @@ remoting.HostNativeMessaging.prototype.getUsageStatsConsent = * @param {boolean} consent Consent to report crash dumps. * @param {function(remoting.HostController.AsyncResult):void} callback * Callback. + * @param {function(remoting.Error):void} onError The callback to be triggered + * on error. * @return {void} Nothing. */ remoting.HostNativeMessaging.prototype.startDaemon = function( - config, consent, callback) { + config, consent, callback, onError) { this.postMessage_({ type: 'startDaemon', config: config, consent: consent - }, callback); + }, callback, onError); }; /** @@ -441,18 +463,24 @@ remoting.HostNativeMessaging.prototype.startDaemon = function( * * @param {function(remoting.HostController.AsyncResult):void} callback * Callback. + * @param {function(remoting.Error):void} onError The callback to be triggered + * on error. * @return {void} Nothing. */ -remoting.HostNativeMessaging.prototype.stopDaemon = function(callback) { - this.postMessage_({type: 'stopDaemon'}, callback); +remoting.HostNativeMessaging.prototype.stopDaemon = function(callback, + onError) { + this.postMessage_({type: 'stopDaemon'}, callback, onError); }; /** * Gets the installed/running state of the Host process. * * @param {function(remoting.HostController.State):void} callback Callback. + * @param {function(remoting.Error):void} onError The callback to be triggered + * on error. * @return {void} Nothing. */ -remoting.HostNativeMessaging.prototype.getDaemonState = function(callback) { - this.postMessage_({type: 'getDaemonState'}, callback); +remoting.HostNativeMessaging.prototype.getDaemonState = function(callback, + onError) { + this.postMessage_({type: 'getDaemonState'}, callback, onError); } |