summaryrefslogtreecommitdiffstats
path: root/remoting/client
diff options
context:
space:
mode:
authorgarykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-28 22:22:38 +0000
committergarykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-28 22:22:38 +0000
commit865aaafd66ea733bacd61a0960417da45cb1d507 (patch)
treeaa6408d3e3c1488d5355e381576ca2cefe6461d6 /remoting/client
parenta09270ae75cce4bfce1caef1f8d6d99aa26493e0 (diff)
downloadchromium_src-865aaafd66ea733bacd61a0960417da45cb1d507.zip
chromium_src-865aaafd66ea733bacd61a0960417da45cb1d507.tar.gz
chromium_src-865aaafd66ea733bacd61a0960417da45cb1d507.tar.bz2
Add debug logging to Chromoting client UI.
Modify chromoting plugin and js to talk to each other. BUG=none TEST=manual Review URL: http://codereview.chromium.org/6591001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76284 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/client')
-rw-r--r--remoting/client/appengine/chromoting_session.html10
-rw-r--r--remoting/client/appengine/static_files/chromoting_session.js59
-rw-r--r--remoting/client/appengine/static_files/main.css31
-rw-r--r--remoting/client/plugin/chromoting_instance.cc7
-rw-r--r--remoting/client/plugin/chromoting_instance.h2
-rw-r--r--remoting/client/plugin/chromoting_scriptable_object.cc51
-rw-r--r--remoting/client/plugin/chromoting_scriptable_object.h18
7 files changed, 159 insertions, 19 deletions
diff --git a/remoting/client/appengine/chromoting_session.html b/remoting/client/appengine/chromoting_session.html
index 2d26b45..3389c09 100644
--- a/remoting/client/appengine/chromoting_session.html
+++ b/remoting/client/appengine/chromoting_session.html
@@ -23,7 +23,11 @@ found in the LICENSE file.
</script>
</head>
<body class="chromoting_body" onload="init();">
- <div id="status_msg" class="status_msg"></div>
+ <div id="status_msg_div">
+ <span id="status_msg" class="status_msg">Initializing...</span>
+ <input type="button" value="Show Debug Log" class="debug_log_toggle"
+ id="debug_log_toggle" onclick="toggleDebugLog();"/>
+ </div>
<div id="login_panel" class="local_login_panel">
<table><tr><td valign="top"
style="text-align:center" nowrap="nowrap" bgcolor="#e8eefa">
@@ -53,9 +57,11 @@ found in the LICENSE file.
</table>
</td></tr></table>
</div>
- <div id="plugin_scroll_panel" class="plugin-scroll-panel">
+ <div id="plugin_scroll_panel" class="plugin_scroll_panel">
<embed name="chromoting" id="chromoting"
src="about://none" type="pepper-application/x-chromoting">
</div>
+ <div id="debug_log" class="debug_log">
+ </div>
</body>
</html>
diff --git a/remoting/client/appengine/static_files/chromoting_session.js b/remoting/client/appengine/static_files/chromoting_session.js
index 18ee990..94faa79 100644
--- a/remoting/client/appengine/static_files/chromoting_session.js
+++ b/remoting/client/appengine/static_files/chromoting_session.js
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// Maximum numer of lines to record in the debug log.
+// Only the most recent <n> lines are displayed.
+var MAX_DEBUG_LOG_SIZE = 1000;
+
// Message id so that we can identify (and ignore) message fade operations for
// old messages. This starts at 1 and is incremented for each new message.
chromoting.messageId = 1;
@@ -18,8 +22,9 @@ function init() {
// Setup the callback that the plugin will call when the connection status
// has changes and the UI needs to be updated. It needs to be an object with
// a 'callback' property that contains the callback function.
- plugin.connectionInfoUpdate = pluginCallback;
- plugin.loginChallenge = pluginLoginChallenge;
+ plugin.connectionInfoUpdate = connectionInfoUpdateCallback;
+ plugin.debugInfoUpdate = debugInfoUpdateCallback;
+ plugin.loginChallenge = loginChallengeCallback;
console.log('connect request received: ' + chromoting.hostname + ' by ' +
chromoting.username);
@@ -35,6 +40,19 @@ function init() {
document.getElementById('title').innerText = chromoting.hostname;
}
+function toggleDebugLog() {
+ debugLog = document.getElementById("debug_log");
+ toggleButton = document.getElementById("debug_log_toggle");
+
+ if (!debugLog.style.display || debugLog.style.display == "none") {
+ debugLog.style.display = "block";
+ toggleButton.value = "Hide Debug Log";
+ } else {
+ debugLog.style.display = "none";
+ toggleButton.value = "Show Debug Log";
+ }
+}
+
function submitLogin() {
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
@@ -48,7 +66,7 @@ function submitLogin() {
* This is the callback method that the plugin calls to request username and
* password for logging into the remote host.
*/
-function pluginLoginChallenge() {
+function loginChallengeCallback() {
// Make the login panel visible.
document.getElementById("login_panel").style.display = "block";
}
@@ -97,7 +115,7 @@ function showClientStateMessage(message, duration) {
* This is that callback that the plugin invokes to indicate that the
* host/client connection status has changed.
*/
-function pluginCallback() {
+function connectionInfoUpdateCallback() {
var status = chromoting.plugin.status;
var quality = chromoting.plugin.quality;
@@ -188,3 +206,36 @@ function fade(name, id, val, delta, delay) {
}
}
}
+
+/**
+ * This is that callback that the plugin invokes to indicate that there
+ * is additional debug log info to display.
+ */
+function debugInfoUpdateCallback() {
+ var debugInfo = chromoting.plugin.debugInfo;
+ addToDebugLog(debugInfo);
+}
+
+/**
+ * Add the given message to the debug log.
+ *
+ * @param {string} message The debug info to add to the log.
+ */
+function addToDebugLog(message) {
+ console.log('DebugLog: ' + message);
+
+ var debugLog = document.getElementById('debug_log');
+
+ // Remove lines from top if we've hit our max log size.
+ if (debugLog.childNodes.length == MAX_DEBUG_LOG_SIZE) {
+ debugLog.removeChild(debugLog.firstChild);
+ }
+
+ // Add the new <p> to the end of the debug log.
+ var p = document.createElement('p');
+ p.appendChild(document.createTextNode(message));
+ debugLog.appendChild(p);
+
+ // Scroll to bottom of div
+ debugLog.scrollTop = debugLog.scrollHeight;
+}
diff --git a/remoting/client/appengine/static_files/main.css b/remoting/client/appengine/static_files/main.css
index 5e5cf29..b8031ec 100644
--- a/remoting/client/appengine/static_files/main.css
+++ b/remoting/client/appengine/static_files/main.css
@@ -105,7 +105,8 @@ a.hostentry { text-decoration: none; }
scrollbars: no;
}
-.status_msg {
+/* Old overlay-style status message. */
+.status_msg_overlay {
-webkit-user-select: none;
position: absolute;
left: 20px;
@@ -115,10 +116,38 @@ a.hostentry { text-decoration: none; }
font-weight: bold;
}
+.status_msg {
+ margin: 5px;
+}
+
.error_msg {
color: red;
}
+.debug_log {
+ -webkit-user-select: text;
+ padding: 0px;
+ margin: 0px;
+ position: fixed;
+ bottom: 0px;
+ width: 100%;
+ height: 150px;
+ overflow: auto;
+ font-family: monospace;
+ font-weight: bold;
+ line-height: 0.5em;
+ border: 2px solid #ffffff;
+ display: none;
+ opacity: 0.9;
+ background-color: #ffffff;
+ z-index: 1;
+}
+
+.debug_log_toggle {
+ line-height: 0.8em;
+ float: right;
+}
+
.gaia_login_panel {
-webkit-user-select: none;
font-family: arial,sans-serif;
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc
index 39cb40f..df4224d 100644
--- a/remoting/client/plugin/chromoting_instance.cc
+++ b/remoting/client/plugin/chromoting_instance.cc
@@ -90,6 +90,8 @@ bool ChromotingInstance::Init(uint32_t argc,
void ChromotingInstance::Connect(const ClientConfig& config) {
DCHECK(CurrentlyOnPluginThread());
+ LogDebugInfo(StringPrintf("Connecting to %s as %s", config.host_jid.c_str(),
+ config.username.c_str()).c_str());
client_.reset(new ChromotingClient(config,
&context_,
host_connection_.get(),
@@ -108,6 +110,7 @@ void ChromotingInstance::Connect(const ClientConfig& config) {
void ChromotingInstance::Disconnect() {
DCHECK(CurrentlyOnPluginThread());
+ LogDebugInfo("Disconnecting from host");
if (client_.get()) {
client_->Stop();
}
@@ -200,6 +203,10 @@ void ChromotingInstance::SubmitLoginInfo(const std::string& username,
new DeleteTask<protocol::LocalLoginCredentials>(credentials));
}
+void ChromotingInstance::LogDebugInfo(const std::string& info) {
+ GetScriptableObject()->LogDebugInfo(info);
+}
+
pp::Var ChromotingInstance::GetInstanceObject() {
if (instance_object_.is_undefined()) {
ChromotingScriptableObject* object = new ChromotingScriptableObject(this);
diff --git a/remoting/client/plugin/chromoting_instance.h b/remoting/client/plugin/chromoting_instance.h
index 8a5f7f6..9e1c2d3 100644
--- a/remoting/client/plugin/chromoting_instance.h
+++ b/remoting/client/plugin/chromoting_instance.h
@@ -76,6 +76,8 @@ class ChromotingInstance : public pp::Instance {
void SubmitLoginInfo(const std::string& username,
const std::string& password);
+ void LogDebugInfo(const std::string& info);
+
private:
FRIEND_TEST_ALL_PREFIXES(ChromotingInstanceTest, TestCaseSetup);
diff --git a/remoting/client/plugin/chromoting_scriptable_object.cc b/remoting/client/plugin/chromoting_scriptable_object.cc
index 11349de..978055d 100644
--- a/remoting/client/plugin/chromoting_scriptable_object.cc
+++ b/remoting/client/plugin/chromoting_scriptable_object.cc
@@ -13,12 +13,14 @@ using pp::Var;
namespace remoting {
-const char kStatusAttribute[] = "status";
-const char kQualityAttribute[] = "quality";
-const char kDesktopWidth[] = "desktopWidth";
-const char kDesktopHeight[] = "desktopHeight";
const char kConnectionInfoUpdate[] = "connectionInfoUpdate";
+const char kDebugInfoUpdate[] = "debugInfoUpdate";
+const char kDebugInfoAttribute[] = "debugInfo";
+const char kDesktopHeight[] = "desktopHeight";
+const char kDesktopWidth[] = "desktopWidth";
const char kLoginChallenge[] = "loginChallenge";
+const char kQualityAttribute[] = "quality";
+const char kStatusAttribute[] = "status";
ChromotingScriptableObject::ChromotingScriptableObject(
ChromotingInstance* instance)
@@ -51,7 +53,11 @@ void ChromotingScriptableObject::Init() {
AddAttribute("QUALITY_GOOD", Var(QUALITY_GOOD));
AddAttribute("QUALITY_BAD", Var(QUALITY_BAD));
+ // Debug info to display.
+ AddAttribute(kDebugInfoAttribute, Var());
+
AddAttribute(kConnectionInfoUpdate, Var());
+ AddAttribute(kDebugInfoUpdate, Var());
AddAttribute(kLoginChallenge, Var());
AddAttribute(kDesktopWidth, Var(0));
AddAttribute(kDesktopHeight, Var(0));
@@ -126,7 +132,7 @@ void ChromotingScriptableObject::GetAllPropertyNames(
void ChromotingScriptableObject::SetProperty(const Var& name,
const Var& value,
Var* exception) {
- // TODO(ajwong): Check if all these name.is_string() sentinels are required. 120 // No externally settable properties for Chromoting.
+ // TODO(ajwong): Check if all these name.is_string() sentinels are required.
if (!name.is_string()) {
*exception = Var("SetProperty expects a string for the name.");
return;
@@ -136,6 +142,7 @@ void ChromotingScriptableObject::SetProperty(const Var& name,
// chromoting_scriptable_object.h for the object interface definition.
std::string property_name = name.AsString();
if (property_name != kConnectionInfoUpdate &&
+ property_name != kDebugInfoUpdate &&
property_name != kLoginChallenge &&
property_name != kDesktopWidth &&
property_name != kDesktopHeight) {
@@ -177,6 +184,17 @@ void ChromotingScriptableObject::SetConnectionInfo(ConnectionStatus status,
}
}
+void ChromotingScriptableObject::LogDebugInfo(const std::string& info) {
+ int debug_info_index = property_names_[kDebugInfoAttribute];
+
+ // Update the debug info string.
+ // Note that this only stores the most recent debug string.
+ properties_[debug_info_index].attribute = Var(info);
+
+ // Signal the client UI to get the updated debug info.
+ SignalDebugInfoChange();
+}
+
void ChromotingScriptableObject::SetDesktopSize(int width, int height) {
int width_index = property_names_[kDesktopWidth];
int height_index = property_names_[kDesktopHeight];
@@ -212,7 +230,24 @@ void ChromotingScriptableObject::SignalConnectionInfoChange() {
cb.Call(Var(), 0, NULL, &exception);
if (!exception.is_undefined()) {
- LOG(WARNING) << "Exception when invoking JS callback"
+ LOG(WARNING) << "Exception when invoking connectionInfoUpdate JS callback"
+ << exception.AsString();
+ }
+}
+
+void ChromotingScriptableObject::SignalDebugInfoChange() {
+ Var exception;
+
+ // The JavaScript callback function is the 'callback' property on the
+ // 'debugInfoUpdate' object.
+ Var cb = GetProperty(Var(kDebugInfoUpdate), &exception);
+
+ // Var() means call the object directly as a function rather than calling
+ // a method in the object.
+ cb.Call(Var(), 0, NULL, &exception);
+
+ if (!exception.is_undefined()) {
+ LOG(WARNING) << "Exception when invoking debugInfoUpdate JS callback"
<< exception.AsString();
}
}
@@ -221,7 +256,7 @@ void ChromotingScriptableObject::SignalLoginChallenge() {
Var exception;
// The JavaScript callback function is the 'callback' property on the
- // 'connectionInfoUpdate' object.
+ // 'loginChallenge' object.
Var cb = GetProperty(Var(kLoginChallenge), &exception);
// Var() means call the object directly as a function rather than calling
@@ -229,7 +264,7 @@ void ChromotingScriptableObject::SignalLoginChallenge() {
cb.Call(Var(), 0, NULL, &exception);
if (!exception.is_undefined()) {
- LOG(WARNING) << "Exception when invoking JS callback"
+ LOG(WARNING) << "Exception when invoking loginChallenge JS callback"
<< exception.AsString();
}
}
diff --git a/remoting/client/plugin/chromoting_scriptable_object.h b/remoting/client/plugin/chromoting_scriptable_object.h
index ad37afc..e5c57b5 100644
--- a/remoting/client/plugin/chromoting_scriptable_object.h
+++ b/remoting/client/plugin/chromoting_scriptable_object.h
@@ -7,13 +7,15 @@
//
// interface ChromotingScriptableObject {
//
-// // Connection status.
-// readonly attribute unsigned short connection_status;
-//
// // Dimension of the desktop area.
// readonly attribute int desktopWidth;
// readonly attribute int desktopHeight;
//
+// // Debug info.
+// readonly attribute string debugInfo;
+//
+// // Connection status.
+// readonly attribute unsigned short status;
// // Constants for connection status.
// const unsigned short STATUS_UNKNOWN = 0;
// const unsigned short STATUS_CONNECTING = 1;
@@ -23,7 +25,7 @@
// const unsigned short STATUS_FAILED = 5;
//
// // Connection quality.
-// readonly attribute unsigned short connection_quality;
+// readonly attribute unsigned short quality;
// // Constants for connection quality
// const unsigned short QUALITY_UNKNOWN = 0;
// const unsigned short QUALITY_GOOD = 1;
@@ -33,6 +35,10 @@
// // status has been updated.
// attribute Function connectionInfoUpdate;
//
+// // JS callback function to call when there is new debug info to display
+// // in the client UI.
+// attribute Function debugInfoUpdate;
+//
// // This function is called when login information for the host machine is
// // needed.
// //
@@ -106,6 +112,7 @@ class ChromotingScriptableObject : public pp::deprecated::ScriptableObject {
pp::Var* exception);
void SetConnectionInfo(ConnectionStatus status, ConnectionQuality quality);
+ void LogDebugInfo(const std::string& info);
void SetDesktopSize(int width, int height);
// This should be called to signal JS code to provide login information.
@@ -143,6 +150,9 @@ class ChromotingScriptableObject : public pp::deprecated::ScriptableObject {
// changed.
void SignalConnectionInfoChange();
+ // Call this to signal that there is new debug info to display.
+ void SignalDebugInfoChange();
+
pp::Var DoConnect(const std::vector<pp::Var>& args, pp::Var* exception);
pp::Var DoDisconnect(const std::vector<pp::Var>& args, pp::Var* exception);