diff options
author | garykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-28 22:22:38 +0000 |
---|---|---|
committer | garykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-28 22:22:38 +0000 |
commit | 865aaafd66ea733bacd61a0960417da45cb1d507 (patch) | |
tree | aa6408d3e3c1488d5355e381576ca2cefe6461d6 /remoting/client | |
parent | a09270ae75cce4bfce1caef1f8d6d99aa26493e0 (diff) | |
download | chromium_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.html | 10 | ||||
-rw-r--r-- | remoting/client/appengine/static_files/chromoting_session.js | 59 | ||||
-rw-r--r-- | remoting/client/appengine/static_files/main.css | 31 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_instance.cc | 7 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_instance.h | 2 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_scriptable_object.cc | 51 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_scriptable_object.h | 18 |
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); |