Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(211)

Side by Side Diff: remoting/webapp/background/it2me_helper_channel.js

Issue 468693002: Hangouts remote desktop part III - It2MeService (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 *
8 * It2MeHelperChannel relays messages between Hangouts and Chrome Remote Desktop
9 * (webapp) for the helper (the Hangouts participant who is giving remote
10 * assistance).
11 *
12 * It runs in the background page and contains two chrome.runtime.Port objects,
13 * respresenting connections to the webapp and hangout, respectively.
14 *
15 * Connection is always initiated from Hangouts.
16 *
17 * Hangout It2MeHelperChannel Chrome Remote Desktop
18 * |-----runtime.connect() ------>| |
19 * |------connect message-------->| |
20 * | |-------appLauncher.launch()---->|
21 * | |<------runtime.connect()------- |
22 * | |<-----sessionStateChanged------ |
23 * |<----sessionStateChanged------| |
24 *
25 * Disconnection can be initiated from either side:
26 * 1. In the normal flow initiated from hangout
27 * Hangout It2MeHelperChannel Chrome Remote Desktop
28 * |-----disconnect message------>| |
29 * |<-sessionStateChanged(CLOSED)-| |
30 * | |-----appLauncher.close()------>|
31 *
32 * 2. In the normal flow initiated from webapp
33 * Hangout It2MeHelperChannel Chrome Remote Desktop
34 * | |<-sessionStateChanged(CLOSED)--|
35 * | |<--------port.disconnect()-----|
36 * |<--------port.disconnect()----| |
37 *
38 * 2. If hangout crashes
39 * Hangout It2MeHelperChannel Chrome Remote Desktop
40 * |---------port.disconnect()--->| |
41 * | |--------port.disconnect()----->|
42 * | |------appLauncher.close()----->|
43 *
44 * 3. If webapp crashes
45 * Hangout It2MeHelperChannel Chrome Remote Desktop
46 * | |<-------port.disconnect()------|
47 * |<-sessionStateChanged(FAILED)-| |
48 * |<--------port.disconnect()----| |
49 */
50
51 'use strict';
52
53 /** @suppress {duplicate} */
54 var remoting = remoting || {};
55
56 /**
57 * @param {remoting.AppLauncher} appLauncher
58 * @param {chrome.runtime.Port} hangoutPort Represents an active connection to
59 * Hangouts.
60 * @param {function(remoting.It2MeHelperChannel)} onDisconnectCallback Callback
61 * to notify when the connection is torn down. IT2MeService uses this
62 * callback to dispose of the channel object.
63 * @constructor
64 */
65 remoting.It2MeHelperChannel =
66 function(appLauncher, hangoutPort, onDisconnectCallback) {
67
68 /**
69 * @type {remoting.AppLauncher}
70 * @private
71 */
72 this.appLauncher_ = appLauncher;
73
74 /**
75 * @type {chrome.runtime.Port}
76 * @private
77 */
78 this.hangoutPort_ = hangoutPort;
79
80 /**
81 * @type {chrome.runtime.Port}
82 * @private
83 */
84 this.webappPort_ = null;
85
86 /**
87 * @type {string}
88 * @private
89 */
90 this.instanceId_ = '';
91
92 /**
93 * @type {remoting.ClientSession.State}
94 * @private
95 */
96 this.sessionState_ = remoting.ClientSession.State.CONNECTING;
97
98 /**
99 * @type {?function(remoting.It2MeHelperChannel)}
100 * @private
101 */
102 this.onDisconnectCallback_ = onDisconnectCallback;
103
104 this.onWebappMessageRef_ = this.onWebappMessage_.bind(this);
105 this.onWebappDisconnectRef_ = this.onWebappDisconnect_.bind(this);
106 this.onHangoutMessageRef_ = this.onHangoutMessage_.bind(this);
107 this.onHangoutDisconnectRef_ = this.onHangoutDisconnect_.bind(this);
108 };
109
110 /** @enum {string} */
111 remoting.It2MeHelperChannel.HangoutMessageTypes = {
112 CONNECT: 'connect',
113 DISCONNECT: 'disconnect'
114 };
115
116 /** @enum {string} */
117 remoting.It2MeHelperChannel.WebappMessageTypes = {
118 SESSION_STATE_CHANGED: 'sessionStateChanged'
119 };
120
121 remoting.It2MeHelperChannel.prototype.init = function() {
122 this.hangoutPort_.onMessage.addListener(this.onHangoutMessageRef_);
123 this.hangoutPort_.onDisconnect.addListener(this.onHangoutDisconnectRef_);
124 };
125
126 /** @return {string} */
127 remoting.It2MeHelperChannel.prototype.instanceId = function() {
128 return this.instanceId_;
129 };
130
131 /**
132 * @param {{method:string, data:Object.<string,*>}} message
133 * @return {boolean} whether the message is handled or not.
134 * @private
135 */
136 remoting.It2MeHelperChannel.prototype.onHangoutMessage_ = function(message) {
137 try {
138 var MessageTypes = remoting.It2MeHelperChannel.HangoutMessageTypes;
139 switch (message.method) {
140 case MessageTypes.CONNECT:
141 this.launchWebapp_(message);
142 return true;
143 case MessageTypes.DISCONNECT:
144 this.closeWebapp_(message);
145 return true;
146 }
147 } catch(e) {
148 var error = /** @type {Error} */ e;
149 console.error(error);
150 this.hangoutPort_.postMessage({
151 method: message.method + 'Response',
152 error: error.message
153 });
154 }
155 return false;
156 };
157
158 /**
159 * Disconnect the existing connection to the helpee.
160 *
161 * @param {{method:string, data:Object.<string,*>}} message
162 * @private
163 */
164 remoting.It2MeHelperChannel.prototype.closeWebapp_ =
165 function(message) {
166 // TODO(kelvinp): Closing the v2 app currently doesn't disconnect the IT2me
167 // session (crbug.com/402137), so send an explicit notification to Hangouts.
168 this.sessionState_ = remoting.ClientSession.State.CLOSED;
169 this.hangoutPort_.postMessage({
170 method: 'sessionStateChanged',
171 state: this.sessionState_
172 });
173 this.appLauncher_.close(this.instanceId_);
174 };
175
176 /**
177 * Launches the web app.
178 *
179 * @param {{method:string, data:Object.<string,*>}} message
180 * @private
181 */
182 remoting.It2MeHelperChannel.prototype.launchWebapp_ =
183 function(message) {
184 var accessCode = getStringAttr(message, 'accessCode');
185 if (!accessCode) {
186 throw new Error('Access code is missing');
187 }
188
189 // Launch the webapp.
190 this.appLauncher_.launch({
191 mode: 'hangout',
192 accessCode: accessCode
193 }).then(
194 /**
195 * @this {remoting.It2MeHelperChannel}
196 * @param {string} instanceId
197 */
198 function(instanceId){
199 this.instanceId_ = instanceId;
200 }.bind(this));
201 };
202
203 /**
204 * @private
205 */
206 remoting.It2MeHelperChannel.prototype.onHangoutDisconnect_ = function() {
207 this.appLauncher_.close(this.instanceId_);
208 this.unhookPorts_();
209 };
210
211 /**
212 * @param {chrome.runtime.Port} port The port represents a connection to the
Jamie 2014/08/14 00:25:06 I think you can get rid of "port represents a" for
213 * webapp.
214 * @param {string} id The id of the tab or window that is hosting the webapp.
215 */
216 remoting.It2MeHelperChannel.prototype.onWebappConnect = function(port, id) {
217 base.debug.assert(id === this.instanceId_);
218 base.debug.assert(this.hangoutPort_ !== null);
219
220 // Hook listeners.
221 port.onMessage.addListener(this.onWebappMessageRef_);
222 port.onDisconnect.addListener(this.onWebappDisconnectRef_);
223 this.webappPort_ = port;
224 };
225
226 /** @param {chrome.runtime.Port} port The webapp port. */
227 remoting.It2MeHelperChannel.prototype.onWebappDisconnect_ = function(port) {
228 // If the webapp port got disconnected while the session is still connected,
229 // treat it as an error.
230 var States = remoting.ClientSession.State;
231 if (this.sessionState_ === States.CONNECTING ||
232 this.sessionState_ === States.CONNECTED) {
233 this.sessionState_ = States.FAILED;
234 this.hangoutPort_.postMessage({
235 method: 'sessionStateChanged',
236 state: this.sessionState_
237 });
238 }
239 this.unhookPorts_();
240 };
241
242 /**
243 * @param {{method:string, data:Object.<string,*>}} message
244 * @private
245 */
246 remoting.It2MeHelperChannel.prototype.onWebappMessage_ = function(message) {
247 try {
248 console.log('It2MeHelperChannel id=' + this.instanceId_ +
249 ' incoming message method=' + message.method);
250 var MessageTypes = remoting.It2MeHelperChannel.WebappMessageTypes;
251 switch (message.method) {
252 case MessageTypes.SESSION_STATE_CHANGED:
253 var state = getNumberAttr(message, 'state');
254 this.sessionState_ =
255 /** @type {remoting.ClientSession.State} */ state;
256 this.hangoutPort_.postMessage(message);
257 return true;
258 }
259 throw new Error('Unknown message method=' + message.method);
260 } catch(e) {
261 var error = /** @type {Error} */ e;
262 console.error(error);
263 this.webappPort_.postMessage({
264 method: message.method + 'Response',
265 error: error.message
266 });
267 }
268 return false;
269 };
270
271 remoting.It2MeHelperChannel.prototype.unhookPorts_ = function() {
272 if (this.webappPort_) {
273 this.webappPort_.onMessage.removeListener(this.onWebappMessageRef_);
274 this.webappPort_.onDisconnect.removeListener(this.onWebappDisconnectRef_);
275 this.webappPort_.disconnect();
276 this.webappPort_ = null;
277 }
278
279 if (this.hangoutPort_) {
280 this.hangoutPort_.onMessage.removeListener(this.onHangoutMessageRef_);
281 this.hangoutPort_.onDisconnect.removeListener(this.onHangoutDisconnectRef_);
282 this.hangoutPort_.disconnect();
283 this.hangoutPort_ = null;
284 }
285
286 if (this.onDisconnectCallback_) {
287 this.onDisconnectCallback_(this);
288 this.onDisconnectCallback_ = null;
289 }
290 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698