Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / remoting / webapp / crd / js / gcd_host_list_api.js
blob42c823493b9fb4b8fd95056ca41e129fa2329d9e
1 // Copyright 2014 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 /**
6  * @fileoverview
7  * REST API for host-list management.
8  */
10 /** @suppress {duplicate} */
11 var remoting = remoting || {};
13 (function() {
15 'use strict';
17 /**
18  * @constructor
19  * @implements {remoting.HostListApi}
20  */
21 remoting.GcdHostListApi = function() {
22   this.gcd_ = new remoting.gcd.Client({
23     apiKey: remoting.settings.GOOGLE_API_KEY
24   });
27 /** @override */
28 remoting.GcdHostListApi.prototype.register = function(
29     hostName, publicKey, hostClientId) {
30   var self = this;
31   var deviceDraft = {
32     channel: {
33       supportedType: 'xmpp'
34     },
35     deviceKind: 'vendor',
36     name: hostName,
37     state: {
38       base: {
39         firmwareVersion: 'none',
40         localDiscoveryEnabled: false,
41         localAnonymousAccessMaxRole: 'none',
42         localPairingEnabled: false,
43         // The leading underscore is necessary for |_publicKey|
44         // because it's not a standard key defined by GCD.
45         _publicKey: publicKey
46       }
47     },
48     'tags': [CHROMOTING_DEVICE_TAG]
49   };
51   return /** @type {!Promise<remoting.HostListApi.RegisterResult>} */ (
52       this.gcd_.insertRegistrationTicket().
53       then(function(ticket) {
54         return self.gcd_.patchRegistrationTicket(
55             ticket.id, deviceDraft, hostClientId);
56       }).
57       then(function(/**remoting.gcd.RegistrationTicket*/ ticket) {
58         return self.gcd_.finalizeRegistrationTicket(ticket.id);
59       }).
60       then(function(/**remoting.gcd.RegistrationTicket*/ ticket) {
61         return {
62           authCode: ticket.robotAccountAuthorizationCode,
63           email: ticket.robotAccountEmail,
64           hostId: ticket.deviceId
65         };
66       }).
67       catch(function(error) {
68         console.error('Error registering device with GCD: ' + error);
69         throw new remoting.Error(remoting.Error.Tag.REGISTRATION_FAILED);
70       }));
73 /** @override */
74 remoting.GcdHostListApi.prototype.get = function() {
75   return this.gcd_.listDevices().
76       then(function(devices) {
77         var hosts = [];
78         devices.forEach(function(device) {
79           try {
80             if (isChromotingHost(device)) {
81               hosts.push(deviceToHost(device));
82             }
83           } catch (/** @type {*} */ error) {
84             console.warn('Invalid device spec:', error);
85           }
86         });
87         return hosts;
88       });
91 /** @override */
92 remoting.GcdHostListApi.prototype.put =
93     function(hostId, hostName, hostPublicKey) {
94   return this.gcd_.patchDevice(hostId, {
95     'name': hostName
96   }).then(function(device) {
97     if (device.name != hostName) {
98       console.error('error updating host name');
99       throw remoting.Error.unexpected();
100     }
101     if (!device.state || device.state['_publicKey'] != hostPublicKey) {
102       // TODO(jrw): Is there any reason to believe this would ever be
103       // happen?
104       console.error('unexpected host public key');
105       throw remoting.Error.unexpected();
106     }
107     // Don't return anything.
108   });
111 /** @override */
112 remoting.GcdHostListApi.prototype.remove = function(hostId) {
113   return this.gcd_.deleteDevice(hostId).then(function(deleted) {
114     if (!deleted) {
115       console.error('error deleting host from GCD');
116       throw remoting.Error.unexpected();
117     }
118     // Don't return anything.
119   });
122 /** @override */
123 remoting.GcdHostListApi.prototype.getSupportHost = function(supportId) {
124   console.error('getSupportHost not supported by HostListApiGclImpl');
125   return Promise.reject(remoting.Error.unexpected());
129  * Tag for distinguishing Chromoting hosts from other devices stored
130  * in GCD.
132  * @const
133  */
134 var CHROMOTING_DEVICE_TAG = '1ce4542c-dd87-4320-ba19-ac173f98c04e';
137  * Check whether a GCD device entry is a Chromoting host.
139  * @param {remoting.gcd.Device} device
140  * @return {boolean}
141  */
142 function isChromotingHost(device) {
143   return device.tags != null &&
144       device.tags.indexOf(CHROMOTING_DEVICE_TAG) != -1;
148  * Converts a GCD device description to a Host object.
150  * @param {!Object} device
151  * @return {!remoting.Host}
152  */
153 function deviceToHost(device) {
154   var statusMap = {
155     'online': 'ONLINE',
156     'offline': 'OFFLINE'
157   };
158   var hostId = base.getStringAttr(device, 'id');
159   var host = new remoting.Host(hostId);
160   host.hostName = base.getStringAttr(device, 'name');
161   host.status = base.getStringAttr(
162       statusMap, base.getStringAttr(device, 'connectionStatus'));
163   var state = base.getObjectAttr(device, 'state', {});
164   var baseState = base.getObjectAttr(state, 'base', {});
165   host.publicKey = base.getStringAttr(baseState, '_publicKey');
166   host.jabberId = base.getStringAttr(baseState, '_jabberId', '');
167   host.hostVersion = base.getStringAttr(baseState, '_hostVersion', '');
168   var creationTimeMs = base.getNumberAttr(device, 'creationTimeMs', 0);
169   if (creationTimeMs) {
170     host.createdTime = new Date(creationTimeMs).toISOString();
171   }
172   var lastUpdateTimeMs = base.getNumberAttr(device, 'lastUpdateTimeMs', 0);
173   if (lastUpdateTimeMs) {
174     host.updatedTime = new Date(lastUpdateTimeMs).toISOString();
175   }
176   return host;
179 })();