diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-23 05:00:32 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-23 05:00:32 +0000 |
commit | a04494cb170366bdf8be44c33e76f6e6ab98ab7b (patch) | |
tree | 985b82ae63b0802eccc75d86c906827da98b8c62 | |
parent | 2c0b4de6127ff608a840e6533d3286fb22f5412a (diff) | |
download | chromium_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.cc | 5 | ||||
-rw-r--r-- | remoting/client/chromoting_client.h | 1 | ||||
-rw-r--r-- | remoting/client/client_user_interface.h | 1 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_instance.cc | 6 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_instance.h | 1 | ||||
-rw-r--r-- | remoting/protocol/connection_to_host.cc | 11 | ||||
-rw-r--r-- | remoting/protocol/connection_to_host.h | 12 | ||||
-rw-r--r-- | remoting/protocol/jingle_session.cc | 5 | ||||
-rw-r--r-- | remoting/protocol/jingle_session.h | 2 | ||||
-rw-r--r-- | remoting/protocol/libjingle_transport_factory.cc | 8 | ||||
-rw-r--r-- | remoting/protocol/session.h | 6 | ||||
-rw-r--r-- | remoting/protocol/transport.h | 8 | ||||
-rw-r--r-- | remoting/webapp/client_plugin.js | 2 | ||||
-rw-r--r-- | remoting/webapp/client_plugin_async.js | 8 | ||||
-rw-r--r-- | remoting/webapp/client_session.js | 23 | ||||
-rw-r--r-- | remoting/webapp/main.css | 5 |
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; |