15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)'use strict';
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** @suppress {duplicate} */
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var remoting = remoting || {};
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** @constructor */
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.HostController = function() {
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  this.hostDaemonFacade_ = this.createDaemonFacade_();
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that the values in the enums below are copied from
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// daemon_controller.h and must be kept in sync.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** @enum {number} */
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.HostController.State = {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOT_IMPLEMENTED: -1,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOT_INSTALLED: 0,
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  INSTALLING: 1,
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STOPPED: 2,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STARTING: 3,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STARTED: 4,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STOPPING: 5,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UNKNOWN: 6
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/**
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {string} state The host controller state name.
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @return {remoting.HostController.State} The state enum value.
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)remoting.HostController.State.fromString = function(state) {
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!remoting.HostController.State.hasOwnProperty(state)) {
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    throw "Invalid HostController.State: " + state;
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return remoting.HostController.State[state];
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** @enum {number} */
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.HostController.AsyncResult = {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OK: 0,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FAILED: 1,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CANCELLED: 2,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FAILED_DIRECTORY: 3
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {string} result The async result name.
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @return {remoting.HostController.AsyncResult} The result enum value.
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)remoting.HostController.AsyncResult.fromString = function(result) {
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!remoting.HostController.AsyncResult.hasOwnProperty(result)) {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    throw "Invalid HostController.AsyncResult: " + result;
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return remoting.HostController.AsyncResult[result];
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/**
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return {remoting.HostDaemonFacade}
61a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * @private
62a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch */
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdochremoting.HostController.prototype.createDaemonFacade_ = function() {
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  /** @type {remoting.HostDaemonFacade} @private */
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var hostDaemonFacade = new remoting.HostDaemonFacade();
66a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  /** @param {string} version */
68a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  var printVersion = function(version) {
69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (version == '') {
70a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      console.log('Host not installed.');
71a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    } else {
72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      console.log('Host version: ' + version);
73a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    }
74a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  };
75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  hostDaemonFacade.getDaemonVersion(printVersion, function() {
77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    console.log('Host version not available.');
78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  });
79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return hostDaemonFacade;
81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch};
82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch/**
84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * Set of features for which hasFeature() can be used to test.
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *
86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * @enum {string}
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) */
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)remoting.HostController.Feature = {
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  PAIRING_REGISTRY: 'pairingRegistry',
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  OAUTH_CLIENT: 'oauthClient'
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)/**
94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * @param {remoting.HostController.Feature} feature The feature to test for.
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * @param {function(boolean):void} callback
96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * @return {void}
97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) */
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)remoting.HostController.prototype.hasFeature = function(feature, callback) {
99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // TODO(rmsousa): This could synchronously return a boolean, provided it were
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // only called after native messaging is completely initialized.
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  this.hostDaemonFacade_.hasFeature(feature, callback);
102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)/**
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * @param {function(boolean, boolean, boolean):void} onDone Callback to be
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *     called when done.
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * @param {function(remoting.Error):void} onError Callback to be called on
108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *     error.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochremoting.HostController.prototype.getConsent = function(onDone, onError) {
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  this.hostDaemonFacade_.getUsageStatsConsent(onDone, onError);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Registers and starts the host.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} hostPin Host PIN.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {boolean} consent The user's consent to crash dump reporting.
119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * @param {function():void} onDone Callback to be called when done.
120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * @param {function(remoting.Error):void} onError Callback to be called on
121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *     error.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochremoting.HostController.prototype.start = function(hostPin, consent, onDone,
125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                                   onError) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /** @type {remoting.HostController} */
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var that = this;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /** @return {string} */
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function generateUuid() {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var random = new Uint16Array(8);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window.crypto.getRandomValues(random);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /** @type {Array.<string>} */
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var e = new Array();
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (var i = 0; i < 8; i++) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      e[i] = (/** @type {number} */random[i] + 0x10000).
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          toString(16).substring(1);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return e[0] + e[1] + '-' + e[2] + '-' + e[3] + '-' +
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        e[4] + '-' + e[5] + e[6] + e[7];
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var newHostId = generateUuid();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  /** @param {remoting.Error} error */
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  function onStartError(error) {
147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Unregister the host if we failed to start it.
148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    remoting.HostList.unregisterHostById(newHostId);
149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    onError(error);
150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /**
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   * @param {string} hostName
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   * @param {string} publicKey
155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch   * @param {remoting.HostController.AsyncResult} result
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   */
157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  function onStarted(hostName, publicKey, result) {
158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (result == remoting.HostController.AsyncResult.OK) {
159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      remoting.hostList.onLocalHostStarted(hostName, newHostId, publicKey);
160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      onDone();
161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else if (result == remoting.HostController.AsyncResult.CANCELLED) {
162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      onStartError(remoting.Error.CANCELLED);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      onStartError(remoting.Error.UNEXPECTED);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /**
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   * @param {string} hostName
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   * @param {string} publicKey
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   * @param {string} privateKey
1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} xmppLogin
1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} refreshToken
1741675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch   * @param {string} clientBaseJid
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   * @param {string} hostSecretHash
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   */
1771675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  function startHostWithHash(hostName, publicKey, privateKey, xmppLogin,
1781675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch                             refreshToken, clientBaseJid, hostSecretHash) {
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    var hostConfig = {
1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      xmpp_login: xmppLogin,
1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      oauth_refresh_token: refreshToken,
1823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      host_id: newHostId,
1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      host_name: hostName,
1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      host_secret_hash: hostSecretHash,
1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      private_key: privateKey
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    };
1871675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    var hostOwner = clientBaseJid;
1881675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    var hostOwnerEmail = remoting.identity.getCachedEmail();
1893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (hostOwner != xmppLogin) {
1903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      hostConfig['host_owner'] = hostOwner;
1911675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      if (hostOwnerEmail != hostOwner) {
1921675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        hostConfig['host_owner_email'] = hostOwnerEmail;
1931675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      }
1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    that.hostDaemonFacade_.startDaemon(
196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        hostConfig, consent, onStarted.bind(null, hostName, publicKey),
197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        onStartError);
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /**
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   * @param {string} hostName
202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch   * @param {string} publicKey
203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch   * @param {string} privateKey
2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} email
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} refreshToken
2061675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch   * @param {string} clientBaseJid
2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   */
2081675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  function onClientBaseJid(
2091675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      hostName, publicKey, privateKey, email, refreshToken, clientBaseJid) {
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    that.hostDaemonFacade_.getPinHash(
2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        newHostId, hostPin,
2121675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        startHostWithHash.bind(null, hostName, publicKey, privateKey,
2131675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch                               email, refreshToken, clientBaseJid),
2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        onError);
2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  /**
2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} hostName
2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} publicKey
2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} privateKey
2211675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch   * @param {string} email
2221675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch   * @param {string} refreshToken
2231675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch   */
2241675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  function onServiceAccountCredentials(
2251675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      hostName, publicKey, privateKey, email, refreshToken) {
2261675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    that.getClientBaseJid_(
2271675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        onClientBaseJid.bind(
2281675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch            null, hostName, publicKey, privateKey, email, refreshToken),
2291675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        onStartError);
2301675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  }
2311675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
2321675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  /**
2331675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch   * @param {string} hostName
2341675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch   * @param {string} publicKey
2351675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch   * @param {string} privateKey
236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch   * @param {XMLHttpRequest} xhr
237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch   */
2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  function onRegistered(
2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      hostName, publicKey, privateKey, xhr) {
240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    var success = (xhr.status == 200);
241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (success) {
2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      var result = jsonParseSafe(xhr.responseText);
2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      if ('data' in result && 'authorizationCode' in result['data']) {
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        that.hostDaemonFacade_.getCredentialsFromAuthCode(
2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            result['data']['authorizationCode'],
2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            onServiceAccountCredentials.bind(
2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                null, hostName, publicKey, privateKey),
2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            onError);
2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      } else {
2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        // No authorization code returned, use regular user credential flow.
252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        that.hostDaemonFacade_.getPinHash(
2533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            newHostId, hostPin, startHostWithHash.bind(
2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                null, hostName, publicKey, privateKey,
2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                remoting.identity.getCachedEmail(),
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                remoting.oauth2.getRefreshToken()),
257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          onError);
2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      }
259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else {
260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      console.log('Failed to register the host. Status: ' + xhr.status +
261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                  ' response: ' + xhr.responseText);
262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      onError(remoting.Error.REGISTRATION_FAILED);
263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  /**
267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch   * @param {string} hostName
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * @param {string} privateKey
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * @param {string} publicKey
2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} hostClientId
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   * @param {string} oauthToken
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   */
2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  function doRegisterHost(
2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      hostName, privateKey, publicKey, hostClientId, oauthToken) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var headers = {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'Authorization': 'OAuth ' + oauthToken,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'Content-type' : 'application/json; charset=UTF-8'
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var newHostDetails = { data: {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       hostId: newHostId,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       hostName: hostName,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       publicKey: publicKey
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } };
2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    var registerHostUrl =
2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        remoting.settings.DIRECTORY_API_BASE_URL + '/@me/hosts';
2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (hostClientId) {
2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      registerHostUrl += '?' + remoting.xhr.urlencodeParamHash(
2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          { hostClientId: hostClientId });
2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    remoting.xhr.post(
2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        registerHostUrl,
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        onRegistered.bind(null, hostName, publicKey, privateKey),
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        JSON.stringify(newHostDetails),
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        headers);
2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /**
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   * @param {string} hostName
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   * @param {string} privateKey
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   * @param {string} publicKey
3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} hostClientId
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   */
3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  function onHostClientId(
3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      hostName, privateKey, publicKey, hostClientId) {
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    remoting.identity.callWithToken(
3103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        doRegisterHost.bind(
3113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            null, hostName, privateKey, publicKey, hostClientId), onError);
3123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  /**
3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} hostName
3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} privateKey
3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} publicKey
3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {boolean} hasFeature
3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   */
3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  function onHasFeatureOAuthClient(
3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      hostName, privateKey, publicKey, hasFeature) {
3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (hasFeature) {
323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      that.hostDaemonFacade_.getHostClientId(
3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          onHostClientId.bind(null, hostName, privateKey, publicKey), onError);
3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      remoting.identity.callWithToken(
3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          doRegisterHost.bind(
3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              null, hostName, privateKey, publicKey, null), onError);
3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  /**
3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} hostName
3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} privateKey
3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   * @param {string} publicKey
3363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   */
3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  function onKeyGenerated(hostName, privateKey, publicKey) {
3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    that.hasFeature(
3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        remoting.HostController.Feature.OAUTH_CLIENT,
3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        onHasFeatureOAuthClient.bind(null, hostName, privateKey, publicKey));
3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /**
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   * @param {string} hostName
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   * @return {void} Nothing.
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   */
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  function startWithHostname(hostName) {
348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    that.hostDaemonFacade_.generateKeyPair(onKeyGenerated.bind(null, hostName),
349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                         onError);
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  this.hostDaemonFacade_.getHostName(startWithHostname, onError);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Stop the daemon process.
357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * @param {function():void} onDone Callback to be called when done.
358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * @param {function(remoting.Error):void} onError Callback to be called on
359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *     error.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing.
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochremoting.HostController.prototype.stop = function(onDone, onError) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /** @type {remoting.HostController} */
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var that = this;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  /** @param {string?} hostId The host id of the local host. */
367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  function unregisterHost(hostId) {
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (hostId) {
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      remoting.HostList.unregisterHostById(hostId);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    onDone();
3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  /** @param {remoting.HostController.AsyncResult} result */
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function onStopped(result) {
376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (result == remoting.HostController.AsyncResult.OK) {
377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      that.getLocalHostId(unregisterHost);
378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else if (result == remoting.HostController.AsyncResult.CANCELLED) {
379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      onError(remoting.Error.CANCELLED);
380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else {
381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      onError(remoting.Error.UNEXPECTED);
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  this.hostDaemonFacade_.stopDaemon(onStopped, onError);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
38990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * Check the host configuration is valid (non-null, and contains both host_id
39090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * and xmpp_login keys).
39190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * @param {Object} config The host configuration.
39290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * @return {boolean} True if it is valid.
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)function isHostConfigValid_(config) {
39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return !!config && typeof config['host_id'] == 'string' &&
39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      typeof config['xmpp_login'] == 'string';
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} newPin The new PIN to set
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * @param {function():void} onDone Callback to be called when done.
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * @param {function(remoting.Error):void} onError Callback to be called on
403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *     error.
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing.
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochremoting.HostController.prototype.updatePin = function(newPin, onDone,
407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                                       onError) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /** @type {remoting.HostController} */
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var that = this;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  /** @param {remoting.HostController.AsyncResult} result */
412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  function onConfigUpdated(result) {
413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (result == remoting.HostController.AsyncResult.OK) {
414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      onDone();
415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else if (result == remoting.HostController.AsyncResult.CANCELLED) {
416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      onError(remoting.Error.CANCELLED);
417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else {
418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      onError(remoting.Error.UNEXPECTED);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
420b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /** @param {string} pinHash */
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  function updateDaemonConfigWithHash(pinHash) {
42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    var newConfig = {
42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      host_secret_hash: pinHash
42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    };
427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    that.hostDaemonFacade_.updateDaemonConfig(newConfig, onConfigUpdated,
428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                            onError);
429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  /** @param {Object} config */
432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  function onConfig(config) {
433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (!isHostConfigValid_(config)) {
434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      onError(remoting.Error.UNEXPECTED);
435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return;
436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    /** @type {string} */
438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    var hostId = config['host_id'];
439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    that.hostDaemonFacade_.getPinHash(
440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        hostId, newPin, updateDaemonConfigWithHash, onError);
441b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(sergeyu): When crbug.com/121518 is fixed: replace this call
44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // with an unprivileged version if that is necessary.
445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  this.hostDaemonFacade_.getDaemonConfig(onConfig, onError);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Get the state of the local host.
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * @param {function(remoting.HostController.State):void} onDone Completion
452eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *     callback.
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)remoting.HostController.prototype.getLocalHostState = function(onDone) {
455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  /** @param {remoting.Error} error */
456116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  function onError(error) {
457116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    onDone((error == remoting.Error.MISSING_PLUGIN) ?
458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               remoting.HostController.State.NOT_INSTALLED :
459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               remoting.HostController.State.UNKNOWN);
460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  this.hostDaemonFacade_.getDaemonState(onDone, onError);
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/**
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Get the id of the local host, or null if it is not registered.
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @param {function(string?):void} onDone Completion callback.
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)remoting.HostController.prototype.getLocalHostId = function(onDone) {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /** @type {remoting.HostController} */
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var that = this;
47290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  /** @param {Object} config */
47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  function onConfig(config) {
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    var hostId = null;
47590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (isHostConfigValid_(config)) {
47690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      hostId = /** @type {string} */ config['host_id'];
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    onDone(hostId);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
481116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  this.hostDaemonFacade_.getDaemonConfig(onConfig, function(error) {
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    onDone(null);
4837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  });
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
486a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch/**
487a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * Fetch the list of paired clients for this host.
488a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch *
489a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * @param {function(Array.<remoting.PairedClient>):void} onDone
490a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * @param {function(remoting.Error):void} onError
491a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * @return {void}
492a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch */
493a3f7b4e666c476898878fa745f637129375cd889Ben Murdochremoting.HostController.prototype.getPairedClients = function(onDone,
494a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                                              onError) {
495116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  this.hostDaemonFacade_.getPairedClients(onDone, onError);
496a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch};
497a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
498a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch/**
499a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * Delete a single paired client.
500a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch *
501a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * @param {string} client The client id of the pairing to delete.
502a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * @param {function():void} onDone Completion callback.
503a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * @param {function(remoting.Error):void} onError Error callback.
504a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * @return {void}
505a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch */
506a3f7b4e666c476898878fa745f637129375cd889Ben Murdochremoting.HostController.prototype.deletePairedClient = function(
507a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    client, onDone, onError) {
508116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  this.hostDaemonFacade_.deletePairedClient(client, onDone, onError);
509a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch};
510a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
511a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch/**
512a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * Delete all paired clients.
513a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch *
514a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * @param {function():void} onDone Completion callback.
515a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * @param {function(remoting.Error):void} onError Error callback.
516a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * @return {void}
517a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch */
518a3f7b4e666c476898878fa745f637129375cd889Ben Murdochremoting.HostController.prototype.clearPairedClients = function(
519a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    onDone, onError) {
520116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  this.hostDaemonFacade_.clearPairedClients(onDone, onError);
521a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch};
522a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
5231675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch/**
5241675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch * Gets the host owner's base JID, used by the host for client authorization.
5251675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch * In most cases this is the same as the owner's email address, but for
5261675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch * non-Gmail accounts, it may be different.
5271675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch *
5281675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch * @private
5291675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch * @param {function(string): void} onSuccess
5301675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch * @param {function(remoting.Error): void} onError
5311675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch */
5321675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdochremoting.HostController.prototype.getClientBaseJid_ = function(
5331675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    onSuccess, onError) {
5341675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  var signalStrategy = null;
5351675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
5361675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  var onState = function(state) {
5371675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    switch (state) {
5381675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      case remoting.SignalStrategy.State.CONNECTED:
5391675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        var jid = signalStrategy.getJid().split('/')[0].toLowerCase();
5401675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        base.dispose(signalStrategy);
5411675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        signalStrategy = null;
5421675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        onSuccess(jid);
5431675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        break;
5441675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
5451675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      case remoting.SignalStrategy.State.FAILED:
5461675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        var error = signalStrategy.getError();
5471675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        base.dispose(signalStrategy);
5481675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        signalStrategy = null;
5491675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        onError(error);
5501675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        break;
5511675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    }
5521675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  };
5531675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
5541675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  signalStrategy = remoting.SignalStrategy.create(onState);
5551675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
5561675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  /** @param {string} token */
5571675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  function connectSignalingWithToken(token) {
5581675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    remoting.identity.getEmail(
5591675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        connectSignalingWithTokenAndEmail.bind(null, token), onError);
5601675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  }
5611675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
5621675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  /**
5631675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch   * @param {string} token
5641675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch   * @param {string} email
5651675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch   */
5661675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  function connectSignalingWithTokenAndEmail(token, email) {
5671675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    signalStrategy.connect(
5681675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch        remoting.settings.XMPP_SERVER_ADDRESS, email, token);
5691675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  }
5701675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
5711675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  remoting.identity.callWithToken(connectSignalingWithToken, onError);
5721675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch};
5731675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** @type {remoting.HostController} */
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.hostController = null;
576