| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/stl_util-inl.h" | 7 #include "base/stl_util-inl.h" |
| 8 #include "base/task.h" | 8 #include "base/task.h" |
| 9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
| 10 #include "remoting/base/constants.h" | 10 #include "remoting/base/constants.h" |
| 11 #include "remoting/base/encoder.h" | 11 #include "remoting/base/encoder.h" |
| 12 #include "remoting/base/encoder_verbatim.h" | 12 #include "remoting/base/encoder_verbatim.h" |
| 13 #include "remoting/base/encoder_vp8.h" | 13 #include "remoting/base/encoder_vp8.h" |
| 14 #include "remoting/base/encoder_zlib.h" | 14 #include "remoting/base/encoder_zlib.h" |
| 15 #include "remoting/host/chromoting_host_context.h" | 15 #include "remoting/host/chromoting_host_context.h" |
| 16 #include "remoting/host/capturer.h" | 16 #include "remoting/host/capturer.h" |
| 17 #include "remoting/host/event_executor.h" | 17 #include "remoting/host/event_executor.h" |
| 18 #include "remoting/host/host_config.h" | 18 #include "remoting/host/host_config.h" |
| 19 #include "remoting/host/session_manager.h" | 19 #include "remoting/host/session_manager.h" |
| 20 #include "remoting/protocol/jingle_chromotocol_server.h" | |
| 21 #include "remoting/protocol/chromotocol_config.h" | 20 #include "remoting/protocol/chromotocol_config.h" |
| 21 #include "remoting/protocol/jingle_session_manager.h" |
| 22 | 22 |
| 23 namespace remoting { | 23 namespace remoting { |
| 24 | 24 |
| 25 ChromotingHost::ChromotingHost(ChromotingHostContext* context, | 25 ChromotingHost::ChromotingHost(ChromotingHostContext* context, |
| 26 MutableHostConfig* config, | 26 MutableHostConfig* config, |
| 27 Capturer* capturer, | 27 Capturer* capturer, |
| 28 EventExecutor* executor) | 28 EventExecutor* executor) |
| 29 : context_(context), | 29 : context_(context), |
| 30 config_(config), | 30 config_(config), |
| 31 capturer_(capturer), | 31 capturer_(capturer), |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 // Disconnect all clients. | 109 // Disconnect all clients. |
| 110 if (client_) { | 110 if (client_) { |
| 111 client_->Disconnect(); | 111 client_->Disconnect(); |
| 112 } | 112 } |
| 113 | 113 |
| 114 // Stop the heartbeat sender. | 114 // Stop the heartbeat sender. |
| 115 if (heartbeat_sender_) { | 115 if (heartbeat_sender_) { |
| 116 heartbeat_sender_->Stop(); | 116 heartbeat_sender_->Stop(); |
| 117 } | 117 } |
| 118 | 118 |
| 119 // Stop chromotocol server. | 119 // Stop chromotocol session manager. |
| 120 if (chromotocol_server_) { | 120 if (session_manager_) { |
| 121 chromotocol_server_->Close( | 121 session_manager_->Close( |
| 122 NewRunnableMethod(this, &ChromotingHost::OnServerClosed)); | 122 NewRunnableMethod(this, &ChromotingHost::OnServerClosed)); |
| 123 } | 123 } |
| 124 | 124 |
| 125 // Disconnect from the talk network. | 125 // Disconnect from the talk network. |
| 126 if (jingle_client_) { | 126 if (jingle_client_) { |
| 127 jingle_client_->Close(); | 127 jingle_client_->Close(); |
| 128 } | 128 } |
| 129 | 129 |
| 130 // Lastly call the shutdown task. | 130 // Lastly call the shutdown task. |
| 131 if (shutdown_task_.get()) { | 131 if (shutdown_task_.get()) { |
| 132 shutdown_task_->Run(); | 132 shutdown_task_->Run(); |
| 133 } | 133 } |
| 134 } | 134 } |
| 135 | 135 |
| 136 // This method is called if a client is connected to this object. | 136 // This method is called if a client is connected to this object. |
| 137 void ChromotingHost::OnClientConnected(ClientConnection* client) { | 137 void ChromotingHost::OnClientConnected(ClientConnection* client) { |
| 138 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); | 138 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); |
| 139 | 139 |
| 140 // Create a new RecordSession if there was none. | 140 // Create a new RecordSession if there was none. |
| 141 if (!session_.get()) { | 141 if (!session_.get()) { |
| 142 // Then we create a SessionManager passing the message loops that | 142 // Then we create a SessionManager passing the message loops that |
| 143 // it should run on. | 143 // it should run on. |
| 144 DCHECK(capturer_.get()); | 144 DCHECK(capturer_.get()); |
| 145 | 145 |
| 146 Encoder* encoder = CreateEncoder(client->connection()->config()); | 146 Encoder* encoder = CreateEncoder(client->session()->config()); |
| 147 | 147 |
| 148 session_ = new SessionManager(context_->capture_message_loop(), | 148 session_ = new SessionManager(context_->capture_message_loop(), |
| 149 context_->encode_message_loop(), | 149 context_->encode_message_loop(), |
| 150 context_->main_message_loop(), | 150 context_->main_message_loop(), |
| 151 capturer_.release(), | 151 capturer_.release(), |
| 152 encoder); | 152 encoder); |
| 153 } | 153 } |
| 154 | 154 |
| 155 // Immediately add the client and start the session. | 155 // Immediately add the client and start the session. |
| 156 session_->AddClient(client); | 156 session_->AddClient(client); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 } | 210 } |
| 211 | 211 |
| 212 //////////////////////////////////////////////////////////////////////////// | 212 //////////////////////////////////////////////////////////////////////////// |
| 213 // JingleClient::Callback implementations | 213 // JingleClient::Callback implementations |
| 214 void ChromotingHost::OnStateChange(JingleClient* jingle_client, | 214 void ChromotingHost::OnStateChange(JingleClient* jingle_client, |
| 215 JingleClient::State state) { | 215 JingleClient::State state) { |
| 216 if (state == JingleClient::CONNECTED) { | 216 if (state == JingleClient::CONNECTED) { |
| 217 DCHECK_EQ(jingle_client_.get(), jingle_client); | 217 DCHECK_EQ(jingle_client_.get(), jingle_client); |
| 218 VLOG(1) << "Host connected as " << jingle_client->GetFullJid(); | 218 VLOG(1) << "Host connected as " << jingle_client->GetFullJid(); |
| 219 | 219 |
| 220 // Create and start |chromotocol_server_|. | 220 // Create and start session manager. |
| 221 JingleChromotocolServer* server = | 221 protocol::JingleSessionManager* server = |
| 222 new JingleChromotocolServer(context_->jingle_thread()); | 222 new protocol::JingleSessionManager(context_->jingle_thread()); |
| 223 // TODO(ajwong): Make this a command switch when we're more stable. | 223 // TODO(ajwong): Make this a command switch when we're more stable. |
| 224 server->set_allow_local_ips(true); | 224 server->set_allow_local_ips(true); |
| 225 server->Init(jingle_client->GetFullJid(), | 225 server->Init(jingle_client->GetFullJid(), |
| 226 jingle_client->session_manager(), | 226 jingle_client->session_manager(), |
| 227 NewCallback(this, &ChromotingHost::OnNewClientConnection)); | 227 NewCallback(this, &ChromotingHost::OnNewClientSession)); |
| 228 chromotocol_server_ = server; | 228 session_manager_ = server; |
| 229 | 229 |
| 230 // Start heartbeating. | 230 // Start heartbeating. |
| 231 heartbeat_sender_->Start(); | 231 heartbeat_sender_->Start(); |
| 232 } else if (state == JingleClient::CLOSED) { | 232 } else if (state == JingleClient::CLOSED) { |
| 233 VLOG(1) << "Host disconnected from talk network."; | 233 VLOG(1) << "Host disconnected from talk network."; |
| 234 | 234 |
| 235 // Stop heartbeating. | 235 // Stop heartbeating. |
| 236 heartbeat_sender_->Stop(); | 236 heartbeat_sender_->Stop(); |
| 237 | 237 |
| 238 // TODO(sergeyu): We should try reconnecting here instead of terminating | 238 // TODO(sergeyu): We should try reconnecting here instead of terminating |
| 239 // the host. | 239 // the host. |
| 240 Shutdown(); | 240 Shutdown(); |
| 241 } | 241 } |
| 242 } | 242 } |
| 243 | 243 |
| 244 void ChromotingHost::OnNewClientConnection( | 244 void ChromotingHost::OnNewClientSession( |
| 245 ChromotocolConnection* connection, | 245 protocol::Session* session, |
| 246 ChromotocolServer::IncomingConnectionResponse* response) { | 246 protocol::SessionManager::IncomingSessionResponse* response) { |
| 247 AutoLock auto_lock(lock_); | 247 AutoLock auto_lock(lock_); |
| 248 // TODO(hclam): Allow multiple clients to connect to the host. | 248 // TODO(hclam): Allow multiple clients to connect to the host. |
| 249 if (client_.get() || state_ != kStarted) { | 249 if (client_.get() || state_ != kStarted) { |
| 250 *response = ChromotocolServer::DECLINE; | 250 *response = protocol::SessionManager::DECLINE; |
| 251 return; | 251 return; |
| 252 } | 252 } |
| 253 | 253 |
| 254 // Check that the user has access to the host. | 254 // Check that the user has access to the host. |
| 255 if (!access_verifier_.VerifyPermissions(connection->jid())) { | 255 if (!access_verifier_.VerifyPermissions(session->jid())) { |
| 256 *response = ChromotocolServer::DECLINE; | 256 *response = protocol::SessionManager::DECLINE; |
| 257 return; | 257 return; |
| 258 } | 258 } |
| 259 | 259 |
| 260 scoped_ptr<CandidateChromotocolConfig> local_config( | 260 scoped_ptr<CandidateChromotocolConfig> local_config( |
| 261 CandidateChromotocolConfig::CreateDefault()); | 261 CandidateChromotocolConfig::CreateDefault()); |
| 262 local_config->SetInitialResolution( | 262 local_config->SetInitialResolution( |
| 263 ScreenResolution(capturer_->width(), capturer_->height())); | 263 ScreenResolution(capturer_->width(), capturer_->height())); |
| 264 // TODO(sergeyu): Respect resolution requested by the client if supported. | 264 // TODO(sergeyu): Respect resolution requested by the client if supported. |
| 265 ChromotocolConfig* config = | 265 ChromotocolConfig* config = |
| 266 local_config->Select(connection->candidate_config(), | 266 local_config->Select(session->candidate_config(), |
| 267 true /* force_host_resolution */); | 267 true /* force_host_resolution */); |
| 268 | 268 |
| 269 if (!config) { | 269 if (!config) { |
| 270 LOG(WARNING) << "Rejecting connection from " << connection->jid() | 270 LOG(WARNING) << "Rejecting connection from " << session->jid() |
| 271 << " because no compartible configuration has been found."; | 271 << " because no compatible configuration has been found."; |
| 272 *response = ChromotocolServer::INCOMPATIBLE; | 272 *response = protocol::SessionManager::INCOMPATIBLE; |
| 273 return; | 273 return; |
| 274 } | 274 } |
| 275 | 275 |
| 276 connection->set_config(config); | 276 session->set_config(config); |
| 277 | 277 |
| 278 *response = ChromotocolServer::ACCEPT; | 278 *response = protocol::SessionManager::ACCEPT; |
| 279 | 279 |
| 280 VLOG(1) << "Client connected: " << connection->jid(); | 280 VLOG(1) << "Client connected: " << session->jid(); |
| 281 | 281 |
| 282 // If we accept the connected then create a client object and set the | 282 // If we accept the connected then create a client object and set the |
| 283 // callback. | 283 // callback. |
| 284 client_ = new ClientConnection(context_->main_message_loop(), this); | 284 client_ = new ClientConnection(context_->main_message_loop(), this); |
| 285 client_->Init(connection); | 285 client_->Init(session); |
| 286 } | 286 } |
| 287 | 287 |
| 288 void ChromotingHost::OnServerClosed() { | 288 void ChromotingHost::OnServerClosed() { |
| 289 // Don't need to do anything here. | 289 // Don't need to do anything here. |
| 290 } | 290 } |
| 291 | 291 |
| 292 // TODO(sergeyu): Move this to SessionManager? | 292 // TODO(sergeyu): Move this to SessionManager? |
| 293 Encoder* ChromotingHost::CreateEncoder(const ChromotocolConfig* config) { | 293 Encoder* ChromotingHost::CreateEncoder(const ChromotocolConfig* config) { |
| 294 const ChannelConfig& video_config = config->video_config(); | 294 const ChannelConfig& video_config = config->video_config(); |
| 295 | 295 |
| 296 if (video_config.codec == ChannelConfig::CODEC_VERBATIM) { | 296 if (video_config.codec == ChannelConfig::CODEC_VERBATIM) { |
| 297 return new remoting::EncoderVerbatim(); | 297 return new remoting::EncoderVerbatim(); |
| 298 } else if (video_config.codec == ChannelConfig::CODEC_ZIP) { | 298 } else if (video_config.codec == ChannelConfig::CODEC_ZIP) { |
| 299 return new remoting::EncoderZlib(); | 299 return new remoting::EncoderZlib(); |
| 300 } | 300 } |
| 301 // TODO(sergeyu): Enable VP8 on ARM builds. | 301 // TODO(sergeyu): Enable VP8 on ARM builds. |
| 302 #if !defined(ARCH_CPU_ARM_FAMILY) | 302 #if !defined(ARCH_CPU_ARM_FAMILY) |
| 303 else if (video_config.codec == ChannelConfig::CODEC_VP8) { | 303 else if (video_config.codec == ChannelConfig::CODEC_VP8) { |
| 304 return new remoting::EncoderVp8(); | 304 return new remoting::EncoderVp8(); |
| 305 } | 305 } |
| 306 #endif | 306 #endif |
| 307 | 307 |
| 308 return NULL; | 308 return NULL; |
| 309 } | 309 } |
| 310 | 310 |
| 311 | 311 |
| 312 } // namespace remoting | 312 } // namespace remoting |
| OLD | NEW |