Revert 264226 "Reduce dependency of TiclInvalidationService on P..."
[chromium-blink-merge.git] / remoting / webapp / host_it2me_native_messaging.js
blob6af8168d2c4e0d20153844076c45613c2b77fecf
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 'use strict';
12 /** @suppress {duplicate} */
13 var remoting = remoting || {};
15 /**
16 * @constructor
18 remoting.HostIt2MeNativeMessaging = function() {
19 /**
20 * @type {number}
21 * @private
23 this.nextId_ = 0;
25 /**
26 * @type {?chrome.extension.Port}
27 * @private
29 this.port_ = null;
31 /**
32 * @type {string}
33 * @private
35 this.accessCode_ = '';
37 /**
38 * @type {number}
39 * @private
41 this.accessCodeLifetime_ = 0;
43 /**
44 * @type {string}
45 * @private
47 this.clientId_ = '';
49 /**
50 * @type {boolean}
51 * @private
53 this.initialized_ = false;
55 /**
56 * @type {function():void}
57 * @private
59 this.onHostStarted_ = function() {};
61 /**
62 * Called if Native Messaging host has failed to start.
63 * @private
64 * */
65 this.onHostInitFailed_ = function() {};
67 /**
68 * Called if the It2Me Native Messaging host sends a malformed message:
69 * missing required attributes, attributes with incorrect types, etc.
70 * @param {remoting.Error} error
71 * @private
73 this.onError_ = function(error) {};
75 /**
76 * @type {function(remoting.HostSession.State):void}
77 * @private
79 this.onStateChanged_ = function() {};
81 /**
82 * @type {function(boolean):void}
83 * @private
85 this.onNatPolicyChanged_ = function() {};
88 /**
89 * Sets up connection to the Native Messaging host process and exchanges
90 * 'hello' messages. If Native Messaging is not supported or if the it2me
91 * native messaging host is not installed, onHostInitFailed is invoked.
92 * Otherwise, onHostStarted is invoked.
94 * @param {function():void} onHostStarted Called after successful
95 * initialization.
96 * @param {function():void} onHostInitFailed Called if cannot connect to host.
97 * @param {function(remoting.Error):void} onError Called on host error after
98 * successfully connecting to the host.
99 * @return {void}
101 remoting.HostIt2MeNativeMessaging.prototype.initialize =
102 function(onHostStarted, onHostInitFailed, onError) {
103 this.onHostStarted_ = onHostStarted;
104 this.onHostInitFailed_ = onHostInitFailed;
105 this.onError_ = onError;
107 try {
108 this.port_ = chrome.runtime.connectNative(
109 'com.google.chrome.remote_assistance');
110 this.port_.onMessage.addListener(this.onIncomingMessage_.bind(this));
111 this.port_.onDisconnect.addListener(this.onHostDisconnect_.bind(this));
112 this.postMessage_({type: 'hello'});
113 } catch (err) {
114 console.log('Native Messaging initialization failed: ',
115 /** @type {*} */ (err));
116 onHostInitFailed();
117 return;
122 * Attaches a new ID to the supplied message, and posts it to the Native
123 * Messaging port.
124 * |message| should have its 'type' field set, and any other fields set
125 * depending on the message type.
127 * @param {{type: string}} message The message to post.
128 * @return {void}
129 * @private
131 remoting.HostIt2MeNativeMessaging.prototype.postMessage_ =
132 function(message) {
133 var id = this.nextId_++;
134 message['id'] = id;
135 this.port_.postMessage(message);
139 * Handler for incoming Native Messages.
141 * @param {Object} message The received message.
142 * @return {void}
143 * @private
145 remoting.HostIt2MeNativeMessaging.prototype.onIncomingMessage_ =
146 function(message) {
147 try {
148 this.handleIncomingMessage_(message);
149 } catch (e) {
150 console.error(/** @type {*} */ (e));
151 this.onError_(remoting.Error.UNEXPECTED);
156 * Handler for incoming Native Messages.
158 * @param {Object} message The received message.
159 * @return {void}
160 * @private
162 remoting.HostIt2MeNativeMessaging.prototype.handleIncomingMessage_ =
163 function(message) {
164 var type = getStringAttr(message, 'type');
166 switch (type) {
167 case 'helloResponse':
168 var version = getStringAttr(message, 'version');
169 console.log('Host version: ', version);
170 this.initialized_ = true;
171 // A "hello" request is sent immediately after the native messaging host
172 // is started. We can proceed to the next task once we receive the
173 // "helloReponse".
174 this.onHostStarted_();
175 break;
177 case 'connectResponse':
178 console.log('connectResponse received');
179 // Response to the "connect" request. No action is needed until we
180 // receive the corresponding "hostStateChanged" message.
181 break;
183 case 'disconnectResponse':
184 console.log('disconnectResponse received');
185 // Response to the "disconnect" request. No action is needed until we
186 // receive the corresponding "hostStateChanged" message.
187 break;
189 case 'hostStateChanged':
190 var stateString = getStringAttr(message, 'state');
191 console.log('hostStateChanged received: ', stateString);
192 var state = remoting.HostSession.State.fromString(stateString);
194 switch (state) {
195 case remoting.HostSession.State.RECEIVED_ACCESS_CODE:
196 var accessCode = getStringAttr(message, 'accessCode');
197 var accessCodeLifetime = getNumberAttr(message, 'accessCodeLifetime');
198 this.onReceivedAccessCode_(accessCode, accessCodeLifetime);
199 break;
201 case remoting.HostSession.State.CONNECTED:
202 var client = getStringAttr(message, 'client');
203 this.onConnected_(client);
204 break;
206 this.onStateChanged_(state);
207 break;
209 case 'natPolicyChanged':
210 var natTraversalEnabled = getBooleanAttr(message, 'natTraversalEnabled');
211 this.onNatPolicyChanged_(natTraversalEnabled);
212 break;
214 case 'error':
215 console.error(getStringAttr(message, 'description'));
216 this.onError_(remoting.Error.UNEXPECTED);
217 break;
219 default:
220 throw 'Unexpected native message: ' + message;
225 * @param {string} email The user's email address.
226 * @param {string} authServiceWithToken Concatenation of the auth service
227 * (e.g. oauth2) and the access token.
228 * @param {function(remoting.HostSession.State):void} onStateChanged Callback to
229 * invoke when the host state changes.
230 * @param {function(boolean):void} onNatPolicyChanged Callback to invoke when
231 * the nat traversal policy changes.
232 * @param {string} xmppServerAddress XMPP server host name (or IP address) and
233 * port.
234 * @param {boolean} xmppServerUseTls Whether to use TLS on connections to the
235 * XMPP server
236 * @param {string} directoryBotJid XMPP JID for the remoting directory server
237 * bot.
238 * @return {void}
240 remoting.HostIt2MeNativeMessaging.prototype.connect =
241 function(email, authServiceWithToken, onStateChanged, onNatPolicyChanged,
242 xmppServerAddress, xmppServerUseTls, directoryBotJid) {
243 this.onStateChanged_ = onStateChanged;
244 this.onNatPolicyChanged_ = onNatPolicyChanged;
245 this.postMessage_({
246 type: 'connect',
247 userName: email,
248 authServiceWithToken: authServiceWithToken,
249 xmppServerAddress: xmppServerAddress,
250 xmppServerUseTls: xmppServerUseTls,
251 directoryBotJid: directoryBotJid});
255 * @return {void}
257 remoting.HostIt2MeNativeMessaging.prototype.disconnect =
258 function() {
259 this.postMessage_({
260 type: 'disconnect'});
264 * @param {string} accessCode
265 * @param {number} accessCodeLifetime
266 * @return {void}
267 * @private
269 remoting.HostIt2MeNativeMessaging.prototype.onReceivedAccessCode_ =
270 function(accessCode, accessCodeLifetime) {
271 this.accessCode_ = accessCode;
272 this.accessCodeLifetime_ = accessCodeLifetime;
276 * @param {string} clientId
277 * @return {void}
278 * @private
280 remoting.HostIt2MeNativeMessaging.prototype.onConnected_ =
281 function(clientId) {
282 this.clientId_ = clientId;
286 * @return {void}
287 * @private
289 remoting.HostIt2MeNativeMessaging.prototype.onHostDisconnect_ = function() {
290 if (!this.initialized_) {
291 // If the host is disconnected before it is initialized, it probably means
292 // the host is not propertly installed (or not installed at all).
293 // E.g., if the host manifest is not present we get "Specified native
294 // messaging host not found" error. If the host manifest is present but
295 // the host binary cannot be found we get the "Native host has exited"
296 // error.
297 console.log('Native Messaging initialization failed: ' +
298 chrome.runtime.lastError.message);
299 this.onHostInitFailed_();
300 } else {
301 console.error('Native Messaging port disconnected.');
302 this.onError_(remoting.Error.UNEXPECTED);
307 * @return {string}
309 remoting.HostIt2MeNativeMessaging.prototype.getAccessCode = function() {
310 return this.accessCode_
314 * @return {number}
316 remoting.HostIt2MeNativeMessaging.prototype.getAccessCodeLifetime = function() {
317 return this.accessCodeLifetime_
321 * @return {string}
323 remoting.HostIt2MeNativeMessaging.prototype.getClient = function() {
324 return this.clientId_;