Chromium Code Reviews| 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 beyond this point if |has_local_route| is false. | |
|
imcheng
2015/10/02 20:59:40
As discussed offline, ObserverList supports removi
apacible
2015/10/02 22:30:59
Done.
| |
| 87 router_->UpdateHasLocalRoute(has_local_route); | |
| 88 } | |
| 89 | |
| 89 MediaRouterMojoImpl::MediaRouterMojoImpl( | 90 MediaRouterMojoImpl::MediaRouterMojoImpl( |
| 90 extensions::EventPageTracker* event_page_tracker) | 91 extensions::EventPageTracker* event_page_tracker) |
| 91 : event_page_tracker_(event_page_tracker), | 92 : event_page_tracker_(event_page_tracker), |
| 92 instance_id_(base::GenerateGUID()) { | 93 instance_id_(base::GenerateGUID()), |
| 94 has_local_route_(false) { | |
| 93 DCHECK(event_page_tracker_); | 95 DCHECK(event_page_tracker_); |
| 94 } | 96 } |
| 95 | 97 |
| 96 MediaRouterMojoImpl::~MediaRouterMojoImpl() { | 98 MediaRouterMojoImpl::~MediaRouterMojoImpl() { |
| 97 DCHECK(thread_checker_.CalledOnValidThread()); | 99 DCHECK(thread_checker_.CalledOnValidThread()); |
| 98 } | 100 } |
| 99 | 101 |
| 100 // static | 102 // static |
| 101 void MediaRouterMojoImpl::BindToRequest( | 103 void MediaRouterMojoImpl::BindToRequest( |
| 102 const std::string& extension_id, | 104 const std::string& extension_id, |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 184 routes_converted.reserve(routes.size()); | 186 routes_converted.reserve(routes.size()); |
| 185 | 187 |
| 186 for (size_t i = 0; i < routes.size(); ++i) { | 188 for (size_t i = 0; i < routes.size(); ++i) { |
| 187 routes_converted.push_back(routes[i].To<MediaRoute>()); | 189 routes_converted.push_back(routes[i].To<MediaRoute>()); |
| 188 } | 190 } |
| 189 | 191 |
| 190 FOR_EACH_OBSERVER(MediaRoutesObserver, routes_observers_, | 192 FOR_EACH_OBSERVER(MediaRoutesObserver, routes_observers_, |
| 191 OnRoutesUpdated(routes_converted)); | 193 OnRoutesUpdated(routes_converted)); |
| 192 } | 194 } |
| 193 | 195 |
| 196 void MediaRouterMojoImpl::RouteResponseReceived( | |
| 197 const std::string& presentation_id, | |
| 198 const std::vector<MediaRouteResponseCallback>& callbacks, | |
| 199 interfaces::MediaRoutePtr media_route, | |
| 200 const mojo::String& error_text) { | |
| 201 scoped_ptr<MediaRoute> route; | |
| 202 std::string actual_presentation_id; | |
| 203 std::string error; | |
| 204 if (media_route.is_null()) { | |
| 205 // An error occurred. | |
| 206 DCHECK(!error_text.is_null()); | |
| 207 error = !error_text.get().empty() ? error_text.get() : "Unknown error."; | |
| 208 } else { | |
| 209 route = media_route.To<scoped_ptr<MediaRoute>>(); | |
| 210 actual_presentation_id = presentation_id; | |
| 211 | |
| 212 UpdateHasLocalRoute(true); | |
| 213 | |
| 214 if (!routes_observer_) | |
| 215 routes_observer_.reset(new MediaRouterMediaRoutesObserver(this)); | |
| 216 } | |
| 217 | |
| 218 for (const MediaRouteResponseCallback& callback : callbacks) | |
| 219 callback.Run(route.get(), actual_presentation_id, error); | |
| 220 } | |
| 221 | |
| 222 void MediaRouterMojoImpl::UpdateHasLocalRoute(bool has_local_route) { | |
| 223 if (has_local_route_ == has_local_route) | |
| 224 return; | |
| 225 | |
| 226 has_local_route_ = has_local_route; | |
| 227 | |
| 228 if (!has_local_route_) | |
| 229 routes_observer_.reset(); | |
| 230 | |
| 231 FOR_EACH_OBSERVER(LocalMediaRoutesObserver, local_routes_observers_, | |
| 232 OnHasLocalRouteUpdated(has_local_route_)); | |
| 233 } | |
| 234 | |
| 194 void MediaRouterMojoImpl::CreateRoute( | 235 void MediaRouterMojoImpl::CreateRoute( |
| 195 const MediaSource::Id& source_id, | 236 const MediaSource::Id& source_id, |
| 196 const MediaSink::Id& sink_id, | 237 const MediaSink::Id& sink_id, |
| 197 const GURL& origin, | 238 const GURL& origin, |
| 198 int tab_id, | 239 int tab_id, |
| 199 const std::vector<MediaRouteResponseCallback>& callbacks) { | 240 const std::vector<MediaRouteResponseCallback>& callbacks) { |
| 200 DCHECK(thread_checker_.CalledOnValidThread()); | 241 DCHECK(thread_checker_.CalledOnValidThread()); |
| 201 | 242 |
| 202 if (!origin.is_valid()) { | 243 if (!origin.is_valid()) { |
| 203 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin; | 244 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin; |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 return; | 426 return; |
| 386 | 427 |
| 387 observer_list->RemoveObserver(observer); | 428 observer_list->RemoveObserver(observer); |
| 388 if (!observer_list->might_have_observers()) { | 429 if (!observer_list->might_have_observers()) { |
| 389 messages_observers_.erase(route_id); | 430 messages_observers_.erase(route_id); |
| 390 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopListeningForRouteMessages, | 431 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopListeningForRouteMessages, |
| 391 base::Unretained(this), route_id)); | 432 base::Unretained(this), route_id)); |
| 392 } | 433 } |
| 393 } | 434 } |
| 394 | 435 |
| 436 void MediaRouterMojoImpl::RegisterLocalMediaRoutesObserver( | |
| 437 LocalMediaRoutesObserver* observer) { | |
| 438 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 439 DCHECK(observer); | |
| 440 | |
| 441 DCHECK(!local_routes_observers_.HasObserver(observer)); | |
| 442 local_routes_observers_.AddObserver(observer); | |
| 443 } | |
| 444 | |
| 445 void MediaRouterMojoImpl::UnregisterLocalMediaRoutesObserver( | |
| 446 LocalMediaRoutesObserver* observer) { | |
| 447 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 448 DCHECK(observer); | |
| 449 | |
| 450 if (!local_routes_observers_.HasObserver(observer)) | |
| 451 return; | |
| 452 local_routes_observers_.RemoveObserver(observer); | |
| 453 } | |
| 454 | |
| 395 void MediaRouterMojoImpl::DoCreateRoute( | 455 void MediaRouterMojoImpl::DoCreateRoute( |
| 396 const MediaSource::Id& source_id, | 456 const MediaSource::Id& source_id, |
| 397 const MediaSink::Id& sink_id, | 457 const MediaSink::Id& sink_id, |
| 398 const std::string& origin, | 458 const std::string& origin, |
| 399 int tab_id, | 459 int tab_id, |
| 400 const std::vector<MediaRouteResponseCallback>& callbacks) { | 460 const std::vector<MediaRouteResponseCallback>& callbacks) { |
| 401 std::string presentation_id("mr_"); | 461 std::string presentation_id("mr_"); |
| 402 presentation_id += base::GenerateGUID(); | 462 presentation_id += base::GenerateGUID(); |
| 403 DVLOG_WITH_INSTANCE(1) << "DoCreateRoute " << source_id << "=>" << sink_id | 463 DVLOG_WITH_INSTANCE(1) << "DoCreateRoute " << source_id << "=>" << sink_id |
| 404 << ", presentation ID: " << presentation_id; | 464 << ", presentation ID: " << presentation_id; |
| 405 media_route_provider_->CreateRoute( | 465 media_route_provider_->CreateRoute( |
| 406 source_id, sink_id, presentation_id, origin, tab_id, | 466 source_id, sink_id, presentation_id, origin, tab_id, |
| 407 base::Bind(&RouteResponseReceived, presentation_id, callbacks)); | 467 base::Bind(&MediaRouterMojoImpl::RouteResponseReceived, |
| 468 base::Unretained(this), presentation_id, callbacks)); | |
| 408 } | 469 } |
| 409 | 470 |
| 410 void MediaRouterMojoImpl::DoJoinRoute( | 471 void MediaRouterMojoImpl::DoJoinRoute( |
| 411 const MediaSource::Id& source_id, | 472 const MediaSource::Id& source_id, |
| 412 const std::string& presentation_id, | 473 const std::string& presentation_id, |
| 413 const std::string& origin, | 474 const std::string& origin, |
| 414 int tab_id, | 475 int tab_id, |
| 415 const std::vector<MediaRouteResponseCallback>& callbacks) { | 476 const std::vector<MediaRouteResponseCallback>& callbacks) { |
| 416 DVLOG_WITH_INSTANCE(1) << "DoJoinRoute " << source_id | 477 DVLOG_WITH_INSTANCE(1) << "DoJoinRoute " << source_id |
| 417 << ", presentation ID: " << presentation_id; | 478 << ", presentation ID: " << presentation_id; |
| 418 media_route_provider_->JoinRoute( | 479 media_route_provider_->JoinRoute( |
| 419 source_id, presentation_id, origin, tab_id, | 480 source_id, presentation_id, origin, tab_id, |
| 420 base::Bind(&RouteResponseReceived, presentation_id, callbacks)); | 481 base::Bind(&MediaRouterMojoImpl::RouteResponseReceived, |
| 482 base::Unretained(this), presentation_id, callbacks)); | |
| 421 } | 483 } |
| 422 | 484 |
| 423 void MediaRouterMojoImpl::DoCloseRoute(const MediaRoute::Id& route_id) { | 485 void MediaRouterMojoImpl::DoCloseRoute(const MediaRoute::Id& route_id) { |
| 424 DVLOG_WITH_INSTANCE(1) << "DoCloseRoute " << route_id; | 486 DVLOG_WITH_INSTANCE(1) << "DoCloseRoute " << route_id; |
| 425 media_route_provider_->CloseRoute(route_id); | 487 media_route_provider_->CloseRoute(route_id); |
| 426 } | 488 } |
| 427 | 489 |
| 428 void MediaRouterMojoImpl::DoSendSessionMessage( | 490 void MediaRouterMojoImpl::DoSendSessionMessage( |
| 429 const MediaRoute::Id& route_id, | 491 const MediaRoute::Id& route_id, |
| 430 const std::string& message, | 492 const std::string& message, |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 510 route_id, base::Bind(&MediaRouterMojoImpl::OnRouteMessagesReceived, | 572 route_id, base::Bind(&MediaRouterMojoImpl::OnRouteMessagesReceived, |
| 511 base::Unretained(this), route_id)); | 573 base::Unretained(this), route_id)); |
| 512 } | 574 } |
| 513 | 575 |
| 514 void MediaRouterMojoImpl::DoOnPresentationSessionDetached( | 576 void MediaRouterMojoImpl::DoOnPresentationSessionDetached( |
| 515 const MediaRoute::Id& route_id) { | 577 const MediaRoute::Id& route_id) { |
| 516 DVLOG_WITH_INSTANCE(1) << "DoOnPresentationSessionDetached " << route_id; | 578 DVLOG_WITH_INSTANCE(1) << "DoOnPresentationSessionDetached " << route_id; |
| 517 media_route_provider_->OnPresentationSessionDetached(route_id); | 579 media_route_provider_->OnPresentationSessionDetached(route_id); |
| 518 } | 580 } |
| 519 | 581 |
| 582 bool MediaRouterMojoImpl::HasLocalRoute() const { | |
| 583 return has_local_route_; | |
| 584 } | |
| 585 | |
| 520 void MediaRouterMojoImpl::DoStartObservingMediaSinks( | 586 void MediaRouterMojoImpl::DoStartObservingMediaSinks( |
| 521 const MediaSource::Id& source_id) { | 587 const MediaSource::Id& source_id) { |
| 522 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaSinks: " << source_id; | 588 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaSinks: " << source_id; |
| 523 media_route_provider_->StartObservingMediaSinks(source_id); | 589 media_route_provider_->StartObservingMediaSinks(source_id); |
| 524 } | 590 } |
| 525 | 591 |
| 526 void MediaRouterMojoImpl::DoStopObservingMediaSinks( | 592 void MediaRouterMojoImpl::DoStopObservingMediaSinks( |
| 527 const MediaSource::Id& source_id) { | 593 const MediaSource::Id& source_id) { |
| 528 DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaSinks: " << source_id; | 594 DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaSinks: " << source_id; |
| 529 media_route_provider_->StopObservingMediaSinks(source_id); | 595 media_route_provider_->StopObservingMediaSinks(source_id); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 583 return; | 649 return; |
| 584 } | 650 } |
| 585 | 651 |
| 586 for (const auto& next_request : pending_requests_) | 652 for (const auto& next_request : pending_requests_) |
| 587 next_request.Run(); | 653 next_request.Run(); |
| 588 | 654 |
| 589 pending_requests_.clear(); | 655 pending_requests_.clear(); |
| 590 } | 656 } |
| 591 | 657 |
| 592 } // namespace media_router | 658 } // namespace media_router |
| OLD | NEW |