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 concurrent helper sessions. | |
Jamie
2014/08/13 01:44:53
Add ", 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 */ | |
Jamie
2014/08/13 01:44:53
Type?
kelvinp
2014/08/13 23:44:10
Will be filled on the next CL
| |
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 /** @enum {string} */ | |
43 remoting.It2MeService.ConnectionTypes = { | |
kelvinp
2014/08/13 00:08:48
These names are not global. They only needs to be
Jamie
2014/08/13 01:44:53
Acknowledged.
| |
44 HELPER_HANGOUT: 'it2me.helper.hangout', | |
45 HELPEE_HANGOUT: 'it2me.helpee.hangout', | |
46 HELPER_WEBAPP: 'it2me.helper.webapp' | |
47 }; | |
48 | |
49 /** | |
50 * Starts listening to external connection from Hangouts and the webapp. | |
51 */ | |
52 remoting.It2MeService.prototype.init = function() { | |
53 chrome.runtime.onConnect.addListener(this.onWebappConnectRef_); | |
54 chrome.runtime.onMessageExternal.addListener(this.onMessageExternalRef_); | |
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.onMessageExternal.removeListener( | |
61 this.onMessageExternalRef_); | |
62 chrome.runtime.onConnectExternal.removeListener( | |
63 this.onConnectExternalRef_); | |
64 }; | |
65 | |
66 /** | |
67 * This function is called when a runtime message is received from an external | |
68 * web page (hangout) or extension. | |
69 * | |
70 * @param {{method:string, data:Object.<string,*>}} message | |
71 * @param {chrome.runtime.MessageSender} sender | |
72 * @param {Function} sendResponse | |
Jamie
2014/08/13 01:44:53
s/Function/function/
Ideally, it should have a pr
kelvinp
2014/08/13 23:44:10
Acknowledged.
| |
73 */ | |
74 remoting.It2MeService.prototype.onMessageExternal_ = | |
75 function(message, sender, sendResponse) { | |
76 try { | |
77 var method = message.method; | |
78 var isHandled = false; | |
Jamie
2014/08/13 01:44:53
You're not using this.
kelvinp
2014/08/13 23:44:10
Done.
| |
79 | |
80 if (method == 'hello') { | |
81 // The hello message is used by hangouts to detect whether the app is | |
82 // installed and what features are supported. | |
83 sendResponse({ | |
84 method: 'helloResponse', | |
85 supportedFeatures: ['it2me'] | |
86 }); | |
87 return true; | |
88 } | |
89 throw new Error('Unknown method: ' + method); | |
90 } catch (e) { | |
91 var error = /** @type {Error} */ e; | |
Jamie
2014/08/13 01:44:53
I think you should log this error.
| |
92 sendResponse({ | |
93 method: message.method + 'Response', | |
Jamie
2014/08/13 01:44:53
Does the API guarantee that message is an object?
kelvinp
2014/08/13 23:44:10
Yes, the messaging API requires the message object
| |
94 error: error.message | |
Jamie
2014/08/13 01:44:53
Are you guaranteed that error will be an object wi
kelvinp
2014/08/13 23:44:10
Errors thrown by sendResponse will still have a me
| |
95 }); | |
96 } | |
Jamie
2014/08/13 01:44:53
return false
kelvinp
2014/08/13 23:44:10
Done.
| |
97 }; | |
98 | |
99 /** | |
100 * This function is called when Hangouts connects via chrome.runtime.connect. | |
101 * Only web pages that are white-listed in the manifest are allowed to connect. | |
102 * | |
103 * @param {chrome.runtime.Port} port | |
104 */ | |
105 remoting.It2MeService.prototype.onConnectExternal_ = function(port) { | |
106 var ConnectionTypes = remoting.It2MeService.ConnectionTypes; | |
107 try { | |
108 switch (port.name) { | |
kelvinp
2014/08/13 00:08:48
Only are web-pages that are white-listed in the ma
Jamie
2014/08/13 01:44:53
Acknowledged.
| |
109 case ConnectionTypes.HELPER_HANGOUT: | |
110 this.handleExternalHelperConnection_(port); | |
111 return true; | |
112 default: | |
113 throw new Error('Unsupported port - ' + port.name); | |
114 } | |
115 } catch (e) { | |
116 port.disconnect(); | |
Jamie
2014/08/13 01:44:53
Log the error?
kelvinp
2014/08/13 23:44:10
Done.
| |
117 } | |
Jamie
2014/08/13 01:44:53
return false
kelvinp
2014/08/13 23:44:10
Done.
| |
118 }; | |
119 | |
120 /** | |
121 * @param {chrome.runtime.Port} port | |
122 */ | |
123 remoting.It2MeService.prototype.onWebappConnect_ = function(port) { | |
124 try { | |
125 console.log('Incoming helper connection from webapp.'); | |
126 | |
127 // The senderId (tabId or windowId) of the webapp is embedded in the port | |
128 // name with the format port_name@senderId. | |
129 var parts = port.name.split('@'); | |
130 var portName = parts[0]; | |
131 var senderId = parts[1]; | |
132 var ConnectionTypes = remoting.It2MeService.ConnectionTypes; | |
133 if (portName === ConnectionTypes.HELPER_WEBAPP && senderId !== undefined) { | |
134 for (var i = 0; i < this.helpers_.length; i++) { | |
135 var helper = this.helpers_[i]; | |
136 if (helper.instanceId() === senderId) { | |
137 helper.onWebappConnect(port, senderId); | |
138 return; | |
139 } | |
140 } | |
141 } | |
142 throw new Error('No matching hangout connection found for ' + port.name); | |
143 } catch (e) { | |
144 var error = /** @type {Error} */ e; | |
145 console.error(error); | |
146 port.disconnect(); | |
147 } | |
148 }; | |
149 | |
150 /** | |
151 * @param {remoting.It2MeHelperChannel} helper | |
152 */ | |
153 remoting.It2MeService.prototype.onHelperChannelDisconnected = function(helper) { | |
154 for (var i = 0; i < this.helpers_.length; i++) { | |
155 if (helper === this.helpers_[i]) { | |
156 this.helpers_.splice(i, 1); | |
157 } | |
158 } | |
159 }; | |
160 | |
161 /** | |
162 * @param {chrome.runtime.Port} port | |
163 */ | |
164 remoting.It2MeService.prototype.handleExternalHelperConnection_ = | |
165 function(port) { | |
166 if (this.helpee_) { | |
167 console.error( | |
168 'Cannot start a helper session while a helpee session is in process.'); | |
kelvinp
2014/08/13 00:08:48
Not sure what do you mean by making this error pro
Jamie
2014/08/13 01:44:53
I think I meant it should be surfaced in the UI so
kelvinp
2014/08/13 23:44:10
Since this is called by external code, I think it
| |
169 port.disconnect(); | |
170 } | |
171 | |
172 console.log('Incoming helper connection from Hangouts'); | |
173 var helper = new remoting.It2MeHelperChannel( | |
174 this.appLauncher_, port, this.onHelperChannelDisconnected.bind(this)); | |
175 helper.init(); | |
176 this.helpers_.push(helper); | |
177 }; | |
OLD | NEW |