summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-23 05:00:32 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-23 05:00:32 +0000
commita04494cb170366bdf8be44c33e76f6e6ab98ab7b (patch)
tree985b82ae63b0802eccc75d86c906827da98b8c62
parent2c0b4de6127ff608a840e6533d3286fb22f5412a (diff)
downloadchromium_src-a04494cb170366bdf8be44c33e76f6e6ab98ab7b.zip
chromium_src-a04494cb170366bdf8be44c33e76f6e6ab98ab7b.tar.gz
chromium_src-a04494cb170366bdf8be44c33e76f6e6ab98ab7b.tar.bz2
Show connection state in the Chromoting client UI.
Now screen is desaturated when we get notification that video channel is not working. BUG=131411 Review URL: https://chromiumcodereview.appspot.com/10692179 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147830 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--remoting/client/chromoting_client.cc5
-rw-r--r--remoting/client/chromoting_client.h1
-rw-r--r--remoting/client/client_user_interface.h1
-rw-r--r--remoting/client/plugin/chromoting_instance.cc6
-rw-r--r--remoting/client/plugin/chromoting_instance.h1
-rw-r--r--remoting/protocol/connection_to_host.cc11
-rw-r--r--remoting/protocol/connection_to_host.h12
-rw-r--r--remoting/protocol/jingle_session.cc5
-rw-r--r--remoting/protocol/jingle_session.h2
-rw-r--r--remoting/protocol/libjingle_transport_factory.cc8
-rw-r--r--remoting/protocol/session.h6
-rw-r--r--remoting/protocol/transport.h8
-rw-r--r--remoting/webapp/client_plugin.js2
-rw-r--r--remoting/webapp/client_plugin_async.js8
-rw-r--r--remoting/webapp/client_session.js23
-rw-r--r--remoting/webapp/main.css5
16 files changed, 102 insertions, 2 deletions
diff --git a/remoting/client/chromoting_client.cc b/remoting/client/chromoting_client.cc
index e77c53a..b66a13c 100644
--- a/remoting/client/chromoting_client.cc
+++ b/remoting/client/chromoting_client.cc
@@ -184,6 +184,11 @@ void ChromotingClient::OnConnectionState(
user_interface_->OnConnectionState(state, error);
}
+void ChromotingClient::OnConnectionReady(bool ready) {
+ VLOG(1) << "ChromotingClient::OnConnectionReady(" << ready << ")";
+ user_interface_->OnConnectionReady(ready);
+}
+
void ChromotingClient::OnPacketDone(bool last_packet,
base::Time decode_start) {
if (!task_runner_->BelongsToCurrentThread()) {
diff --git a/remoting/client/chromoting_client.h b/remoting/client/chromoting_client.h
index d68ae3b..377badb 100644
--- a/remoting/client/chromoting_client.h
+++ b/remoting/client/chromoting_client.h
@@ -73,6 +73,7 @@ class ChromotingClient : public protocol::ConnectionToHost::HostEventCallback,
virtual void OnConnectionState(
protocol::ConnectionToHost::State state,
protocol::ErrorCode error) OVERRIDE;
+ virtual void OnConnectionReady(bool ready) OVERRIDE;
// VideoStub implementation.
virtual void ProcessVideoPacket(scoped_ptr<VideoPacket> packet,
diff --git a/remoting/client/client_user_interface.h b/remoting/client/client_user_interface.h
index e6498fb..4b32a70 100644
--- a/remoting/client/client_user_interface.h
+++ b/remoting/client/client_user_interface.h
@@ -27,6 +27,7 @@ class ClientUserInterface {
// Record the update the state of the connection, updating the UI as needed.
virtual void OnConnectionState(protocol::ConnectionToHost::State state,
protocol::ErrorCode error) = 0;
+ virtual void OnConnectionReady(bool ready) = 0;
// Get the view's ClipboardStub implementation.
virtual protocol::ClipboardStub* GetClipboardStub() = 0;
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc
index c1eeee3..873586c 100644
--- a/remoting/client/plugin/chromoting_instance.cc
+++ b/remoting/client/plugin/chromoting_instance.cc
@@ -393,6 +393,12 @@ void ChromotingInstance::OnConnectionState(
PostChromotingMessage("onConnectionStatus", data.Pass());
}
+void ChromotingInstance::OnConnectionReady(bool ready) {
+ scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue());
+ data->SetBoolean("ready", ready);
+ PostChromotingMessage("onConnectionReady", data.Pass());
+}
+
protocol::ClipboardStub* ChromotingInstance::GetClipboardStub() {
// TODO(sergeyu): Move clipboard handling to a separate class.
// crbug.com/138108
diff --git a/remoting/client/plugin/chromoting_instance.h b/remoting/client/plugin/chromoting_instance.h
index baa98bf..7d0e5a2 100644
--- a/remoting/client/plugin/chromoting_instance.h
+++ b/remoting/client/plugin/chromoting_instance.h
@@ -108,6 +108,7 @@ class ChromotingInstance :
// ClientUserInterface interface.
virtual void OnConnectionState(protocol::ConnectionToHost::State state,
protocol::ErrorCode error) OVERRIDE;
+ virtual void OnConnectionReady(bool ready) OVERRIDE;
virtual protocol::ClipboardStub* GetClipboardStub() OVERRIDE;
virtual protocol::CursorShapeStub* GetCursorShapeStub() OVERRIDE;
diff --git a/remoting/protocol/connection_to_host.cc b/remoting/protocol/connection_to_host.cc
index 5794c50..144c1fc 100644
--- a/remoting/protocol/connection_to_host.cc
+++ b/remoting/protocol/connection_to_host.cc
@@ -209,6 +209,17 @@ void ConnectionToHost::OnSessionRouteChange(const std::string& channel_name,
const TransportRoute& route) {
}
+void ConnectionToHost::OnSessionChannelReady(const std::string& channel_name,
+ bool ready) {
+ if (ready) {
+ not_ready_channels_.erase(channel_name);
+ } else if (!ready) {
+ not_ready_channels_.insert(channel_name);
+ }
+
+ event_callback_->OnConnectionReady(ready);
+}
+
ConnectionToHost::State ConnectionToHost::state() const {
return state_;
}
diff --git a/remoting/protocol/connection_to_host.h b/remoting/protocol/connection_to_host.h
index 4eb7d15..6ba89dc9 100644
--- a/remoting/protocol/connection_to_host.h
+++ b/remoting/protocol/connection_to_host.h
@@ -5,6 +5,7 @@
#ifndef REMOTING_PROTOCOL_CONNECTION_TO_HOST_H_
#define REMOTING_PROTOCOL_CONNECTION_TO_HOST_H_
+#include <set>
#include <string>
#include "base/callback_forward.h"
@@ -64,6 +65,12 @@ class ConnectionToHost : public SignalStrategy::Listener,
// Called when state of the connection changes.
virtual void OnConnectionState(State state, ErrorCode error) = 0;
+
+ // Called when ready state of the connection changes. When |ready|
+ // is set to false some data sent by the peers may be
+ // delayed. This is used to indicate in the UI when connection is
+ // temporarily broken.
+ virtual void OnConnectionReady(bool ready) = 0;
};
ConnectionToHost(bool allow_nat_traversal);
@@ -104,6 +111,8 @@ class ConnectionToHost : public SignalStrategy::Listener,
virtual void OnSessionStateChange(Session::State state) OVERRIDE;
virtual void OnSessionRouteChange(const std::string& channel_name,
const TransportRoute& route) OVERRIDE;
+ virtual void OnSessionChannelReady(const std::string& channel_name,
+ bool ready) OVERRIDE;
// Return the current state of ConnectionToHost.
State state() const;
@@ -150,6 +159,9 @@ class ConnectionToHost : public SignalStrategy::Listener,
State state_;
ErrorCode error_;
+ // List of channels that are not currently ready.
+ std::set<std::string> not_ready_channels_;
+
private:
DISALLOW_COPY_AND_ASSIGN(ConnectionToHost);
};
diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc
index b5fe2a9..814e09f 100644
--- a/remoting/protocol/jingle_session.cc
+++ b/remoting/protocol/jingle_session.cc
@@ -254,6 +254,11 @@ void JingleSession::OnTransportRouteChange(Transport* transport,
event_handler_->OnSessionRouteChange(transport->name(), route);
}
+void JingleSession::OnTransportReady(Transport* transport, bool ready) {
+ if (event_handler_)
+ event_handler_->OnSessionChannelReady(transport->name(), ready);
+}
+
void JingleSession::OnTransportDeleted(Transport* transport) {
ChannelsMap::iterator it = channels_.find(transport->name());
DCHECK_EQ(it->second, transport);
diff --git a/remoting/protocol/jingle_session.h b/remoting/protocol/jingle_session.h
index 109c8da..3fd6cdd 100644
--- a/remoting/protocol/jingle_session.h
+++ b/remoting/protocol/jingle_session.h
@@ -60,6 +60,8 @@ class JingleSession : public Session,
const cricket::Candidate& candidate) OVERRIDE;
virtual void OnTransportRouteChange(Transport* transport,
const TransportRoute& route) OVERRIDE;
+ virtual void OnTransportReady(Transport* transport,
+ bool ready) OVERRIDE;
virtual void OnTransportDeleted(Transport* transport) OVERRIDE;
private:
diff --git a/remoting/protocol/libjingle_transport_factory.cc b/remoting/protocol/libjingle_transport_factory.cc
index 60be636..afe66e7 100644
--- a/remoting/protocol/libjingle_transport_factory.cc
+++ b/remoting/protocol/libjingle_transport_factory.cc
@@ -58,6 +58,7 @@ class LibjingleStreamTransport : public StreamTransport,
const cricket::Candidate& candidate);
void OnRouteChange(cricket::TransportChannel* channel,
const cricket::Candidate& candidate);
+ void OnWritableState(cricket::TransportChannel* channel);
void OnTcpConnected(int result);
void OnAuthenticationDone(net::Error error,
@@ -146,6 +147,8 @@ void LibjingleStreamTransport::Connect(
this, &LibjingleStreamTransport::OnCandidateReady);
channel_->SignalRouteChange.connect(
this, &LibjingleStreamTransport::OnRouteChange);
+ channel_->SignalWritableState.connect(
+ this, &LibjingleStreamTransport::OnWritableState);
channel_->set_incoming_only(incoming_only_);
channel_->Connect();
@@ -238,6 +241,11 @@ void LibjingleStreamTransport::OnRouteChange(
event_handler_->OnTransportRouteChange(this, route);
}
+void LibjingleStreamTransport::OnWritableState(
+ cricket::TransportChannel* channel) {
+ event_handler_->OnTransportReady(this, !channel->writable());
+}
+
void LibjingleStreamTransport::OnTcpConnected(int result) {
DCHECK(CalledOnValidThread());
diff --git a/remoting/protocol/session.h b/remoting/protocol/session.h
index 3137c3e..9148318 100644
--- a/remoting/protocol/session.h
+++ b/remoting/protocol/session.h
@@ -66,6 +66,12 @@ class Session : public base::NonThreadSafe {
// handler of this event.
virtual void OnSessionRouteChange(const std::string& channel_name,
const TransportRoute& route) = 0;
+
+ // Called when ready state on one of the channels changes. See
+ // comments in transport.h for explanation on what this state
+ // means and how it can used.
+ virtual void OnSessionChannelReady(const std::string& channel_name,
+ bool ready) {}
};
// TODO(sergeyu): Specify connection error code when channel
diff --git a/remoting/protocol/transport.h b/remoting/protocol/transport.h
index 251724c..fe11c08 100644
--- a/remoting/protocol/transport.h
+++ b/remoting/protocol/transport.h
@@ -81,6 +81,14 @@ class Transport : public base::NonThreadSafe {
virtual void OnTransportRouteChange(Transport* transport,
const TransportRoute& route) = 0;
+ // Called when the transport inactivity state changes. When
+ // |ready| is set to false incoming and outgoing data may be
+ // delayed until connection goes back to the active state, at
+ // which point that method is called again with |ready| set to
+ // true. This is useful for UI indication of temporarily broken
+ // connections.
+ virtual void OnTransportReady(Transport* transport, bool ready) = 0;
+
// Called when the transport is about to be deleted.
virtual void OnTransportDeleted(Transport* transport) = 0;
};
diff --git a/remoting/webapp/client_plugin.js b/remoting/webapp/client_plugin.js
index c6b66ef..93d4d61 100644
--- a/remoting/webapp/client_plugin.js
+++ b/remoting/webapp/client_plugin.js
@@ -27,6 +27,8 @@ remoting.ClientPlugin.prototype.onOutgoingIqHandler;
remoting.ClientPlugin.prototype.onDebugMessageHandler;
/** @type {function(number, number): void} State change callback. */
remoting.ClientPlugin.prototype.onConnectionStatusUpdateHandler;
+/** @type {function(boolean): void} Connection ready state callback. */
+remoting.ClientPlugin.prototype.onConnectionReadyHandler;
/** @type {function(): void} Desktop size change callback. */
remoting.ClientPlugin.prototype.onDesktopSizeUpdateHandler;
diff --git a/remoting/webapp/client_plugin_async.js b/remoting/webapp/client_plugin_async.js
index dd1b5cd..744d223 100644
--- a/remoting/webapp/client_plugin_async.js
+++ b/remoting/webapp/client_plugin_async.js
@@ -38,6 +38,8 @@ remoting.ClientPluginAsync = function(plugin) {
* @param {number} error The error code, if any.
*/
this.onConnectionStatusUpdateHandler = function(state, error) {};
+ /** @param {boolean} ready Connection ready state. */
+ this.onConnectionReadyHandler = function(ready) {};
this.onDesktopSizeUpdateHandler = function () {};
/** @type {number} */
@@ -196,6 +198,12 @@ remoting.ClientPluginAsync.prototype.handleMessage_ = function(messageStr) {
if (remoting.clientSession) {
remoting.clientSession.onFirstFrameReceived();
}
+ } else if (message.method == 'onConnectionReady') {
+ if (typeof message.data['ready'] != 'boolean') {
+ console.error('Received incorrect onConnectionReady message.');
+ return;
+ }
+ this.onConnectionReadyHandler(message.data['ready']);
}
}
diff --git a/remoting/webapp/client_session.js b/remoting/webapp/client_session.js
index 24a5d23..da8051e 100644
--- a/remoting/webapp/client_session.js
+++ b/remoting/webapp/client_session.js
@@ -303,7 +303,9 @@ remoting.ClientSession.prototype.onPluginInitialized_ =
};
this.plugin.onConnectionStatusUpdateHandler =
- this.connectionStatusUpdateCallback.bind(this);
+ this.onConnectionStatusUpdate_.bind(this);
+ this.plugin.onConnectionReadyHandler =
+ this.onConnectionReady_.bind(this);
this.plugin.onDesktopSizeUpdateHandler =
this.onDesktopSizeChanged_.bind(this);
@@ -479,10 +481,11 @@ remoting.ClientSession.prototype.connectPluginToWcs_ =
* Callback that the plugin invokes to indicate that the connection
* status has changed.
*
+ * @private
* @param {number} status The plugin's status.
* @param {number} error The plugin's error state, if any.
*/
-remoting.ClientSession.prototype.connectionStatusUpdateCallback =
+remoting.ClientSession.prototype.onConnectionStatusUpdate_ =
function(status, error) {
if (status == remoting.ClientSession.State.CONNECTED) {
this.onDesktopSizeChanged_();
@@ -493,6 +496,21 @@ remoting.ClientSession.prototype.connectionStatusUpdateCallback =
};
/**
+ * Callback that the plugin invokes to indicate when the connection is
+ * ready.
+ *
+ * @private
+ * @param {boolean} ready True if the connection is ready.
+ */
+remoting.ClientSession.prototype.onConnectionReady_ = function(ready) {
+ if (!ready) {
+ this.plugin.element().classList.add("session-client-inactive");
+ } else {
+ this.plugin.element().classList.remove("session-client-inactive");
+ }
+}
+
+/**
* @private
* @param {remoting.ClientSession.State} newState The new state for the session.
* @return {void} Nothing.
@@ -707,6 +725,7 @@ remoting.ClientSession.prototype.scroll_ = function(dx, dy) {
/**
* Enable or disable bump-scrolling.
+ * @private
* @param {boolean} enable True to enable bump-scrolling, false to disable it.
*/
remoting.ClientSession.prototype.enableBumpScroll_ = function(enable) {
diff --git a/remoting/webapp/main.css b/remoting/webapp/main.css
index fb4d1dd..ed4de9f 100644
--- a/remoting/webapp/main.css
+++ b/remoting/webapp/main.css
@@ -562,6 +562,11 @@ button {
display: block;
}
+.session-client-inactive {
+ -webkit-filter: grayscale(70%);
+ -webkit-transition: -webkit-filter 0.218s;
+}
+
#set-pin-table td {
border-bottom: 6px solid transparent;
text-align: right;