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