summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--remoting/resources/remoting_strings.grd2
-rw-r--r--remoting/webapp/error.js8
-rw-r--r--remoting/webapp/host_controller.js189
-rw-r--r--remoting/webapp/host_setup_dialog.js139
4 files changed, 202 insertions, 136 deletions
diff --git a/remoting/resources/remoting_strings.grd b/remoting/resources/remoting_strings.grd
index 0cfd5cd..2d0c3c6 100644
--- a/remoting/resources/remoting_strings.grd
+++ b/remoting/resources/remoting_strings.grd
@@ -393,7 +393,7 @@
<message desc="Message shown when user has attempted to continue past the manual install dialog, but the Host components are not yet installed." name="IDR_HOST_SETUP_INSTALL_PENDING">
Please run the installer before continuing.
</message>
- <message desc="Message shown when host registration fails when enabling the host on local computer." name="IDR_HOST_SETUP_REGISTRATION_FAILED">
+ <message desc="Message shown when host registration fails when enabling the host on local computer." name="IDR_ERROR_HOST_REGISTRATION_FAILED">
Failed to register this computer.
</message>
<message desc="Message shown after access to local computer has been enabled successfully." name="IDR_HOST_SETUP_STARTED">
diff --git a/remoting/webapp/error.js b/remoting/webapp/error.js
index a1e3ab3..756e3e6 100644
--- a/remoting/webapp/error.js
+++ b/remoting/webapp/error.js
@@ -11,6 +11,11 @@ var remoting = remoting || {};
* @enum {string} All error messages from messages.json
*/
remoting.Error = {
+ // Used to signify that an operation was cancelled by the user. This should
+ // not normally cause the error text to be shown to the user, so the
+ // i18n-content prefix is not needed in this case.
+ CANCELLED: '__CANCELLED__',
+
INVALID_ACCESS_CODE: /*i18n-content*/'ERROR_INVALID_ACCESS_CODE',
MISSING_PLUGIN: /*i18n-content*/'ERROR_MISSING_PLUGIN',
AUTHENTICATION_FAILED: /*i18n-content*/'ERROR_AUTHENTICATION_FAILED',
@@ -23,5 +28,6 @@ remoting.Error = {
SERVICE_UNAVAILABLE: /*i18n-content*/'ERROR_SERVICE_UNAVAILABLE',
NOT_AUTHENTICATED: /*i18n-content*/'ERROR_NOT_AUTHENTICATED',
INVALID_HOST_DOMAIN: /*i18n-content*/'ERROR_INVALID_HOST_DOMAIN',
- P2P_FAILURE: /*i18n-content*/'ERROR_P2P_FAILURE'
+ P2P_FAILURE: /*i18n-content*/'ERROR_P2P_FAILURE',
+ REGISTRATION_FAILED: /*i18n-content*/'ERROR_HOST_REGISTRATION_FAILED'
};
diff --git a/remoting/webapp/host_controller.js b/remoting/webapp/host_controller.js
index 1529e3c..de1a0a9 100644
--- a/remoting/webapp/host_controller.js
+++ b/remoting/webapp/host_controller.js
@@ -58,12 +58,13 @@ remoting.HostController.AsyncResult = {
};
/**
- * @param {function(boolean, boolean, boolean):void} callback Callback to be
+ * @param {function(boolean, boolean, boolean):void} onDone Callback to be
* called when done.
+ * @param {function(remoting.Error):void} onError Callback to be called on
+ * error.
*/
-remoting.HostController.prototype.getConsent = function(callback) {
- this.hostDispatcher_.getUsageStatsConsent(callback,
- remoting.showErrorMessage);
+remoting.HostController.prototype.getConsent = function(onDone, onError) {
+ this.hostDispatcher_.getUsageStatsConsent(onDone, onError);
};
/**
@@ -71,11 +72,13 @@ remoting.HostController.prototype.getConsent = function(callback) {
*
* @param {string} hostPin Host PIN.
* @param {boolean} consent The user's consent to crash dump reporting.
- * @param {function(remoting.HostController.AsyncResult):void} callback
- * callback Callback to be called when done.
+ * @param {function():void} onDone Callback to be called when done.
+ * @param {function(remoting.Error):void} onError Callback to be called on
+ * error.
* @return {void} Nothing.
*/
-remoting.HostController.prototype.start = function(hostPin, consent, callback) {
+remoting.HostController.prototype.start = function(hostPin, consent, onDone,
+ onError) {
/** @type {remoting.HostController} */
var that = this;
@@ -95,39 +98,28 @@ remoting.HostController.prototype.start = function(hostPin, consent, callback) {
var newHostId = generateUuid();
- /** @param {function(remoting.HostController.AsyncResult):void} callback
- * @param {remoting.HostController.AsyncResult} result
- * @param {string} hostName
- * @param {string} publicKey */
- function onStarted(callback, result, hostName, publicKey) {
- if (result == remoting.HostController.AsyncResult.OK) {
- remoting.hostList.onLocalHostStarted(hostName, newHostId, publicKey);
- } else {
- // Unregister the host if we failed to start it.
- remoting.HostList.unregisterHostById(newHostId);
- }
- callback(result);
- };
+ /** @param {remoting.Error} error */
+ function onStartError(error) {
+ // Unregister the host if we failed to start it.
+ remoting.HostList.unregisterHostById(newHostId);
+ onError(error);
+ }
/**
* @param {string} hostName
* @param {string} publicKey
- * @param {string} privateKey
- * @param {XMLHttpRequest} xhr
+ * @param {remoting.HostController.AsyncResult} result
*/
- function onRegistered(hostName, publicKey, privateKey, xhr) {
- var success = (xhr.status == 200);
-
- if (success) {
- that.hostDispatcher_.getPinHash(newHostId, hostPin,
- startHostWithHash.bind(null, hostName, publicKey, privateKey, xhr),
- remoting.showErrorMessage);
+ function onStarted(hostName, publicKey, result) {
+ if (result == remoting.HostController.AsyncResult.OK) {
+ remoting.hostList.onLocalHostStarted(hostName, newHostId, publicKey);
+ onDone();
+ } else if (result == remoting.HostController.AsyncResult.CANCELLED) {
+ onStartError(remoting.Error.CANCELLED);
} else {
- console.log('Failed to register the host. Status: ' + xhr.status +
- ' response: ' + xhr.responseText);
- callback(remoting.HostController.AsyncResult.FAILED_DIRECTORY);
+ onStartError(remoting.Error.UNEXPECTED);
}
- };
+ }
/**
* @param {string} hostName
@@ -146,16 +138,33 @@ remoting.HostController.prototype.start = function(hostPin, consent, callback) {
host_secret_hash: hostSecretHash,
private_key: privateKey
};
- /** @param {remoting.HostController.AsyncResult} result */
- var onStartDaemon = function(result) {
- onStarted(callback, result, hostName, publicKey);
- };
- that.hostDispatcher_.startDaemon(hostConfig, consent, onStartDaemon,
- remoting.showErrorMessage);
+ that.hostDispatcher_.startDaemon(hostConfig, consent,
+ onStarted.bind(null, hostName, publicKey),
+ onStartError);
}
/**
* @param {string} hostName
+ * @param {string} publicKey
+ * @param {string} privateKey
+ * @param {XMLHttpRequest} xhr
+ */
+ function onRegistered(hostName, publicKey, privateKey, xhr) {
+ var success = (xhr.status == 200);
+
+ if (success) {
+ that.hostDispatcher_.getPinHash(newHostId, hostPin,
+ startHostWithHash.bind(null, hostName, publicKey, privateKey, xhr),
+ onError);
+ } else {
+ console.log('Failed to register the host. Status: ' + xhr.status +
+ ' response: ' + xhr.responseText);
+ onError(remoting.Error.REGISTRATION_FAILED);
+ }
+ };
+
+ /**
+ * @param {string} hostName
* @param {string} privateKey
* @param {string} publicKey
* @param {string} oauthToken
@@ -173,8 +182,7 @@ remoting.HostController.prototype.start = function(hostPin, consent, callback) {
} };
remoting.xhr.post(
remoting.settings.DIRECTORY_API_BASE_URL + '/@me/hosts/',
- /** @param {XMLHttpRequest} xhr */
- function (xhr) { onRegistered(hostName, publicKey, privateKey, xhr); },
+ onRegistered.bind(null, hostName, publicKey, privateKey),
JSON.stringify(newHostDetails),
headers);
};
@@ -186,15 +194,8 @@ remoting.HostController.prototype.start = function(hostPin, consent, callback) {
*/
function onKeyGenerated(hostName, privateKey, publicKey) {
remoting.identity.callWithToken(
- /** @param {string} oauthToken */
- function(oauthToken) {
- doRegisterHost(hostName, privateKey, publicKey, oauthToken);
- },
- /** @param {remoting.Error} error */
- function(error) {
- // TODO(jamiewalch): Have a more specific error code here?
- callback(remoting.HostController.AsyncResult.FAILED);
- });
+ doRegisterHost.bind(null, hostName, privateKey, publicKey),
+ onError);
};
/**
@@ -203,48 +204,43 @@ remoting.HostController.prototype.start = function(hostPin, consent, callback) {
*/
function startWithHostname(hostName) {
that.hostDispatcher_.generateKeyPair(onKeyGenerated.bind(null, hostName),
- remoting.showErrorMessage);
+ onError);
}
- this.hostDispatcher_.getHostName(startWithHostname,
- remoting.showErrorMessage);
+ this.hostDispatcher_.getHostName(startWithHostname, onError);
};
/**
* Stop the daemon process.
- * @param {function(remoting.HostController.AsyncResult):void} callback
- * Callback to be called when finished.
+ * @param {function():void} onDone Callback to be called when done.
+ * @param {function(remoting.Error):void} onError Callback to be called on
+ * error.
* @return {void} Nothing.
*/
-remoting.HostController.prototype.stop = function(callback) {
+remoting.HostController.prototype.stop = function(onDone, onError) {
/** @type {remoting.HostController} */
var that = this;
- /**
- * @param {remoting.HostController.AsyncResult} result The result of the
- * stopDaemon call, to be passed to the callback.
- * @param {string?} hostId The host id of the local host.
- */
- function unregisterHost(result, hostId) {
+ /** @param {string?} hostId The host id of the local host. */
+ function unregisterHost(hostId) {
if (hostId) {
remoting.HostList.unregisterHostById(hostId);
}
- callback(result);
+ onDone();
};
- /**
- * @param {remoting.HostController.AsyncResult} result The result of the
- * stopDaemon call, to be passed to the callback.
- */
+ /** @param {remoting.HostController.AsyncResult} result */
function onStopped(result) {
- if (result != remoting.HostController.AsyncResult.OK) {
- callback(result);
- return;
+ if (result == remoting.HostController.AsyncResult.OK) {
+ that.getLocalHostId(unregisterHost);
+ } else if (result == remoting.HostController.AsyncResult.CANCELLED) {
+ onError(remoting.Error.CANCELLED);
+ } else {
+ onError(remoting.Error.UNEXPECTED);
}
- that.getLocalHostId(unregisterHost.bind(null, result));
- };
+ }
- this.hostDispatcher_.stopDaemon(onStopped, remoting.showErrorMessage);
+ this.hostDispatcher_.stopDaemon(onStopped, onError);
};
/**
@@ -260,24 +256,25 @@ function isHostConfigValid_(config) {
/**
* @param {string} newPin The new PIN to set
- * @param {function(remoting.HostController.AsyncResult):void} callback
- * Callback to be called when finished.
+ * @param {function():void} onDone Callback to be called when done.
+ * @param {function(remoting.Error):void} onError Callback to be called on
+ * error.
* @return {void} Nothing.
*/
-remoting.HostController.prototype.updatePin = function(newPin, callback) {
+remoting.HostController.prototype.updatePin = function(newPin, onDone,
+ onError) {
/** @type {remoting.HostController} */
var that = this;
- /** @param {Object} config */
- function onConfig(config) {
- if (!isHostConfigValid_(config)) {
- callback(remoting.HostController.AsyncResult.FAILED);
- return;
+ /** @param {remoting.HostController.AsyncResult} result */
+ function onConfigUpdated(result) {
+ if (result == remoting.HostController.AsyncResult.OK) {
+ onDone();
+ } else if (result == remoting.HostController.AsyncResult.CANCELLED) {
+ onError(remoting.Error.CANCELLED);
+ } else {
+ onError(remoting.Error.UNEXPECTED);
}
- /** @type {string} */
- var hostId = config['host_id'];
- that.hostDispatcher_.getPinHash(hostId, newPin, updateDaemonConfigWithHash,
- remoting.showErrorMessage);
}
/** @param {string} pinHash */
@@ -285,20 +282,32 @@ remoting.HostController.prototype.updatePin = function(newPin, callback) {
var newConfig = {
host_secret_hash: pinHash
};
- that.hostDispatcher_.updateDaemonConfig(newConfig, callback,
- remoting.showErrorMessage);
+ that.hostDispatcher_.updateDaemonConfig(newConfig, onConfigUpdated,
+ onError);
+ }
+
+ /** @param {Object} config */
+ function onConfig(config) {
+ if (!isHostConfigValid_(config)) {
+ onError(remoting.Error.UNEXPECTED);
+ return;
+ }
+ /** @type {string} */
+ var hostId = config['host_id'];
+ that.hostDispatcher_.getPinHash(hostId, newPin, updateDaemonConfigWithHash,
+ onError);
}
// TODO(sergeyu): When crbug.com/121518 is fixed: replace this call
// with an unprivileged version if that is necessary.
- this.hostDispatcher_.getDaemonConfig(onConfig, remoting.showErrorMessage);
+ this.hostDispatcher_.getDaemonConfig(onConfig, onError);
};
/**
* Get the state of the local host.
*
- * @param {function(remoting.HostController.State):void} onDone
- * Completion callback.
+ * @param {function(remoting.HostController.State):void} onDone Completion
+ * callback.
*/
remoting.HostController.prototype.getLocalHostState = function(onDone) {
this.hostDispatcher_.getDaemonState(onDone, function() {
diff --git a/remoting/webapp/host_setup_dialog.js b/remoting/webapp/host_setup_dialog.js
index c3b76e9..eb52b7c1 100644
--- a/remoting/webapp/host_setup_dialog.js
+++ b/remoting/webapp/host_setup_dialog.js
@@ -52,31 +52,30 @@ remoting.HostSetupFlow.prototype.getState = function() {
return this.state_;
};
-/**
- * @param {remoting.HostController.AsyncResult} result Result of the
- * current step.
- * @return {remoting.HostSetupFlow.State} New state.
- */
-remoting.HostSetupFlow.prototype.switchToNextStep = function(result) {
+remoting.HostSetupFlow.prototype.switchToNextStep = function() {
if (this.state_ == remoting.HostSetupFlow.State.NONE) {
- return this.state_;
+ return;
}
- if (result == remoting.HostController.AsyncResult.OK) {
- // If the current step was successful then switch to the next
- // step in the sequence.
- if (this.currentStep_ < this.sequence_.length - 1) {
- this.currentStep_ += 1;
- this.state_ = this.sequence_[this.currentStep_];
- } else {
- this.state_ = remoting.HostSetupFlow.State.NONE;
- }
- } else if (result == remoting.HostController.AsyncResult.CANCELLED) {
+
+ if (this.currentStep_ < this.sequence_.length - 1) {
+ this.currentStep_ += 1;
+ this.state_ = this.sequence_[this.currentStep_];
+ } else {
+ this.state_ = remoting.HostSetupFlow.State.NONE;
+ }
+};
+
+/**
+ * @param {remoting.Error} error
+ */
+remoting.HostSetupFlow.prototype.switchToErrorState = function(error) {
+ if (error == remoting.Error.CANCELLED) {
// Stop the setup flow if user rejected one of the actions.
this.state_ = remoting.HostSetupFlow.State.NONE;
} else {
// Current step failed, so switch to corresponding error state.
if (this.state_ == remoting.HostSetupFlow.State.STARTING_HOST) {
- if (result == remoting.HostController.AsyncResult.FAILED_DIRECTORY) {
+ if (error == remoting.Error.REGISTRATION_FAILED) {
this.state_ = remoting.HostSetupFlow.State.REGISTRATION_FAILED;
} else {
this.state_ = remoting.HostSetupFlow.State.START_HOST_FAILED;
@@ -90,7 +89,6 @@ remoting.HostSetupFlow.prototype.switchToNextStep = function(result) {
this.state_ = remoting.HostSetupFlow.State.START_HOST_FAILED;
}
}
- return this.state_;
};
/**
@@ -204,14 +202,25 @@ remoting.HostSetupDialog.prototype.showForStartWithToken_ =
* @param {boolean} set_by_policy True if crash dump reporting is controlled
* by policy.
*/
- var onGetConsent = function(supported, allowed, set_by_policy) {
+ function onGetConsent(supported, allowed, set_by_policy) {
that.usageStats_.hidden = !supported;
that.usageStatsCheckbox_.checked = allowed;
that.usageStatsCheckbox_.disabled = set_by_policy;
- };
+ }
+
+ /** @param {remoting.Error} error */
+ function onError(error) {
+ console.error('Error getting consent status: ' + error);
+ }
+
this.usageStats_.hidden = false;
this.usageStatsCheckbox_.checked = false;
- this.hostController_.getConsent(onGetConsent);
+
+ // Prevent user from ticking the box until the current consent status is
+ // known.
+ this.usageStatsCheckbox_.disabled = true;
+
+ this.hostController_.getConsent(onGetConsent, onError);
var flow = [
remoting.HostSetupFlow.State.ASK_PIN,
@@ -337,7 +346,7 @@ remoting.HostSetupDialog.prototype.updateState_ = function() {
} else if (state == remoting.HostSetupFlow.State.HOST_STOPPED) {
showDoneMessage(/*i18n-content*/'HOST_SETUP_STOPPED');
} else if (state == remoting.HostSetupFlow.State.REGISTRATION_FAILED) {
- showErrorMessage(/*i18n-content*/'HOST_SETUP_REGISTRATION_FAILED');
+ showErrorMessage(/*i18n-content*/'ERROR_HOST_REGISTRATION_FAILED');
} else if (state == remoting.HostSetupFlow.State.START_HOST_FAILED) {
showErrorMessage(/*i18n-content*/'HOST_SETUP_HOST_FAILED');
} else if (state == remoting.HostSetupFlow.State.UPDATE_PIN_FAILED) {
@@ -356,18 +365,33 @@ remoting.HostSetupDialog.prototype.startHost_ = function() {
/** @type {remoting.HostSetupFlow} */
var flow = this.flow_;
- /** @param {remoting.HostController.AsyncResult} result */
- function onHostStarted(result) {
+ /** @return {boolean} */
+ function isFlowActive() {
if (flow !== that.flow_ ||
flow.getState() != remoting.HostSetupFlow.State.STARTING_HOST) {
console.error('Host setup was interrupted when starting the host');
- return;
+ return false;
}
+ return true;
+ }
- flow.switchToNextStep(result);
- that.updateState_();
+ function onHostStarted() {
+ if (isFlowActive()) {
+ flow.switchToNextStep();
+ that.updateState_();
+ }
}
- this.hostController_.start(this.flow_.pin, this.flow_.consent, onHostStarted);
+
+ /** @param {remoting.Error} error */
+ function onError(error) {
+ if (isFlowActive()) {
+ flow.switchToErrorState(error);
+ that.updateState_();
+ }
+ }
+
+ this.hostController_.start(this.flow_.pin, this.flow_.consent, onHostStarted,
+ onError);
};
remoting.HostSetupDialog.prototype.updatePin_ = function() {
@@ -376,20 +400,33 @@ remoting.HostSetupDialog.prototype.updatePin_ = function() {
/** @type {remoting.HostSetupFlow} */
var flow = this.flow_;
- /** @param {remoting.HostController.AsyncResult} result */
- function onPinUpdated(result) {
+ /** @return {boolean} */
+ function isFlowActive() {
if (flow !== that.flow_ ||
flow.getState() != remoting.HostSetupFlow.State.UPDATING_PIN) {
console.error('Host setup was interrupted when updating PIN');
- return;
+ return false;
}
+ return true;
+ }
- flow.switchToNextStep(result);
- that.updateState_();
+ function onPinUpdated() {
+ if (isFlowActive()) {
+ flow.switchToNextStep();
+ that.updateState_();
+ }
}
- this.hostController_.updatePin(flow.pin, onPinUpdated);
-}
+ /** @param {remoting.Error} error */
+ function onError(error) {
+ if (isFlowActive()) {
+ flow.switchToErrorState(error);
+ that.updateState_();
+ }
+ }
+
+ this.hostController_.updatePin(flow.pin, onPinUpdated, onError);
+};
/**
* Stops the host.
@@ -400,18 +437,32 @@ remoting.HostSetupDialog.prototype.stopHost_ = function() {
/** @type {remoting.HostSetupFlow} */
var flow = this.flow_;
- /** @param {remoting.HostController.AsyncResult} result */
- function onHostStopped(result) {
+ /** @return {boolean} */
+ function isFlowActive() {
if (flow !== that.flow_ ||
flow.getState() != remoting.HostSetupFlow.State.STOPPING_HOST) {
console.error('Host setup was interrupted when stopping the host');
- return;
+ return false;
+ }
+ return true;
+ }
+
+ function onHostStopped() {
+ if (isFlowActive()) {
+ flow.switchToNextStep();
+ that.updateState_();
}
+ }
- flow.switchToNextStep(result);
- that.updateState_();
+ /** @param {remoting.Error} error */
+ function onError(error) {
+ if (isFlowActive()) {
+ flow.switchToErrorState(error);
+ that.updateState_();
+ }
}
- this.hostController_.stop(onHostStopped);
+
+ this.hostController_.stop(onHostStopped, onError);
};
/**
@@ -452,7 +503,7 @@ remoting.HostSetupDialog.prototype.onPinSubmit_ = function() {
this.flow_.pin = pin1;
this.flow_.consent = !this.usageStats_.hidden &&
this.usageStatsCheckbox_.checked;
- this.flow_.switchToNextStep(remoting.HostController.AsyncResult.OK);
+ this.flow_.switchToNextStep();
this.updateState_();
};
@@ -501,7 +552,7 @@ remoting.HostSetupDialog.prototype.onInstallDialogOk = function() {
state != remoting.HostController.State.NOT_INSTALLED &&
state != remoting.HostController.State.INSTALLING;
if (installed) {
- that.flow_.switchToNextStep(remoting.HostController.AsyncResult.OK);
+ that.flow_.switchToNextStep();
that.updateState_();
} else {
remoting.setMode(remoting.AppMode.HOST_SETUP_INSTALL_PENDING);