[email protected] | 44f6076 | 2011-03-23 12:13:35 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | cd8d237 | 2010-11-04 01:18:04 | [diff] [blame] | 5 | #include "remoting/protocol/connection_to_client.h" |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 6 | |
[email protected] | 182ec8f2 | 2011-08-11 02:14:35 | [diff] [blame] | 7 | #include "base/bind.h" |
[email protected] | c62dd9d | 2011-09-21 18:05:41 | [diff] [blame] | 8 | #include "base/location.h" |
[email protected] | 60fc9600 | 2011-08-12 23:07:05 | [diff] [blame] | 9 | #include "base/message_loop_proxy.h" |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 10 | #include "google/protobuf/message.h" |
[email protected] | c3af26f33 | 2010-10-06 22:46:00 | [diff] [blame] | 11 | #include "net/base/io_buffer.h" |
[email protected] | 35b9c56 | 2010-11-09 02:22:43 | [diff] [blame] | 12 | #include "remoting/protocol/client_control_sender.h" |
[email protected] | 6fd3d6a1 | 2010-11-16 19:53:35 | [diff] [blame] | 13 | #include "remoting/protocol/host_message_dispatcher.h" |
[email protected] | f0a9d1b | 2011-03-04 21:31:44 | [diff] [blame] | 14 | #include "remoting/protocol/host_stub.h" |
| 15 | #include "remoting/protocol/input_stub.h" |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 16 | |
[email protected] | cd8d237 | 2010-11-04 01:18:04 | [diff] [blame] | 17 | // TODO(hclam): Remove this header once MessageDispatcher is used. |
[email protected] | b3c0340 | 2010-11-16 01:27:46 | [diff] [blame] | 18 | #include "remoting/base/compound_buffer.h" |
[email protected] | cd8d237 | 2010-11-04 01:18:04 | [diff] [blame] | 19 | |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 20 | namespace remoting { |
[email protected] | d87c404 | 2010-11-04 00:46:01 | [diff] [blame] | 21 | namespace protocol { |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 22 | |
| 23 | // Determine how many update streams we should count to find the size of |
| 24 | // average update stream. |
[email protected] | 887cec8 | 2010-06-15 22:13:43 | [diff] [blame] | 25 | static const size_t kAverageUpdateStream = 10; |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 26 | |
[email protected] | 60fc9600 | 2011-08-12 23:07:05 | [diff] [blame] | 27 | ConnectionToClient::ConnectionToClient(base::MessageLoopProxy* message_loop, |
[email protected] | 4ea2c7c | 2011-03-31 14:20:06 | [diff] [blame] | 28 | EventHandler* handler) |
[email protected] | 60fc9600 | 2011-08-12 23:07:05 | [diff] [blame] | 29 | : message_loop_(message_loop), |
[email protected] | 6fd3d6a1 | 2010-11-16 19:53:35 | [diff] [blame] | 30 | handler_(handler), |
[email protected] | 44f6076 | 2011-03-23 12:13:35 | [diff] [blame] | 31 | host_stub_(NULL), |
[email protected] | 182ec8f2 | 2011-08-11 02:14:35 | [diff] [blame] | 32 | input_stub_(NULL), |
| 33 | control_connected_(false), |
| 34 | input_connected_(false), |
| 35 | video_connected_(false) { |
[email protected] | 60fc9600 | 2011-08-12 23:07:05 | [diff] [blame] | 36 | DCHECK(message_loop_); |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 37 | DCHECK(handler_); |
| 38 | } |
| 39 | |
[email protected] | cd8d237 | 2010-11-04 01:18:04 | [diff] [blame] | 40 | ConnectionToClient::~ConnectionToClient() { |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 41 | // TODO(hclam): When we shut down the viewer we may have to close the |
[email protected] | c3af26f33 | 2010-10-06 22:46:00 | [diff] [blame] | 42 | // connection. |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 43 | } |
| 44 | |
[email protected] | cd8d237 | 2010-11-04 01:18:04 | [diff] [blame] | 45 | void ConnectionToClient::Init(protocol::Session* session) { |
[email protected] | 60fc9600 | 2011-08-12 23:07:05 | [diff] [blame] | 46 | DCHECK(message_loop_->BelongsToCurrentThread()); |
[email protected] | 964bd39 | 2011-07-06 17:25:25 | [diff] [blame] | 47 | session_.reset(session); |
[email protected] | 230d2fd | 2010-11-03 21:56:42 | [diff] [blame] | 48 | session_->SetStateChangeCallback( |
[email protected] | 9e2a313 | 2011-10-07 05:07:40 | [diff] [blame] | 49 | base::Bind(&ConnectionToClient::OnSessionStateChange, |
| 50 | base::Unretained(this))); |
[email protected] | e295ff06 | 2010-07-15 22:56:04 | [diff] [blame] | 51 | } |
| 52 | |
[email protected] | cd8d237 | 2010-11-04 01:18:04 | [diff] [blame] | 53 | protocol::Session* ConnectionToClient::session() { |
[email protected] | 964bd39 | 2011-07-06 17:25:25 | [diff] [blame] | 54 | return session_.get(); |
[email protected] | d6e6d13c | 2010-10-27 19:11:44 | [diff] [blame] | 55 | } |
| 56 | |
[email protected] | cd8d237 | 2010-11-04 01:18:04 | [diff] [blame] | 57 | void ConnectionToClient::Disconnect() { |
[email protected] | 28876a7 | 2010-11-30 22:12:33 | [diff] [blame] | 58 | // This method can be called from main thread so perform threading switching. |
[email protected] | 60fc9600 | 2011-08-12 23:07:05 | [diff] [blame] | 59 | if (!message_loop_->BelongsToCurrentThread()) { |
| 60 | message_loop_->PostTask( |
[email protected] | 1e1cb3b | 2011-11-10 02:07:41 | [diff] [blame^] | 61 | FROM_HERE, base::Bind(&ConnectionToClient::Disconnect, this)); |
[email protected] | 28876a7 | 2010-11-30 22:12:33 | [diff] [blame] | 62 | return; |
| 63 | } |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 64 | |
[email protected] | 86dbc72 | 2011-06-30 23:23:30 | [diff] [blame] | 65 | CloseChannels(); |
| 66 | |
[email protected] | 3962b77 | 2011-07-07 21:07:54 | [diff] [blame] | 67 | // If there is a session then release it, causing it to close. |
| 68 | if (session_.get()) |
[email protected] | 964bd39 | 2011-07-06 17:25:25 | [diff] [blame] | 69 | session_.reset(); |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 70 | } |
| 71 | |
[email protected] | c0f7082 | 2011-05-06 21:19:29 | [diff] [blame] | 72 | void ConnectionToClient::UpdateSequenceNumber(int64 sequence_number) { |
| 73 | handler_->OnSequenceNumberUpdated(this, sequence_number); |
| 74 | } |
| 75 | |
[email protected] | c56acf54ff | 2010-11-19 23:44:45 | [diff] [blame] | 76 | VideoStub* ConnectionToClient::video_stub() { |
| 77 | return video_writer_.get(); |
| 78 | } |
[email protected] | b104b50 | 2010-10-18 20:21:31 | [diff] [blame] | 79 | |
[email protected] | c56acf54ff | 2010-11-19 23:44:45 | [diff] [blame] | 80 | // Return pointer to ClientStub. |
| 81 | ClientStub* ConnectionToClient::client_stub() { |
[email protected] | 86dbc72 | 2011-06-30 23:23:30 | [diff] [blame] | 82 | return client_control_sender_.get(); |
[email protected] | c56acf54ff | 2010-11-19 23:44:45 | [diff] [blame] | 83 | } |
| 84 | |
[email protected] | 44f6076 | 2011-03-23 12:13:35 | [diff] [blame] | 85 | void ConnectionToClient::set_host_stub(protocol::HostStub* host_stub) { |
| 86 | host_stub_ = host_stub; |
| 87 | } |
| 88 | |
[email protected] | 4ea2c7c | 2011-03-31 14:20:06 | [diff] [blame] | 89 | void ConnectionToClient::set_input_stub(protocol::InputStub* input_stub) { |
| 90 | input_stub_ = input_stub; |
| 91 | } |
| 92 | |
[email protected] | c56acf54ff | 2010-11-19 23:44:45 | [diff] [blame] | 93 | void ConnectionToClient::OnSessionStateChange(protocol::Session::State state) { |
[email protected] | 60fc9600 | 2011-08-12 23:07:05 | [diff] [blame] | 94 | DCHECK(message_loop_->BelongsToCurrentThread()); |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 95 | |
| 96 | DCHECK(handler_); |
| 97 | switch(state) { |
[email protected] | 230d2fd | 2010-11-03 21:56:42 | [diff] [blame] | 98 | case protocol::Session::CONNECTING: |
[email protected] | 182ec8f2 | 2011-08-11 02:14:35 | [diff] [blame] | 99 | // Don't care about this message. |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 100 | break; |
[email protected] | 182ec8f2 | 2011-08-11 02:14:35 | [diff] [blame] | 101 | |
[email protected] | 230d2fd | 2010-11-03 21:56:42 | [diff] [blame] | 102 | case protocol::Session::CONNECTED: |
[email protected] | 60fc9600 | 2011-08-12 23:07:05 | [diff] [blame] | 103 | video_writer_.reset( |
| 104 | VideoWriter::Create(message_loop_, session_->config())); |
[email protected] | 182ec8f2 | 2011-08-11 02:14:35 | [diff] [blame] | 105 | video_writer_->Init( |
| 106 | session_.get(), base::Bind(&ConnectionToClient::OnVideoInitialized, |
| 107 | base::Unretained(this))); |
| 108 | break; |
| 109 | |
| 110 | case protocol::Session::CONNECTED_CHANNELS: |
[email protected] | 86dbc72 | 2011-06-30 23:23:30 | [diff] [blame] | 111 | client_control_sender_.reset( |
[email protected] | 60fc9600 | 2011-08-12 23:07:05 | [diff] [blame] | 112 | new ClientControlSender(message_loop_, session_->control_channel())); |
[email protected] | 86dbc72 | 2011-06-30 23:23:30 | [diff] [blame] | 113 | dispatcher_.reset(new HostMessageDispatcher()); |
| 114 | dispatcher_->Initialize(this, host_stub_, input_stub_); |
[email protected] | 1290af9 | 2011-08-10 01:05:31 | [diff] [blame] | 115 | |
[email protected] | 182ec8f2 | 2011-08-11 02:14:35 | [diff] [blame] | 116 | control_connected_ = true; |
| 117 | input_connected_ = true; |
| 118 | NotifyIfChannelsReady(); |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 119 | break; |
[email protected] | 182ec8f2 | 2011-08-11 02:14:35 | [diff] [blame] | 120 | |
[email protected] | 230d2fd | 2010-11-03 21:56:42 | [diff] [blame] | 121 | case protocol::Session::CLOSED: |
[email protected] | 86dbc72 | 2011-06-30 23:23:30 | [diff] [blame] | 122 | CloseChannels(); |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 123 | handler_->OnConnectionClosed(this); |
| 124 | break; |
[email protected] | 182ec8f2 | 2011-08-11 02:14:35 | [diff] [blame] | 125 | |
[email protected] | 230d2fd | 2010-11-03 21:56:42 | [diff] [blame] | 126 | case protocol::Session::FAILED: |
[email protected] | 182ec8f2 | 2011-08-11 02:14:35 | [diff] [blame] | 127 | CloseOnError(); |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 128 | break; |
[email protected] | 182ec8f2 | 2011-08-11 02:14:35 | [diff] [blame] | 129 | |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 130 | default: |
| 131 | // We shouldn't receive other states. |
| 132 | NOTREACHED(); |
| 133 | } |
| 134 | } |
| 135 | |
[email protected] | 182ec8f2 | 2011-08-11 02:14:35 | [diff] [blame] | 136 | void ConnectionToClient::OnVideoInitialized(bool successful) { |
| 137 | if (!successful) { |
| 138 | LOG(ERROR) << "Failed to connect video channel"; |
| 139 | CloseOnError(); |
| 140 | return; |
| 141 | } |
| 142 | |
| 143 | video_connected_ = true; |
| 144 | NotifyIfChannelsReady(); |
| 145 | } |
| 146 | |
| 147 | void ConnectionToClient::NotifyIfChannelsReady() { |
| 148 | if (control_connected_ && input_connected_ && video_connected_) |
| 149 | handler_->OnConnectionOpened(this); |
| 150 | } |
| 151 | |
| 152 | void ConnectionToClient::CloseOnError() { |
| 153 | CloseChannels(); |
| 154 | handler_->OnConnectionFailed(this); |
| 155 | } |
| 156 | |
[email protected] | 86dbc72 | 2011-06-30 23:23:30 | [diff] [blame] | 157 | void ConnectionToClient::CloseChannels() { |
| 158 | if (video_writer_.get()) |
| 159 | video_writer_->Close(); |
| 160 | if (client_control_sender_.get()) |
| 161 | client_control_sender_->Close(); |
| 162 | } |
| 163 | |
[email protected] | d87c404 | 2010-11-04 00:46:01 | [diff] [blame] | 164 | } // namespace protocol |
[email protected] | cb3b1f931 | 2010-06-07 19:58:23 | [diff] [blame] | 165 | } // namespace remoting |