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 default: | |
298 throw 'Unexpected native message: ' + message; | |
299 } | |
300 }; | |
301 | |
302 /** | |
303 * @return {void} Nothing. | 209 * @return {void} Nothing. |
304 * @private | 210 * @private |
305 */ | 211 */ |
306 remoting.HostDaemonFacade.prototype.onDisconnect_ = function() { | 212 remoting.HostDaemonFacade.prototype.onDisconnect_ = function() { |
307 console.error('Native Message port disconnected'); | 213 console.error('Native Message port disconnected'); |
308 | 214 |
309 this.port_.onDisconnect.removeListener(this.onDisconnectCallback_); | 215 this.port_.onDisconnect.removeListener(this.onDisconnectCallback_); |
310 this.port_.onMessage.removeListener(this.onIncomingMessageCallback_); | 216 this.port_.onMessage.removeListener(this.onIncomingMessageCallback_); |
311 this.port_ = null; | 217 this.port_ = null; |
312 | 218 |
(...skipping 11 matching lines...) Expand all Loading... |
324 pendingReplies[num_id].deferred.reject(this.error_); | 230 pendingReplies[num_id].deferred.reject(this.error_); |
325 } | 231 } |
326 } | 232 } |
327 | 233 |
328 /** | 234 /** |
329 * Gets local hostname. | 235 * Gets local hostname. |
330 * | 236 * |
331 * @return {!Promise<string>} | 237 * @return {!Promise<string>} |
332 */ | 238 */ |
333 remoting.HostDaemonFacade.prototype.getHostName = function() { | 239 remoting.HostDaemonFacade.prototype.getHostName = function() { |
334 return this.postMessage_({type: 'getHostName'}); | 240 return this.postMessage_({type: 'getHostName'}).then(function(reply) { |
| 241 return base.getStringAttr(reply, 'hostname'); |
| 242 }); |
335 }; | 243 }; |
336 | 244 |
337 /** | 245 /** |
338 * 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 |
339 * hash value base64-encoded to the callback. | 247 * hash value base64-encoded to the callback. |
340 * | 248 * |
341 * @param {string} hostId The host ID. | 249 * @param {string} hostId The host ID. |
342 * @param {string} pin The PIN. | 250 * @param {string} pin The PIN. |
343 * @return {!Promise<string>} | 251 * @return {!Promise<string>} |
344 */ | 252 */ |
345 remoting.HostDaemonFacade.prototype.getPinHash = function(hostId, pin) { | 253 remoting.HostDaemonFacade.prototype.getPinHash = function(hostId, pin) { |
346 return this.postMessage_({ | 254 return this.postMessage_({ |
347 type: 'getPinHash', | 255 type: 'getPinHash', |
348 hostId: hostId, | 256 hostId: hostId, |
349 pin: pin | 257 pin: pin |
| 258 }).then(function(reply) { |
| 259 return base.getStringAttr(reply, 'hash'); |
350 }); | 260 }); |
351 }; | 261 }; |
352 | 262 |
353 /** | 263 /** |
354 * 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 |
355 * 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 |
356 * host (PublicKeyInfo structure encoded with ASN.1 DER, and then BASE64). | 266 * host (PublicKeyInfo structure encoded with ASN.1 DER, and then BASE64). |
357 * | 267 * |
358 * @return {!Promise<remoting.KeyPair>} | 268 * @return {!Promise<remoting.KeyPair>} |
359 */ | 269 */ |
360 remoting.HostDaemonFacade.prototype.generateKeyPair = function() { | 270 remoting.HostDaemonFacade.prototype.generateKeyPair = function() { |
361 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 }); |
362 }; | 277 }; |
363 | 278 |
364 /** | 279 /** |
365 * Updates host config with the values specified in |config|. All | 280 * Updates host config with the values specified in |config|. All |
366 * fields that are not specified in |config| remain | 281 * fields that are not specified in |config| remain |
367 * unchanged. Following parameters cannot be changed using this | 282 * unchanged. Following parameters cannot be changed using this |
368 * function: host_id, xmpp_login. Error is returned if |config| | 283 * function: host_id, xmpp_login. Error is returned if |config| |
369 * includes these parameters. Changes take effect before the callback | 284 * includes these parameters. Changes take effect before the callback |
370 * is called. | 285 * is called. |
371 * | 286 * |
372 * TODO(jrw): Consider conversion exceptions to AsyncResult values. | 287 * TODO(jrw): Consider conversion exceptions to AsyncResult values. |
373 * | 288 * |
374 * @param {Object} config The new config parameters. | 289 * @param {Object} config The new config parameters. |
375 * @return {!Promise<remoting.HostController.AsyncResult>} | 290 * @return {!Promise<remoting.HostController.AsyncResult>} |
376 */ | 291 */ |
377 remoting.HostDaemonFacade.prototype.updateDaemonConfig = function(config) { | 292 remoting.HostDaemonFacade.prototype.updateDaemonConfig = function(config) { |
378 return this.postMessage_({ | 293 return this.postMessage_({ |
379 type: 'updateDaemonConfig', | 294 type: 'updateDaemonConfig', |
380 config: config | 295 config: config |
| 296 }).then(function(reply) { |
| 297 return remoting.HostController.AsyncResult.fromString( |
| 298 base.getStringAttr(reply, 'result')); |
381 }); | 299 }); |
382 }; | 300 }; |
383 | 301 |
384 /** | 302 /** |
385 * 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 |
386 * callback. | 304 * callback. |
387 * @return {!Promise<Object>} | 305 * @return {!Promise<Object>} |
388 */ | 306 */ |
389 remoting.HostDaemonFacade.prototype.getDaemonConfig = function() { | 307 remoting.HostDaemonFacade.prototype.getDaemonConfig = function() { |
390 return this.postMessage_({type: 'getDaemonConfig'}); | 308 return this.postMessage_({type: 'getDaemonConfig'}).then(function(reply) { |
| 309 return base.getObjectAttr(reply, 'config'); |
| 310 }); |
391 }; | 311 }; |
392 | 312 |
393 /** | 313 /** |
394 * Retrieves daemon version. The version is returned as a dotted decimal | 314 * Retrieves daemon version. The version is returned as a dotted decimal |
395 * string of the form major.minor.build.patch. | 315 * string of the form major.minor.build.patch. |
396 * | 316 * |
397 * @return {!Promise<string>} | 317 * @return {!Promise<string>} |
398 */ | 318 */ |
399 remoting.HostDaemonFacade.prototype.getDaemonVersion = function() { | 319 remoting.HostDaemonFacade.prototype.getDaemonVersion = function() { |
400 /** @type {remoting.HostDaemonFacade} */ | 320 /** @type {remoting.HostDaemonFacade} */ |
401 var that = this; | 321 var that = this; |
402 return this.initialize_().then(function() { | 322 return this.initialize_().then(function() { |
403 return that.version_; | 323 return that.version_; |
404 }, function() { | 324 }, function() { |
405 throw that.error_; | 325 throw that.error_; |
406 }); | 326 }); |
407 }; | 327 }; |
408 | 328 |
409 /** | 329 /** |
410 * 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 |
411 * the callback as booleans: supported, allowed, set-by-policy. | 331 * the callback as booleans: supported, allowed, set-by-policy. |
412 * | 332 * |
413 * @return {!Promise<remoting.UsageStatsConsent>} | 333 * @return {!Promise<remoting.UsageStatsConsent>} |
414 */ | 334 */ |
415 remoting.HostDaemonFacade.prototype.getUsageStatsConsent = function() { | 335 remoting.HostDaemonFacade.prototype.getUsageStatsConsent = function() { |
416 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 }); |
417 }; | 344 }; |
418 | 345 |
419 /** | 346 /** |
420 * Starts the daemon process with the specified configuration. | 347 * Starts the daemon process with the specified configuration. |
421 * | 348 * |
422 * TODO(jrw): Consider conversion exceptions to AsyncResult values. | 349 * TODO(jrw): Consider conversion exceptions to AsyncResult values. |
423 * | 350 * |
424 * @param {Object} config Host configuration. | 351 * @param {Object} config Host configuration. |
425 * @param {boolean} consent Consent to report crash dumps. | 352 * @param {boolean} consent Consent to report crash dumps. |
426 * @return {!Promise<remoting.HostController.AsyncResult>} | 353 * @return {!Promise<remoting.HostController.AsyncResult>} |
427 */ | 354 */ |
428 remoting.HostDaemonFacade.prototype.startDaemon = function(config, consent) { | 355 remoting.HostDaemonFacade.prototype.startDaemon = function(config, consent) { |
429 return this.postMessage_({ | 356 return this.postMessage_({ |
430 type: 'startDaemon', | 357 type: 'startDaemon', |
431 config: config, | 358 config: config, |
432 consent: consent | 359 consent: consent |
| 360 }).then(function(reply) { |
| 361 return remoting.HostController.AsyncResult.fromString( |
| 362 base.getStringAttr(reply, 'result')); |
433 }); | 363 }); |
434 }; | 364 }; |
435 | 365 |
436 /** | 366 /** |
437 * Stops the daemon process. | 367 * Stops the daemon process. |
438 * | 368 * |
439 * TODO(jrw): Consider conversion exceptions to AsyncResult values. | 369 * TODO(jrw): Consider conversion exceptions to AsyncResult values. |
440 * | 370 * |
441 * @return {!Promise<remoting.HostController.AsyncResult>} | 371 * @return {!Promise<remoting.HostController.AsyncResult>} |
442 */ | 372 */ |
443 remoting.HostDaemonFacade.prototype.stopDaemon = | 373 remoting.HostDaemonFacade.prototype.stopDaemon = |
444 function() { | 374 function() { |
445 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 }); |
446 }; | 379 }; |
447 | 380 |
448 /** | 381 /** |
449 * Gets the installed/running state of the Host process. | 382 * Gets the installed/running state of the Host process. |
450 * | 383 * |
451 * @return {!Promise<remoting.HostController.State>} | 384 * @return {!Promise<remoting.HostController.State>} |
452 */ | 385 */ |
453 remoting.HostDaemonFacade.prototype.getDaemonState = function() { | 386 remoting.HostDaemonFacade.prototype.getDaemonState = function() { |
454 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 }); |
455 }; | 391 }; |
456 | 392 |
457 /** | 393 /** |
458 * Retrieves the list of paired clients. | 394 * Retrieves the list of paired clients. |
459 * | 395 * |
460 * @return {!Promise<Array<remoting.PairedClient>>} | 396 * @return {!Promise<Array<remoting.PairedClient>>} |
461 */ | 397 */ |
462 remoting.HostDaemonFacade.prototype.getPairedClients = function() { | 398 remoting.HostDaemonFacade.prototype.getPairedClients = function() { |
463 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 }); |
464 }; | 408 }; |
465 | 409 |
466 /** | 410 /** |
467 * Clears all paired clients from the registry. | 411 * Clears all paired clients from the registry. |
468 * | 412 * |
469 * @return {!Promise<boolean>} | 413 * @return {!Promise<boolean>} |
470 */ | 414 */ |
471 remoting.HostDaemonFacade.prototype.clearPairedClients = function() { | 415 remoting.HostDaemonFacade.prototype.clearPairedClients = function() { |
472 return this.postMessage_({type: 'clearPairedClients'}); | 416 return this.postMessage_({type: 'clearPairedClients'}).then(function(reply) { |
| 417 return base.getBooleanAttr(reply, 'result'); |
| 418 }); |
473 }; | 419 }; |
474 | 420 |
475 /** | 421 /** |
476 * Deletes a paired client referenced by client id. | 422 * Deletes a paired client referenced by client id. |
477 * | 423 * |
478 * @param {string} client Client to delete. | 424 * @param {string} client Client to delete. |
479 * @return {!Promise<boolean>} | 425 * @return {!Promise<boolean>} |
480 */ | 426 */ |
481 remoting.HostDaemonFacade.prototype.deletePairedClient = function(client) { | 427 remoting.HostDaemonFacade.prototype.deletePairedClient = function(client) { |
482 return this.postMessage_({ | 428 return this.postMessage_({ |
483 type: 'deletePairedClient', | 429 type: 'deletePairedClient', |
484 clientId: client | 430 clientId: client |
| 431 }).then(function(reply) { |
| 432 return base.getBooleanAttr(reply, 'result'); |
485 }); | 433 }); |
486 }; | 434 }; |
487 | 435 |
488 /** | 436 /** |
489 * Gets the API keys to obtain/use service account credentials. | 437 * Gets the API keys to obtain/use service account credentials. |
490 * | 438 * |
491 * @return {!Promise<string>} | 439 * @return {!Promise<string>} |
492 */ | 440 */ |
493 remoting.HostDaemonFacade.prototype.getHostClientId = function() { | 441 remoting.HostDaemonFacade.prototype.getHostClientId = function() { |
494 return this.postMessage_({type: 'getHostClientId'}); | 442 return this.postMessage_({type: 'getHostClientId'}).then(function(reply) { |
| 443 return base.getStringAttr(reply, 'clientId'); |
| 444 }); |
495 }; | 445 }; |
496 | 446 |
497 /** | 447 /** |
498 * | |
499 * @param {string} authorizationCode OAuth authorization code. | 448 * @param {string} authorizationCode OAuth authorization code. |
500 * @return {!Promise<{remoting.XmppCredentials}>} | 449 * @return {!Promise<{remoting.XmppCredentials}>} |
501 */ | 450 */ |
502 remoting.HostDaemonFacade.prototype.getCredentialsFromAuthCode = | 451 remoting.HostDaemonFacade.prototype.getCredentialsFromAuthCode = |
503 function(authorizationCode) { | 452 function(authorizationCode) { |
504 return this.postMessage_({ | 453 return this.postMessage_({ |
505 type: 'getCredentialsFromAuthCode', | 454 type: 'getCredentialsFromAuthCode', |
506 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 } |
507 }); | 467 }); |
508 }; | 468 }; |
| 469 |
| 470 /** |
| 471 * @param {string} authorizationCode OAuth authorization code. |
| 472 * @return {!Promise<string>} |
| 473 */ |
| 474 remoting.HostDaemonFacade.prototype.getRefreshTokenFromAuthCode = |
| 475 function(authorizationCode) { |
| 476 return this.postMessage_({ |
| 477 type: 'getRefreshTokenFromAuthCode', |
| 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 } |
| 486 }); |
| 487 }; |
OLD | NEW |