OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview | 6 * @fileoverview |
7 * Class to communicate with the host daemon via Native Messaging. | 7 * Class to communicate with the host daemon via Native Messaging. |
8 */ | 8 */ |
9 | 9 |
10 'use strict'; | 10 'use strict'; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 }; | 77 }; |
78 | 78 |
79 /** | 79 /** |
80 * Connects to the native messaging host and sends a hello message. | 80 * Connects to the native messaging host and sends a hello message. |
81 * | 81 * |
82 * @return {Promise} A promise that fulfills when the connection attempt | 82 * @return {Promise} A promise that fulfills when the connection attempt |
83 * succeeds or fails. | 83 * succeeds or fails. |
84 * @private | 84 * @private |
85 */ | 85 */ |
86 remoting.HostDaemonFacade.prototype.connectNative_ = function() { | 86 remoting.HostDaemonFacade.prototype.connectNative_ = function() { |
| 87 var that = this; |
87 try { | 88 try { |
88 this.port_ = chrome.runtime.connectNative( | 89 this.port_ = chrome.runtime.connectNative( |
89 'com.google.chrome.remote_desktop'); | 90 'com.google.chrome.remote_desktop'); |
90 this.port_.onMessage.addListener(this.onIncomingMessageCallback_); | 91 this.port_.onMessage.addListener(this.onIncomingMessageCallback_); |
91 this.port_.onDisconnect.addListener(this.onDisconnectCallback_); | 92 this.port_.onDisconnect.addListener(this.onDisconnectCallback_); |
92 return this.postMessageInternal_({type: 'hello'}); | 93 return this.postMessageInternal_({type: 'hello'}).then(function(reply) { |
| 94 that.version_ = base.getStringAttr(reply, 'version'); |
| 95 // Old versions of the native messaging host do not return this list. |
| 96 // Those versions default to the empty list of supported features. |
| 97 that.supportedFeatures_ = |
| 98 base.getArrayAttr(reply, 'supportedFeatures', []); |
| 99 }); |
93 } catch (/** @type {*} */ err) { | 100 } catch (/** @type {*} */ err) { |
94 console.log('Native Messaging initialization failed: ', err); | 101 console.log('Native Messaging initialization failed: ', err); |
95 throw remoting.Error.unexpected(); | 102 throw remoting.Error.unexpected(); |
96 } | 103 } |
97 }; | 104 }; |
98 | 105 |
99 /** | 106 /** |
100 * Type used for entries of |pendingReplies_| list. | 107 * Type used for entries of |pendingReplies_| list. |
101 * | 108 * |
102 * @param {string} type Type of the originating request. | 109 * @param {string} type Type of the originating request. |
(...skipping 21 matching lines...) Expand all Loading... |
124 return that.supportedFeatures_.indexOf(feature) >= 0; | 131 return that.supportedFeatures_.indexOf(feature) >= 0; |
125 }, function () { | 132 }, function () { |
126 return false; | 133 return false; |
127 }); | 134 }); |
128 }; | 135 }; |
129 | 136 |
130 /** | 137 /** |
131 * Initializes that the Daemon if necessary and posts the supplied message. | 138 * Initializes that the Daemon if necessary and posts the supplied message. |
132 * | 139 * |
133 * @param {{type: string}} message The message to post. | 140 * @param {{type: string}} message The message to post. |
134 * @return {!Promise} | 141 * @return {!Promise<!Object>} |
135 * @private | 142 * @private |
136 */ | 143 */ |
137 remoting.HostDaemonFacade.prototype.postMessage_ = | 144 remoting.HostDaemonFacade.prototype.postMessage_ = |
138 function(message) { | 145 function(message) { |
139 /** @type {remoting.HostDaemonFacade} */ | 146 /** @type {remoting.HostDaemonFacade} */ |
140 var that = this; | 147 var that = this; |
141 return this.initialize_().then(function() { | 148 return this.initialize_().then(function() { |
142 return that.postMessageInternal_(message); | 149 return that.postMessageInternal_(message); |
143 }, function() { | 150 }, function() { |
144 throw that.error_; | 151 throw that.error_; |
145 }); | 152 }); |
146 }; | 153 }; |
147 | 154 |
148 /** | 155 /** |
149 * Attaches a new ID to the supplied message, and posts it to the | 156 * Attaches a new ID to the supplied message, and posts it to the |
150 * Native Messaging port, adding a Deferred object to the list of | 157 * Native Messaging port, adding a Deferred object to the list of |
151 * pending replies. |message| should have its 'type' field set, and | 158 * pending replies. |message| should have its 'type' field set, and |
152 * any other fields set depending on the message type. | 159 * any other fields set depending on the message type. |
153 * | 160 * |
154 * @param {{type: string}} message The message to post. | 161 * @param {{type: string}} message The message to post. |
155 * @return {!Promise} | 162 * @return {!Promise<!Object>} |
156 * @private | 163 * @private |
157 */ | 164 */ |
158 remoting.HostDaemonFacade.prototype.postMessageInternal_ = function(message) { | 165 remoting.HostDaemonFacade.prototype.postMessageInternal_ = function(message) { |
159 var id = this.nextId_++; | 166 var id = this.nextId_++; |
160 message['id'] = id; | 167 message['id'] = id; |
161 var deferred = new base.Deferred(); | 168 var deferred = new base.Deferred(); |
162 this.pendingReplies_[id] = new remoting.HostDaemonFacade.PendingReply( | 169 this.pendingReplies_[id] = new remoting.HostDaemonFacade.PendingReply( |
163 message.type + 'Response', deferred); | 170 message.type + 'Response', deferred); |
164 this.port_.postMessage(message); | 171 this.port_.postMessage(message); |
165 return deferred.promise(); | 172 return deferred.promise(); |
(...skipping 18 matching lines...) Expand all Loading... |
184 console.error('NativeMessaging: unexpected id: ', id); | 191 console.error('NativeMessaging: unexpected id: ', id); |
185 return; | 192 return; |
186 } | 193 } |
187 delete this.pendingReplies_[id]; | 194 delete this.pendingReplies_[id]; |
188 | 195 |
189 try { | 196 try { |
190 var type = base.getStringAttr(message, 'type'); | 197 var type = base.getStringAttr(message, 'type'); |
191 if (type != reply.type) { | 198 if (type != reply.type) { |
192 throw 'Expected reply type: ' + reply.type + ', got: ' + type; | 199 throw 'Expected reply type: ' + reply.type + ', got: ' + type; |
193 } | 200 } |
194 | 201 reply.deferred.resolve(message); |
195 reply.deferred.resolve(this.handleIncomingMessage_(message)); | |
196 } catch (/** @type {*} */ e) { | 202 } catch (/** @type {*} */ e) { |
197 console.error('Error while processing native message', e); | 203 console.error('Error while processing native message', e); |
198 reply.deferred.reject(remoting.Error.unexpected()); | 204 reply.deferred.reject(remoting.Error.unexpected()); |
199 } | 205 } |
200 }; | 206 }; |
201 | 207 |
202 /** | 208 /** |
203 * Handler for incoming Native Messages. | |
204 * | |
205 * TODO(jrw) Consider refactoring so each method handles its own | |
206 * response, e.g.: | |
207 * | |
208 * remoting.HostDaemonFacade.prototype.generateKeyPair = function() { | |
209 * this.postMessage_({type: 'generateKeyPair'}).then(function(message) { | |
210 * return { | |
211 * privateKey: base.getStringAttr(message, 'privateKey'), | |
212 * publicKey: base.getStringAttr(message, 'publicKey') | |
213 * } | |
214 * }); | |
215 * }; | |
216 * | |
217 * @param {Object} message The received message. | |
218 * @return {*} | |
219 * @private | |
220 */ | |
221 remoting.HostDaemonFacade.prototype.handleIncomingMessage_ = | |
222 function(message) { | |
223 var type = base.getStringAttr(message, 'type'); | |
224 | |
225 switch (type) { | |
226 case 'helloResponse': | |
227 this.version_ = base.getStringAttr(message, 'version'); | |
228 // Old versions of the native messaging host do not return this list. | |
229 // Those versions default to the empty list of supported features. | |
230 this.supportedFeatures_ = | |
231 base.getArrayAttr(message, 'supportedFeatures', []); | |
232 return null; | |
233 | |
234 case 'getHostNameResponse': | |
235 return base.getStringAttr(message, 'hostname'); | |
236 | |
237 case 'getPinHashResponse': | |
238 return base.getStringAttr(message, 'hash'); | |
239 | |
240 case 'generateKeyPairResponse': | |
241 return { | |
242 privateKey: base.getStringAttr(message, 'privateKey'), | |
243 publicKey: base.getStringAttr(message, 'publicKey') | |
244 }; | |
245 | |
246 case 'updateDaemonConfigResponse': | |
247 return remoting.HostController.AsyncResult.fromString( | |
248 base.getStringAttr(message, 'result')); | |
249 | |
250 case 'getDaemonConfigResponse': | |
251 return base.getObjectAttr(message, 'config'); | |
252 | |
253 case 'getUsageStatsConsentResponse': | |
254 return { | |
255 supported: base.getBooleanAttr(message, 'supported'), | |
256 allowed: base.getBooleanAttr(message, 'allowed'), | |
257 setByPolicy: base.getBooleanAttr(message, 'setByPolicy') | |
258 }; | |
259 | |
260 case 'startDaemonResponse': | |
261 case 'stopDaemonResponse': | |
262 return remoting.HostController.AsyncResult.fromString( | |
263 base.getStringAttr(message, 'result')); | |
264 | |
265 case 'getDaemonStateResponse': | |
266 return remoting.HostController.State.fromString( | |
267 base.getStringAttr(message, 'state')); | |
268 | |
269 case 'getPairedClientsResponse': | |
270 var pairedClients = remoting.PairedClient.convertToPairedClientArray( | |
271 message['pairedClients']); | |
272 if (pairedClients != null) { | |
273 return pairedClients; | |
274 } else { | |
275 throw 'No paired clients!'; | |
276 } | |
277 | |
278 case 'clearPairedClientsResponse': | |
279 case 'deletePairedClientResponse': | |
280 return base.getBooleanAttr(message, 'result'); | |
281 | |
282 case 'getHostClientIdResponse': | |
283 return base.getStringAttr(message, 'clientId'); | |
284 | |
285 case 'getCredentialsFromAuthCodeResponse': | |
286 var userEmail = base.getStringAttr(message, 'userEmail'); | |
287 var refreshToken = base.getStringAttr(message, 'refreshToken'); | |
288 if (userEmail && refreshToken) { | |
289 return { | |
290 userEmail: userEmail, | |
291 refreshToken: refreshToken | |
292 }; | |
293 } else { | |
294 throw 'Missing userEmail or refreshToken'; | |
295 } | |
296 | |
297 case 'getRefreshTokenFromAuthCodeResponse': | |
298 var refreshToken = base.getStringAttr(message, 'refreshToken'); | |
299 if (refreshToken) { | |
300 return refreshToken; | |
301 } else { | |
302 throw 'Missing refreshToken'; | |
303 } | |
304 | |
305 default: | |
306 throw 'Unexpected native message: ' + message; | |
307 } | |
308 }; | |
309 | |
310 /** | |
311 * @return {void} Nothing. | 209 * @return {void} Nothing. |
312 * @private | 210 * @private |
313 */ | 211 */ |
314 remoting.HostDaemonFacade.prototype.onDisconnect_ = function() { | 212 remoting.HostDaemonFacade.prototype.onDisconnect_ = function() { |
315 console.error('Native Message port disconnected'); | 213 console.error('Native Message port disconnected'); |
316 | 214 |
317 this.port_.onDisconnect.removeListener(this.onDisconnectCallback_); | 215 this.port_.onDisconnect.removeListener(this.onDisconnectCallback_); |
318 this.port_.onMessage.removeListener(this.onIncomingMessageCallback_); | 216 this.port_.onMessage.removeListener(this.onIncomingMessageCallback_); |
319 this.port_ = null; | 217 this.port_ = null; |
320 | 218 |
(...skipping 11 matching lines...) Expand all Loading... |
332 pendingReplies[num_id].deferred.reject(this.error_); | 230 pendingReplies[num_id].deferred.reject(this.error_); |
333 } | 231 } |
334 } | 232 } |
335 | 233 |
336 /** | 234 /** |
337 * Gets local hostname. | 235 * Gets local hostname. |
338 * | 236 * |
339 * @return {!Promise<string>} | 237 * @return {!Promise<string>} |
340 */ | 238 */ |
341 remoting.HostDaemonFacade.prototype.getHostName = function() { | 239 remoting.HostDaemonFacade.prototype.getHostName = function() { |
342 return this.postMessage_({type: 'getHostName'}); | 240 return this.postMessage_({type: 'getHostName'}).then(function(reply) { |
| 241 return base.getStringAttr(reply, 'hostname'); |
| 242 }); |
343 }; | 243 }; |
344 | 244 |
345 /** | 245 /** |
346 * Calculates PIN hash value to be stored in the config, passing the resulting | 246 * Calculates PIN hash value to be stored in the config, passing the resulting |
347 * hash value base64-encoded to the callback. | 247 * hash value base64-encoded to the callback. |
348 * | 248 * |
349 * @param {string} hostId The host ID. | 249 * @param {string} hostId The host ID. |
350 * @param {string} pin The PIN. | 250 * @param {string} pin The PIN. |
351 * @return {!Promise<string>} | 251 * @return {!Promise<string>} |
352 */ | 252 */ |
353 remoting.HostDaemonFacade.prototype.getPinHash = function(hostId, pin) { | 253 remoting.HostDaemonFacade.prototype.getPinHash = function(hostId, pin) { |
354 return this.postMessage_({ | 254 return this.postMessage_({ |
355 type: 'getPinHash', | 255 type: 'getPinHash', |
356 hostId: hostId, | 256 hostId: hostId, |
357 pin: pin | 257 pin: pin |
| 258 }).then(function(reply) { |
| 259 return base.getStringAttr(reply, 'hash'); |
358 }); | 260 }); |
359 }; | 261 }; |
360 | 262 |
361 /** | 263 /** |
362 * Generates new key pair to use for the host. The specified callback is called | 264 * Generates new key pair to use for the host. The specified callback is called |
363 * when the key is generated. The key is returned in format understood by the | 265 * when the key is generated. The key is returned in format understood by the |
364 * host (PublicKeyInfo structure encoded with ASN.1 DER, and then BASE64). | 266 * host (PublicKeyInfo structure encoded with ASN.1 DER, and then BASE64). |
365 * | 267 * |
366 * @return {!Promise<remoting.KeyPair>} | 268 * @return {!Promise<remoting.KeyPair>} |
367 */ | 269 */ |
368 remoting.HostDaemonFacade.prototype.generateKeyPair = function() { | 270 remoting.HostDaemonFacade.prototype.generateKeyPair = function() { |
369 return this.postMessage_({type: 'generateKeyPair'}); | 271 return this.postMessage_({type: 'generateKeyPair'}).then(function(reply) { |
| 272 return { |
| 273 privateKey: base.getStringAttr(reply, 'privateKey'), |
| 274 publicKey: base.getStringAttr(reply, 'publicKey') |
| 275 }; |
| 276 }); |
370 }; | 277 }; |
371 | 278 |
372 /** | 279 /** |
373 * Updates host config with the values specified in |config|. All | 280 * Updates host config with the values specified in |config|. All |
374 * fields that are not specified in |config| remain | 281 * fields that are not specified in |config| remain |
375 * unchanged. Following parameters cannot be changed using this | 282 * unchanged. Following parameters cannot be changed using this |
376 * function: host_id, xmpp_login. Error is returned if |config| | 283 * function: host_id, xmpp_login. Error is returned if |config| |
377 * includes these parameters. Changes take effect before the callback | 284 * includes these parameters. Changes take effect before the callback |
378 * is called. | 285 * is called. |
379 * | 286 * |
380 * TODO(jrw): Consider conversion exceptions to AsyncResult values. | 287 * TODO(jrw): Consider conversion exceptions to AsyncResult values. |
381 * | 288 * |
382 * @param {Object} config The new config parameters. | 289 * @param {Object} config The new config parameters. |
383 * @return {!Promise<remoting.HostController.AsyncResult>} | 290 * @return {!Promise<remoting.HostController.AsyncResult>} |
384 */ | 291 */ |
385 remoting.HostDaemonFacade.prototype.updateDaemonConfig = function(config) { | 292 remoting.HostDaemonFacade.prototype.updateDaemonConfig = function(config) { |
386 return this.postMessage_({ | 293 return this.postMessage_({ |
387 type: 'updateDaemonConfig', | 294 type: 'updateDaemonConfig', |
388 config: config | 295 config: config |
| 296 }).then(function(reply) { |
| 297 return remoting.HostController.AsyncResult.fromString( |
| 298 base.getStringAttr(reply, 'result')); |
389 }); | 299 }); |
390 }; | 300 }; |
391 | 301 |
392 /** | 302 /** |
393 * Loads daemon config. The config is passed as a JSON formatted string to the | 303 * Loads daemon config. The config is passed as a JSON formatted string to the |
394 * callback. | 304 * callback. |
395 * @return {!Promise<Object>} | 305 * @return {!Promise<Object>} |
396 */ | 306 */ |
397 remoting.HostDaemonFacade.prototype.getDaemonConfig = function() { | 307 remoting.HostDaemonFacade.prototype.getDaemonConfig = function() { |
398 return this.postMessage_({type: 'getDaemonConfig'}); | 308 return this.postMessage_({type: 'getDaemonConfig'}).then(function(reply) { |
| 309 return base.getObjectAttr(reply, 'config'); |
| 310 }); |
399 }; | 311 }; |
400 | 312 |
401 /** | 313 /** |
402 * Retrieves daemon version. The version is returned as a dotted decimal | 314 * Retrieves daemon version. The version is returned as a dotted decimal |
403 * string of the form major.minor.build.patch. | 315 * string of the form major.minor.build.patch. |
404 * | 316 * |
405 * @return {!Promise<string>} | 317 * @return {!Promise<string>} |
406 */ | 318 */ |
407 remoting.HostDaemonFacade.prototype.getDaemonVersion = function() { | 319 remoting.HostDaemonFacade.prototype.getDaemonVersion = function() { |
408 /** @type {remoting.HostDaemonFacade} */ | 320 /** @type {remoting.HostDaemonFacade} */ |
409 var that = this; | 321 var that = this; |
410 return this.initialize_().then(function() { | 322 return this.initialize_().then(function() { |
411 return that.version_; | 323 return that.version_; |
412 }, function() { | 324 }, function() { |
413 throw that.error_; | 325 throw that.error_; |
414 }); | 326 }); |
415 }; | 327 }; |
416 | 328 |
417 /** | 329 /** |
418 * Get the user's consent to crash reporting. The consent flags are passed to | 330 * Get the user's consent to crash reporting. The consent flags are passed to |
419 * the callback as booleans: supported, allowed, set-by-policy. | 331 * the callback as booleans: supported, allowed, set-by-policy. |
420 * | 332 * |
421 * @return {!Promise<remoting.UsageStatsConsent>} | 333 * @return {!Promise<remoting.UsageStatsConsent>} |
422 */ | 334 */ |
423 remoting.HostDaemonFacade.prototype.getUsageStatsConsent = function() { | 335 remoting.HostDaemonFacade.prototype.getUsageStatsConsent = function() { |
424 return this.postMessage_({type: 'getUsageStatsConsent'}); | 336 return this.postMessage_({type: 'getUsageStatsConsent'}). |
| 337 then(function(reply) { |
| 338 return { |
| 339 supported: base.getBooleanAttr(reply, 'supported'), |
| 340 allowed: base.getBooleanAttr(reply, 'allowed'), |
| 341 setByPolicy: base.getBooleanAttr(reply, 'setByPolicy') |
| 342 }; |
| 343 }); |
425 }; | 344 }; |
426 | 345 |
427 /** | 346 /** |
428 * Starts the daemon process with the specified configuration. | 347 * Starts the daemon process with the specified configuration. |
429 * | 348 * |
430 * TODO(jrw): Consider conversion exceptions to AsyncResult values. | 349 * TODO(jrw): Consider conversion exceptions to AsyncResult values. |
431 * | 350 * |
432 * @param {Object} config Host configuration. | 351 * @param {Object} config Host configuration. |
433 * @param {boolean} consent Consent to report crash dumps. | 352 * @param {boolean} consent Consent to report crash dumps. |
434 * @return {!Promise<remoting.HostController.AsyncResult>} | 353 * @return {!Promise<remoting.HostController.AsyncResult>} |
435 */ | 354 */ |
436 remoting.HostDaemonFacade.prototype.startDaemon = function(config, consent) { | 355 remoting.HostDaemonFacade.prototype.startDaemon = function(config, consent) { |
437 return this.postMessage_({ | 356 return this.postMessage_({ |
438 type: 'startDaemon', | 357 type: 'startDaemon', |
439 config: config, | 358 config: config, |
440 consent: consent | 359 consent: consent |
| 360 }).then(function(reply) { |
| 361 return remoting.HostController.AsyncResult.fromString( |
| 362 base.getStringAttr(reply, 'result')); |
441 }); | 363 }); |
442 }; | 364 }; |
443 | 365 |
444 /** | 366 /** |
445 * Stops the daemon process. | 367 * Stops the daemon process. |
446 * | 368 * |
447 * TODO(jrw): Consider conversion exceptions to AsyncResult values. | 369 * TODO(jrw): Consider conversion exceptions to AsyncResult values. |
448 * | 370 * |
449 * @return {!Promise<remoting.HostController.AsyncResult>} | 371 * @return {!Promise<remoting.HostController.AsyncResult>} |
450 */ | 372 */ |
451 remoting.HostDaemonFacade.prototype.stopDaemon = | 373 remoting.HostDaemonFacade.prototype.stopDaemon = |
452 function() { | 374 function() { |
453 return this.postMessage_({type: 'stopDaemon'}); | 375 return this.postMessage_({type: 'stopDaemon'}).then(function(reply) { |
| 376 return remoting.HostController.AsyncResult.fromString( |
| 377 base.getStringAttr(reply, 'result')); |
| 378 }); |
454 }; | 379 }; |
455 | 380 |
456 /** | 381 /** |
457 * Gets the installed/running state of the Host process. | 382 * Gets the installed/running state of the Host process. |
458 * | 383 * |
459 * @return {!Promise<remoting.HostController.State>} | 384 * @return {!Promise<remoting.HostController.State>} |
460 */ | 385 */ |
461 remoting.HostDaemonFacade.prototype.getDaemonState = function() { | 386 remoting.HostDaemonFacade.prototype.getDaemonState = function() { |
462 return this.postMessage_({type: 'getDaemonState'}); | 387 return this.postMessage_({type: 'getDaemonState'}).then(function(reply) { |
| 388 return remoting.HostController.State.fromString( |
| 389 base.getStringAttr(reply, 'state')); |
| 390 }); |
463 }; | 391 }; |
464 | 392 |
465 /** | 393 /** |
466 * Retrieves the list of paired clients. | 394 * Retrieves the list of paired clients. |
467 * | 395 * |
468 * @return {!Promise<Array<remoting.PairedClient>>} | 396 * @return {!Promise<Array<remoting.PairedClient>>} |
469 */ | 397 */ |
470 remoting.HostDaemonFacade.prototype.getPairedClients = function() { | 398 remoting.HostDaemonFacade.prototype.getPairedClients = function() { |
471 return this.postMessage_({type: 'getPairedClients'}); | 399 return this.postMessage_({type: 'getPairedClients'}).then(function(reply) { |
| 400 var pairedClients =remoting.PairedClient.convertToPairedClientArray( |
| 401 reply['pairedClients']); |
| 402 if (pairedClients != null) { |
| 403 return pairedClients; |
| 404 } else { |
| 405 throw remoting.Error.unexpected('No paired clients!'); |
| 406 } |
| 407 }); |
472 }; | 408 }; |
473 | 409 |
474 /** | 410 /** |
475 * Clears all paired clients from the registry. | 411 * Clears all paired clients from the registry. |
476 * | 412 * |
477 * @return {!Promise<boolean>} | 413 * @return {!Promise<boolean>} |
478 */ | 414 */ |
479 remoting.HostDaemonFacade.prototype.clearPairedClients = function() { | 415 remoting.HostDaemonFacade.prototype.clearPairedClients = function() { |
480 return this.postMessage_({type: 'clearPairedClients'}); | 416 return this.postMessage_({type: 'clearPairedClients'}).then(function(reply) { |
| 417 return base.getBooleanAttr(reply, 'result'); |
| 418 }); |
481 }; | 419 }; |
482 | 420 |
483 /** | 421 /** |
484 * Deletes a paired client referenced by client id. | 422 * Deletes a paired client referenced by client id. |
485 * | 423 * |
486 * @param {string} client Client to delete. | 424 * @param {string} client Client to delete. |
487 * @return {!Promise<boolean>} | 425 * @return {!Promise<boolean>} |
488 */ | 426 */ |
489 remoting.HostDaemonFacade.prototype.deletePairedClient = function(client) { | 427 remoting.HostDaemonFacade.prototype.deletePairedClient = function(client) { |
490 return this.postMessage_({ | 428 return this.postMessage_({ |
491 type: 'deletePairedClient', | 429 type: 'deletePairedClient', |
492 clientId: client | 430 clientId: client |
| 431 }).then(function(reply) { |
| 432 return base.getBooleanAttr(reply, 'result'); |
493 }); | 433 }); |
494 }; | 434 }; |
495 | 435 |
496 /** | 436 /** |
497 * Gets the API keys to obtain/use service account credentials. | 437 * Gets the API keys to obtain/use service account credentials. |
498 * | 438 * |
499 * @return {!Promise<string>} | 439 * @return {!Promise<string>} |
500 */ | 440 */ |
501 remoting.HostDaemonFacade.prototype.getHostClientId = function() { | 441 remoting.HostDaemonFacade.prototype.getHostClientId = function() { |
502 return this.postMessage_({type: 'getHostClientId'}); | 442 return this.postMessage_({type: 'getHostClientId'}).then(function(reply) { |
| 443 return base.getStringAttr(reply, 'clientId'); |
| 444 }); |
503 }; | 445 }; |
504 | 446 |
505 /** | 447 /** |
506 * @param {string} authorizationCode OAuth authorization code. | 448 * @param {string} authorizationCode OAuth authorization code. |
507 * @return {!Promise<{remoting.XmppCredentials}>} | 449 * @return {!Promise<{remoting.XmppCredentials}>} |
508 */ | 450 */ |
509 remoting.HostDaemonFacade.prototype.getCredentialsFromAuthCode = | 451 remoting.HostDaemonFacade.prototype.getCredentialsFromAuthCode = |
510 function(authorizationCode) { | 452 function(authorizationCode) { |
511 return this.postMessage_({ | 453 return this.postMessage_({ |
512 type: 'getCredentialsFromAuthCode', | 454 type: 'getCredentialsFromAuthCode', |
513 authorizationCode: authorizationCode | 455 authorizationCode: authorizationCode |
| 456 }).then(function(reply) { |
| 457 var userEmail = base.getStringAttr(reply, 'userEmail'); |
| 458 var refreshToken = base.getStringAttr(reply, 'refreshToken'); |
| 459 if (userEmail && refreshToken) { |
| 460 return { |
| 461 userEmail: userEmail, |
| 462 refreshToken: refreshToken |
| 463 }; |
| 464 } else { |
| 465 throw remoting.Error.unexpected('Missing userEmail or refreshToken'); |
| 466 } |
514 }); | 467 }); |
515 }; | 468 }; |
516 | 469 |
517 /** | 470 /** |
518 * @param {string} authorizationCode OAuth authorization code. | 471 * @param {string} authorizationCode OAuth authorization code. |
519 * @return {!Promise<string>} | 472 * @return {!Promise<string>} |
520 */ | 473 */ |
521 remoting.HostDaemonFacade.prototype.getRefreshTokenFromAuthCode = | 474 remoting.HostDaemonFacade.prototype.getRefreshTokenFromAuthCode = |
522 function(authorizationCode) { | 475 function(authorizationCode) { |
523 return this.postMessage_({ | 476 return this.postMessage_({ |
524 type: 'getRefreshTokenFromAuthCode', | 477 type: 'getRefreshTokenFromAuthCode', |
525 authorizationCode: authorizationCode | 478 authorizationCode: authorizationCode |
| 479 }).then(function(reply) { |
| 480 var refreshToken = base.getStringAttr(reply, 'refreshToken'); |
| 481 if (refreshToken) { |
| 482 return refreshToken |
| 483 } else { |
| 484 throw remoting.Error.unexpected('Missing refreshToken'); |
| 485 } |
526 }); | 486 }); |
527 }; | 487 }; |
OLD | NEW |