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