summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-15 04:04:20 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-15 04:04:20 +0000
commita11c5b6f8af29722d014f94d86ac0e4559b1f8f4 (patch)
tree5449c0327acf90f48bc0d3a843413fd0400314df
parentd0dc9d004602783b07b0b9686837d3318b111236 (diff)
downloadchromium_src-a11c5b6f8af29722d014f94d86ac0e4559b1f8f4.zip
chromium_src-a11c5b6f8af29722d014f94d86ac0e4559b1f8f4.tar.gz
chromium_src-a11c5b6f8af29722d014f94d86ac0e4559b1f8f4.tar.bz2
Make remoting.ClientPlugin an abstract interface.
Now remoting.ClientPlugin is an abstract interface for the plugin intgration code. ClientPluginV1 implements the current version of the plugin interface. Messaging-based interface will be added in a separate CL. BUG=88353 Review URL: http://codereview.chromium.org/9395020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@122027 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--remoting/remoting.gyp1
-rw-r--r--remoting/webapp/choice.html2
-rw-r--r--remoting/webapp/client_plugin.js221
-rw-r--r--remoting/webapp/client_plugin_v1.js221
-rw-r--r--remoting/webapp/client_screen.js2
-rw-r--r--remoting/webapp/client_session.js86
-rw-r--r--remoting/webapp/debug_log.js72
-rw-r--r--remoting/webapp/log_to_server.js2
-rw-r--r--remoting/webapp/server_log_entry.js2
-rw-r--r--remoting/webapp/viewer_plugin_proto.js3
10 files changed, 376 insertions, 236 deletions
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index e14a3c4..20cb1f3 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -110,6 +110,7 @@
'webapp/choice.css',
'webapp/choice.html',
'webapp/client_plugin.js',
+ 'webapp/client_plugin_v1.js',
'webapp/client_screen.js',
'webapp/client_session.js',
'webapp/cs_oauth2_trampoline.js',
diff --git a/remoting/webapp/choice.html b/remoting/webapp/choice.html
index 3f066c5..e0289f9 100644
--- a/remoting/webapp/choice.html
+++ b/remoting/webapp/choice.html
@@ -15,8 +15,8 @@ found in the LICENSE file.
<link rel="stylesheet" href="main.css" />
<link rel="stylesheet" href="choice.css" />
<link rel="stylesheet" href="toolbar.css" />
- <script src="client_plugin.js"></script>
<script src="ask_pin_dialog.js"></script>
+ <script src="client_plugin_v1.js"></script>
<script src="client_screen.js"></script>
<script src="client_session.js"></script>
<script src="daemon_plugin.js"></script>
diff --git a/remoting/webapp/client_plugin.js b/remoting/webapp/client_plugin.js
index 9430115..23be145 100644
--- a/remoting/webapp/client_plugin.js
+++ b/remoting/webapp/client_plugin.js
@@ -2,181 +2,72 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-/**
- * @fileoverview
- * Class that wraps low-level details of interacting with the client plugin.
- *
- * This abstracts a <embed> element and controls the plugin which does
- * the actual remoting work. It also handles differences between
- * client plugins versions when it is necessary.
- */
-
-'use strict';
-
/** @suppress {duplicate} */
var remoting = remoting || {};
/**
- * @param {Element} container The element to add the plugin to.
- * @param {string} id Id to use for the plugin element .
- * @constructor
- */
-remoting.ClientPlugin = function(container, id) {
- this.plugin = /** @type {remoting.ViewerPlugin} */
- document.createElement('embed');
-
- this.plugin.id = id;
- this.plugin.src = 'about://none';
- this.plugin.type = 'application/vnd.chromium.remoting-viewer';
- this.plugin.width = 0;
- this.plugin.height = 0;
- this.plugin.tabIndex = 0; // Required, otherwise focus() doesn't work.
- container.appendChild(this.plugin);
-
- this.desktopWidth = 0;
- this.desktopHeight = 0;
-
- /** @param {string} iq The Iq stanza received from the host. */
- this.onOutgoingIqHandler = function (iq) {};
- /** @param {string} message Log message. */
- this.onDebugMessageHandler = function (message) {};
- /**
- * @param {number} status The plugin status.
- * @param {number} error The plugin error status, if any.
- */
- this.onConnectionStatusUpdateHandler = function(status, error) {};
- this.onDesktopSizeUpdateHandler = function () {};
-
- // Connect Event Handlers
-
- /** @type {remoting.ClientPlugin} */
- var that = this;
-
- /** @param {string} iq The IQ stanza to send. */
- this.plugin.sendIq = function(iq) { that.onSendIq_(iq); };
-
- /** @param {string} msg The message to log. */
- this.plugin.debugInfo = function(msg) { that.onDebugInfo_(msg); };
-
- /**
- * @param {number} status The plugin status.
- * @param {number} error The plugin error status, if any.
- */
- this.plugin.connectionInfoUpdate = function(status, error) {
- that.onConnectionInfoUpdate_(status, error);
- };
- this.plugin.desktopSizeUpdate = function() { that.onDesktopSizeUpdate_(); };
-};
-
-/** @param {string} iq The Iq stanza received from the host. */
-remoting.ClientPlugin.prototype.onSendIq_ = function(iq) {
- this.onOutgoingIqHandler(iq);
-}
-
- /** @param {string} message The IQ stanza to send. */
-remoting.ClientPlugin.prototype.onDebugInfo_ = function(message) {
- this.onDebugMessageHandler(message);
-}
-
-/**
- * @param {number} status The plugin status.
- * @param {number} error The plugin error status, if any.
+ * Interface used for ClientPlugin objects.
+ * @interface
*/
-remoting.ClientPlugin.prototype.onConnectionInfoUpdate_=
- function(status, error) {
- // Old plugins didn't pass the status and error values, so get
- // them directly. Note that there is a race condition inherent in
- // this approach.
- if (typeof(status) == 'undefined')
- status = this.plugin.status;
- if (typeof(error) == 'undefined')
- error = this.plugin.error;
- this.onConnectionStatusUpdateHandler(status, error);
+remoting.ClientPlugin = function() {
};
-remoting.ClientPlugin.prototype.onDesktopSizeUpdate_ = function() {
- this.desktopWidth = this.plugin.desktopWidth;
- this.desktopHeight = this.plugin.desktopHeight;
- this.onDesktopSizeUpdateHandler();
-}
+/** @type {number} Desktop width */
+remoting.ClientPlugin.prototype.desktopWidth;
+/** @type {number} Desktop height */
+remoting.ClientPlugin.prototype.desktopHeight;
-/**
- * Chromoting session API version (for this javascript).
- * This is compared with the plugin API version to verify that they are
- * compatible.
- *
- * @const
- * @private
- */
-remoting.ClientPlugin.prototype.API_VERSION_ = 4;
+/** @type {function(string): void} Outgoing signaling message callback. */
+remoting.ClientPlugin.prototype.onOutgoingIqHandler;
+/** @type {function(string): void} Debug messages callback. */
+remoting.ClientPlugin.prototype.onDebugMessageHandler;
+/** @type {function(number, number): void} State change callback. */
+remoting.ClientPlugin.prototype.onConnectionStatusUpdateHandler;
+/** @type {function(): void} Desktop size change callback. */
+remoting.ClientPlugin.prototype.onDesktopSizeUpdateHandler;
/**
- * The oldest API version that we support.
- * This will differ from the |API_VERSION_| if we maintain backward
- * compatibility with older API versions.
+ * Initializes the plugin asynchronously and calls specified function
+ * when done.
*
- * @const
- * @private
- */
-remoting.ClientPlugin.prototype.API_MIN_VERSION_ = 2;
-
-
-/**
- * Deletes the plugin.
+ * @param {function(boolean): void} onDone Function to be called when
+ * the plugin is initialized. Parameter is set to true when the plugin
+ * is loaded successfully.
*/
-remoting.ClientPlugin.prototype.cleanup = function() {
- this.plugin.parentNode.removeChild(this.plugin);
-};
+remoting.ClientPlugin.prototype.initialize = function(onDone) {};
/**
- * @return {HTMLElement} HTML element that correspods to the plugin.
+ * @return {boolean} True if the plugin and web-app versions are compatible.
*/
-remoting.ClientPlugin.prototype.element = function() {
- return this.plugin;
-};
+remoting.ClientPlugin.prototype.isSupportedVersion = function() {};
/**
- * @return {boolean} True if the plugin was loaded succesfully.
+ * @return {Element} HTML element that correspods to the plugin.
*/
-remoting.ClientPlugin.prototype.isLoaded = function() {
- return typeof this.plugin.connect === 'function';
-}
+remoting.ClientPlugin.prototype.element = function() {};
/**
- * @return {boolean} True if the plugin and web-app versions are compatible.
+ * Deletes the plugin.
*/
-remoting.ClientPlugin.prototype.isSupportedVersion = function() {
- return this.API_VERSION_ >= this.plugin.apiMinVersion &&
- this.plugin.apiVersion >= this.API_MIN_VERSION_;
-};
+remoting.ClientPlugin.prototype.cleanup = function() {};
/**
* @return {boolean} True if the plugin supports high-quality scaling.
*/
-remoting.ClientPlugin.prototype.isHiQualityScalingSupported = function() {
- return this.plugin.apiVersion >= 3;
-};
+remoting.ClientPlugin.prototype.isHiQualityScalingSupported =
+ function() {};
/**
+ * Must be called for each incoming stanza received from the host.
* @param {string} iq Incoming IQ stanza.
*/
-remoting.ClientPlugin.prototype.onIncomingIq = function(iq) {
- if (this.plugin && this.plugin.onIq) {
- this.plugin.onIq(iq);
- } else {
- // plugin.onIq may not be set after the plugin has been shut
- // down. Particularly this happens when we receive response to
- // session-terminate stanza.
- remoting.debug.log(
- 'plugin.onIq is not set so dropping incoming message.');
- }
-};
+remoting.ClientPlugin.prototype.onIncomingIq = function(iq) {};
/**
* @param {string} hostJid The jid of the host to connect to.
* @param {string} hostPublicKey The base64 encoded version of the host's
* public key.
- * @param {string} clientJid Local jid.
+ * @param {string} localJid Local jid.
* @param {string} sharedSecret The access code for IT2Me or the PIN
* for Me2Me.
* @param {string} authenticationMethods Comma-separated list of
@@ -185,55 +76,23 @@ remoting.ClientPlugin.prototype.onIncomingIq = function(iq) {
* authentication hashes.
*/
remoting.ClientPlugin.prototype.connect = function(
- hostJid, hostPublicKey, clientJid, sharedSecret,
- authenticationMethods, authenticationTag) {
- if (this.plugin.apiVersion < 4) {
- // Client plugin versions prior to 4 didn't support the last two
- // parameters.
- this.plugin.connect(hostJid, hostPublicKey, clientJid, sharedSecret);
- } else {
- this.plugin.connect(hostJid, hostPublicKey, clientJid, sharedSecret,
- authenticationMethods, authenticationTag);
- }
-}
+ hostJid, hostPublicKey, localJid, sharedSecret,
+ authenticationMethods, authenticationTag) {};
/**
* @param {boolean} scaleToFit True if scale-to-fit should be enabled.
*/
-remoting.ClientPlugin.prototype.setScaleToFit = function(scaleToFit) {
- // scaleToFit() will be removed in future versions of the plugin.
- if (!!this.plugin && typeof this.plugin.setScaleToFit === 'function')
- this.plugin.setScaleToFit(scaleToFit);
-};
-
+remoting.ClientPlugin.prototype.setScaleToFit =
+ function(scaleToFit) {};
/**
- *
+ * Release all currently pressed keys.
*/
-remoting.ClientPlugin.prototype.releaseAllKeys = function() {
- this.plugin.releaseAllKeys();
-};
+remoting.ClientPlugin.prototype.releaseAllKeys = function() {};
/**
* Returns an associative array with a set of stats for this connection.
*
- * @return {Object.<string, number>} The connection statistics.
+ * @return {remoting.ClientSession.PerfStats} The connection statistics.
*/
-remoting.ClientPlugin.prototype.getPerfStats = function() {
- var dict = {};
- dict[remoting.ClientSession.STATS_KEY_VIDEO_BANDWIDTH] =
- this.plugin.videoBandwidth;
- dict[remoting.ClientSession.STATS_KEY_VIDEO_FRAME_RATE] =
- this.plugin.videoFrameRate;
- dict[remoting.ClientSession.STATS_KEY_CAPTURE_LATENCY] =
- this.plugin.videoCaptureLatency;
- dict[remoting.ClientSession.STATS_KEY_ENCODE_LATENCY] =
- this.plugin.videoEncodeLatency;
- dict[remoting.ClientSession.STATS_KEY_DECODE_LATENCY] =
- this.plugin.videoDecodeLatency;
- dict[remoting.ClientSession.STATS_KEY_RENDER_LATENCY] =
- this.plugin.videoRenderLatency;
- dict[remoting.ClientSession.STATS_KEY_ROUNDTRIP_LATENCY] =
- this.plugin.roundTripLatency;
- return dict;
-};
+remoting.ClientPlugin.prototype.getPerfStats = function() {};
diff --git a/remoting/webapp/client_plugin_v1.js b/remoting/webapp/client_plugin_v1.js
new file mode 100644
index 0000000..c4785e2
--- /dev/null
+++ b/remoting/webapp/client_plugin_v1.js
@@ -0,0 +1,221 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview
+ * Class that wraps low-level details of interacting with the client plugin.
+ *
+ * This abstracts a <embed> element and controls the plugin which does
+ * the actual remoting work. It also handles differences between
+ * client plugins versions when it is necessary.
+ */
+
+'use strict';
+
+/** @suppress {duplicate} */
+var remoting = remoting || {};
+
+/**
+ * @param {remoting.ViewerPlugin} plugin The plugin embed element.
+ * @constructor
+ * @implements {remoting.ClientPlugin}
+ */
+remoting.ClientPluginV1 = function(plugin) {
+ this.plugin = plugin;
+
+ this.desktopWidth = 0;
+ this.desktopHeight = 0;
+
+ /** @param {string} iq The Iq stanza received from the host. */
+ this.onOutgoingIqHandler = function (iq) {};
+ /** @param {string} message Log message. */
+ this.onDebugMessageHandler = function (message) {};
+ /**
+ * @param {number} status The plugin status.
+ * @param {number} error The plugin error status, if any.
+ */
+ this.onConnectionStatusUpdateHandler = function(status, error) {};
+ this.onDesktopSizeUpdateHandler = function () {};
+
+ // Connect event handlers.
+
+ /** @type {remoting.ClientPluginV1} */
+ var that = this;
+
+ /** @param {string} iq The IQ stanza to send. */
+ this.plugin.sendIq = function(iq) { that.onSendIq_(iq); };
+
+ /** @param {string} msg The message to log. */
+ this.plugin.debugInfo = function(msg) { that.onDebugInfo_(msg); };
+
+ /**
+ * @param {number} status The plugin status.
+ * @param {number} error The plugin error status, if any.
+ */
+ this.plugin.connectionInfoUpdate = function(status, error) {
+ that.onConnectionInfoUpdate_(status, error);
+ };
+ this.plugin.desktopSizeUpdate = function() { that.onDesktopSizeUpdate_(); };
+};
+
+/**
+ * Chromoting session API version (for this javascript).
+ * This is compared with the plugin API version to verify that they are
+ * compatible.
+ *
+ * @const
+ * @private
+ */
+remoting.ClientPluginV1.prototype.API_VERSION_ = 4;
+
+/**
+ * The oldest API version that we support.
+ * This will differ from the |API_VERSION_| if we maintain backward
+ * compatibility with older API versions.
+ *
+ * @const
+ * @private
+ */
+remoting.ClientPluginV1.prototype.API_MIN_VERSION_ = 2;
+
+/** @param {string} iq The Iq stanza received from the host. */
+remoting.ClientPluginV1.prototype.onSendIq_ = function(iq) {
+ this.onOutgoingIqHandler(iq);
+}
+
+ /** @param {string} message The IQ stanza to send. */
+remoting.ClientPluginV1.prototype.onDebugInfo_ = function(message) {
+ this.onDebugMessageHandler(message);
+}
+
+/**
+ * @param {number} status The plugin status.
+ * @param {number} error The plugin error status, if any.
+ */
+remoting.ClientPluginV1.prototype.onConnectionInfoUpdate_=
+ function(status, error) {
+ // Old plugins didn't pass the status and error values, so get
+ // them directly. Note that there is a race condition inherent in
+ // this approach.
+ if (typeof(status) == 'undefined')
+ status = this.plugin.status;
+ if (typeof(error) == 'undefined')
+ error = this.plugin.error;
+ this.onConnectionStatusUpdateHandler(status, error);
+};
+
+remoting.ClientPluginV1.prototype.onDesktopSizeUpdate_ = function() {
+ this.desktopWidth = this.plugin.desktopWidth;
+ this.desktopHeight = this.plugin.desktopHeight;
+ this.onDesktopSizeUpdateHandler();
+}
+
+/**
+ * Deletes the plugin.
+ */
+remoting.ClientPluginV1.prototype.cleanup = function() {
+ this.plugin.parentNode.removeChild(this.plugin);
+};
+
+/**
+ * @return {Element} HTML element that correspods to the plugin.
+ */
+remoting.ClientPluginV1.prototype.element = function() {
+ return this.plugin;
+};
+
+/**
+ * @param {function(boolean): void} onDone
+ */
+remoting.ClientPluginV1.prototype.initialize = function(onDone) {
+ onDone(typeof this.plugin.connect === 'function');
+};
+
+/**
+ * @return {boolean} True if the plugin and web-app versions are compatible.
+ */
+remoting.ClientPluginV1.prototype.isSupportedVersion = function() {
+ return this.API_VERSION_ >= this.plugin.apiMinVersion &&
+ this.plugin.apiVersion >= this.API_MIN_VERSION_;
+};
+
+/**
+ * @return {boolean} True if the plugin supports high-quality scaling.
+ */
+remoting.ClientPluginV1.prototype.isHiQualityScalingSupported = function() {
+ return this.plugin.apiVersion >= 3;
+};
+
+/**
+ * @param {string} iq Incoming IQ stanza.
+ */
+remoting.ClientPluginV1.prototype.onIncomingIq = function(iq) {
+ if (this.plugin && this.plugin.onIq) {
+ this.plugin.onIq(iq);
+ } else {
+ // plugin.onIq may not be set after the plugin has been shut
+ // down. Particularly this happens when we receive response to
+ // session-terminate stanza.
+ remoting.debug.log(
+ 'plugin.onIq is not set so dropping incoming message.');
+ }
+};
+
+/**
+ * @param {string} hostJid The jid of the host to connect to.
+ * @param {string} hostPublicKey The base64 encoded version of the host's
+ * public key.
+ * @param {string} clientJid Local jid.
+ * @param {string} sharedSecret The access code for IT2Me or the PIN
+ * for Me2Me.
+ * @param {string} authenticationMethods Comma-separated list of
+ * authentication methods the client should attempt to use.
+ * @param {string} authenticationTag A host-specific tag to mix into
+ * authentication hashes.
+ */
+remoting.ClientPluginV1.prototype.connect = function(
+ hostJid, hostPublicKey, clientJid, sharedSecret,
+ authenticationMethods, authenticationTag) {
+ if (this.plugin.apiVersion < 4) {
+ // Client plugin versions prior to 4 didn't support the last two
+ // parameters.
+ this.plugin.connect(hostJid, hostPublicKey, clientJid, sharedSecret);
+ } else {
+ this.plugin.connect(hostJid, hostPublicKey, clientJid, sharedSecret,
+ authenticationMethods, authenticationTag);
+ }
+};
+
+/**
+ * @param {boolean} scaleToFit True if scale-to-fit should be enabled.
+ */
+remoting.ClientPluginV1.prototype.setScaleToFit = function(scaleToFit) {
+ // scaleToFit() will be removed in future versions of the plugin.
+ if (!!this.plugin && typeof this.plugin.setScaleToFit === 'function')
+ this.plugin.setScaleToFit(scaleToFit);
+};
+
+
+/**
+ * Release all currently pressed keys.
+ */
+remoting.ClientPluginV1.prototype.releaseAllKeys = function() {
+ this.plugin.releaseAllKeys();
+};
+
+/**
+ * Returns an associative array with a set of stats for this connection.
+ *
+ * @return {remoting.ClientSession.PerfStats} The connection statistics.
+ */
+remoting.ClientPluginV1.prototype.getPerfStats = function() {
+ /** @type {remoting.ClientSession.PerfStats} */
+ return { videoBandwidth: this.plugin.videoBandwidth,
+ videoFrameRate: this.plugin.videoFrameRate,
+ captureLatency: this.plugin.videoCaptureLatency,
+ encodeLatency: this.plugin.videoEncodeLatency,
+ decodeLatency: this.plugin.videoDecodeLatency,
+ renderLatency: this.plugin.videoRenderLatency,
+ roundtripLatency: this.plugin.roundTripLatency };
+};
diff --git a/remoting/webapp/client_screen.js b/remoting/webapp/client_screen.js
index 3e6ae7c..8d68fbb 100644
--- a/remoting/webapp/client_screen.js
+++ b/remoting/webapp/client_screen.js
@@ -231,7 +231,7 @@ function onClientStateChange_(oldState, newState) {
showConnectError_(remoting.Error.INVALID_ACCESS_CODE);
}
- } else if (newState == remoting.ClientSession.State.CONNECTION_FAILED) {
+ } else if (newState == remoting.ClientSession.State.FAILED) {
remoting.debug.log('Client plugin reported connection failed: ' +
remoting.clientSession.error);
clearPin = true;
diff --git a/remoting/webapp/client_session.js b/remoting/webapp/client_session.js
index f6d2e2e..c7318d7 100644
--- a/remoting/webapp/client_session.js
+++ b/remoting/webapp/client_session.js
@@ -78,7 +78,7 @@ remoting.ClientSession.State = {
INITIALIZING: 2,
CONNECTED: 3,
CLOSED: 4,
- CONNECTION_FAILED: 5
+ FAILED: 5
};
/** @enum {number} */
@@ -97,14 +97,34 @@ remoting.ClientSession.Mode = {
ME2ME: 1
};
+/**
+ * Type used for performance statistics collected by the plugin.
+ * @constructor
+ */
+remoting.ClientSession.PerfStats = function() {};
+/** @type {number} */
+remoting.ClientSession.PerfStats.prototype.videoBandwidth;
+/** @type {number} */
+remoting.ClientSession.PerfStats.prototype.videoFrameRate;
+/** @type {number} */
+remoting.ClientSession.PerfStats.prototype.captureLatency;
+/** @type {number} */
+remoting.ClientSession.PerfStats.prototype.encodeLatency;
+/** @type {number} */
+remoting.ClientSession.PerfStats.prototype.decodeLatency;
+/** @type {number} */
+remoting.ClientSession.PerfStats.prototype.renderLatency;
+/** @type {number} */
+remoting.ClientSession.PerfStats.prototype.roundtripLatency;
+
// Keys for connection statistics.
-remoting.ClientSession.STATS_KEY_VIDEO_BANDWIDTH = 'video_bandwidth';
-remoting.ClientSession.STATS_KEY_VIDEO_FRAME_RATE = 'video_frame_rate';
-remoting.ClientSession.STATS_KEY_CAPTURE_LATENCY = 'capture_latency';
-remoting.ClientSession.STATS_KEY_ENCODE_LATENCY = 'encode_latency';
-remoting.ClientSession.STATS_KEY_DECODE_LATENCY = 'decode_latency';
-remoting.ClientSession.STATS_KEY_RENDER_LATENCY = 'render_latency';
-remoting.ClientSession.STATS_KEY_ROUNDTRIP_LATENCY = 'roundtrip_latency';
+remoting.ClientSession.STATS_KEY_VIDEO_BANDWIDTH = 'videoBandwidth';
+remoting.ClientSession.STATS_KEY_VIDEO_FRAME_RATE = 'videoFrameRate';
+remoting.ClientSession.STATS_KEY_CAPTURE_LATENCY = 'captureLatency';
+remoting.ClientSession.STATS_KEY_ENCODE_LATENCY = 'encodeLatency';
+remoting.ClientSession.STATS_KEY_DECODE_LATENCY = 'decodeLatency';
+remoting.ClientSession.STATS_KEY_RENDER_LATENCY = 'renderLatency';
+remoting.ClientSession.STATS_KEY_ROUNDTRIP_LATENCY = 'roundtripLatency';
/**
* The current state of the session.
@@ -113,7 +133,7 @@ remoting.ClientSession.STATS_KEY_ROUNDTRIP_LATENCY = 'roundtrip_latency';
remoting.ClientSession.prototype.state = remoting.ClientSession.State.UNKNOWN;
/**
- * The last connection error. Set when state is set to CONNECTION_FAILED.
+ * The last connection error. Set when state is set to FAILED.
* @type {remoting.ClientSession.ConnectionError}
*/
remoting.ClientSession.prototype.error =
@@ -136,20 +156,54 @@ remoting.ClientSession.prototype.onStateChange =
function(oldState, newState) { };
/**
+ * @param {Element} container The element to add the plugin to.
+ * @param {string} id Id to use for the plugin element .
+ * @return {remoting.ClientPlugin} Create plugin object for the locally
+ * installed plugin.
+ */
+remoting.ClientSession.prototype.createClientPlugin_ = function(container, id) {
+ var plugin = /** @type {remoting.ViewerPlugin} */
+ document.createElement('embed');
+
+ plugin.id = id;
+ plugin.src = 'about://none';
+ plugin.type = 'application/vnd.chromium.remoting-viewer';
+ plugin.width = 0;
+ plugin.height = 0;
+ plugin.tabIndex = 0; // Required, otherwise focus() doesn't work.
+ container.appendChild(plugin);
+
+ return new remoting.ClientPluginV1(plugin);
+};
+
+/**
* Adds <embed> element to |container| and readies the sesion object.
*
* @param {Element} container The element to add the plugin to.
* @param {string} oauth2AccessToken A valid OAuth2 access token.
- * @return {void} Nothing.
*/
remoting.ClientSession.prototype.createPluginAndConnect =
function(container, oauth2AccessToken) {
- this.plugin = new remoting.ClientPlugin(container, this.PLUGIN_ID);
+ this.plugin = this.createClientPlugin_(container, this.PLUGIN_ID);
this.plugin.element().focus();
this.plugin.element().addEventListener('blur', this.refocusPlugin_, false);
- if (!this.plugin.isLoaded()) {
+ /** @type {remoting.ClientSession} */
+ var that = this;
+ /** @param {boolean} result */
+ this.plugin.initialize(function(result) {
+ that.onPluginInitialized_(oauth2AccessToken, result);
+ });
+};
+
+/**
+ * @param {string} oauth2AccessToken
+ * @param {boolean} initialized
+ */
+remoting.ClientSession.prototype.onPluginInitialized_ =
+ function(oauth2AccessToken, initialized) {
+ if (!initialized) {
remoting.debug.log('ERROR: remoting plugin not loaded');
this.plugin.cleanup();
delete this.plugin;
@@ -281,7 +335,7 @@ remoting.ClientSession.prototype.sendIq_ = function(msg) {
remoting.wcs.sendIq(msg);
} else {
remoting.debug.log('Tried to send IQ before WCS was ready.');
- this.setState_(remoting.ClientSession.State.CONNECTION_FAILED);
+ this.setState_(remoting.ClientSession.State.FAILED);
}
};
@@ -323,7 +377,7 @@ remoting.ClientSession.prototype.connectionStatusUpdateCallback =
function(status, error) {
if (status == remoting.ClientSession.State.CONNECTED) {
this.onDesktopSizeChanged_();
- } else if (status == remoting.ClientSession.State.CONNECTION_FAILED) {
+ } else if (status == remoting.ClientSession.State.FAILED) {
this.error = /** @type {remoting.ClientSession.ConnectionError} */ (error);
}
this.setState_(/** @type {remoting.ClientSession.State} */ (status));
@@ -422,7 +476,7 @@ remoting.ClientSession.prototype.updateDimensions = function() {
/**
* Returns an associative array with a set of stats for this connection.
*
- * @return {Object.<string, number>} The connection statistics.
+ * @return {remoting.ClientSession.PerfStats} The connection statistics.
*/
remoting.ClientSession.prototype.getPerfStats = function() {
return this.plugin.getPerfStats();
@@ -431,7 +485,7 @@ remoting.ClientSession.prototype.getPerfStats = function() {
/**
* Logs statistics.
*
- * @param {Object.<string, number>} stats
+ * @param {remoting.ClientSession.PerfStats} stats
*/
remoting.ClientSession.prototype.logStatistics = function(stats) {
this.logToServer.logStatistics(stats, this.mode);
diff --git a/remoting/webapp/debug_log.js b/remoting/webapp/debug_log.js
index a7a13e4..8cbdf39 100644
--- a/remoting/webapp/debug_log.js
+++ b/remoting/webapp/debug_log.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -86,46 +86,48 @@ remoting.DebugLog.prototype.toggle = function() {
/**
* Update the statistics panel.
- * @param {Object.<string, number>} stats The connection statistics.
+ * @param {remoting.ClientSession.PerfStats} stats The connection statistics.
*/
remoting.DebugLog.prototype.updateStatistics = function(stats) {
var units = '';
- var videoBandwidth = stats[remoting.ClientSession.STATS_KEY_VIDEO_BANDWIDTH];
- if (videoBandwidth < 1024) {
- units = 'Bps';
- } else if (videoBandwidth < 1048576) {
- units = 'KiBps';
- videoBandwidth = videoBandwidth / 1024;
- } else if (videoBandwidth < 1073741824) {
- units = 'MiBps';
- videoBandwidth = videoBandwidth / 1048576;
- } else {
- units = 'GiBps';
- videoBandwidth = videoBandwidth / 1073741824;
+ var videoBandwidth = stats.videoBandwidth;
+ if (videoBandwidth != undefined) {
+ if (videoBandwidth < 1024) {
+ units = 'Bps';
+ } else if (videoBandwidth < 1048576) {
+ units = 'KiBps';
+ videoBandwidth = videoBandwidth / 1024;
+ } else if (videoBandwidth < 1073741824) {
+ units = 'MiBps';
+ videoBandwidth = videoBandwidth / 1048576;
+ } else {
+ units = 'GiBps';
+ videoBandwidth = videoBandwidth / 1073741824;
+ }
+ }
+
+ /**
+ * @param {number} value
+ * @param {string} units
+ * @returns {string} Formatted number.
+ */
+ function formatStatNumber(value, units) {
+ if (value != undefined) {
+ return value.toFixed(2) + ' ' + units;
+ } else {
+ return "n/a";
+ }
}
var statistics = document.getElementById('statistics');
- this.statsElement.innerText =
- 'Bandwidth: ' + videoBandwidth.toFixed(2) + units +
- ', Frame Rate: ' +
- (stats[remoting.ClientSession.STATS_KEY_VIDEO_FRAME_RATE] ?
- stats[remoting.ClientSession.STATS_KEY_VIDEO_FRAME_RATE].toFixed(2)
- + ' fps' : 'n/a') +
- ', Capture: ' +
- stats[remoting.ClientSession.STATS_KEY_CAPTURE_LATENCY].toFixed(2) +
- 'ms' +
- ', Encode: ' +
- stats[remoting.ClientSession.STATS_KEY_ENCODE_LATENCY].toFixed(2) +
- 'ms' +
- ', Decode: ' +
- stats[remoting.ClientSession.STATS_KEY_DECODE_LATENCY].toFixed(2) +
- 'ms' +
- ', Render: ' +
- stats[remoting.ClientSession.STATS_KEY_RENDER_LATENCY].toFixed(2) +
- 'ms' +
- ', Latency: ' +
- stats[remoting.ClientSession.STATS_KEY_ROUNDTRIP_LATENCY].toFixed(2) +
- 'ms';
+ this.statsElement.innerText = (
+ 'Bandwidth: ' + formatStatNumber(videoBandwidth, units) +
+ ', Frame Rate: ' + formatStatNumber(stats.videoFrameRate, 'fps') +
+ ', Capture: ' + formatStatNumber(stats.captureLatency, 'ms') +
+ ', Encode: ' + formatStatNumber(stats.encodeLatency, 'ms') +
+ ', Decode: ' + formatStatNumber(stats.decodeLatency, 'ms') +
+ ', Render: ' + formatStatNumber(stats.renderLatency, 'ms') +
+ ', Latency: ' + formatStatNumber(stats.roundtripLatency, 'ms'));
};
/**
diff --git a/remoting/webapp/log_to_server.js b/remoting/webapp/log_to_server.js
index cc2310f..83d623e 100644
--- a/remoting/webapp/log_to_server.js
+++ b/remoting/webapp/log_to_server.js
@@ -109,7 +109,7 @@ remoting.LogToServer.isStartOfSession = function(state) {
*/
remoting.LogToServer.isEndOfSession = function(state) {
return ((state == remoting.ClientSession.State.CLOSED) ||
- (state == remoting.ClientSession.State.CONNECTION_FAILED));
+ (state == remoting.ClientSession.State.FAILED));
};
/**
diff --git a/remoting/webapp/server_log_entry.js b/remoting/webapp/server_log_entry.js
index cdc0b1e..ad0379b 100644
--- a/remoting/webapp/server_log_entry.js
+++ b/remoting/webapp/server_log_entry.js
@@ -60,7 +60,7 @@ remoting.ServerLogEntry.getValueForSessionState = function(state) {
return 'connected';
case remoting.ClientSession.State.CLOSED:
return 'closed';
- case remoting.ClientSession.State.CONNECTION_FAILED:
+ case remoting.ClientSession.State.FAILED:
return 'connection-failed';
default:
return 'undefined-' + state;
diff --git a/remoting/webapp/viewer_plugin_proto.js b/remoting/webapp/viewer_plugin_proto.js
index df725a5..786f408 100644
--- a/remoting/webapp/viewer_plugin_proto.js
+++ b/remoting/webapp/viewer_plugin_proto.js
@@ -13,6 +13,9 @@ var remoting = remoting || {};
*/
remoting.ViewerPlugin = function() { };
+/** @param {string} message The message to send to the host. */
+remoting.ViewerPlugin.prototype.postMessage = function(message) {};
+
/** @param {string} iq The Iq stanza received from the host. */
remoting.ViewerPlugin.prototype.onIq = function(iq) {};