OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/chromoting_host.h" | 5 #include "remoting/host/chromoting_host.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/logging.h" |
9 #include "build/build_config.h" | 10 #include "build/build_config.h" |
10 #include "remoting/base/constants.h" | 11 #include "remoting/base/constants.h" |
11 #include "remoting/base/encoder.h" | 12 #include "remoting/base/encoder.h" |
12 #include "remoting/base/encoder_row_based.h" | 13 #include "remoting/base/encoder_row_based.h" |
13 #include "remoting/base/encoder_vp8.h" | 14 #include "remoting/base/encoder_vp8.h" |
| 15 #include "remoting/base/logger.h" |
14 #include "remoting/host/chromoting_host_context.h" | 16 #include "remoting/host/chromoting_host_context.h" |
15 #include "remoting/host/curtain.h" | 17 #include "remoting/host/curtain.h" |
16 #include "remoting/host/desktop_environment.h" | 18 #include "remoting/host/desktop_environment.h" |
17 #include "remoting/host/event_executor.h" | 19 #include "remoting/host/event_executor.h" |
18 #include "remoting/host/host_config.h" | 20 #include "remoting/host/host_config.h" |
19 #include "remoting/host/host_key_pair.h" | 21 #include "remoting/host/host_key_pair.h" |
20 #include "remoting/host/screen_recorder.h" | 22 #include "remoting/host/screen_recorder.h" |
21 #include "remoting/host/user_authenticator.h" | 23 #include "remoting/host/user_authenticator.h" |
22 #include "remoting/jingle_glue/xmpp_signal_strategy.h" | 24 #include "remoting/jingle_glue/xmpp_signal_strategy.h" |
23 #include "remoting/proto/auth.pb.h" | 25 #include "remoting/proto/auth.pb.h" |
24 #include "remoting/protocol/connection_to_client.h" | 26 #include "remoting/protocol/connection_to_client.h" |
25 #include "remoting/protocol/client_stub.h" | 27 #include "remoting/protocol/client_stub.h" |
26 #include "remoting/protocol/host_stub.h" | 28 #include "remoting/protocol/host_stub.h" |
27 #include "remoting/protocol/input_stub.h" | 29 #include "remoting/protocol/input_stub.h" |
28 #include "remoting/protocol/jingle_session_manager.h" | 30 #include "remoting/protocol/jingle_session_manager.h" |
29 #include "remoting/protocol/session_config.h" | 31 #include "remoting/protocol/session_config.h" |
30 | 32 |
31 using remoting::protocol::ConnectionToClient; | 33 using remoting::protocol::ConnectionToClient; |
32 using remoting::protocol::InputStub; | 34 using remoting::protocol::InputStub; |
33 | 35 |
34 namespace remoting { | 36 namespace remoting { |
35 | 37 |
36 // static | 38 // static |
37 ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context, | 39 ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context, |
38 MutableHostConfig* config, | 40 MutableHostConfig* config, |
39 AccessVerifier* access_verifier) { | 41 AccessVerifier* access_verifier, |
| 42 Logger* logger) { |
40 DesktopEnvironment* desktop_env = DesktopEnvironment::Create(context); | 43 DesktopEnvironment* desktop_env = DesktopEnvironment::Create(context); |
41 return Create(context, config, desktop_env, access_verifier); | 44 return Create(context, config, desktop_env, access_verifier, logger); |
42 } | 45 } |
43 | 46 |
44 // static | 47 // static |
45 ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context, | 48 ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context, |
46 MutableHostConfig* config, | 49 MutableHostConfig* config, |
47 DesktopEnvironment* environment, | 50 DesktopEnvironment* environment, |
48 AccessVerifier* access_verifier) { | 51 AccessVerifier* access_verifier, |
49 return new ChromotingHost(context, config, environment, access_verifier); | 52 Logger* logger) { |
| 53 return new ChromotingHost(context, config, environment, access_verifier, |
| 54 logger); |
50 } | 55 } |
51 | 56 |
52 ChromotingHost::ChromotingHost(ChromotingHostContext* context, | 57 ChromotingHost::ChromotingHost(ChromotingHostContext* context, |
53 MutableHostConfig* config, | 58 MutableHostConfig* config, |
54 DesktopEnvironment* environment, | 59 DesktopEnvironment* environment, |
55 AccessVerifier* access_verifier) | 60 AccessVerifier* access_verifier, |
| 61 Logger* logger) |
56 : context_(context), | 62 : context_(context), |
57 config_(config), | 63 config_(config), |
58 desktop_environment_(environment), | 64 desktop_environment_(environment), |
59 access_verifier_(access_verifier), | 65 access_verifier_(access_verifier), |
| 66 logger_(logger), |
60 state_(kInitial), | 67 state_(kInitial), |
61 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), | 68 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), |
62 is_curtained_(false), | 69 is_curtained_(false), |
63 is_it2me_(false) { | 70 is_it2me_(false) { |
64 DCHECK(desktop_environment_.get()); | 71 DCHECK(desktop_environment_.get()); |
65 desktop_environment_->set_host(this); | 72 desktop_environment_->set_host(this); |
66 } | 73 } |
67 | 74 |
68 ChromotingHost::~ChromotingHost() { | 75 ChromotingHost::~ChromotingHost() { |
69 } | 76 } |
70 | 77 |
71 void ChromotingHost::Start() { | 78 void ChromotingHost::Start() { |
72 if (MessageLoop::current() != context_->network_message_loop()) { | 79 if (MessageLoop::current() != context_->network_message_loop()) { |
73 context_->network_message_loop()->PostTask( | 80 context_->network_message_loop()->PostTask( |
74 FROM_HERE, base::Bind(&ChromotingHost::Start, this)); | 81 FROM_HERE, base::Bind(&ChromotingHost::Start, this)); |
75 return; | 82 return; |
76 } | 83 } |
77 | 84 |
| 85 logger_->Log(logging::LOG_INFO, "Starting host"); |
78 DCHECK(!signal_strategy_.get()); | 86 DCHECK(!signal_strategy_.get()); |
79 DCHECK(access_verifier_.get()); | 87 DCHECK(access_verifier_.get()); |
80 | 88 |
81 // Make sure this object is not started. | 89 // Make sure this object is not started. |
82 { | 90 { |
83 base::AutoLock auto_lock(lock_); | 91 base::AutoLock auto_lock(lock_); |
84 if (state_ != kInitial) | 92 if (state_ != kInitial) |
85 return; | 93 return; |
86 state_ = kStarted; | 94 state_ = kStarted; |
87 } | 95 } |
88 | 96 |
89 std::string xmpp_login; | 97 std::string xmpp_login; |
90 std::string xmpp_auth_token; | 98 std::string xmpp_auth_token; |
91 std::string xmpp_auth_service; | 99 std::string xmpp_auth_service; |
92 if (!config_->GetString(kXmppLoginConfigPath, &xmpp_login) || | 100 if (!config_->GetString(kXmppLoginConfigPath, &xmpp_login) || |
93 !config_->GetString(kXmppAuthTokenConfigPath, &xmpp_auth_token) || | 101 !config_->GetString(kXmppAuthTokenConfigPath, &xmpp_auth_token) || |
94 !config_->GetString(kXmppAuthServiceConfigPath, &xmpp_auth_service)) { | 102 !config_->GetString(kXmppAuthServiceConfigPath, &xmpp_auth_service)) { |
95 LOG(ERROR) << "XMPP credentials are not defined in the config."; | 103 logger_->Log(logging::LOG_ERROR, |
| 104 "XMPP credentials are not defined in the config."); |
96 return; | 105 return; |
97 } | 106 } |
98 | 107 |
99 // Connect to the talk network with a JingleClient. | 108 // Connect to the talk network with a JingleClient. |
100 signal_strategy_.reset( | 109 signal_strategy_.reset( |
101 new XmppSignalStrategy(context_->jingle_thread(), xmpp_login, | 110 new XmppSignalStrategy(context_->jingle_thread(), xmpp_login, |
102 xmpp_auth_token, | 111 xmpp_auth_token, |
103 xmpp_auth_service)); | 112 xmpp_auth_service)); |
104 signal_strategy_->Init(this); | 113 signal_strategy_->Init(this); |
105 } | 114 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 | 157 |
149 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { | 158 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { |
150 DCHECK_EQ(state_, kInitial); | 159 DCHECK_EQ(state_, kInitial); |
151 status_observers_.push_back(observer); | 160 status_observers_.push_back(observer); |
152 } | 161 } |
153 | 162 |
154 //////////////////////////////////////////////////////////////////////////// | 163 //////////////////////////////////////////////////////////////////////////// |
155 // protocol::ConnectionToClient::EventHandler implementations | 164 // protocol::ConnectionToClient::EventHandler implementations |
156 void ChromotingHost::OnConnectionOpened(ConnectionToClient* connection) { | 165 void ChromotingHost::OnConnectionOpened(ConnectionToClient* connection) { |
157 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); | 166 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); |
158 VLOG(1) << "Connection to client established."; | 167 logger_->VLog(1, "Connection to client established."); |
159 // TODO(wez): ChromotingHost shouldn't need to know about Me2Mom. | 168 // TODO(wez): ChromotingHost shouldn't need to know about Me2Mom. |
160 if (is_it2me_) { | 169 if (is_it2me_) { |
161 context_->main_message_loop()->PostTask( | 170 context_->main_message_loop()->PostTask( |
162 FROM_HERE, base::Bind(&ChromotingHost::ProcessPreAuthentication, this, | 171 FROM_HERE, base::Bind(&ChromotingHost::ProcessPreAuthentication, this, |
163 make_scoped_refptr(connection))); | 172 make_scoped_refptr(connection))); |
164 } | 173 } |
165 } | 174 } |
166 | 175 |
167 void ChromotingHost::OnConnectionClosed(ConnectionToClient* connection) { | 176 void ChromotingHost::OnConnectionClosed(ConnectionToClient* connection) { |
168 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); | 177 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); |
169 | 178 |
170 VLOG(1) << "Connection to client closed."; | 179 logger_->VLog(1, "Connection to client closed."); |
171 context_->main_message_loop()->PostTask( | 180 context_->main_message_loop()->PostTask( |
172 FROM_HERE, base::Bind(&ChromotingHost::OnClientDisconnected, this, | 181 FROM_HERE, base::Bind(&ChromotingHost::OnClientDisconnected, this, |
173 make_scoped_refptr(connection))); | 182 make_scoped_refptr(connection))); |
174 } | 183 } |
175 | 184 |
176 void ChromotingHost::OnConnectionFailed(ConnectionToClient* connection) { | 185 void ChromotingHost::OnConnectionFailed(ConnectionToClient* connection) { |
177 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); | 186 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); |
178 | 187 |
179 LOG(ERROR) << "Connection failed unexpectedly."; | 188 logger_->Log(logging::LOG_ERROR, "Connection failed unexpectedly."); |
180 context_->main_message_loop()->PostTask( | 189 context_->main_message_loop()->PostTask( |
181 FROM_HERE, base::Bind(&ChromotingHost::OnClientDisconnected, this, | 190 FROM_HERE, base::Bind(&ChromotingHost::OnClientDisconnected, this, |
182 make_scoped_refptr(connection))); | 191 make_scoped_refptr(connection))); |
183 } | 192 } |
184 | 193 |
185 void ChromotingHost::OnSequenceNumberUpdated(ConnectionToClient* connection, | 194 void ChromotingHost::OnSequenceNumberUpdated(ConnectionToClient* connection, |
186 int64 sequence_number) { | 195 int64 sequence_number) { |
187 // Update the sequence number in ScreenRecorder. | 196 // Update the sequence number in ScreenRecorder. |
188 if (MessageLoop::current() != context_->main_message_loop()) { | 197 if (MessageLoop::current() != context_->main_message_loop()) { |
189 context_->main_message_loop()->PostTask( | 198 context_->main_message_loop()->PostTask( |
190 FROM_HERE, base::Bind(&ChromotingHost::OnSequenceNumberUpdated, this, | 199 FROM_HERE, base::Bind(&ChromotingHost::OnSequenceNumberUpdated, this, |
191 make_scoped_refptr(connection), sequence_number)); | 200 make_scoped_refptr(connection), sequence_number)); |
192 return; | 201 return; |
193 } | 202 } |
194 | 203 |
195 if (recorder_.get()) | 204 if (recorder_.get()) |
196 recorder_->UpdateSequenceNumber(sequence_number); | 205 recorder_->UpdateSequenceNumber(sequence_number); |
197 } | 206 } |
198 | 207 |
199 //////////////////////////////////////////////////////////////////////////// | 208 //////////////////////////////////////////////////////////////////////////// |
200 // JingleClient::Callback implementations | 209 // JingleClient::Callback implementations |
201 void ChromotingHost::OnStateChange( | 210 void ChromotingHost::OnStateChange( |
202 SignalStrategy::StatusObserver::State state) { | 211 SignalStrategy::StatusObserver::State state) { |
203 DCHECK_EQ(MessageLoop::current(), context_->network_message_loop()); | 212 DCHECK_EQ(MessageLoop::current(), context_->network_message_loop()); |
204 | 213 |
205 if (state == SignalStrategy::StatusObserver::CONNECTED) { | 214 if (state == SignalStrategy::StatusObserver::CONNECTED) { |
206 VLOG(1) << "Host connected as " << local_jid_; | 215 logger_->Log(logging::LOG_INFO, "Host connected as %s", local_jid_.c_str()); |
207 | 216 |
208 // Create and start session manager. | 217 // Create and start session manager. |
209 protocol::JingleSessionManager* server = | 218 protocol::JingleSessionManager* server = |
210 protocol::JingleSessionManager::CreateNotSandboxed(); | 219 protocol::JingleSessionManager::CreateNotSandboxed(); |
211 // TODO(ajwong): Make this a command switch when we're more stable. | 220 // TODO(ajwong): Make this a command switch when we're more stable. |
212 server->set_allow_local_ips(true); | 221 server->set_allow_local_ips(true); |
213 | 222 |
214 // Assign key and certificate to server. | 223 // Assign key and certificate to server. |
215 HostKeyPair key_pair; | 224 HostKeyPair key_pair; |
216 CHECK(key_pair.Load(config_)) | 225 CHECK(key_pair.Load(config_)) |
217 << "Failed to load server authentication data"; | 226 << "Failed to load server authentication data"; |
218 | 227 |
219 server->Init(local_jid_, signal_strategy_.get(), | 228 server->Init(local_jid_, signal_strategy_.get(), |
220 NewCallback(this, &ChromotingHost::OnNewClientSession), | 229 NewCallback(this, &ChromotingHost::OnNewClientSession), |
221 key_pair.CopyPrivateKey(), key_pair.GenerateCertificate()); | 230 key_pair.CopyPrivateKey(), key_pair.GenerateCertificate()); |
222 | 231 |
223 session_manager_.reset(server); | 232 session_manager_.reset(server); |
224 | 233 |
225 for (StatusObserverList::iterator it = status_observers_.begin(); | 234 for (StatusObserverList::iterator it = status_observers_.begin(); |
226 it != status_observers_.end(); ++it) { | 235 it != status_observers_.end(); ++it) { |
227 (*it)->OnSignallingConnected(signal_strategy_.get(), local_jid_); | 236 (*it)->OnSignallingConnected(signal_strategy_.get(), local_jid_); |
228 } | 237 } |
229 } else if (state == SignalStrategy::StatusObserver::CLOSED) { | 238 } else if (state == SignalStrategy::StatusObserver::CLOSED) { |
230 VLOG(1) << "Host disconnected from talk network."; | 239 logger_->Log(logging::LOG_INFO, "Host disconnected from talk network."); |
231 for (StatusObserverList::iterator it = status_observers_.begin(); | 240 for (StatusObserverList::iterator it = status_observers_.begin(); |
232 it != status_observers_.end(); ++it) { | 241 it != status_observers_.end(); ++it) { |
233 (*it)->OnSignallingDisconnected(); | 242 (*it)->OnSignallingDisconnected(); |
234 } | 243 } |
235 // TODO(sergeyu): Don't shutdown the host and let the upper level | 244 // TODO(sergeyu): Don't shutdown the host and let the upper level |
236 // decide what needs to be done when signalling channel is | 245 // decide what needs to be done when signalling channel is |
237 // disconnected. | 246 // disconnected. |
238 Shutdown(NULL); | 247 Shutdown(NULL); |
239 } | 248 } |
240 } | 249 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 | 284 |
276 // TODO(simonmorris): The resolution is set in the video stream now, | 285 // TODO(simonmorris): The resolution is set in the video stream now, |
277 // so it doesn't need to be set here. | 286 // so it doesn't need to be set here. |
278 *protocol_config_->mutable_initial_resolution() = | 287 *protocol_config_->mutable_initial_resolution() = |
279 protocol::ScreenResolution(2048, 2048); | 288 protocol::ScreenResolution(2048, 2048); |
280 // TODO(sergeyu): Respect resolution requested by the client if supported. | 289 // TODO(sergeyu): Respect resolution requested by the client if supported. |
281 protocol::SessionConfig* config = protocol_config_->Select( | 290 protocol::SessionConfig* config = protocol_config_->Select( |
282 session->candidate_config(), true /* force_host_resolution */); | 291 session->candidate_config(), true /* force_host_resolution */); |
283 | 292 |
284 if (!config) { | 293 if (!config) { |
285 LOG(WARNING) << "Rejecting connection from " << session->jid() | 294 logger_->Log(logging::LOG_WARNING, |
286 << " because no compatible configuration has been found."; | 295 "Rejecting connection from %s because no compatible" |
| 296 " configuration has been found.", session->jid().c_str()); |
287 *response = protocol::SessionManager::INCOMPATIBLE; | 297 *response = protocol::SessionManager::INCOMPATIBLE; |
288 return; | 298 return; |
289 } | 299 } |
290 | 300 |
291 session->set_config(config); | 301 session->set_config(config); |
292 session->set_receiver_token( | 302 session->set_receiver_token( |
293 GenerateHostAuthToken(session->initiator_token())); | 303 GenerateHostAuthToken(session->initiator_token())); |
294 | 304 |
295 *response = protocol::SessionManager::ACCEPT; | 305 *response = protocol::SessionManager::ACCEPT; |
296 | 306 |
297 VLOG(1) << "Client connected: " << session->jid(); | 307 logger_->Log(logging::LOG_INFO, "Client connected: %s", |
| 308 session->jid().c_str()); |
298 | 309 |
299 // We accept the connection, so create a connection object. | 310 // We accept the connection, so create a connection object. |
300 ConnectionToClient* connection = new ConnectionToClient( | 311 ConnectionToClient* connection = new ConnectionToClient( |
301 context_->network_message_loop(), this); | 312 context_->network_message_loop(), this); |
302 | 313 |
303 // Create a client object. | 314 // Create a client object. |
304 ClientSession* client = new ClientSession( | 315 ClientSession* client = new ClientSession( |
305 this, | 316 this, |
306 UserAuthenticator::Create(), | 317 UserAuthenticator::Create(), |
307 connection, | 318 connection, |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 | 605 |
595 for (std::vector<Task*>::iterator it = shutdown_tasks_.begin(); | 606 for (std::vector<Task*>::iterator it = shutdown_tasks_.begin(); |
596 it != shutdown_tasks_.end(); ++it) { | 607 it != shutdown_tasks_.end(); ++it) { |
597 (*it)->Run(); | 608 (*it)->Run(); |
598 delete *it; | 609 delete *it; |
599 } | 610 } |
600 shutdown_tasks_.clear(); | 611 shutdown_tasks_.clear(); |
601 } | 612 } |
602 | 613 |
603 } // namespace remoting | 614 } // namespace remoting |
OLD | NEW |