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/protocol/jingle_chromotocol_server.h" | 5 #include "remoting/protocol/jingle_session_manager.h" |
6 | 6 |
7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
8 #include "base/string_number_conversions.h" | 8 #include "base/string_number_conversions.h" |
9 #include "remoting/base/constants.h" | 9 #include "remoting/base/constants.h" |
10 #include "remoting/jingle_glue/jingle_thread.h" | 10 #include "remoting/jingle_glue/jingle_thread.h" |
11 #include "third_party/libjingle/source/talk/p2p/base/constants.h" | 11 #include "third_party/libjingle/source/talk/p2p/base/constants.h" |
12 #include "third_party/libjingle/source/talk/p2p/base/transport.h" | 12 #include "third_party/libjingle/source/talk/p2p/base/transport.h" |
13 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | 13 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
14 | 14 |
15 using cricket::ContentDescription; | 15 using cricket::ContentDescription; |
16 using cricket::SessionDescription; | 16 using cricket::SessionDescription; |
17 using cricket::Session; | |
18 using cricket::SessionManager; | |
19 using buzz::QName; | 17 using buzz::QName; |
20 using buzz::XmlElement; | 18 using buzz::XmlElement; |
21 | 19 |
22 namespace remoting { | 20 namespace remoting { |
23 | 21 |
| 22 namespace protocol { |
| 23 |
24 namespace { | 24 namespace { |
25 | 25 |
26 const char kDefaultNs[] = ""; | 26 const char kDefaultNs[] = ""; |
27 | 27 |
28 const char kChromotingContentName[] = "chromoting"; | 28 const char kChromotingContentName[] = "chromoting"; |
29 | 29 |
30 // Following constants are used to format session description in XML. | 30 // Following constants are used to format session description in XML. |
31 const char kDescriptionTag[] = "description"; | 31 const char kDescriptionTag[] = "description"; |
32 const char kControlTag[] = "control"; | 32 const char kControlTag[] = "control"; |
33 const char kEventTag[] = "event"; | 33 const char kEventTag[] = "event"; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 } | 143 } |
144 } else { | 144 } else { |
145 config->codec = ChannelConfig::CODEC_UNDEFINED; | 145 config->codec = ChannelConfig::CODEC_UNDEFINED; |
146 } | 146 } |
147 | 147 |
148 return true; | 148 return true; |
149 } | 149 } |
150 | 150 |
151 } // namespace | 151 } // namespace |
152 | 152 |
153 ChromotocolContentDescription::ChromotocolContentDescription( | 153 ContentDescription::ContentDescription( |
154 const CandidateChromotocolConfig* config) | 154 const CandidateChromotocolConfig* config) |
155 : candidate_config_(config) { | 155 : candidate_config_(config) { |
156 } | 156 } |
157 | 157 |
158 ChromotocolContentDescription::~ChromotocolContentDescription() { } | 158 ContentDescription::~ContentDescription() { } |
159 | 159 |
160 JingleChromotocolServer::JingleChromotocolServer( | 160 JingleSessionManager::JingleSessionManager( |
161 JingleThread* jingle_thread) | 161 JingleThread* jingle_thread) |
162 : jingle_thread_(jingle_thread), | 162 : jingle_thread_(jingle_thread), |
163 session_manager_(NULL), | 163 cricket_session_manager_(NULL), |
164 allow_local_ips_(false), | 164 allow_local_ips_(false), |
165 closed_(false) { | 165 closed_(false) { |
166 DCHECK(jingle_thread_); | 166 DCHECK(jingle_thread_); |
167 } | 167 } |
168 | 168 |
169 void JingleChromotocolServer::Init( | 169 void JingleSessionManager::Init( |
170 const std::string& local_jid, | 170 const std::string& local_jid, |
171 cricket::SessionManager* session_manager, | 171 cricket::SessionManager* cricket_session_manager, |
172 IncomingConnectionCallback* incoming_connection_callback) { | 172 IncomingSessionCallback* incoming_session_callback) { |
173 if (MessageLoop::current() != message_loop()) { | 173 if (MessageLoop::current() != message_loop()) { |
174 message_loop()->PostTask( | 174 message_loop()->PostTask( |
175 FROM_HERE, NewRunnableMethod( | 175 FROM_HERE, NewRunnableMethod( |
176 this, &JingleChromotocolServer::Init, | 176 this, &JingleSessionManager::Init, |
177 local_jid, session_manager, incoming_connection_callback)); | 177 local_jid, cricket_session_manager, incoming_session_callback)); |
178 return; | 178 return; |
179 } | 179 } |
180 | 180 |
181 DCHECK(session_manager); | 181 DCHECK(cricket_session_manager); |
182 DCHECK(incoming_connection_callback); | 182 DCHECK(incoming_session_callback); |
183 | 183 |
184 local_jid_ = local_jid; | 184 local_jid_ = local_jid; |
185 incoming_connection_callback_.reset(incoming_connection_callback); | 185 incoming_session_callback_.reset(incoming_session_callback); |
186 session_manager_ = session_manager; | 186 cricket_session_manager_ = cricket_session_manager; |
187 session_manager_->AddClient(kChromotingXmlNamespace, this); | 187 cricket_session_manager_->AddClient(kChromotingXmlNamespace, this); |
188 } | 188 } |
189 | 189 |
190 JingleChromotocolServer::~JingleChromotocolServer() { | 190 JingleSessionManager::~JingleSessionManager() { |
191 DCHECK(closed_); | 191 DCHECK(closed_); |
192 } | 192 } |
193 | 193 |
194 void JingleChromotocolServer::Close(Task* closed_task) { | 194 void JingleSessionManager::Close(Task* closed_task) { |
195 if (MessageLoop::current() != message_loop()) { | 195 if (MessageLoop::current() != message_loop()) { |
196 message_loop()->PostTask( | 196 message_loop()->PostTask( |
197 FROM_HERE, NewRunnableMethod(this, &JingleChromotocolServer::Close, | 197 FROM_HERE, NewRunnableMethod(this, &JingleSessionManager::Close, |
198 closed_task)); | 198 closed_task)); |
199 return; | 199 return; |
200 } | 200 } |
201 | 201 |
202 if (!closed_) { | 202 if (!closed_) { |
203 // Close all connections. | 203 // Close all connections. |
204 session_manager_->RemoveClient(kChromotingXmlNamespace); | 204 cricket_session_manager_->RemoveClient(kChromotingXmlNamespace); |
205 while (!connections_.empty()) { | 205 while (!sessions_.empty()) { |
206 Session* session = connections_.front()->ReleaseSession(); | 206 cricket::Session* session = sessions_.front()->ReleaseSession(); |
207 session_manager_->DestroySession(session); | 207 cricket_session_manager_->DestroySession(session); |
208 connections_.pop_front(); | 208 sessions_.pop_front(); |
209 } | 209 } |
210 closed_ = true; | 210 closed_ = true; |
211 } | 211 } |
212 | 212 |
213 closed_task->Run(); | 213 closed_task->Run(); |
214 delete closed_task; | 214 delete closed_task; |
215 } | 215 } |
216 | 216 |
217 void JingleChromotocolServer::set_allow_local_ips(bool allow_local_ips) { | 217 void JingleSessionManager::set_allow_local_ips(bool allow_local_ips) { |
218 allow_local_ips_ = allow_local_ips; | 218 allow_local_ips_ = allow_local_ips; |
219 } | 219 } |
220 | 220 |
221 scoped_refptr<ChromotocolConnection> JingleChromotocolServer::Connect( | 221 scoped_refptr<protocol::Session> JingleSessionManager::Connect( |
222 const std::string& jid, | 222 const std::string& jid, |
223 CandidateChromotocolConfig* chromotocol_config, | 223 CandidateChromotocolConfig* chromotocol_config, |
224 ChromotocolConnection::StateChangeCallback* state_change_callback) { | 224 protocol::Session::StateChangeCallback* state_change_callback) { |
225 // Can be called from any thread. | 225 // Can be called from any thread. |
226 scoped_refptr<JingleChromotocolConnection> connection( | 226 scoped_refptr<JingleSession> jingle_session( |
227 new JingleChromotocolConnection(this)); | 227 new JingleSession(this)); |
228 connection->set_candidate_config(chromotocol_config); | 228 jingle_session->set_candidate_config(chromotocol_config); |
229 message_loop()->PostTask( | 229 message_loop()->PostTask( |
230 FROM_HERE, NewRunnableMethod(this, &JingleChromotocolServer::DoConnect, | 230 FROM_HERE, NewRunnableMethod(this, &JingleSessionManager::DoConnect, |
231 connection, jid, | 231 jingle_session, jid, |
232 state_change_callback)); | 232 state_change_callback)); |
233 return connection; | 233 return jingle_session; |
234 } | 234 } |
235 | 235 |
236 void JingleChromotocolServer::DoConnect( | 236 void JingleSessionManager::DoConnect( |
237 scoped_refptr<JingleChromotocolConnection> connection, | 237 scoped_refptr<JingleSession> jingle_session, |
238 const std::string& jid, | 238 const std::string& jid, |
239 ChromotocolConnection::StateChangeCallback* state_change_callback) { | 239 protocol::Session::StateChangeCallback* state_change_callback) { |
240 DCHECK_EQ(message_loop(), MessageLoop::current()); | 240 DCHECK_EQ(message_loop(), MessageLoop::current()); |
241 Session* session = session_manager_->CreateSession( | 241 cricket::Session* cricket_session = cricket_session_manager_->CreateSession( |
242 local_jid_, kChromotingXmlNamespace); | 242 local_jid_, kChromotingXmlNamespace); |
243 | 243 |
244 // Initialize connection object before we send initiate stanza. | 244 // Initialize connection object before we send initiate stanza. |
245 connection->SetStateChangeCallback(state_change_callback); | 245 jingle_session->SetStateChangeCallback(state_change_callback); |
246 connection->Init(session); | 246 jingle_session->Init(cricket_session); |
247 connections_.push_back(connection); | 247 sessions_.push_back(jingle_session); |
248 | 248 |
249 session->Initiate( | 249 cricket_session->Initiate( |
250 jid, CreateSessionDescription(connection->candidate_config()->Clone())); | 250 jid, |
| 251 CreateSessionDescription(jingle_session->candidate_config()->Clone())); |
251 } | 252 } |
252 | 253 |
253 JingleThread* JingleChromotocolServer::jingle_thread() { | 254 JingleThread* JingleSessionManager::jingle_thread() { |
254 return jingle_thread_; | 255 return jingle_thread_; |
255 } | 256 } |
256 | 257 |
257 MessageLoop* JingleChromotocolServer::message_loop() { | 258 MessageLoop* JingleSessionManager::message_loop() { |
258 return jingle_thread_->message_loop(); | 259 return jingle_thread_->message_loop(); |
259 } | 260 } |
260 | 261 |
261 void JingleChromotocolServer::OnSessionCreate( | 262 void JingleSessionManager::OnSessionCreate( |
262 Session* session, bool incoming) { | 263 cricket::Session* cricket_session, bool incoming) { |
263 DCHECK_EQ(message_loop(), MessageLoop::current()); | 264 DCHECK_EQ(message_loop(), MessageLoop::current()); |
264 | 265 |
265 // Allow local connections if neccessary. | 266 // Allow local connections if neccessary. |
266 session->set_allow_local_ips(allow_local_ips_); | 267 cricket_session->set_allow_local_ips(allow_local_ips_); |
267 | 268 |
268 // If this is an outcoming session the connection object is already | 269 // If this is an outcoming session the connection object is already |
269 // created. | 270 // created. |
270 if (incoming) { | 271 if (incoming) { |
271 JingleChromotocolConnection* connection = | 272 JingleSession* jingle_session = new JingleSession(this); |
272 new JingleChromotocolConnection(this); | 273 sessions_.push_back(make_scoped_refptr(jingle_session)); |
273 connections_.push_back(make_scoped_refptr(connection)); | 274 jingle_session->Init(cricket_session); |
274 connection->Init(session); | |
275 } | 275 } |
276 } | 276 } |
277 | 277 |
278 void JingleChromotocolServer::OnSessionDestroy(Session* session) { | 278 void JingleSessionManager::OnSessionDestroy(cricket::Session* cricket_session) { |
279 DCHECK_EQ(message_loop(), MessageLoop::current()); | 279 DCHECK_EQ(message_loop(), MessageLoop::current()); |
280 | 280 |
281 std::list<scoped_refptr<JingleChromotocolConnection> >::iterator it; | 281 std::list<scoped_refptr<JingleSession> >::iterator it; |
282 for (it = connections_.begin(); it != connections_.end(); ++it) { | 282 for (it = sessions_.begin(); it != sessions_.end(); ++it) { |
283 if ((*it)->HasSession(session)) { | 283 if ((*it)->HasSession(cricket_session)) { |
284 (*it)->ReleaseSession(); | 284 (*it)->ReleaseSession(); |
285 connections_.erase(it); | 285 sessions_.erase(it); |
286 return; | 286 return; |
287 } | 287 } |
288 } | 288 } |
289 } | 289 } |
290 | 290 |
291 void JingleChromotocolServer::AcceptConnection( | 291 void JingleSessionManager::AcceptConnection( |
292 JingleChromotocolConnection* connection, | 292 JingleSession* jingle_session, |
293 Session* session) { | 293 cricket::Session* cricket_session) { |
294 DCHECK_EQ(message_loop(), MessageLoop::current()); | 294 DCHECK_EQ(message_loop(), MessageLoop::current()); |
295 | 295 |
296 // Reject connection if we are closed. | 296 // Reject connection if we are closed. |
297 if (closed_) { | 297 if (closed_) { |
298 session->Reject(cricket::STR_TERMINATE_DECLINE); | 298 cricket_session->Reject(cricket::STR_TERMINATE_DECLINE); |
299 return; | 299 return; |
300 } | 300 } |
301 | 301 |
302 const cricket::SessionDescription* session_description = | 302 const cricket::SessionDescription* session_description = |
303 session->remote_description(); | 303 cricket_session->remote_description(); |
304 const cricket::ContentInfo* content = | 304 const cricket::ContentInfo* content = |
305 session_description->FirstContentByType(kChromotingXmlNamespace); | 305 session_description->FirstContentByType(kChromotingXmlNamespace); |
306 | 306 |
307 CHECK(content); | 307 CHECK(content); |
308 | 308 |
309 const ChromotocolContentDescription* content_description = | 309 const ContentDescription* content_description = |
310 static_cast<const ChromotocolContentDescription*>(content->description); | 310 static_cast<const ContentDescription*>(content->description); |
311 connection->set_candidate_config(content_description->config()->Clone()); | 311 jingle_session->set_candidate_config(content_description->config()->Clone()); |
312 | 312 |
313 IncomingConnectionResponse response = ChromotocolServer::DECLINE; | 313 IncomingSessionResponse response = protocol::SessionManager::DECLINE; |
314 | 314 |
315 // Always reject connection if there is no callback. | 315 // Always reject connection if there is no callback. |
316 if (incoming_connection_callback_.get()) | 316 if (incoming_session_callback_.get()) |
317 incoming_connection_callback_->Run(connection, &response); | 317 incoming_session_callback_->Run(jingle_session, &response); |
318 | 318 |
319 switch (response) { | 319 switch (response) { |
320 case ChromotocolServer::ACCEPT: { | 320 case protocol::SessionManager::ACCEPT: { |
321 // Connection must be configured by the callback. | 321 // Connection must be configured by the callback. |
322 DCHECK(connection->config()); | 322 DCHECK(jingle_session->config()); |
323 CandidateChromotocolConfig* candidate_config = | 323 CandidateChromotocolConfig* candidate_config = |
324 CandidateChromotocolConfig::CreateFrom(connection->config()); | 324 CandidateChromotocolConfig::CreateFrom(jingle_session->config()); |
325 session->Accept(CreateSessionDescription(candidate_config)); | 325 cricket_session->Accept(CreateSessionDescription(candidate_config)); |
326 break; | 326 break; |
327 } | 327 } |
328 | 328 |
329 case ChromotocolServer::INCOMPATIBLE: { | 329 case protocol::SessionManager::INCOMPATIBLE: { |
330 session->Reject(cricket::STR_TERMINATE_INCOMPATIBLE_PARAMETERS); | 330 cricket_session->Reject(cricket::STR_TERMINATE_INCOMPATIBLE_PARAMETERS); |
331 break; | 331 break; |
332 } | 332 } |
333 | 333 |
334 case ChromotocolServer::DECLINE: { | 334 case protocol::SessionManager::DECLINE: { |
335 session->Reject(cricket::STR_TERMINATE_DECLINE); | 335 cricket_session->Reject(cricket::STR_TERMINATE_DECLINE); |
336 break; | 336 break; |
337 } | 337 } |
338 | 338 |
339 default: { | 339 default: { |
340 NOTREACHED(); | 340 NOTREACHED(); |
341 } | 341 } |
342 } | 342 } |
343 } | 343 } |
344 | 344 |
345 // Parse content description generated by WriteContent(). | 345 // Parse content description generated by WriteContent(). |
346 bool JingleChromotocolServer::ParseContent( | 346 bool JingleSessionManager::ParseContent( |
347 cricket::SignalingProtocol protocol, | 347 cricket::SignalingProtocol protocol, |
348 const XmlElement* element, | 348 const XmlElement* element, |
349 const cricket::ContentDescription** content, | 349 const cricket::ContentDescription** content, |
350 cricket::ParseError* error) { | 350 cricket::ParseError* error) { |
351 if (element->Name() == QName(kChromotingXmlNamespace, kDescriptionTag)) { | 351 if (element->Name() == QName(kChromotingXmlNamespace, kDescriptionTag)) { |
352 scoped_ptr<CandidateChromotocolConfig> config( | 352 scoped_ptr<CandidateChromotocolConfig> config( |
353 CandidateChromotocolConfig::CreateEmpty()); | 353 CandidateChromotocolConfig::CreateEmpty()); |
354 const XmlElement* child = NULL; | 354 const XmlElement* child = NULL; |
355 | 355 |
356 // <control> tags. | 356 // <control> tags. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 &height)) { | 398 &height)) { |
399 return false; | 399 return false; |
400 } | 400 } |
401 ScreenResolution resolution(width, height); | 401 ScreenResolution resolution(width, height); |
402 if (!resolution.IsValid()) { | 402 if (!resolution.IsValid()) { |
403 return false; | 403 return false; |
404 } | 404 } |
405 | 405 |
406 config->SetInitialResolution(resolution); | 406 config->SetInitialResolution(resolution); |
407 | 407 |
408 *content = new ChromotocolContentDescription(config.release()); | 408 *content = new ContentDescription(config.release()); |
409 return true; | 409 return true; |
410 } | 410 } |
411 LOG(ERROR) << "Invalid description: " << element->Str(); | 411 LOG(ERROR) << "Invalid description: " << element->Str(); |
412 return false; | 412 return false; |
413 } | 413 } |
414 | 414 |
415 // WriteContent creates content description for chromoting session. The | 415 // WriteContent creates content description for chromoting session. The |
416 // description looks as follows: | 416 // description looks as follows: |
417 // <description xmlns="google:remoting"> | 417 // <description xmlns="google:remoting"> |
418 // <control transport="stream" version="1" /> | 418 // <control transport="stream" version="1" /> |
419 // <event transport="datagram" version="1" /> | 419 // <event transport="datagram" version="1" /> |
420 // <video transport="srtp" codec="vp8" version="1" /> | 420 // <video transport="srtp" codec="vp8" version="1" /> |
421 // <initial-resolution width="800" height="600" /> | 421 // <initial-resolution width="800" height="600" /> |
422 // </description> | 422 // </description> |
423 // | 423 // |
424 bool JingleChromotocolServer::WriteContent( | 424 bool JingleSessionManager::WriteContent( |
425 cricket::SignalingProtocol protocol, | 425 cricket::SignalingProtocol protocol, |
426 const cricket::ContentDescription* content, | 426 const cricket::ContentDescription* content, |
427 XmlElement** elem, | 427 XmlElement** elem, |
428 cricket::WriteError* error) { | 428 cricket::WriteError* error) { |
429 const ChromotocolContentDescription* desc = | 429 const ContentDescription* desc = |
430 static_cast<const ChromotocolContentDescription*>(content); | 430 static_cast<const ContentDescription*>(content); |
431 | 431 |
432 XmlElement* root = new XmlElement( | 432 XmlElement* root = new XmlElement( |
433 QName(kChromotingXmlNamespace, kDescriptionTag), true); | 433 QName(kChromotingXmlNamespace, kDescriptionTag), true); |
434 | 434 |
435 const CandidateChromotocolConfig* config = desc->config(); | 435 const CandidateChromotocolConfig* config = desc->config(); |
436 std::vector<ChannelConfig>::const_iterator it; | 436 std::vector<ChannelConfig>::const_iterator it; |
437 | 437 |
438 for (it = config->control_configs().begin(); | 438 for (it = config->control_configs().begin(); |
439 it != config->control_configs().end(); ++it) { | 439 it != config->control_configs().end(); ++it) { |
440 root->AddElement(FormatChannelConfig(*it, kControlTag)); | 440 root->AddElement(FormatChannelConfig(*it, kControlTag)); |
(...skipping 16 matching lines...) Expand all Loading... |
457 config->initial_resolution().width)); | 457 config->initial_resolution().width)); |
458 resolution_tag->AddAttr(QName(kDefaultNs, kHeightAttr), | 458 resolution_tag->AddAttr(QName(kDefaultNs, kHeightAttr), |
459 base::IntToString( | 459 base::IntToString( |
460 config->initial_resolution().height)); | 460 config->initial_resolution().height)); |
461 root->AddElement(resolution_tag); | 461 root->AddElement(resolution_tag); |
462 | 462 |
463 *elem = root; | 463 *elem = root; |
464 return true; | 464 return true; |
465 } | 465 } |
466 | 466 |
467 SessionDescription* JingleChromotocolServer::CreateSessionDescription( | 467 SessionDescription* JingleSessionManager::CreateSessionDescription( |
468 const CandidateChromotocolConfig* config) { | 468 const CandidateChromotocolConfig* config) { |
469 SessionDescription* desc = new SessionDescription(); | 469 SessionDescription* desc = new SessionDescription(); |
470 desc->AddContent(JingleChromotocolConnection::kChromotingContentName, | 470 desc->AddContent(JingleSession::kChromotingContentName, |
471 kChromotingXmlNamespace, | 471 kChromotingXmlNamespace, |
472 new ChromotocolContentDescription(config)); | 472 new ContentDescription(config)); |
473 return desc; | 473 return desc; |
474 } | 474 } |
475 | 475 |
| 476 } // namespace protocol |
| 477 |
476 } // namespace remoting | 478 } // namespace remoting |
OLD | NEW |