OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/router/media_router_mojo_impl.h" | 5 #include "chrome/browser/media/router/media_router_mojo_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/guid.h" | 8 #include "base/guid.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_vector.h" | 10 #include "base/memory/scoped_vector.h" |
11 #include "base/observer_list.h" | 11 #include "base/observer_list.h" |
12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
13 #include "chrome/browser/media/router/issues_observer.h" | 13 #include "chrome/browser/media/router/issues_observer.h" |
| 14 #include "chrome/browser/media/router/local_media_routes_observer.h" |
14 #include "chrome/browser/media/router/media_router_factory.h" | 15 #include "chrome/browser/media/router/media_router_factory.h" |
15 #include "chrome/browser/media/router/media_router_type_converters.h" | 16 #include "chrome/browser/media/router/media_router_type_converters.h" |
16 #include "chrome/browser/media/router/media_routes_observer.h" | 17 #include "chrome/browser/media/router/media_routes_observer.h" |
17 #include "chrome/browser/media/router/media_sinks_observer.h" | 18 #include "chrome/browser/media/router/media_sinks_observer.h" |
18 #include "chrome/browser/media/router/presentation_session_messages_observer.h" | 19 #include "chrome/browser/media/router/presentation_session_messages_observer.h" |
19 #include "extensions/browser/process_manager.h" | 20 #include "extensions/browser/process_manager.h" |
20 | 21 |
21 #define DVLOG_WITH_INSTANCE(level) \ | 22 #define DVLOG_WITH_INSTANCE(level) \ |
22 DVLOG(level) << "MR #" << instance_id_ << ": " | 23 DVLOG(level) << "MR #" << instance_id_ << ": " |
23 | 24 |
24 #define DLOG_WITH_INSTANCE(level) DLOG(level) << "MR #" << instance_id_ << ": " | 25 #define DLOG_WITH_INSTANCE(level) DLOG(level) << "MR #" << instance_id_ << ": " |
25 | 26 |
26 namespace media_router { | 27 namespace media_router { |
27 namespace { | 28 namespace { |
28 | 29 |
29 // Converts the callback result of calling Mojo CreateRoute()/JoinRoute() | |
30 // into a local callback. | |
31 void RouteResponseReceived( | |
32 const std::string& presentation_id, | |
33 const std::vector<MediaRouteResponseCallback>& callbacks, | |
34 interfaces::MediaRoutePtr media_route, | |
35 const mojo::String& error_text) { | |
36 scoped_ptr<MediaRoute> route; | |
37 std::string actual_presentation_id; | |
38 std::string error; | |
39 if (media_route.is_null()) { | |
40 // An error occurred. | |
41 DCHECK(!error_text.is_null()); | |
42 error = !error_text.get().empty() ? error_text.get() : "Unknown error."; | |
43 } else { | |
44 route = media_route.To<scoped_ptr<MediaRoute>>(); | |
45 actual_presentation_id = presentation_id; | |
46 } | |
47 | |
48 for (const MediaRouteResponseCallback& callback : callbacks) | |
49 callback.Run(route.get(), actual_presentation_id, error); | |
50 } | |
51 | |
52 // TODO(imcheng): We should handle failure in this case. One way is to invoke | 30 // TODO(imcheng): We should handle failure in this case. One way is to invoke |
53 // all pending requests with failure. (crbug.com/490787) | 31 // all pending requests with failure. (crbug.com/490787) |
54 void EventPageWakeComplete(bool success) { | 32 void EventPageWakeComplete(bool success) { |
55 if (!success) | 33 if (!success) |
56 LOG(ERROR) << "An error encountered while waking the event page."; | 34 LOG(ERROR) << "An error encountered while waking the event page."; |
57 } | 35 } |
58 | 36 |
59 scoped_ptr<content::PresentationSessionMessage> | 37 scoped_ptr<content::PresentationSessionMessage> |
60 ConvertToPresentationSessionMessage(interfaces::RouteMessagePtr input) { | 38 ConvertToPresentationSessionMessage(interfaces::RouteMessagePtr input) { |
61 DCHECK(!input.is_null()); | 39 DCHECK(!input.is_null()); |
(...skipping 17 matching lines...) Expand all Loading... |
79 return output.Pass(); | 57 return output.Pass(); |
80 } | 58 } |
81 } | 59 } |
82 | 60 |
83 NOTREACHED() << "Invalid route message type " << input->type; | 61 NOTREACHED() << "Invalid route message type " << input->type; |
84 return output.Pass(); | 62 return output.Pass(); |
85 } | 63 } |
86 | 64 |
87 } // namespace | 65 } // namespace |
88 | 66 |
| 67 MediaRouterMojoImpl::MediaRouterMediaRoutesObserver:: |
| 68 MediaRouterMediaRoutesObserver(MediaRouterMojoImpl* router) |
| 69 : MediaRoutesObserver(router), |
| 70 router_(router) { |
| 71 DCHECK(router); |
| 72 } |
| 73 |
| 74 MediaRouterMojoImpl::MediaRouterMediaRoutesObserver:: |
| 75 ~MediaRouterMediaRoutesObserver() { |
| 76 } |
| 77 |
| 78 void MediaRouterMojoImpl::MediaRouterMediaRoutesObserver::OnRoutesUpdated( |
| 79 const std::vector<media_router::MediaRoute>& routes) { |
| 80 bool has_local_route = |
| 81 std::find_if(routes.begin(), routes.end(), |
| 82 [](const media_router::MediaRoute& route) { |
| 83 return route.is_local(); }) != |
| 84 routes.end(); |
| 85 |
| 86 // |this| will be deleted in UpdateHasLocalRoute() if |has_local_route| is |
| 87 // false. Note that ObserverList supports removing an observer while |
| 88 // iterating through it. |
| 89 router_->UpdateHasLocalRoute(has_local_route); |
| 90 } |
| 91 |
89 MediaRouterMojoImpl::MediaRouterMojoImpl( | 92 MediaRouterMojoImpl::MediaRouterMojoImpl( |
90 extensions::EventPageTracker* event_page_tracker) | 93 extensions::EventPageTracker* event_page_tracker) |
91 : event_page_tracker_(event_page_tracker), | 94 : event_page_tracker_(event_page_tracker), |
92 instance_id_(base::GenerateGUID()) { | 95 instance_id_(base::GenerateGUID()), |
| 96 has_local_route_(false) { |
93 DCHECK(event_page_tracker_); | 97 DCHECK(event_page_tracker_); |
94 } | 98 } |
95 | 99 |
96 MediaRouterMojoImpl::~MediaRouterMojoImpl() { | 100 MediaRouterMojoImpl::~MediaRouterMojoImpl() { |
97 DCHECK(thread_checker_.CalledOnValidThread()); | 101 DCHECK(thread_checker_.CalledOnValidThread()); |
98 } | 102 } |
99 | 103 |
100 // static | 104 // static |
101 void MediaRouterMojoImpl::BindToRequest( | 105 void MediaRouterMojoImpl::BindToRequest( |
102 const std::string& extension_id, | 106 const std::string& extension_id, |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 routes_converted.reserve(routes.size()); | 188 routes_converted.reserve(routes.size()); |
185 | 189 |
186 for (size_t i = 0; i < routes.size(); ++i) { | 190 for (size_t i = 0; i < routes.size(); ++i) { |
187 routes_converted.push_back(routes[i].To<MediaRoute>()); | 191 routes_converted.push_back(routes[i].To<MediaRoute>()); |
188 } | 192 } |
189 | 193 |
190 FOR_EACH_OBSERVER(MediaRoutesObserver, routes_observers_, | 194 FOR_EACH_OBSERVER(MediaRoutesObserver, routes_observers_, |
191 OnRoutesUpdated(routes_converted)); | 195 OnRoutesUpdated(routes_converted)); |
192 } | 196 } |
193 | 197 |
| 198 void MediaRouterMojoImpl::RouteResponseReceived( |
| 199 const std::string& presentation_id, |
| 200 const std::vector<MediaRouteResponseCallback>& callbacks, |
| 201 interfaces::MediaRoutePtr media_route, |
| 202 const mojo::String& error_text) { |
| 203 scoped_ptr<MediaRoute> route; |
| 204 std::string actual_presentation_id; |
| 205 std::string error; |
| 206 if (media_route.is_null()) { |
| 207 // An error occurred. |
| 208 DCHECK(!error_text.is_null()); |
| 209 error = !error_text.get().empty() ? error_text.get() : "Unknown error."; |
| 210 } else { |
| 211 route = media_route.To<scoped_ptr<MediaRoute>>(); |
| 212 actual_presentation_id = presentation_id; |
| 213 |
| 214 UpdateHasLocalRoute(true); |
| 215 |
| 216 if (!routes_observer_) |
| 217 routes_observer_.reset(new MediaRouterMediaRoutesObserver(this)); |
| 218 } |
| 219 |
| 220 for (const MediaRouteResponseCallback& callback : callbacks) |
| 221 callback.Run(route.get(), actual_presentation_id, error); |
| 222 } |
| 223 |
| 224 void MediaRouterMojoImpl::UpdateHasLocalRoute(bool has_local_route) { |
| 225 if (has_local_route_ == has_local_route) |
| 226 return; |
| 227 |
| 228 has_local_route_ = has_local_route; |
| 229 |
| 230 if (!has_local_route_) |
| 231 routes_observer_.reset(); |
| 232 |
| 233 FOR_EACH_OBSERVER(LocalMediaRoutesObserver, local_routes_observers_, |
| 234 OnHasLocalRouteUpdated(has_local_route_)); |
| 235 } |
| 236 |
194 void MediaRouterMojoImpl::CreateRoute( | 237 void MediaRouterMojoImpl::CreateRoute( |
195 const MediaSource::Id& source_id, | 238 const MediaSource::Id& source_id, |
196 const MediaSink::Id& sink_id, | 239 const MediaSink::Id& sink_id, |
197 const GURL& origin, | 240 const GURL& origin, |
198 int tab_id, | 241 int tab_id, |
199 const std::vector<MediaRouteResponseCallback>& callbacks) { | 242 const std::vector<MediaRouteResponseCallback>& callbacks) { |
200 DCHECK(thread_checker_.CalledOnValidThread()); | 243 DCHECK(thread_checker_.CalledOnValidThread()); |
201 | 244 |
202 if (!origin.is_valid()) { | 245 if (!origin.is_valid()) { |
203 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin; | 246 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin; |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 return; | 429 return; |
387 | 430 |
388 observer_list->RemoveObserver(observer); | 431 observer_list->RemoveObserver(observer); |
389 if (!observer_list->might_have_observers()) { | 432 if (!observer_list->might_have_observers()) { |
390 messages_observers_.erase(route_id); | 433 messages_observers_.erase(route_id); |
391 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopListeningForRouteMessages, | 434 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopListeningForRouteMessages, |
392 base::Unretained(this), route_id)); | 435 base::Unretained(this), route_id)); |
393 } | 436 } |
394 } | 437 } |
395 | 438 |
| 439 void MediaRouterMojoImpl::RegisterLocalMediaRoutesObserver( |
| 440 LocalMediaRoutesObserver* observer) { |
| 441 DCHECK(thread_checker_.CalledOnValidThread()); |
| 442 DCHECK(observer); |
| 443 |
| 444 DCHECK(!local_routes_observers_.HasObserver(observer)); |
| 445 local_routes_observers_.AddObserver(observer); |
| 446 } |
| 447 |
| 448 void MediaRouterMojoImpl::UnregisterLocalMediaRoutesObserver( |
| 449 LocalMediaRoutesObserver* observer) { |
| 450 DCHECK(thread_checker_.CalledOnValidThread()); |
| 451 DCHECK(observer); |
| 452 |
| 453 if (!local_routes_observers_.HasObserver(observer)) |
| 454 return; |
| 455 local_routes_observers_.RemoveObserver(observer); |
| 456 } |
| 457 |
396 void MediaRouterMojoImpl::DoCreateRoute( | 458 void MediaRouterMojoImpl::DoCreateRoute( |
397 const MediaSource::Id& source_id, | 459 const MediaSource::Id& source_id, |
398 const MediaSink::Id& sink_id, | 460 const MediaSink::Id& sink_id, |
399 const std::string& origin, | 461 const std::string& origin, |
400 int tab_id, | 462 int tab_id, |
401 const std::vector<MediaRouteResponseCallback>& callbacks) { | 463 const std::vector<MediaRouteResponseCallback>& callbacks) { |
402 std::string presentation_id("mr_"); | 464 std::string presentation_id("mr_"); |
403 presentation_id += base::GenerateGUID(); | 465 presentation_id += base::GenerateGUID(); |
404 DVLOG_WITH_INSTANCE(1) << "DoCreateRoute " << source_id << "=>" << sink_id | 466 DVLOG_WITH_INSTANCE(1) << "DoCreateRoute " << source_id << "=>" << sink_id |
405 << ", presentation ID: " << presentation_id; | 467 << ", presentation ID: " << presentation_id; |
406 media_route_provider_->CreateRoute( | 468 media_route_provider_->CreateRoute( |
407 source_id, sink_id, presentation_id, origin, tab_id, | 469 source_id, sink_id, presentation_id, origin, tab_id, |
408 base::Bind(&RouteResponseReceived, presentation_id, callbacks)); | 470 base::Bind(&MediaRouterMojoImpl::RouteResponseReceived, |
| 471 base::Unretained(this), presentation_id, callbacks)); |
409 } | 472 } |
410 | 473 |
411 void MediaRouterMojoImpl::DoJoinRoute( | 474 void MediaRouterMojoImpl::DoJoinRoute( |
412 const MediaSource::Id& source_id, | 475 const MediaSource::Id& source_id, |
413 const std::string& presentation_id, | 476 const std::string& presentation_id, |
414 const std::string& origin, | 477 const std::string& origin, |
415 int tab_id, | 478 int tab_id, |
416 const std::vector<MediaRouteResponseCallback>& callbacks) { | 479 const std::vector<MediaRouteResponseCallback>& callbacks) { |
417 DVLOG_WITH_INSTANCE(1) << "DoJoinRoute " << source_id | 480 DVLOG_WITH_INSTANCE(1) << "DoJoinRoute " << source_id |
418 << ", presentation ID: " << presentation_id; | 481 << ", presentation ID: " << presentation_id; |
419 media_route_provider_->JoinRoute( | 482 media_route_provider_->JoinRoute( |
420 source_id, presentation_id, origin, tab_id, | 483 source_id, presentation_id, origin, tab_id, |
421 base::Bind(&RouteResponseReceived, presentation_id, callbacks)); | 484 base::Bind(&MediaRouterMojoImpl::RouteResponseReceived, |
| 485 base::Unretained(this), presentation_id, callbacks)); |
422 } | 486 } |
423 | 487 |
424 void MediaRouterMojoImpl::DoCloseRoute(const MediaRoute::Id& route_id) { | 488 void MediaRouterMojoImpl::DoCloseRoute(const MediaRoute::Id& route_id) { |
425 DVLOG_WITH_INSTANCE(1) << "DoCloseRoute " << route_id; | 489 DVLOG_WITH_INSTANCE(1) << "DoCloseRoute " << route_id; |
426 media_route_provider_->CloseRoute(route_id); | 490 media_route_provider_->CloseRoute(route_id); |
427 } | 491 } |
428 | 492 |
429 void MediaRouterMojoImpl::DoSendSessionMessage( | 493 void MediaRouterMojoImpl::DoSendSessionMessage( |
430 const MediaRoute::Id& route_id, | 494 const MediaRoute::Id& route_id, |
431 const std::string& message, | 495 const std::string& message, |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 route_id, base::Bind(&MediaRouterMojoImpl::OnRouteMessagesReceived, | 575 route_id, base::Bind(&MediaRouterMojoImpl::OnRouteMessagesReceived, |
512 base::Unretained(this), route_id)); | 576 base::Unretained(this), route_id)); |
513 } | 577 } |
514 | 578 |
515 void MediaRouterMojoImpl::DoOnPresentationSessionDetached( | 579 void MediaRouterMojoImpl::DoOnPresentationSessionDetached( |
516 const MediaRoute::Id& route_id) { | 580 const MediaRoute::Id& route_id) { |
517 DVLOG_WITH_INSTANCE(1) << "DoOnPresentationSessionDetached " << route_id; | 581 DVLOG_WITH_INSTANCE(1) << "DoOnPresentationSessionDetached " << route_id; |
518 media_route_provider_->OnPresentationSessionDetached(route_id); | 582 media_route_provider_->OnPresentationSessionDetached(route_id); |
519 } | 583 } |
520 | 584 |
| 585 bool MediaRouterMojoImpl::HasLocalRoute() const { |
| 586 return has_local_route_; |
| 587 } |
| 588 |
521 void MediaRouterMojoImpl::DoStartObservingMediaSinks( | 589 void MediaRouterMojoImpl::DoStartObservingMediaSinks( |
522 const MediaSource::Id& source_id) { | 590 const MediaSource::Id& source_id) { |
523 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaSinks: " << source_id; | 591 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaSinks: " << source_id; |
524 media_route_provider_->StartObservingMediaSinks(source_id); | 592 media_route_provider_->StartObservingMediaSinks(source_id); |
525 } | 593 } |
526 | 594 |
527 void MediaRouterMojoImpl::DoStopObservingMediaSinks( | 595 void MediaRouterMojoImpl::DoStopObservingMediaSinks( |
528 const MediaSource::Id& source_id) { | 596 const MediaSource::Id& source_id) { |
529 DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaSinks: " << source_id; | 597 DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaSinks: " << source_id; |
530 media_route_provider_->StopObservingMediaSinks(source_id); | 598 media_route_provider_->StopObservingMediaSinks(source_id); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 return; | 652 return; |
585 } | 653 } |
586 | 654 |
587 for (const auto& next_request : pending_requests_) | 655 for (const auto& next_request : pending_requests_) |
588 next_request.Run(); | 656 next_request.Run(); |
589 | 657 |
590 pending_requests_.clear(); | 658 pending_requests_.clear(); |
591 } | 659 } |
592 | 660 |
593 } // namespace media_router | 661 } // namespace media_router |
OLD | NEW |