Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / remoting / webapp / crd / js / it2me_host_facade.js
blob23a70acb73dca5cc24d5df707c4af65287266656
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}
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}
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;
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.
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}
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;
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}
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;
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
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}
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}
169 remoting.It2MeHostFacade.prototype.disconnect = function() {
170 if (this.port_)
171 this.port_.postMessage({type: 'disconnect'});
175 * @return {boolean}
177 remoting.It2MeHostFacade.prototype.initialized = function() {
178 return this.initialized_;
182 * @return {string}
184 remoting.It2MeHostFacade.prototype.getAccessCode = function() {
185 return this.accessCode_;
189 * @return {number}
191 remoting.It2MeHostFacade.prototype.getAccessCodeLifetime = function() {
192 return this.accessCodeLifetime_;
196 * @return {string}
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
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_();
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 console.log('hostStateChanged received: ', stateString);
241 var state = remoting.HostSession.State.fromString(stateString);
243 switch (state) {
244 case remoting.HostSession.State.RECEIVED_ACCESS_CODE:
245 var accessCode = base.getStringAttr(message, 'accessCode');
246 var accessCodeLifetime =
247 base.getNumberAttr(message, 'accessCodeLifetime');
248 this.onReceivedAccessCode_(accessCode, accessCodeLifetime);
249 break;
251 case remoting.HostSession.State.CONNECTED:
252 var client = base.getStringAttr(message, 'client');
253 this.onConnected_(client);
254 break;
256 if (this.onStateChanged_) {
257 this.onStateChanged_(state);
259 break;
261 case 'natPolicyChanged':
262 if (this.onNatPolicyChanged_) {
263 var natTraversalEnabled =
264 base.getBooleanAttr(message, 'natTraversalEnabled');
265 this.onNatPolicyChanged_(natTraversalEnabled);
267 break;
269 case 'error':
270 console.error(base.getStringAttr(message, 'description'));
271 if (this.onError_) {
272 this.onError_(remoting.Error.unexpected());
274 break;
276 default:
277 throw 'Unexpected native message: ' + message;
282 * @param {string} accessCode
283 * @param {number} accessCodeLifetime
284 * @return {void}
285 * @private
287 remoting.It2MeHostFacade.prototype.onReceivedAccessCode_ =
288 function(accessCode, accessCodeLifetime) {
289 this.accessCode_ = accessCode;
290 this.accessCodeLifetime_ = accessCodeLifetime;
294 * @param {string} clientId
295 * @return {void}
296 * @private
298 remoting.It2MeHostFacade.prototype.onConnected_ = function(clientId) {
299 this.clientId_ = clientId;
303 * @return {void}
304 * @private
306 remoting.It2MeHostFacade.prototype.onHostDisconnect_ = function() {
307 if (!this.initialized_) {
308 // If the host is disconnected before it is initialized, it probably means
309 // the host is not propertly installed (or not installed at all).
310 // E.g., if the host manifest is not present we get "Specified native
311 // messaging host not found" error. If the host manifest is present but
312 // the host binary cannot be found we get the "Native host has exited"
313 // error.
314 console.log('Native Messaging initialization failed: ' +
315 chrome.runtime.lastError.message);
316 this.onInitializationFailed_();
317 } else {
318 console.error('Native Messaging port disconnected.');
319 this.port_ = null;
320 this.onError_(remoting.Error.unexpected());
324 })();