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 for incoming connections request from the hangout | |
Jamie
2014/08/12 02:24:59
s/connections request/connection requests/
kelvinp
2014/08/12 21:42:41
Done.
| |
8 * and webapp and creates a It2MeHelperChannel between them. | |
9 * It supports multiple concurrent helper sessions. | |
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 * @private | |
24 * @type {remoting.AppLauncher} | |
25 */ | |
26 this.appLauncher_ = appLauncher; | |
27 | |
28 /** | |
29 * @private | |
30 * @type {Array.<remoting.It2MeHelperChannel>} | |
31 */ | |
32 this.helpers_ = []; | |
33 | |
34 /** @private */ | |
35 this.helpee_ = null; | |
36 | |
37 this.onWebappConnectRef_ = this.onWebappConnect_.bind(this); | |
38 this.onMessageExternalRef_ = this.onMessageExternal_.bind(this); | |
39 this.onConnectExternalRef_ = this.onConnectExternal_.bind(this); | |
40 }; | |
41 | |
42 remoting.It2MeService.ConnectionTypes = { | |
43 HELPER_HANGOUT: 'it2me.helper.hangout', | |
44 HELPEE_HANGOUT: 'it2me.helpee.hangout', | |
45 HELPER_WEBAPP: 'it2me.helper.webapp' | |
Jamie
2014/08/12 02:24:59
Are these names global? If so, then they should pr
kelvinp
2014/08/12 21:42:42
Those names are only valid within our extension.
| |
46 }; | |
47 | |
48 remoting.It2MeService.prototype.init = function() { | |
49 chrome.runtime.onConnect.addListener(this.onWebappConnectRef_); | |
50 chrome.runtime.onMessageExternal.addListener(this.onMessageExternalRef_); | |
51 chrome.runtime.onConnectExternal.addListener(this.onConnectExternalRef_); | |
52 }; | |
53 | |
54 remoting.It2MeService.prototype.dispose = function() { | |
55 chrome.runtime.onConnect.removeListener(this.onWebappConnectRef_); | |
56 chrome.runtime.onMessageExternal.removeListener( | |
57 this.onMessageExternalRef_); | |
58 chrome.runtime.onConnectExternal.removeListener( | |
59 this.onConnectExternalRef_); | |
60 }; | |
61 | |
62 /** | |
63 * This function is called when a runtime message is received from an external | |
64 * web page (hangout) or extension. | |
65 * @param {{method:string, data:Object.<string,*>}} message | |
Jamie
2014/08/12 02:24:59
Nit: Blank line between function comment and type
kelvinp
2014/08/12 21:42:41
Acknowledged.
kelvinp
2014/08/12 21:42:41
Done.
| |
66 * @param {chrome.runtime.MessageSender} sender | |
67 * @param {Function} sendResponse | |
68 */ | |
69 remoting.It2MeService.prototype.onMessageExternal_ = | |
70 function(message, sender, sendResponse) { | |
71 /** | |
72 * @param {Object} value | |
73 * @param {string=} opt_error | |
74 */ | |
75 function doSendResponse(value, opt_error) { | |
76 var errorMessage = opt_error || chrome.runtime.lastError.message; | |
77 sendResponse({'value': value, 'error': errorMessage}); | |
78 } | |
Jamie
2014/08/12 02:24:59
I don't think this helper actually helps much, sin
| |
79 | |
80 try { | |
81 var method = message.method; | |
82 var isHandled = false; | |
83 | |
84 if (method == 'hello') { | |
85 // The hello message is used by hangouts to detect whether the app is | |
86 // installed and what features are supported. | |
87 doSendResponse({'supportedFeatures': ['it2me']}); | |
88 return true; | |
89 } | |
90 throw new Error('Unknown method: ' + method); | |
91 } catch (e) { | |
92 var error = /** @type {Error} */ e; | |
93 doSendResponse(null, error.name + ': ' + error.message); | |
94 } | |
95 }; | |
96 | |
97 /** | |
98 * @param {chrome.runtime.Port} port | |
99 */ | |
100 remoting.It2MeService.prototype.onConnectExternal_ = function(port) { | |
101 var ConnectionTypes = remoting.It2MeService.ConnectionTypes; | |
102 try { | |
103 switch (port.name) { | |
Jamie
2014/08/12 02:24:58
Presumably port.name can be spoofed. Can/should we
kelvinp
2014/08/12 21:42:41
Yes, not every webpage can connect to our list. O
| |
104 case ConnectionTypes.HELPER_HANGOUT: | |
105 this.handleExternalHelperConnection_(port); | |
106 return true; | |
107 default: | |
108 throw new Error('Unsupported port - ' + port.name); | |
109 } | |
110 } catch (e) { | |
111 port.disconnect(); | |
112 } | |
113 }; | |
114 | |
115 /** | |
116 * @param {chrome.runtime.Port} port | |
117 */ | |
118 remoting.It2MeService.prototype.onWebappConnect_ = function(port) { | |
119 try { | |
120 console.log('Incoming helper connection from webapp.'); | |
121 | |
122 // The senderId (tabId or windowId) of the webapp is embedded in the port | |
123 // name with the format port_name@senderId. | |
124 var parts = port.name.split('@'); | |
125 var portName = parts[0]; | |
126 var senderId = parts[1]; | |
127 var ConnectionTypes = remoting.It2MeService.ConnectionTypes; | |
128 if (portName === ConnectionTypes.HELPER_WEBAPP && senderId !== undefined) { | |
129 for (var i = 0; i < this.helpers_.length; i++) { | |
130 var helper = this.helpers_[i]; | |
131 if (helper.instanceId() === senderId) { | |
132 helper.onWebappConnect(port, senderId); | |
133 return; | |
134 } | |
135 } | |
136 } | |
137 throw new Error('No matching hangout connection found for ' + port.name); | |
138 } catch (e) { | |
139 var error = /** @type {Error} */ e; | |
140 console.error(error); | |
141 port.disconnect(); | |
142 } | |
143 }; | |
144 | |
145 /** | |
146 * @param {remoting.It2MeHelperChannel} helper | |
147 */ | |
148 remoting.It2MeService.prototype.onHelperChannelDisconnected = function (helper){ | |
Jamie
2014/08/12 02:24:59
Nit: Space before '{'
Jamie
2014/08/12 02:24:59
Is this a public method? If so, it should be moved
kelvinp
2014/08/12 21:42:41
Done.
| |
149 for (var i = 0; i < this.helpers_.length; i++) { | |
150 if (helper === this.helpers_[i]) { | |
151 this.helpers_.splice(i, 1); | |
152 } | |
153 } | |
154 }; | |
155 | |
156 /** | |
157 * @param {chrome.runtime.Port} port | |
158 */ | |
159 remoting.It2MeService.prototype.handleExternalHelperConnection_ = | |
160 function(port) { | |
161 if (this.helpee_) { | |
162 console.error('An existing helpee connection is in process.'); | |
Jamie
2014/08/12 02:24:59
This error should probably be more prominent. Is a
kelvinp
2014/08/12 21:42:41
The hangout code should guarantee this should neve
| |
163 port.disconnect(); | |
164 } | |
165 | |
166 console.log('Incoming helper connection from Hangout'); | |
167 var helper = new remoting.It2MeHelperChannel( | |
168 this.appLauncher_, port, this.onHelperChannelDisconnected.bind(this)); | |
169 helper.init(); | |
170 this.helpers_.push(helper); | |
171 }; | |
OLD | NEW |