Updating XTBs based on .GRDs from branch master
[chromium-blink-merge.git] / remoting / webapp / crd / js / it2me_host_facade.js
blob64428f34813453cbf0a31926d47f10d0928f9b2b
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  * Class to communicate with the It2me Host component via Native Messaging.
8  */
10 /** @suppress {duplicate} */
11 var remoting = remoting || {};
13 (function() {
15 'use strict';
17 /**
18  * @constructor
19  * @implements {base.Disposable}
20  */
21 remoting.It2MeHostFacade = function() {
22   /** @private {number} */
23   this.nextId_ = 0;
25   /** @private {?Port} */
26   this.port_ = null;
28   /** @private {string} */
29   this.accessCode_ = '';
31   /** @private {number} */
32   this.accessCodeLifetime_ = 0;
34   /** @private {string} */
35   this.clientId_ = '';
37   /** @private {boolean} */
38   this.initialized_ = false;
40   /** @private {base.Disposables} */
41   this.eventHooks_ = null;
43   /** @private {?function():void} */
44   this.onInitialized_ = function() {};
46   /**
47    * Called if Native Messaging host has failed to start.
48    * @private
49    * */
50   this.onInitializationFailed_ = function() {};
52   /**
53    * Called if the It2Me Native Messaging host sends a malformed message:
54    * missing required attributes, attributes with incorrect types, etc.
55    * @private {?function(!remoting.Error):void}
56    */
57   this.onError_ = function(error) {};
59   /** @private {?function(remoting.HostSession.State):void} */
60   this.onStateChanged_ = function() {};
62   /** @private {?function(boolean):void} */
63   this.onNatPolicyChanged_ = function() {};
66 remoting.It2MeHostFacade.prototype.dispose = function() {
67   base.dispose(this.eventHooks_);
68   this.eventHooks_ = null;
69   if (this.port_) {
70     this.port_.disconnect();
71     this.port_ = null;
72   }
75 /**
76  * Sets up connection to the Native Messaging host process and exchanges
77  * 'hello' messages. If Native Messaging is not supported or if the it2me
78  * native messaging host is not installed, onInitializationFailed is invoked.
79  * Otherwise, onInitialized is invoked.
80  *
81  * @param {function(*=):void} onInitialized Called after successful
82  *     initialization.
83  * @param {function(*=):void} onInitializationFailed Called if cannot connect to
84  *     the native messaging host.
85  * @return {void}
86  */
87 remoting.It2MeHostFacade.prototype.initialize =
88     function(onInitialized, onInitializationFailed) {
89   this.onInitialized_ = onInitialized;
90   this.onInitializationFailed_ = onInitializationFailed;
92   try {
93     this.port_ = chrome.runtime.connectNative(
94         'com.google.chrome.remote_assistance');
95     this.eventHooks_ = new base.Disposables(
96         new base.ChromeEventHook(this.port_.onMessage,
97                                  this.onIncomingMessage_.bind(this)),
98         new base.ChromeEventHook(this.port_.onDisconnect,
99                                  this.onHostDisconnect_.bind(this)));
100     this.port_.postMessage({type: 'hello'});
101   } catch (/** @type {*} */ err) {
102     console.log('Native Messaging initialization failed: ', err);
103     onInitializationFailed();
104     return;
105   }
109  * @param {string} email The user's email address.
110  * @param {string} authServiceWithToken Concatenation of the auth service
111  *     (e.g. oauth2) and the access token.
112  * @param {function(remoting.HostSession.State):void} onStateChanged Callback to
113  *     invoke when the host state changes.
114  * @param {function(boolean):void} onNatPolicyChanged Callback to invoke when
115  *     the nat traversal policy changes.
116  * @param {function(string):void} logDebugInfo Callback allowing the plugin
117  *     to log messages to the debug log.
118  * @param {string} xmppServerAddress XMPP server host name (or IP address) and
119  *     port.
120  * @param {boolean} xmppServerUseTls Whether to use TLS on connections to the
121  *     XMPP server
122  * @param {string} directoryBotJid XMPP JID for the remoting directory server
123  *     bot.
124  * @param {function(!remoting.Error):void} onError Callback to invoke in case of
125  *     an error.
126  * @return {void}
127  */
128 remoting.It2MeHostFacade.prototype.connect =
129     function(email, authServiceWithToken, onStateChanged, onNatPolicyChanged,
130              logDebugInfo, xmppServerAddress, xmppServerUseTls, directoryBotJid,
131              onError) {
132   if (!this.port_) {
133     console.error(
134         'remoting.It2MeHostFacade.connect() without initialization.');
135     onError(remoting.Error.unexpected());
136     return;
137   }
139   this.onStateChanged_ = onStateChanged;
140   this.onNatPolicyChanged_ = onNatPolicyChanged;
141   this.onError_ = onError;
142   this.port_.postMessage({
143     type: 'connect',
144     userName: email,
145     authServiceWithToken: authServiceWithToken,
146     xmppServerAddress: xmppServerAddress,
147     xmppServerUseTls: xmppServerUseTls,
148     directoryBotJid: directoryBotJid
149   });
153  * Unhooks the |onStateChanged|, |onError|, |onNatPolicyChanged| and
154  * |onInitalized| callbacks.  This is called when the client shuts down so that
155  * the callbacks will not be invoked on a disposed client.
157  * @return {void}
158  */
159 remoting.It2MeHostFacade.prototype.unhookCallbacks = function() {
160   this.onStateChanged_ = null;
161   this.onNatPolicyChanged_ = null;
162   this.onError_ = null;
163   this.onInitialized_ = null;
167  * @return {void}
168  */
169 remoting.It2MeHostFacade.prototype.disconnect = function() {
170   if (this.port_)
171     this.port_.postMessage({type: 'disconnect'});
175  * @return {boolean}
176  */
177 remoting.It2MeHostFacade.prototype.initialized = function() {
178   return this.initialized_;
182  * @return {string}
183  */
184 remoting.It2MeHostFacade.prototype.getAccessCode = function() {
185   return this.accessCode_;
189  * @return {number}
190  */
191 remoting.It2MeHostFacade.prototype.getAccessCodeLifetime = function() {
192   return this.accessCodeLifetime_;
196  * @return {string}
197  */
198 remoting.It2MeHostFacade.prototype.getClient = function() {
199   return this.clientId_;
203  * Handler for incoming messages.
205  * @param {Object} message The received message.
206  * @return {void}
207  * @private
208  */
209 remoting.It2MeHostFacade.prototype.onIncomingMessage_ =
210     function(message) {
211   var type = base.getStringAttr(message, 'type');
213   switch (type) {
214     case 'helloResponse':
215       var version = base.getStringAttr(message, 'version');
216       console.log('Host version: ', version);
217       this.initialized_ = true;
218       // A "hello" request is sent immediately after the native messaging host
219       // is started. We can proceed to the next task once we receive the
220       // "helloReponse".
221       if (this.onInitialized_) {
222         this.onInitialized_();
223       }
224       break;
226     case 'connectResponse':
227       console.log('connectResponse received');
228       // Response to the "connect" request. No action is needed until we
229       // receive the corresponding "hostStateChanged" message.
230       break;
232     case 'disconnectResponse':
233       console.log('disconnectResponse received');
234       // Response to the "disconnect" request. No action is needed until we
235       // receive the corresponding "hostStateChanged" message.
236       break;
238     case 'hostStateChanged':
239       var stateString = base.getStringAttr(message, 'state');
240       var errorMessage = base.getStringAttr(message, 'error_message', '');
241       console.log('hostStateChanged received: ' + stateString);
242       var state = remoting.HostSession.State.fromString(stateString);
244       switch (state) {
245         case remoting.HostSession.State.RECEIVED_ACCESS_CODE:
246           var accessCode = base.getStringAttr(message, 'accessCode');
247           var accessCodeLifetime =
248               base.getNumberAttr(message, 'accessCodeLifetime');
249           this.onReceivedAccessCode_(accessCode, accessCodeLifetime);
250           break;
252         case remoting.HostSession.State.CONNECTED:
253           var client = base.getStringAttr(message, 'client');
254           this.onConnected_(client);
255           break;
256       }
257       if (this.onStateChanged_) {
258         this.onStateChanged_(state);
259       }
260       break;
262     case 'natPolicyChanged':
263       if (this.onNatPolicyChanged_) {
264         var natTraversalEnabled =
265             base.getBooleanAttr(message, 'natTraversalEnabled');
266         this.onNatPolicyChanged_(natTraversalEnabled);
267       }
268       break;
270     case 'error':
271       console.error(base.getStringAttr(message, 'description'));
272       if (this.onError_) {
273         this.onError_(remoting.Error.unexpected());
274       }
275       break;
277     default:
278       throw 'Unexpected native message: ' + message;
279   }
283  * @param {string} accessCode
284  * @param {number} accessCodeLifetime
285  * @return {void}
286  * @private
287  */
288 remoting.It2MeHostFacade.prototype.onReceivedAccessCode_ =
289     function(accessCode, accessCodeLifetime) {
290   this.accessCode_ = accessCode;
291   this.accessCodeLifetime_ = accessCodeLifetime;
295  * @param {string} clientId
296  * @return {void}
297  * @private
298  */
299 remoting.It2MeHostFacade.prototype.onConnected_ = function(clientId) {
300   this.clientId_ = clientId;
304  * @return {void}
305  * @private
306  */
307 remoting.It2MeHostFacade.prototype.onHostDisconnect_ = function() {
308   if (!this.initialized_) {
309     // If the host is disconnected before it is initialized, it probably means
310     // the host is not propertly installed (or not installed at all).
311     // E.g., if the host manifest is not present we get "Specified native
312     // messaging host not found" error. If the host manifest is present but
313     // the host binary cannot be found we get the "Native host has exited"
314     // error.
315     console.log('Native Messaging initialization failed: ' +
316                 chrome.runtime.lastError.message);
317     this.onInitializationFailed_();
318   } else {
319     console.error('Native Messaging port disconnected.');
320     this.port_ = null;
321     this.onError_(remoting.Error.unexpected());
322   }
325 })();