OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "chrome/browser/media/cast_remoting_connector.h" | 5 #include "chrome/browser/media/cast_remoting_connector.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
13 #include "chrome/browser/media/cast_remoting_connector_messaging.h" | 13 #include "chrome/browser/media/cast_remoting_connector_messaging.h" |
14 #include "chrome/browser/media/cast_remoting_sender.h" | 14 #include "chrome/browser/media/cast_remoting_sender.h" |
15 #include "chrome/browser/media/router/media_router.h" | 15 #include "chrome/browser/media/router/media_router.h" |
16 #include "chrome/browser/media/router/media_router_factory.h" | 16 #include "chrome/browser/media/router/media_router_factory.h" |
17 #include "chrome/browser/media/router/route_message_observer.h" | 17 #include "chrome/browser/media/router/route_message_observer.h" |
18 #include "chrome/browser/sessions/session_tab_helper.h" | 18 #include "chrome/browser/sessions/session_tab_helper.h" |
19 #include "chrome/common/chrome_features.h" | 19 #include "chrome/common/chrome_features.h" |
20 #include "chrome/common/media_router/media_source_helper.h" | 20 #include "chrome/common/media_router/media_source_helper.h" |
21 #include "chrome/common/media_router/route_message.h" | |
22 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
23 #include "content/public/browser/render_frame_host.h" | 22 #include "content/public/browser/render_frame_host.h" |
24 #include "content/public/browser/render_process_host.h" | 23 #include "content/public/browser/render_process_host.h" |
25 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
26 #include "mojo/public/cpp/bindings/strong_binding.h" | 25 #include "mojo/public/cpp/bindings/strong_binding.h" |
27 | 26 |
28 using content::BrowserThread; | 27 using content::BrowserThread; |
29 using media::mojom::RemotingSinkCapabilities; | 28 using media::mojom::RemotingSinkCapabilities; |
30 using media::mojom::RemotingStartFailReason; | 29 using media::mojom::RemotingStartFailReason; |
31 using media::mojom::RemotingStopReason; | 30 using media::mojom::RemotingStopReason; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 : public media_router::RouteMessageObserver { | 115 : public media_router::RouteMessageObserver { |
117 public: | 116 public: |
118 MessageObserver(media_router::MediaRouter* router, | 117 MessageObserver(media_router::MediaRouter* router, |
119 const media_router::MediaRoute::Id& route_id, | 118 const media_router::MediaRoute::Id& route_id, |
120 CastRemotingConnector* connector) | 119 CastRemotingConnector* connector) |
121 : RouteMessageObserver(router, route_id), connector_(connector) {} | 120 : RouteMessageObserver(router, route_id), connector_(connector) {} |
122 ~MessageObserver() final {} | 121 ~MessageObserver() final {} |
123 | 122 |
124 private: | 123 private: |
125 void OnMessagesReceived( | 124 void OnMessagesReceived( |
126 const std::vector<media_router::RouteMessage>& messages) final { | 125 const std::vector<content::PresentationConnectionMessage>& messages) |
| 126 final { |
127 connector_->ProcessMessagesFromRoute(messages); | 127 connector_->ProcessMessagesFromRoute(messages); |
128 } | 128 } |
129 | 129 |
130 CastRemotingConnector* const connector_; | 130 CastRemotingConnector* const connector_; |
131 }; | 131 }; |
132 | 132 |
133 // static | 133 // static |
134 const void* const CastRemotingConnector::kUserDataKey = &kUserDataKey; | 134 const void* const CastRemotingConnector::kUserDataKey = &kUserDataKey; |
135 | 135 |
136 // static | 136 // static |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 struct Helper { | 358 struct Helper { |
359 static void IgnoreSendMessageResult(bool ignored) {} | 359 static void IgnoreSendMessageResult(bool ignored) {} |
360 }; | 360 }; |
361 media_router::MediaRoutesObserver::router()->SendRouteMessage( | 361 media_router::MediaRoutesObserver::router()->SendRouteMessage( |
362 message_observer_->route_id(), message, | 362 message_observer_->route_id(), message, |
363 base::Bind(&Helper::IgnoreSendMessageResult)); | 363 base::Bind(&Helper::IgnoreSendMessageResult)); |
364 } | 364 } |
365 } | 365 } |
366 | 366 |
367 void CastRemotingConnector::ProcessMessagesFromRoute( | 367 void CastRemotingConnector::ProcessMessagesFromRoute( |
368 const std::vector<media_router::RouteMessage>& messages) { | 368 const std::vector<content::PresentationConnectionMessage>& messages) { |
369 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 369 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
370 | 370 |
371 // Note: If any calls to message parsing functions are added/changed here, | 371 // Note: If any calls to message parsing functions are added/changed here, |
372 // please update cast_remoting_connector_fuzzertest.cc as well! | 372 // please update cast_remoting_connector_fuzzertest.cc as well! |
373 | 373 |
374 for (const media_router::RouteMessage& message : messages) { | 374 for (const auto& message : messages) { |
375 switch (message.type) { | 375 if (message.is_binary()) { |
376 case media_router::RouteMessage::TEXT: | 376 // All binary messages are passed through to the source during an active |
377 // This is a notification message from the Cast Provider, about the | 377 // remoting session. |
378 // execution state of the media remoting session between Chrome and the | 378 if (active_bridge_) |
379 // remote device. | 379 active_bridge_->OnMessageFromSink(*message.data); |
380 DCHECK(message.text); | |
381 | 380 |
382 // If this is a "start streams" acknowledgement message, the | 381 continue; |
383 // CastRemotingSenders should now be available to begin consuming from | 382 } |
384 // the data pipes. | |
385 if (active_bridge_ && | |
386 Messaging::IsMessageForSession( | |
387 *message.text, | |
388 Messaging::kStartedStreamsMessageFormatPartial, | |
389 session_counter_)) { | |
390 if (pending_audio_sender_request_.is_pending()) { | |
391 cast::CastRemotingSender::FindAndBind( | |
392 Messaging::GetStreamIdFromStartedMessage( | |
393 *message.text, | |
394 Messaging::kStartedStreamsMessageAudioIdSpecifier), | |
395 std::move(pending_audio_pipe_), | |
396 std::move(pending_audio_sender_request_), | |
397 base::Bind(&CastRemotingConnector::OnDataSendFailed, | |
398 weak_factory_.GetWeakPtr())); | |
399 } | |
400 if (pending_video_sender_request_.is_pending()) { | |
401 cast::CastRemotingSender::FindAndBind( | |
402 Messaging::GetStreamIdFromStartedMessage( | |
403 *message.text, | |
404 Messaging::kStartedStreamsMessageVideoIdSpecifier), | |
405 std::move(pending_video_pipe_), | |
406 std::move(pending_video_sender_request_), | |
407 base::Bind(&CastRemotingConnector::OnDataSendFailed, | |
408 weak_factory_.GetWeakPtr())); | |
409 } | |
410 break; | |
411 } | |
412 | 383 |
413 // If this is a failure message, call StopRemoting(). | 384 // This is a notification message from the Cast Provider, about the |
414 if (active_bridge_ && | 385 // execution state of the media remoting session between Chrome and the |
415 Messaging::IsMessageForSession(*message.text, | 386 // remote device. |
416 Messaging::kFailedMessageFormat, | |
417 session_counter_)) { | |
418 StopRemoting(active_bridge_, RemotingStopReason::UNEXPECTED_FAILURE); | |
419 break; | |
420 } | |
421 | 387 |
422 // If this is a stop acknowledgement message, indicating that the last | 388 // If this is a "start streams" acknowledgement message, the |
423 // session was stopped, notify all sources that the sink is once again | 389 // CastRemotingSenders should now be available to begin consuming from |
424 // available. | 390 // the data pipes. |
425 if (Messaging::IsMessageForSession(*message.text, | 391 if (active_bridge_ && |
426 Messaging::kStoppedMessageFormat, | 392 Messaging::IsMessageForSession( |
427 session_counter_)) { | 393 *message.message, Messaging::kStartedStreamsMessageFormatPartial, |
428 if (active_bridge_) { | 394 session_counter_)) { |
429 // Hmm...The Cast Provider was in a state that disagrees with this | 395 if (pending_audio_sender_request_.is_pending()) { |
430 // connector. Attempt to resolve this by shutting everything down to | 396 cast::CastRemotingSender::FindAndBind( |
431 // effectively reset to a known state. | 397 Messaging::GetStreamIdFromStartedMessage( |
432 LOG(WARNING) << "BUG: Cast Provider sent 'stopped' message during " | 398 *message.message, |
433 "an active remoting session."; | 399 Messaging::kStartedStreamsMessageAudioIdSpecifier), |
434 StopRemoting(active_bridge_, | 400 std::move(pending_audio_pipe_), |
435 RemotingStopReason::UNEXPECTED_FAILURE); | 401 std::move(pending_audio_sender_request_), |
436 } | 402 base::Bind(&CastRemotingConnector::OnDataSendFailed, |
437 for (RemotingBridge* notifyee : bridges_) | 403 weak_factory_.GetWeakPtr())); |
438 notifyee->OnSinkAvailable(enabled_features_); | 404 } |
439 break; | 405 if (pending_video_sender_request_.is_pending()) { |
440 } | 406 cast::CastRemotingSender::FindAndBind( |
441 | 407 Messaging::GetStreamIdFromStartedMessage( |
442 LOG(WARNING) << "BUG: Unexpected message from Cast Provider: " | 408 *message.message, |
443 << *message.text; | 409 Messaging::kStartedStreamsMessageVideoIdSpecifier), |
444 break; | 410 std::move(pending_video_pipe_), |
445 | 411 std::move(pending_video_sender_request_), |
446 case media_router::RouteMessage::BINARY: // This is for the source. | 412 base::Bind(&CastRemotingConnector::OnDataSendFailed, |
447 DCHECK(message.binary); | 413 weak_factory_.GetWeakPtr())); |
448 | 414 } |
449 // All binary messages are passed through to the source during an active | 415 } else if (active_bridge_ && |
450 // remoting session. | 416 Messaging::IsMessageForSession(*message.message, |
451 if (active_bridge_) | 417 Messaging::kFailedMessageFormat, |
452 active_bridge_->OnMessageFromSink(*message.binary); | 418 session_counter_)) { |
453 break; | 419 // If this is a failure message, call StopRemoting(). |
| 420 StopRemoting(active_bridge_, RemotingStopReason::UNEXPECTED_FAILURE); |
| 421 } else if (Messaging::IsMessageForSession(*message.message, |
| 422 Messaging::kStoppedMessageFormat, |
| 423 session_counter_)) { |
| 424 // If this is a stop acknowledgement message, indicating that the last |
| 425 // session was stopped, notify all sources that the sink is once again |
| 426 // available. |
| 427 if (active_bridge_) { |
| 428 // Hmm...The Cast Provider was in a state that disagrees with this |
| 429 // connector. Attempt to resolve this by shutting everything down to |
| 430 // effectively reset to a known state. |
| 431 LOG(WARNING) << "BUG: Cast Provider sent 'stopped' message during " |
| 432 "an active remoting session."; |
| 433 StopRemoting(active_bridge_, RemotingStopReason::UNEXPECTED_FAILURE); |
| 434 } |
| 435 for (RemotingBridge* notifyee : bridges_) |
| 436 notifyee->OnSinkAvailable(enabled_features_); |
| 437 } else { |
| 438 LOG(WARNING) << "BUG: Unexpected message from Cast Provider: " |
| 439 << *message.message; |
454 } | 440 } |
455 } | 441 } |
456 } | 442 } |
457 | 443 |
458 void CastRemotingConnector::HandleSendMessageResult(bool success) { | 444 void CastRemotingConnector::HandleSendMessageResult(bool success) { |
459 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 445 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
460 // A single message send failure is treated as fatal to an active remoting | 446 // A single message send failure is treated as fatal to an active remoting |
461 // session. | 447 // session. |
462 if (!success && active_bridge_) | 448 if (!success && active_bridge_) |
463 StopRemoting(active_bridge_, RemotingStopReason::MESSAGE_SEND_FAILED); | 449 StopRemoting(active_bridge_, RemotingStopReason::MESSAGE_SEND_FAILED); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 media_router::MediaRoutesObserver::router(), route.media_route_id(), | 491 media_router::MediaRoutesObserver::router(), route.media_route_id(), |
506 this)); | 492 this)); |
507 // TODO(miu): In the future, scan the route ID for sink capabilities | 493 // TODO(miu): In the future, scan the route ID for sink capabilities |
508 // properties and pass these to the source in the OnSinkAvailable() | 494 // properties and pass these to the source in the OnSinkAvailable() |
509 // notification. | 495 // notification. |
510 for (RemotingBridge* notifyee : bridges_) | 496 for (RemotingBridge* notifyee : bridges_) |
511 notifyee->OnSinkAvailable(enabled_features_); | 497 notifyee->OnSinkAvailable(enabled_features_); |
512 break; | 498 break; |
513 } | 499 } |
514 } | 500 } |
OLD | NEW |