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

Side by Side Diff: remoting/webapp/me2mom/client_session.js

Issue 8336004: Improve web-app type safety. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 2 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
« no previous file with comments | « no previous file | remoting/webapp/me2mom/debug_log.js » ('j') | remoting/webapp/me2mom/debug_log.js » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @fileoverview 6 * @fileoverview
7 * Session class that handles creation and teardown of a remoting session. 7 * Session class that handles creation and teardown of a remoting session.
8 * 8 *
9 * This abstracts a <embed> element and controls the plugin which does the 9 * This abstracts a <embed> element and controls the plugin which does the
10 * actual remoting work. There should be no UI code inside this class. It 10 * actual remoting work. There should be no UI code inside this class. It
11 * should be purely thought of as a controller of sorts. 11 * should be purely thought of as a controller of sorts.
12 */ 12 */
13 13
14 'use strict'; 14 'use strict';
15 15
16 /** @suppress {duplicate} */ 16 /** @suppress {duplicate} */
17 var remoting = remoting || {}; 17 var remoting = remoting || {};
18 18
19 (function() {
Jamie 2011/10/18 00:19:27 JSCompiler doesn't recognise types inside anonymou
simonmorris 2011/10/18 00:55:36 OK.
20 /** 19 /**
21 * @param {string} hostJid The jid of the host to connect to. 20 * @param {string} hostJid The jid of the host to connect to.
22 * @param {string} hostPublicKey The base64 encoded version of the host's 21 * @param {string} hostPublicKey The base64 encoded version of the host's
23 * public key. 22 * public key.
24 * @param {string} accessCode The access code for the IT2Me connection. 23 * @param {string} accessCode The access code for the IT2Me connection.
25 * @param {string} email The username for the talk network. 24 * @param {string} email The username for the talk network.
26 * @param {function(remoting.ClientSession.State):void} onStateChange 25 * @param {function(remoting.ClientSession.State):void} onStateChange
27 * The callback to invoke when the session changes state. This callback 26 * The callback to invoke when the session changes state. This callback
28 * occurs after the state changes and is passed the previous state; the 27 * occurs after the state changes and is passed the previous state; the
29 * new state is accessible via ClientSession's |state| property. 28 * new state is accessible via ClientSession's |state| property.
30 * @constructor 29 * @constructor
31 */ 30 */
32 remoting.ClientSession = function(hostJid, hostPublicKey, accessCode, email, 31 remoting.ClientSession = function(hostJid, hostPublicKey, accessCode, email,
33 onStateChange) { 32 onStateChange) {
34 this.state = remoting.ClientSession.State.CREATED; 33 this.state = remoting.ClientSession.State.CREATED;
35 34
36 this.hostJid = hostJid; 35 this.hostJid = hostJid;
37 this.hostPublicKey = hostPublicKey; 36 this.hostPublicKey = hostPublicKey;
38 this.accessCode = accessCode; 37 this.accessCode = accessCode;
39 this.email = email; 38 this.email = email;
40 this.clientJid = ''; 39 this.clientJid = '';
40 this.sessionId = '';
41 /** @type {remoting.ViewerPlugin} */ this.plugin = null;
42
41 this.onStateChange = onStateChange; 43 this.onStateChange = onStateChange;
42 }; 44 };
43 45
44 /** @enum {number} */ 46 /** @enum {number} */
45 remoting.ClientSession.State = { 47 remoting.ClientSession.State = {
46 UNKNOWN: 0, 48 UNKNOWN: 0,
47 CREATED: 1, 49 CREATED: 1,
48 BAD_PLUGIN_VERSION: 2, 50 BAD_PLUGIN_VERSION: 2,
49 UNKNOWN_PLUGIN_ERROR: 3, 51 UNKNOWN_PLUGIN_ERROR: 3,
50 CONNECTING: 4, 52 CONNECTING: 4,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 /** 112 /**
111 * The id of the client plugin 113 * The id of the client plugin
112 * 114 *
113 * @const 115 * @const
114 */ 116 */
115 remoting.ClientSession.prototype.PLUGIN_ID = 'session-client-plugin'; 117 remoting.ClientSession.prototype.PLUGIN_ID = 'session-client-plugin';
116 118
117 /** 119 /**
118 * Callback to invoke when the state is changed. 120 * Callback to invoke when the state is changed.
119 * 121 *
120 * @type {function(remoting.ClientSession.State):void} 122 * @param {remoting.ClientSession.State} state The previous state.
121 */ 123 */
122 remoting.ClientSession.prototype.onStateChange = function(state) { }; 124 remoting.ClientSession.prototype.onStateChange = function(state) { };
123 125
124 /** 126 /**
125 * Adds <embed> element to |container| and readies the sesion object. 127 * Adds <embed> element to |container| and readies the sesion object.
126 * 128 *
127 * @param {Element} container The element to add the plugin to. 129 * @param {Element} container The element to add the plugin to.
128 * @param {string} oauth2AccessToken A valid OAuth2 access token. 130 * @param {string} oauth2AccessToken A valid OAuth2 access token.
129 * @return {void} Nothing. 131 * @return {void} Nothing.
130 */ 132 */
131 remoting.ClientSession.prototype.createPluginAndConnect = 133 remoting.ClientSession.prototype.createPluginAndConnect =
132 function(container, oauth2AccessToken) { 134 function(container, oauth2AccessToken) {
133 this.plugin = /** @type {remoting.ViewerPlugin} */ 135 this.plugin = /** @type {remoting.ViewerPlugin} */
134 document.createElement('embed'); 136 document.createElement('embed');
135 this.plugin.id = this.PLUGIN_ID; 137 this.plugin.id = this.PLUGIN_ID;
136 this.plugin.src = 'about://none'; 138 this.plugin.src = 'about://none';
137 this.plugin.type = 'pepper-application/x-chromoting'; 139 this.plugin.type = 'pepper-application/x-chromoting';
138 this.plugin.width = 0; 140 this.plugin.width = 0;
139 this.plugin.height = 0; 141 this.plugin.height = 0;
140 container.appendChild(this.plugin); 142 container.appendChild(this.plugin);
141 143
142 if (!this.isPluginVersionSupported_(this.plugin)) { 144 if (!this.isPluginVersionSupported_(this.plugin)) {
143 // TODO(ajwong): Remove from parent. 145 // TODO(ajwong): Remove from parent.
144 delete this.plugin; 146 delete this.plugin;
145 this.setState_(remoting.ClientSession.State.BAD_PLUGIN_VERSION); 147 this.setState_(remoting.ClientSession.State.BAD_PLUGIN_VERSION);
146 return; 148 return;
147 } 149 }
148 150
149 var that = this; 151 /** @type {remoting.ClientSession} */ var that = this;
Jamie 2011/10/18 00:19:27 I don't know why the compiler can't infer the type
simonmorris 2011/10/18 00:55:36 Probably because |this| is a keyword, not a variab
simonmorris 2011/10/18 00:55:36 No newline between "...*/" and "var ..."?
Jamie 2011/10/18 01:42:01 Good point about the callback behaviour. I'd forgo
simonmorris 2011/10/18 15:26:02 OK.
152 /** @param {string} msg The IQ stanza to send. */
150 this.plugin.sendIq = function(msg) { that.sendIq_(msg); }; 153 this.plugin.sendIq = function(msg) { that.sendIq_(msg); };
154 /** @param {string} msg The message to log. */
151 this.plugin.debugInfo = function(msg) { 155 this.plugin.debugInfo = function(msg) {
152 remoting.debug.log('plugin: ' + msg); 156 remoting.debug.log('plugin: ' + msg);
153 }; 157 };
154 158
155 // TODO(ajwong): Is it even worth having this class handle these events? 159 // TODO(ajwong): Is it even worth having this class handle these events?
156 // Or would it be better to just allow users to pass in their own handlers 160 // Or would it be better to just allow users to pass in their own handlers
157 // and leave these blank by default? 161 // and leave these blank by default?
158 this.plugin.connectionInfoUpdate = function() { 162 this.plugin.connectionInfoUpdate = function() {
159 that.connectionInfoUpdateCallback(); 163 that.connectionInfoUpdateCallback();
160 }; 164 };
(...skipping 12 matching lines...) Expand all
173 }; 177 };
174 178
175 /** 179 /**
176 * Deletes the <embed> element from the container, without sending a 180 * Deletes the <embed> element from the container, without sending a
177 * session_terminate request. This is to be called when the session was 181 * session_terminate request. This is to be called when the session was
178 * disconnected by the Host. 182 * disconnected by the Host.
179 * 183 *
180 * @return {void} Nothing. 184 * @return {void} Nothing.
181 */ 185 */
182 remoting.ClientSession.prototype.removePlugin = function() { 186 remoting.ClientSession.prototype.removePlugin = function() {
183 var plugin = document.getElementById(this.PLUGIN_ID); 187 if (this.plugin) {
Jamie 2011/10/18 00:19:27 We've stored the plugin already--not sure why we w
simonmorris 2011/10/18 00:55:36 Are you certain |this| is always what you think it
Jamie 2011/10/18 01:42:01 Previously the function referred to both this.plug
simonmorris 2011/10/18 15:26:02 Right - there's a |this.plugin| in the previous ve
184 if (plugin) {
185 var parentNode = this.plugin.parentNode; 188 var parentNode = this.plugin.parentNode;
186 parentNode.removeChild(plugin); 189 parentNode.removeChild(this.plugin);
187 plugin = null; 190 this.plugin = null;
188 } 191 }
189 } 192 };
190 193
191 /** 194 /**
192 * Deletes the <embed> element from the container and disconnects. 195 * Deletes the <embed> element from the container and disconnects.
193 * 196 *
194 * @return {void} Nothing. 197 * @return {void} Nothing.
195 */ 198 */
196 remoting.ClientSession.prototype.disconnect = function() { 199 remoting.ClientSession.prototype.disconnect = function() {
197 if (remoting.wcs) { 200 if (remoting.wcs) {
198 remoting.wcs.setOnIq(function(stanza) {}); 201 remoting.wcs.setOnIq(function(stanza) {});
199 } 202 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 * @private 262 * @private
260 * @param {string} oauth2AccessToken A valid OAuth2 access token. 263 * @param {string} oauth2AccessToken A valid OAuth2 access token.
261 * @return {void} Nothing. 264 * @return {void} Nothing.
262 */ 265 */
263 remoting.ClientSession.prototype.connectPluginToWcs_ = 266 remoting.ClientSession.prototype.connectPluginToWcs_ =
264 function(oauth2AccessToken) { 267 function(oauth2AccessToken) {
265 this.clientJid = remoting.wcs.getJid(); 268 this.clientJid = remoting.wcs.getJid();
266 if (this.clientJid == '') { 269 if (this.clientJid == '') {
267 remoting.debug.log('Tried to connect without a full JID.'); 270 remoting.debug.log('Tried to connect without a full JID.');
268 } 271 }
269 var that = this; 272 /** @type {remoting.ClientSession} */ var that = this;
270 remoting.wcs.setOnIq(function(stanza) { 273 /** @param {string} stanza The IQ stanza received. */
271 remoting.debug.log('Receiving Iq: ' + stanza); 274 var onIq = function(stanza) {
Jamie 2011/10/18 00:19:27 It's fiddly to add type information to anonymous f
simonmorris 2011/10/18 00:55:36 OK.
272 that.plugin.onIq(stanza); 275 remoting.debug.log('Receiving Iq: ' + stanza);
273 }); 276 that.plugin.onIq(stanza);
277 }
278 remoting.wcs.setOnIq(onIq);
274 that.plugin.connect(this.hostJid, this.hostPublicKey, this.clientJid, 279 that.plugin.connect(this.hostJid, this.hostPublicKey, this.clientJid,
275 this.accessCode); 280 this.accessCode);
276 }; 281 };
277 282
278 /** 283 /**
279 * Callback that the plugin invokes to indicate that the connection 284 * Callback that the plugin invokes to indicate that the connection
280 * status has changed. 285 * status has changed.
281 */ 286 */
282 remoting.ClientSession.prototype.connectionInfoUpdateCallback = function() { 287 remoting.ClientSession.prototype.connectionInfoUpdateCallback = function() {
283 var state = this.plugin.status; 288 var state = this.plugin.status;
(...skipping 11 matching lines...) Expand all
295 } else if (state == this.plugin.STATUS_CLOSED) { 300 } else if (state == this.plugin.STATUS_CLOSED) {
296 this.setState_(remoting.ClientSession.State.CLOSED); 301 this.setState_(remoting.ClientSession.State.CLOSED);
297 } else if (state == this.plugin.STATUS_FAILED) { 302 } else if (state == this.plugin.STATUS_FAILED) {
298 var error = this.plugin.error; 303 var error = this.plugin.error;
299 if (error == this.plugin.ERROR_HOST_IS_OFFLINE) { 304 if (error == this.plugin.ERROR_HOST_IS_OFFLINE) {
300 error = remoting.ClientSession.ConnectionError.HOST_IS_OFFLINE; 305 error = remoting.ClientSession.ConnectionError.HOST_IS_OFFLINE;
301 } else if (error == this.plugin.ERROR_SESSION_REJECTED) { 306 } else if (error == this.plugin.ERROR_SESSION_REJECTED) {
302 error = remoting.ClientSession.ConnectionError.SESSION_REJECTED; 307 error = remoting.ClientSession.ConnectionError.SESSION_REJECTED;
303 } else if (error == this.plugin.ERROR_INCOMPATIBLE_PROTOCOL) { 308 } else if (error == this.plugin.ERROR_INCOMPATIBLE_PROTOCOL) {
304 error = remoting.ClientSession.ConnectionError.INCOMPATIBLE_PROTOCOL; 309 error = remoting.ClientSession.ConnectionError.INCOMPATIBLE_PROTOCOL;
305 } else if (error == this.plugin.NETWORK_FAILURE) { 310 } else if (error == this.plugin.ERROR_NETWORK_FAILURE) {
Jamie 2011/10/18 00:19:27 A genuine error! My efforts were not wasted after
306 error = remoting.ClientSession.ConnectionError.NETWORK_FAILURE; 311 error = remoting.ClientSession.ConnectionError.NETWORK_FAILURE;
307 } else { 312 } else {
308 error = remoting.ClientSession.ConnectionError.OTHER; 313 error = remoting.ClientSession.ConnectionError.OTHER;
309 } 314 }
310 this.setState_(remoting.ClientSession.State.CONNECTION_FAILED); 315 this.setState_(remoting.ClientSession.State.CONNECTION_FAILED);
311 } 316 }
312 }; 317 };
313 318
314 /** 319 /**
315 * @private 320 * @private
316 * @param {remoting.ClientSession.State} state The new state for the session. 321 * @param {remoting.ClientSession.State} state The new state for the session.
317 * @return {void} Nothing. 322 * @return {void} Nothing.
318 */ 323 */
319 remoting.ClientSession.prototype.setState_ = function(state) { 324 remoting.ClientSession.prototype.setState_ = function(state) {
320 var oldState = this.state; 325 var oldState = this.state;
321 this.state = state; 326 this.state = state;
322 if (this.onStateChange) { 327 if (this.onStateChange) {
323 this.onStateChange(oldState); 328 this.onStateChange(oldState);
324 } 329 }
325 }; 330 };
326 331
327 /** 332 /**
328 * This is a callback that gets called when the window is resized. 333 * This is a callback that gets called when the window is resized.
329 * 334 *
330 * @private
Jamie 2011/10/18 00:19:27 This is called externally.
331 * @return {void} Nothing. 335 * @return {void} Nothing.
332 */ 336 */
333 remoting.ClientSession.prototype.onWindowSizeChanged = function() { 337 remoting.ClientSession.prototype.onWindowSizeChanged = function() {
334 remoting.debug.log('window size changed: ' + 338 remoting.debug.log('window size changed: ' +
335 window.innerWidth + 'x' + 339 window.innerWidth + 'x' +
336 window.innerHeight); 340 window.innerHeight);
337 this.updateDimensions(); 341 this.updateDimensions();
338 }; 342 };
339 343
340 /** 344 /**
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 // Resize the plugin if necessary. 379 // Resize the plugin if necessary.
376 this.plugin.width = this.plugin.desktopWidth * scale; 380 this.plugin.width = this.plugin.desktopWidth * scale;
377 this.plugin.height = this.plugin.desktopHeight * scale; 381 this.plugin.height = this.plugin.desktopHeight * scale;
378 382
379 // Position the container. 383 // Position the container.
380 // TODO(wez): We should take into account scrollbars when positioning. 384 // TODO(wez): We should take into account scrollbars when positioning.
381 var parentNode = this.plugin.parentNode; 385 var parentNode = this.plugin.parentNode;
382 if (this.plugin.width < windowWidth) 386 if (this.plugin.width < windowWidth)
383 parentNode.style.left = (windowWidth - this.plugin.width) / 2 + 'px'; 387 parentNode.style.left = (windowWidth - this.plugin.width) / 2 + 'px';
384 else 388 else
385 parentNode.style.left = 0; 389 parentNode.style.left = '0';
Jamie 2011/10/18 00:19:27 Setting this to 0 works fine, but the property sho
386 if (this.plugin.height < windowHeight) 390 if (this.plugin.height < windowHeight)
387 parentNode.style.top = (windowHeight - this.plugin.height) / 2 + 'px'; 391 parentNode.style.top = (windowHeight - this.plugin.height) / 2 + 'px';
388 else 392 else
389 parentNode.style.top = 0; 393 parentNode.style.top = '0';
390 394
391 remoting.debug.log('plugin dimensions: ' + 395 remoting.debug.log('plugin dimensions: ' +
392 parentNode.style.left + ',' + 396 parentNode.style.left + ',' +
393 parentNode.style.top + '-' + 397 parentNode.style.top + '-' +
394 this.plugin.width + 'x' + this.plugin.height + '.'); 398 this.plugin.width + 'x' + this.plugin.height + '.');
395 this.plugin.setScaleToFit(remoting.scaleToFit); 399 this.plugin.setScaleToFit(remoting.scaleToFit);
396 }; 400 };
397 401
398 /** 402 /**
399 * Returns an associative array with a set of stats for this connection. 403 * Returns an associative array with a set of stats for this connection.
400 * 404 *
401 * @return {Object} The connection statistics. 405 * @return {Object.<string, number>} The connection statistics.
402 */ 406 */
403 remoting.ClientSession.prototype.stats = function() { 407 remoting.ClientSession.prototype.stats = function() {
404 return { 408 return {
405 'video_bandwidth': this.plugin.videoBandwidth, 409 'video_bandwidth': this.plugin.videoBandwidth,
406 'capture_latency': this.plugin.videoCaptureLatency, 410 'capture_latency': this.plugin.videoCaptureLatency,
407 'encode_latency': this.plugin.videoEncodeLatency, 411 'encode_latency': this.plugin.videoEncodeLatency,
408 'decode_latency': this.plugin.videoDecodeLatency, 412 'decode_latency': this.plugin.videoDecodeLatency,
409 'render_latency': this.plugin.videoRenderLatency, 413 'render_latency': this.plugin.videoRenderLatency,
410 'roundtrip_latency': this.plugin.roundTripLatency 414 'roundtrip_latency': this.plugin.roundTripLatency
411 }; 415 };
412 }; 416 };
413
414 }());
OLDNEW
« no previous file with comments | « no previous file | remoting/webapp/me2mom/debug_log.js » ('j') | remoting/webapp/me2mom/debug_log.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698