blob: 449d013cdb4e44a7b6f19825836aef2aa414ce7d [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview
* REST API for host-list management.
*/
/** @suppress {duplicate} */
var remoting = remoting || {};
(function() {
'use strict';
/**
* @constructor
* @implements {remoting.HostListApi}
*/
remoting.GcdHostListApi = function() {
this.gcd_ = new remoting.gcd.Client({
apiKey: remoting.settings.GOOGLE_API_KEY
});
};
/** @override */
remoting.GcdHostListApi.prototype.register = function(
hostName, publicKey, hostClientId) {
var self = this;
var deviceDraft = {
channel: {
supportedType: 'xmpp'
},
deviceKind: 'vendor',
name: hostName,
state: {
base: {
firmwareVersion: 'none',
localDiscoveryEnabled: false,
localAnonymousAccessMaxRole: 'none',
localPairingEnabled: false,
// The leading underscore is necessary for |_publicKey|
// because it's not a standard key defined by GCD.
_publicKey: publicKey
}
},
'tags': [CHROMOTING_DEVICE_TAG]
};
return /** @type {!Promise<remoting.HostListApi.RegisterResult>} */ (
this.gcd_.insertRegistrationTicket().
then(function(ticket) {
return self.gcd_.patchRegistrationTicket(
ticket.id, deviceDraft, hostClientId);
}).
then(function(/**remoting.gcd.RegistrationTicket*/ ticket) {
return self.gcd_.finalizeRegistrationTicket(ticket.id);
}).
then(function(/**remoting.gcd.RegistrationTicket*/ ticket) {
return {
authCode: ticket.robotAccountAuthorizationCode,
email: ticket.robotAccountEmail,
hostId: ticket.deviceId
};
}).
catch(function(error) {
console.error('Error registering device with GCD: ' + error);
throw new remoting.Error(remoting.Error.Tag.REGISTRATION_FAILED);
}));
};
/** @override */
remoting.GcdHostListApi.prototype.get = function() {
return this.gcd_.listDevices().
then(function(devices) {
var hosts = [];
devices.forEach(function(device) {
try {
if (isChromotingHost(device)) {
hosts.push(deviceToHost(device));
}
} catch (/** @type {*} */ error) {
console.warn('Invalid device spec:', error);
}
});
return hosts;
});
};
/** @override */
remoting.GcdHostListApi.prototype.put =
function(hostId, hostName, hostPublicKey) {
return this.gcd_.patchDevice(hostId, {
'name': hostName
}).then(function(device) {
if (device.name != hostName) {
console.error('error updating host name');
throw remoting.Error.unexpected();
}
if (!device.state || device.state['_publicKey'] != hostPublicKey) {
// TODO(jrw): Is there any reason to believe this would ever be
// happen?
console.error('unexpected host public key');
throw remoting.Error.unexpected();
}
// Don't return anything.
});
};
/** @override */
remoting.GcdHostListApi.prototype.remove = function(hostId) {
return this.gcd_.deleteDevice(hostId).then(function(deleted) {
if (!deleted) {
console.error('error deleting host from GCD');
throw remoting.Error.unexpected();
}
// Don't return anything.
});
};
/** @override */
remoting.GcdHostListApi.prototype.getSupportHost = function(supportId) {
console.error('getSupportHost not supported by HostListApiGclImpl');
return Promise.reject(remoting.Error.unexpected());
};
/**
* Tag for distinguishing Chromoting hosts from other devices stored
* in GCD.
*
* @const
*/
var CHROMOTING_DEVICE_TAG = '1ce4542c-dd87-4320-ba19-ac173f98c04e';
/**
* Check whether a GCD device entry is a Chromoting host.
*
* @param {remoting.gcd.Device} device
* @return {boolean}
*/
function isChromotingHost(device) {
return device.tags != null &&
device.tags.indexOf(CHROMOTING_DEVICE_TAG) != -1;
}
/**
* Converts a GCD device description to a Host object.
*
* @param {!Object} device
* @return {!remoting.Host}
*/
function deviceToHost(device) {
var statusMap = {
'online': 'ONLINE',
'offline': 'OFFLINE'
};
var hostId = base.getStringAttr(device, 'id');
var host = new remoting.Host(hostId);
host.hostName = base.getStringAttr(device, 'name');
host.status = base.getStringAttr(
statusMap, base.getStringAttr(device, 'connectionStatus'));
var state = base.getObjectAttr(device, 'state', {});
var baseState = base.getObjectAttr(state, 'base', {});
host.publicKey = base.getStringAttr(baseState, '_publicKey');
host.jabberId = base.getStringAttr(baseState, '_jabberId', '');
host.hostVersion = base.getStringAttr(baseState, '_hostVersion', '');
host.hostOs = remoting.ChromotingEvent.toOs(
base.getStringAttr(baseState, '_hostOs', ''));
host.hostOsVersion = base.getStringAttr(baseState, '_hostOsVersion', '');
var creationTimeMs = base.getNumberAttr(device, 'creationTimeMs', 0);
if (creationTimeMs) {
host.createdTime = new Date(creationTimeMs).toISOString();
}
var lastUpdateTimeMs = base.getNumberAttr(device, 'lastUpdateTimeMs', 0);
if (lastUpdateTimeMs) {
host.updatedTime = new Date(lastUpdateTimeMs).toISOString();
}
return host;
};
})();