Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / remoting / webapp / background / it2me_service.js
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.
4
5 /**
6  * @fileoverview
7  * It2MeService listens to incoming connections requests from Hangouts
8  * and the webapp and creates a It2MeHelperChannel between them.
9  * It supports multiple helper sessions, but only a single helpee.
10  */
11
12 'use strict';
13
14 /** @suppress {duplicate} */
15 var remoting = remoting || {};
16
17 /**
18  * @param {remoting.AppLauncher} appLauncher
19  * @constructor
20  */
21 remoting.It2MeService = function(appLauncher) {
22   /**
23    * @type {remoting.AppLauncher}
24    * @private
25    */
26   this.appLauncher_ = appLauncher;
27
28   /**
29    * @type {Array.<remoting.It2MeHelperChannel>}
30    * @private
31    */
32   this.helpers_ = [];
33
34   /** @private */
35   this.helpee_ = null;
36
37   this.onWebappConnectRef_ = this.onWebappConnect_.bind(this);
38   this.onConnectExternalRef_ = this.onConnectExternal_.bind(this);
39 };
40
41 /** @enum {string} */
42 remoting.It2MeService.ConnectionTypes = {
43   HELPER_HANGOUT: 'it2me.helper.hangout',
44   HELPEE_HANGOUT: 'it2me.helpee.hangout',
45   HELPER_WEBAPP: 'it2me.helper.webapp'
46 };
47
48 /**
49  * Starts listening to external connection from Hangouts and the webapp.
50  */
51 remoting.It2MeService.prototype.init = function() {
52   chrome.runtime.onConnect.addListener(this.onWebappConnectRef_);
53   chrome.runtime.onConnectExternal.addListener(this.onConnectExternalRef_);
54 };
55
56 remoting.It2MeService.prototype.dispose = function() {
57   chrome.runtime.onConnect.removeListener(this.onWebappConnectRef_);
58   chrome.runtime.onConnectExternal.removeListener(
59       this.onConnectExternalRef_);
60 };
61
62 /**
63  * This function is called when Hangouts connects via chrome.runtime.connect.
64  * Only web pages that are white-listed in the manifest are allowed to connect.
65  *
66  * @param {chrome.runtime.Port} port
67  * @private
68  */
69 remoting.It2MeService.prototype.onConnectExternal_ = function(port) {
70   var ConnectionTypes = remoting.It2MeService.ConnectionTypes;
71   try {
72     switch (port.name) {
73       case ConnectionTypes.HELPER_HANGOUT:
74         this.handleExternalHelperConnection_(port);
75         return true;
76       case ConnectionTypes.HELPEE_HANGOUT:
77         this.handleExternalHelpeeConnection_(port);
78         return true;
79       default:
80         throw new Error('Unsupported port - ' + port.name);
81     }
82   } catch (e) {
83     var error = /**@type {Error} */ e;
84     console.error(error);
85     port.disconnect();
86   }
87   return false;
88 };
89
90 /**
91  * @param {chrome.runtime.Port} port
92  * @private
93  */
94 remoting.It2MeService.prototype.onWebappConnect_ = function(port) {
95   try {
96     console.log('Incoming helper connection from webapp.');
97
98     // The senderId (tabId or windowId) of the webapp is embedded in the port
99     // name with the format port_name@senderId.
100     var parts = port.name.split('@');
101     var portName = parts[0];
102     var senderId = parts[1];
103     var ConnectionTypes = remoting.It2MeService.ConnectionTypes;
104     if (portName === ConnectionTypes.HELPER_WEBAPP && senderId !== undefined) {
105       for (var i = 0; i < this.helpers_.length; i++) {
106         var helper = this.helpers_[i];
107         if (helper.instanceId() === senderId) {
108           helper.onWebappConnect(port, senderId);
109           return;
110         }
111       }
112     }
113     throw new Error('No matching hangout connection found for ' + port.name);
114   } catch (e) {
115     var error = /** @type {Error} */ e;
116     console.error(error);
117     port.disconnect();
118   }
119 };
120
121 /**
122  * @param {remoting.It2MeHelperChannel} helper
123  */
124 remoting.It2MeService.prototype.onHelperChannelDisconnected = function(helper) {
125   for (var i = 0; i < this.helpers_.length; i++) {
126     if (helper === this.helpers_[i]) {
127       this.helpers_.splice(i, 1);
128     }
129   }
130 };
131
132 remoting.It2MeService.prototype.onHelpeeChannelDisconnected = function() {
133   base.debug.assert(this.helpee_ !== null);
134   this.helpee_ = null;
135 };
136
137 /**
138  * @param {chrome.runtime.Port} port
139  * @private
140  */
141 remoting.It2MeService.prototype.handleExternalHelperConnection_ =
142     function(port) {
143   if (this.helpee_) {
144     console.error(
145         'Cannot start a helper session while a helpee session is in process.');
146     port.disconnect();
147     return;
148   }
149
150   console.log('Incoming helper connection from Hangouts');
151   var helper = new remoting.It2MeHelperChannel(
152       this.appLauncher_, port, this.onHelperChannelDisconnected.bind(this));
153   helper.init();
154   this.helpers_.push(helper);
155 };
156
157 /**
158  * @param {chrome.runtime.Port} hangoutPort Represents a connection to Hangouts.
159  * @private
160  */
161 remoting.It2MeService.prototype.handleExternalHelpeeConnection_ =
162     function(hangoutPort) {
163   if (this.helpee_) {
164     console.error('An existing helpee session is in process.');
165     hangoutPort.disconnect();
166     return;
167   }
168
169   console.log('Incoming helpee connection from Hangouts');
170   this.helpee_ = new remoting.It2MeHelpeeChannel(
171       hangoutPort,
172       new remoting.It2MeHostFacade(),
173       new remoting.HostInstaller(),
174       this.onHelpeeChannelDisconnected.bind(this));
175   this.helpee_.init();
176 };