Revert 168224 - Update V8 to version 3.15.4.
[chromium-blink-merge.git] / remoting / webapp / host_controller.js
blob0dfabdb57b7bf3f268dcec80338f121086d1dd6e
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
3 // found in the LICENSE file.
5 'use strict';
7 /** @suppress {duplicate} */
8 var remoting = remoting || {};
10 /** @constructor */
11 remoting.HostController = function() {
12 /** @type {remoting.HostPlugin} @private */
13 this.plugin_ = remoting.HostSession.createPlugin();
14 /** @type {HTMLElement} @private */
15 this.container_ = document.getElementById('daemon-plugin-container');
16 this.container_.appendChild(this.plugin_);
17 /** @type {string?} */
18 this.localHostId_ = null;
19 /** @param {string} version */
20 var printVersion = function(version) {
21 if (version == '') {
22 console.log('Host not installed.');
23 } else {
24 console.log('Host version: ' + version);
27 try {
28 this.plugin_.getDaemonVersion(printVersion);
29 } catch (err) {
30 console.log('Host version not available.');
34 // Note that the values in the enums below are copied from
35 // daemon_controller.h and must be kept in sync.
36 /** @enum {number} */
37 remoting.HostController.State = {
38 NOT_IMPLEMENTED: -1,
39 NOT_INSTALLED: 0,
40 INSTALLING: 1,
41 STOPPED: 2,
42 STARTING: 3,
43 STARTED: 4,
44 STOPPING: 5,
45 UNKNOWN: 6
48 /** @enum {number} */
49 remoting.HostController.AsyncResult = {
50 OK: 0,
51 FAILED: 1,
52 CANCELLED: 2,
53 FAILED_DIRECTORY: 3
56 /** @return {remoting.HostController.State} The current state of the daemon. */
57 remoting.HostController.prototype.state = function() {
58 var result = this.plugin_.daemonState;
59 if (typeof(result) == 'undefined') {
60 // If the plug-in can't be instantiated, for example on ChromeOS, then
61 // return something sensible.
62 return remoting.HostController.State.NOT_IMPLEMENTED;
63 } else {
64 return result;
68 /**
69 * @param {function(boolean, boolean, boolean):void} callback Callback to be
70 * called when done.
72 remoting.HostController.prototype.getConsent = function(callback) {
73 this.plugin_.getUsageStatsConsent(callback);
76 /**
77 * Registers and starts the host.
78 * @param {string} hostPin Host PIN.
79 * @param {boolean} consent The user's consent to crash dump reporting.
80 * @param {function(remoting.HostController.AsyncResult):void} callback
81 * callback Callback to be called when done.
82 * @return {void} Nothing.
84 remoting.HostController.prototype.start = function(hostPin, consent, callback) {
85 /** @type {remoting.HostController} */
86 var that = this;
87 var hostName = this.plugin_.getHostName();
89 /** @return {string} */
90 function generateUuid() {
91 var random = new Uint16Array(8);
92 window.crypto.getRandomValues(random);
93 /** @type {Array.<string>} */
94 var e = new Array();
95 for (var i = 0; i < 8; i++) {
96 e[i] = (/** @type {number} */random[i] + 0x10000).
97 toString(16).substring(1);
99 return e[0] + e[1] + '-' + e[2] + "-" + e[3] + '-' +
100 e[4] + '-' + e[5] + e[6] + e[7];
103 var newHostId = generateUuid();
105 /** @param {function(remoting.HostController.AsyncResult):void} callback
106 * @param {remoting.HostController.AsyncResult} result
107 * @param {string} hostName
108 * @param {string} publicKey */
109 function onStarted(callback, result, hostName, publicKey) {
110 if (result == remoting.HostController.AsyncResult.OK) {
111 that.localHostId_ = newHostId;
112 remoting.hostList.onLocalHostStarted(hostName, newHostId, publicKey);
113 } else {
114 that.localHostId_ = null;
115 // Unregister the host if we failed to start it.
116 remoting.HostList.unregisterHostById(newHostId);
118 callback(result);
121 /** @param {string} publicKey
122 * @param {string} privateKey
123 * @param {XMLHttpRequest} xhr */
124 function onRegistered(publicKey, privateKey, xhr) {
125 var success = (xhr.status == 200);
127 if (success) {
128 var hostSecretHash =
129 that.plugin_.getPinHash(newHostId, hostPin);
130 var hostConfig = JSON.stringify({
131 xmpp_login: remoting.oauth2.getCachedEmail(),
132 oauth_refresh_token: remoting.oauth2.exportRefreshToken(),
133 host_id: newHostId,
134 host_name: hostName,
135 host_secret_hash: hostSecretHash,
136 private_key: privateKey
138 /** @param {remoting.HostController.AsyncResult} result */
139 var onStartDaemon = function(result) {
140 onStarted(callback, result, hostName, publicKey);
142 that.plugin_.startDaemon(hostConfig, consent, onStartDaemon);
143 } else {
144 console.log('Failed to register the host. Status: ' + xhr.status +
145 ' response: ' + xhr.responseText);
146 callback(remoting.HostController.AsyncResult.FAILED_DIRECTORY);
151 * @param {string} privateKey
152 * @param {string} publicKey
153 * @param {string} oauthToken
155 function doRegisterHost(privateKey, publicKey, oauthToken) {
156 var headers = {
157 'Authorization': 'OAuth ' + oauthToken,
158 'Content-type' : 'application/json; charset=UTF-8'
161 var newHostDetails = { data: {
162 hostId: newHostId,
163 hostName: hostName,
164 publicKey: publicKey
165 } };
166 remoting.xhr.post(
167 'https://www.googleapis.com/chromoting/v1/@me/hosts/',
168 /** @param {XMLHttpRequest} xhr */
169 function (xhr) { onRegistered(publicKey, privateKey, xhr); },
170 JSON.stringify(newHostDetails),
171 headers);
174 /** @param {string} privateKey
175 * @param {string} publicKey */
176 function onKeyGenerated(privateKey, publicKey) {
177 remoting.oauth2.callWithToken(
178 /** @param {string} oauthToken */
179 function(oauthToken) {
180 doRegisterHost(privateKey, publicKey, oauthToken);
182 /** @param {remoting.Error} error */
183 function(error) {
184 // TODO(jamiewalch): Have a more specific error code here?
185 callback(remoting.HostController.AsyncResult.FAILED);
189 this.plugin_.generateKeyPair(onKeyGenerated);
193 * Stop the daemon process.
194 * @param {function(remoting.HostController.AsyncResult):void} callback
195 * Callback to be called when finished.
196 * @return {void} Nothing.
198 remoting.HostController.prototype.stop = function(callback) {
199 /** @type {remoting.HostController} */
200 var that = this;
202 /** @param {remoting.HostController.AsyncResult} result */
203 function onStopped(result) {
204 if (result == remoting.HostController.AsyncResult.OK &&
205 that.localHostId_) {
206 remoting.HostList.unregisterHostById(that.localHostId_);
208 callback(result);
210 this.plugin_.stopDaemon(onStopped);
214 * Parse a stringified host configuration and return it as a dictionary if it
215 * is well-formed and contains both host_id and xmpp_login keys. null is
216 * returned if either key is missing, or if the configuration is corrupt.
217 * @param {string} configStr The host configuration, JSON encoded to a string.
218 * @return {Object.<string,string>|null} The host configuration.
220 function parseHostConfig_(configStr) {
221 var config = /** @type {Object.<string,string>} */ jsonParseSafe(configStr);
222 if (config &&
223 typeof config['host_id'] == 'string' &&
224 typeof config['xmpp_login'] == 'string') {
225 return config;
226 } else {
227 // {} means that host is not configured; '' means that the config file could
228 // not be read.
229 // TODO(jamiewalch): '' is expected if the host isn't installed, but should
230 // be reported as an error otherwise. Fix this once we have an event-based
231 // daemon state mechanism.
232 if (configStr != '{}' && configStr != '') {
233 console.error('Invalid getDaemonConfig response.');
236 return null;
240 * @param {string} newPin The new PIN to set
241 * @param {function(remoting.HostController.AsyncResult):void} callback
242 * Callback to be called when finished.
243 * @return {void} Nothing.
245 remoting.HostController.prototype.updatePin = function(newPin, callback) {
246 /** @type {remoting.HostController} */
247 var that = this;
249 /** @param {string} configStr */
250 function onConfig(configStr) {
251 var config = parseHostConfig_(configStr);
252 if (!config) {
253 callback(remoting.HostController.AsyncResult.FAILED);
254 return;
256 var hostId = config['host_id'];
257 var newConfig = JSON.stringify({
258 host_secret_hash: that.plugin_.getPinHash(hostId, newPin)
260 that.plugin_.updateDaemonConfig(newConfig, callback);
263 // TODO(sergeyu): When crbug.com/121518 is fixed: replace this call
264 // with an upriveleged version if that is necessary.
265 this.plugin_.getDaemonConfig(onConfig);
269 * Update the internal state so that the local host can be correctly filtered
270 * out of the host list.
272 * @param {function(string?):void} onDone Completion callback.
274 remoting.HostController.prototype.getLocalHostId = function(onDone) {
275 /** @type {remoting.HostController} */
276 var that = this;
277 /** @param {string} configStr */
278 function onConfig(configStr) {
279 var config = parseHostConfig_(configStr);
280 if (config) {
281 that.localHostId_ = config['host_id'];
282 onDone(that.localHostId_);
283 } else {
284 onDone(null);
287 try {
288 this.plugin_.getDaemonConfig(onConfig);
289 } catch (err) {
290 onDone(null);
294 /** @type {remoting.HostController} */
295 remoting.hostController = null;