Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / remoting / webapp / crd / js / gcd_client.js
blob5bfab9fdef3ecc98a1fd2d9072bd05cd85a925d4
1 // Copyright 2015 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 * Client for the GCD REST API.
8 * TODO: Add link to GCD docs.
9 */
11 /** @suppress {duplicate} */
12 var remoting = remoting || {};
14 /**
15 * Namespace for GCD definitions
16 * @type {Object}
18 remoting.gcd = remoting.gcd || {};
20 /**
21 * @typedef {{
22 * id: string,
23 * robotAccountEmail: string,
24 * robotAccountAuthorizationCode: string,
25 * deviceId: string,
26 * deviceDraft: Object
27 * }}
29 remoting.gcd.RegistrationTicket;
31 /**
32 * TODO: Flesh out with typical fields.
33 * @typedef {{
34 * id:string,
35 * name:string,
36 * state:(!Object|undefined),
37 * tags:(!Array<string>|undefined)
38 * }}
40 remoting.gcd.Device;
42 /**
43 * @typedef {!Object}
45 remoting.gcd.DevicePatch;
47 /**
48 * @typedef {{
49 * devices: (Array<remoting.gcd.Device>|undefined)
50 * }}
52 remoting.gcd.DeviceListResponse;
54 (function() {
55 'use strict';
57 /**
58 * Interprets an HTTP response as a JSON object with a specific value
59 * in the 'kind' field.
60 * @param {remoting.Xhr.Response} response
61 * @param {string} expectedKind
62 * @return {!Object}
63 * @throws {remoting.Error}
65 var responseAsObject = function(response, expectedKind) {
66 if (typeof response.getJson() != 'object') {
67 console.error(
68 'invalid response; expected object, got:', response.getJson());
69 throw remoting.Error.unexpected();
71 var obj = base.assertObject(response.getJson());
72 var kind = base.getStringAttr(obj, 'kind');
73 if (kind != expectedKind) {
74 console.error(
75 'invalid resonse kind; expected ' + expectedKind + ', got ' + kind);
76 throw remoting.Error.unexpected();
78 return obj;
81 /**
82 * Interprets an HTTP response as containing a GCD registration ticket.
83 * @param {remoting.Xhr.Response} response
84 * @return {!remoting.gcd.RegistrationTicket}
85 * @throws {remoting.Error}
87 var responseAsGcdRegistrationTicket = function(response) {
88 return /** @type {!remoting.gcd.RegistrationTicket} */ (
89 responseAsObject(
90 response, 'clouddevices#registrationTicket'));
93 /**
94 * Interprets an HTTP response as containing a GCD device defintion.
95 * @param {remoting.Xhr.Response} response
96 * @return {!remoting.gcd.Device}
97 * @throws {remoting.Error}
99 var responseAsGcdDevice = function(response) {
100 return /** @type {!remoting.gcd.Device} */ (
101 responseAsObject(response, 'clouddevices#device'));
105 * Interprets an HTTP response as containing a GCD device list.
106 * @param {remoting.Xhr.Response} response
107 * @return {!remoting.gcd.DeviceListResponse}
108 * @throws {remoting.Error}
110 var responseAsGcdDeviceListResponse = function(response) {
111 return /** @type {!remoting.gcd.DeviceListResponse} */ (
112 responseAsObject(response, 'clouddevices#devicesListResponse'));
116 * Creates a new client using a specific API key, and optionall a
117 * specific base URL, and OAuth2 client ID.
118 * @param {{
119 * apiKey: string,
120 * apiBaseUrl: (string|undefined)
121 * }} options
122 * @constructor
124 remoting.gcd.Client = function(options) {
125 /** @const */
126 this.apiKey_ = options.apiKey;
127 /** @const */
128 this.apiBaseUrl_ = options.apiBaseUrl ||
129 'https://www.googleapis.com/clouddevices/v1';
133 * Creates a new registration ticket.
134 * TODO: Add link to GCD docs.
135 * @return {!Promise<remoting.gcd.RegistrationTicket>}
137 remoting.gcd.Client.prototype.insertRegistrationTicket = function() {
138 return new remoting.Xhr({
139 method: 'POST',
140 url: this.apiBaseUrl_ + '/registrationTickets',
141 jsonContent: { 'userEmail': 'me' },
142 useIdentity: true,
143 acceptJson: true
144 }).start().then(function(/** remoting.Xhr.Response */ response) {
145 if (response.isError()) {
146 console.error('error creating registration ticket');
147 throw remoting.Error.unexpected();
149 return responseAsGcdRegistrationTicket(response);
154 * Updates an existing registration ticket using patch semantics.
155 * TODO: Add link to GCD docs.
156 * @param {string} ticketId
157 * @param {!Object<*>} deviceDraft
158 * @param {string} oauthClientId
159 * @return {!Promise<remoting.gcd.RegistrationTicket>}
161 remoting.gcd.Client.prototype.patchRegistrationTicket = function(
162 ticketId, deviceDraft, oauthClientId) {
163 return new remoting.Xhr({
164 method: 'PATCH',
165 url: this.apiBaseUrl_ + '/registrationTickets/' +
166 encodeURIComponent(ticketId),
167 urlParams: {
168 'key': this.apiKey_
170 jsonContent: {
171 'deviceDraft': deviceDraft,
172 'oauthClientId': oauthClientId
174 acceptJson: true
175 }).start().then(function(response) {
176 if (response.isError()) {
177 console.error('error patching registration ticket');
178 throw remoting.Error.unexpected();
180 return responseAsGcdRegistrationTicket(response);
185 * Finalizes device registration and returns its credentials.
186 * TODO: Add link to GCD docs.
187 * @param {string} ticketId
188 * @return {!Promise<remoting.gcd.RegistrationTicket>}
190 remoting.gcd.Client.prototype.finalizeRegistrationTicket = function(ticketId) {
191 return new remoting.Xhr({
192 method: 'POST',
193 url: this.apiBaseUrl_ + '/registrationTickets/' +
194 encodeURIComponent(ticketId) + '/finalize',
195 urlParams: {
196 'key': this.apiKey_
198 acceptJson: true
199 }).start().then(function(response) {
200 if (response.isError()) {
201 console.error('error finalizing registration ticket');
202 throw remoting.Error.unexpected();
204 return responseAsGcdRegistrationTicket(response);
209 * Lists devices user has access to.
210 * TODO: Add link to GCD docs.
211 * @return {!Promise<!Array<remoting.gcd.Device>>}
213 remoting.gcd.Client.prototype.listDevices = function() {
214 return new remoting.Xhr({
215 method: 'GET',
216 url: this.apiBaseUrl_ + '/devices',
217 useIdentity: true,
218 acceptJson: true
219 }).start().then(function(response) {
220 if (response.isError()) {
221 console.error('error getting device list');
222 throw remoting.Error.unexpected();
224 var hosts = responseAsGcdDeviceListResponse(response);
225 return hosts.devices || [];
230 * Deletes a device from the system.
231 * TODO: Add link to GCD docs.
232 * @param {string} deviceId
233 * @return {!Promise<boolean>} Promise that resolves to true if the
234 * device was deleted, false if there was no such device ID.
236 remoting.gcd.Client.prototype.deleteDevice = function(deviceId) {
237 return new remoting.Xhr({
238 method: 'DELETE',
239 url: this.apiBaseUrl_ + '/devices/' + deviceId,
240 useIdentity: true
241 }).start().then(function(response) {
242 if (response.status == 404) {
243 return false;
245 if (response.isError()) {
246 console.error('error deleting device');
247 throw remoting.Error.unexpected();
249 return true;
254 * Updates a device data using patch semantics.
255 * TODO: Add link to GCD docs.
256 * @param {string} deviceId
257 * @param {!Object<*>} patch
258 * @return {!Promise<remoting.gcd.Device>}
260 remoting.gcd.Client.prototype.patchDevice = function(deviceId, patch) {
261 return new remoting.Xhr({
262 method: 'PATCH',
263 url: this.apiBaseUrl_ + '/devices/' + deviceId,
264 jsonContent: patch,
265 useIdentity: true,
266 acceptJson: true
267 }).start().then(function(response) {
268 if (response.isError()) {
269 console.error('error patching device');
270 throw remoting.Error.unexpected();
272 return responseAsGcdDevice(response);
276 })();