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" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 MediaRouterMediaRoutesObserver(MediaRouterMojoImpl* router) | 66 MediaRouterMediaRoutesObserver(MediaRouterMojoImpl* router) |
| 67 : MediaRoutesObserver(router), | 67 : MediaRoutesObserver(router), |
| 68 router_(router) { | 68 router_(router) { |
| 69 DCHECK(router); | 69 DCHECK(router); |
| 70 } | 70 } |
| 71 | 71 |
| 72 MediaRouterMojoImpl::MediaRouterMediaRoutesObserver:: | 72 MediaRouterMojoImpl::MediaRouterMediaRoutesObserver:: |
| 73 ~MediaRouterMediaRoutesObserver() { | 73 ~MediaRouterMediaRoutesObserver() { |
| 74 } | 74 } |
| 75 | 75 |
| 76 MediaRouterMojoImpl::MediaRoutesQuery::MediaRoutesQuery() = default; | |
| 77 | |
| 78 MediaRouterMojoImpl::MediaRoutesQuery::~MediaRoutesQuery() = default; | |
| 79 | |
| 76 MediaRouterMojoImpl::MediaSinksQuery::MediaSinksQuery() = default; | 80 MediaRouterMojoImpl::MediaSinksQuery::MediaSinksQuery() = default; |
| 77 | 81 |
| 78 MediaRouterMojoImpl::MediaSinksQuery::~MediaSinksQuery() = default; | 82 MediaRouterMojoImpl::MediaSinksQuery::~MediaSinksQuery() = default; |
| 79 | 83 |
| 80 void MediaRouterMojoImpl::MediaRouterMediaRoutesObserver::OnRoutesUpdated( | 84 void MediaRouterMojoImpl::MediaRouterMediaRoutesObserver::OnRoutesUpdated( |
| 81 const std::vector<media_router::MediaRoute>& routes) { | 85 const std::vector<media_router::MediaRoute>& routes, |
| 86 const std::vector<media_router::MediaRoute::Id>& joinable_route_ids) { | |
| 87 | |
|
imcheng
2015/12/01 23:45:06
remove empty line
matt.boetger
2015/12/03 01:19:20
Done.
| |
| 82 bool has_local_route = | 88 bool has_local_route = |
| 83 std::find_if(routes.begin(), routes.end(), | 89 std::find_if(routes.begin(), routes.end(), |
| 84 [](const media_router::MediaRoute& route) { | 90 [](const media_router::MediaRoute& route) { |
| 85 return route.is_local(); }) != | 91 return route.is_local(); }) != |
| 86 routes.end(); | 92 routes.end(); |
| 87 | 93 |
| 88 // |this| will be deleted in UpdateHasLocalRoute() if |has_local_route| is | 94 // |this| will be deleted in UpdateHasLocalRoute() if |has_local_route| is |
| 89 // false. Note that ObserverList supports removing an observer while | 95 // false. Note that ObserverList supports removing an observer while |
| 90 // iterating through it. | 96 // iterating through it. |
| 91 router_->UpdateHasLocalRoute(has_local_route); | 97 router_->UpdateHasLocalRoute(has_local_route); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 !(it->second->observers.might_have_observers())) { | 208 !(it->second->observers.might_have_observers())) { |
| 203 DVLOG_WITH_INSTANCE(1) | 209 DVLOG_WITH_INSTANCE(1) |
| 204 << "Received sink list without any active observers: " << media_source; | 210 << "Received sink list without any active observers: " << media_source; |
| 205 } else { | 211 } else { |
| 206 FOR_EACH_OBSERVER(MediaSinksObserver, it->second->observers, | 212 FOR_EACH_OBSERVER(MediaSinksObserver, it->second->observers, |
| 207 OnSinksReceived(sinks_converted)); | 213 OnSinksReceived(sinks_converted)); |
| 208 } | 214 } |
| 209 } | 215 } |
| 210 | 216 |
| 211 void MediaRouterMojoImpl::OnRoutesUpdated( | 217 void MediaRouterMojoImpl::OnRoutesUpdated( |
| 212 mojo::Array<interfaces::MediaRoutePtr> routes) { | 218 const mojo::String& media_source, |
| 219 mojo::Array<interfaces::MediaRoutePtr> routes, | |
| 220 mojo::Array<mojo::String> joinable_route_ids) { | |
| 213 DCHECK(thread_checker_.CalledOnValidThread()); | 221 DCHECK(thread_checker_.CalledOnValidThread()); |
| 214 | 222 |
| 215 DVLOG_WITH_INSTANCE(1) << "OnRoutesUpdated"; | 223 DVLOG_WITH_INSTANCE(1) << "OnRoutesUpdated"; |
| 216 | 224 |
| 217 std::vector<MediaRoute> routes_converted; | 225 std::vector<MediaRoute> routes_converted; |
| 218 routes_converted.reserve(routes.size()); | 226 routes_converted.reserve(routes.size()); |
| 219 | 227 |
| 220 for (size_t i = 0; i < routes.size(); ++i) { | 228 std::vector<MediaRoute::Id> joinable_routes_converted; |
| 229 joinable_routes_converted.reserve(joinable_route_ids.size()); | |
| 230 | |
| 231 for (size_t i = 0; i < routes.size(); ++i) | |
| 221 routes_converted.push_back(routes[i].To<MediaRoute>()); | 232 routes_converted.push_back(routes[i].To<MediaRoute>()); |
| 233 | |
| 234 for (size_t i = 0; i < joinable_route_ids.size(); ++i) | |
| 235 joinable_routes_converted.push_back(joinable_route_ids[i].get()); | |
|
imcheng
2015/12/01 23:45:06
.get() not needed - conversion to std::string shou
matt.boetger
2015/12/03 01:19:20
Done.
| |
| 236 | |
| 237 auto it = routes_queries_.find(media_source); | |
|
imcheng
2015/12/01 23:45:06
It should probably be better to do this check befo
matt.boetger
2015/12/03 01:19:20
Done.
| |
| 238 if (it == routes_queries_.end() || | |
| 239 !(it->second->observers.might_have_observers())) { | |
| 240 DVLOG_WITH_INSTANCE(1) | |
| 241 << "Received route list without any active observers: " << media_source; | |
| 242 } else { | |
| 243 FOR_EACH_OBSERVER(MediaRoutesObserver, it->second->observers, | |
| 244 OnRoutesUpdated(routes_converted, | |
| 245 joinable_routes_converted)); | |
| 222 } | 246 } |
| 223 | |
| 224 FOR_EACH_OBSERVER(MediaRoutesObserver, routes_observers_, | |
| 225 OnRoutesUpdated(routes_converted)); | |
| 226 } | 247 } |
| 227 | 248 |
| 228 void MediaRouterMojoImpl::RouteResponseReceived( | 249 void MediaRouterMojoImpl::RouteResponseReceived( |
| 229 const std::string& presentation_id, | 250 const std::string& presentation_id, |
| 230 const std::vector<MediaRouteResponseCallback>& callbacks, | 251 const std::vector<MediaRouteResponseCallback>& callbacks, |
| 231 interfaces::MediaRoutePtr media_route, | 252 interfaces::MediaRoutePtr media_route, |
| 232 const mojo::String& error_text) { | 253 const mojo::String& error_text) { |
| 233 scoped_ptr<MediaRoute> route; | 254 scoped_ptr<MediaRoute> route; |
| 234 std::string actual_presentation_id; | 255 std::string actual_presentation_id; |
| 235 std::string error; | 256 std::string error; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 300 return; | 321 return; |
| 301 } | 322 } |
| 302 | 323 |
| 303 int tab_id = SessionTabHelper::IdForTab(web_contents); | 324 int tab_id = SessionTabHelper::IdForTab(web_contents); |
| 304 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoJoinRoute, | 325 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoJoinRoute, |
| 305 base::Unretained(this), source_id, presentation_id, | 326 base::Unretained(this), source_id, presentation_id, |
| 306 origin.is_empty() ? "" : origin.spec(), tab_id, | 327 origin.is_empty() ? "" : origin.spec(), tab_id, |
| 307 callbacks)); | 328 callbacks)); |
| 308 } | 329 } |
| 309 | 330 |
| 331 void MediaRouterMojoImpl::JoinRouteByRouteId( | |
| 332 const MediaSource::Id& source_id, | |
| 333 const MediaRoute::Id& route_id, | |
| 334 const GURL& origin, | |
| 335 content::WebContents* web_contents, | |
| 336 const std::vector<MediaRouteResponseCallback>& callbacks) { | |
| 337 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 338 | |
| 339 if (!origin.is_valid()) { | |
| 340 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin; | |
| 341 for (const MediaRouteResponseCallback& callback : callbacks) | |
| 342 callback.Run(nullptr, "", "Invalid origin"); | |
| 343 return; | |
| 344 } | |
| 345 | |
| 346 int tab_id = SessionTabHelper::IdForTab(web_contents); | |
| 347 std::string presentation_id("non-local-join_"); | |
| 348 presentation_id += route_id; | |
| 349 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoJoinRoute, | |
| 350 base::Unretained(this), source_id, presentation_id, | |
| 351 origin.is_empty() ? "" : origin.spec(), tab_id, | |
| 352 callbacks)); | |
| 353 } | |
| 354 | |
| 310 void MediaRouterMojoImpl::CloseRoute(const MediaRoute::Id& route_id) { | 355 void MediaRouterMojoImpl::CloseRoute(const MediaRoute::Id& route_id) { |
| 311 DCHECK(thread_checker_.CalledOnValidThread()); | 356 DCHECK(thread_checker_.CalledOnValidThread()); |
| 312 | 357 |
| 313 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoCloseRoute, | 358 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoCloseRoute, |
| 314 base::Unretained(this), route_id)); | 359 base::Unretained(this), route_id)); |
| 315 } | 360 } |
| 316 | 361 |
| 317 void MediaRouterMojoImpl::SendRouteMessage( | 362 void MediaRouterMojoImpl::SendRouteMessage( |
| 318 const MediaRoute::Id& route_id, | 363 const MediaRoute::Id& route_id, |
| 319 const std::string& message, | 364 const std::string& message, |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 base::Unretained(this), source_id)); | 452 base::Unretained(this), source_id)); |
| 408 } else { | 453 } else { |
| 409 sinks_queries_.erase(source_id); | 454 sinks_queries_.erase(source_id); |
| 410 } | 455 } |
| 411 } | 456 } |
| 412 } | 457 } |
| 413 | 458 |
| 414 void MediaRouterMojoImpl::RegisterMediaRoutesObserver( | 459 void MediaRouterMojoImpl::RegisterMediaRoutesObserver( |
| 415 MediaRoutesObserver* observer) { | 460 MediaRoutesObserver* observer) { |
| 416 DCHECK(thread_checker_.CalledOnValidThread()); | 461 DCHECK(thread_checker_.CalledOnValidThread()); |
| 417 DCHECK(!routes_observers_.HasObserver(observer)); | 462 const MediaSource::Id source_id = observer->source_id(); |
| 463 auto* routes_query = routes_queries_.get(source_id); | |
| 464 if (!routes_query) { | |
| 465 routes_query = new MediaRoutesQuery; | |
| 466 routes_queries_.add(source_id, make_scoped_ptr(routes_query)); | |
| 467 } else { | |
| 468 DCHECK(!routes_query->observers.HasObserver(observer)); | |
| 469 } | |
| 418 | 470 |
| 471 routes_query->observers.AddObserver(observer); | |
| 419 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaRoutes, | 472 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaRoutes, |
| 420 base::Unretained(this))); | 473 base::Unretained(this), source_id)); |
| 421 routes_observers_.AddObserver(observer); | |
| 422 } | 474 } |
| 423 | 475 |
| 424 void MediaRouterMojoImpl::UnregisterMediaRoutesObserver( | 476 void MediaRouterMojoImpl::UnregisterMediaRoutesObserver( |
| 425 MediaRoutesObserver* observer) { | 477 MediaRoutesObserver* observer) { |
| 426 if (!routes_observers_.HasObserver(observer)) | 478 const MediaSource::Id source_id = observer->source_id(); |
| 479 auto* routes_query = routes_queries_.get(source_id); | |
| 480 if (!routes_query || !routes_query->observers.HasObserver(observer)) { | |
| 427 return; | 481 return; |
| 482 } | |
| 428 | 483 |
| 429 routes_observers_.RemoveObserver(observer); | 484 // If we are removing the final observer for the source, then stop |
| 430 if (!routes_observers_.might_have_observers()) { | 485 // observing routes for it. |
| 486 // might_have_observers() is reliable here on the assumption that this call | |
| 487 // is not inside the ObserverList iteration. | |
| 488 routes_query->observers.RemoveObserver(observer); | |
| 489 if (!routes_query->observers.might_have_observers()) { | |
| 431 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopObservingMediaRoutes, | 490 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopObservingMediaRoutes, |
| 432 base::Unretained(this))); | 491 base::Unretained(this), source_id)); |
| 433 } | 492 } |
| 434 } | 493 } |
| 435 | 494 |
| 436 void MediaRouterMojoImpl::RegisterIssuesObserver(IssuesObserver* observer) { | 495 void MediaRouterMojoImpl::RegisterIssuesObserver(IssuesObserver* observer) { |
| 437 DCHECK(thread_checker_.CalledOnValidThread()); | 496 DCHECK(thread_checker_.CalledOnValidThread()); |
| 438 issue_manager_.RegisterObserver(observer); | 497 issue_manager_.RegisterObserver(observer); |
| 439 } | 498 } |
| 440 | 499 |
| 441 void MediaRouterMojoImpl::UnregisterIssuesObserver(IssuesObserver* observer) { | 500 void MediaRouterMojoImpl::UnregisterIssuesObserver(IssuesObserver* observer) { |
| 442 DCHECK(thread_checker_.CalledOnValidThread()); | 501 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 684 if (!sinks_query || !sinks_query->is_active || | 743 if (!sinks_query || !sinks_query->is_active || |
| 685 sinks_query->observers.might_have_observers()) { | 744 sinks_query->observers.might_have_observers()) { |
| 686 return; | 745 return; |
| 687 } | 746 } |
| 688 | 747 |
| 689 DVLOG_WITH_INSTANCE(1) << "MRPM.StopObservingMediaSinks: " << source_id; | 748 DVLOG_WITH_INSTANCE(1) << "MRPM.StopObservingMediaSinks: " << source_id; |
| 690 media_route_provider_->StopObservingMediaSinks(source_id); | 749 media_route_provider_->StopObservingMediaSinks(source_id); |
| 691 sinks_queries_.erase(source_id); | 750 sinks_queries_.erase(source_id); |
| 692 } | 751 } |
| 693 | 752 |
| 694 void MediaRouterMojoImpl::DoStartObservingMediaRoutes() { | 753 void MediaRouterMojoImpl::DoStartObservingMediaRoutes( |
| 754 const MediaSource::Id& source_id) { | |
| 695 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaRoutes"; | 755 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaRoutes"; |
| 696 media_route_provider_->StartObservingMediaRoutes(); | 756 |
| 757 // No need to call MRPM if all observers have been removed in the meantime. | |
| 758 auto* routes_query = routes_queries_.get(source_id); | |
| 759 if (!routes_query || !routes_query->observers.might_have_observers()) { | |
| 760 return; | |
| 761 } | |
| 762 | |
| 763 DVLOG_WITH_INSTANCE(1) << "MRPM.StartObservingMediaRoutes: " << source_id; | |
| 764 media_route_provider_->StartObservingMediaRoutes(source_id); | |
| 765 routes_query->is_active = true; | |
| 697 } | 766 } |
| 698 | 767 |
| 699 void MediaRouterMojoImpl::DoStopObservingMediaRoutes() { | 768 void MediaRouterMojoImpl::DoStopObservingMediaRoutes( |
| 769 const MediaSource::Id& source_id) { | |
| 700 DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaRoutes"; | 770 DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaRoutes"; |
| 701 media_route_provider_->StopObservingMediaRoutes(); | 771 |
| 772 auto* routes_query = routes_queries_.get(source_id); | |
| 773 // No need to call MRPM if observers have been added in the meantime, | |
| 774 // or StopObservingMediaSinks has already been called. | |
| 775 if (!routes_query || !routes_query->is_active || | |
| 776 routes_query->observers.might_have_observers()) { | |
| 777 return; | |
| 778 } | |
| 779 | |
| 780 DVLOG_WITH_INSTANCE(1) << "MRPM.StopObservingMediaRoutes: " << source_id; | |
| 781 media_route_provider_->StopObservingMediaRoutes(source_id); | |
| 782 routes_queries_.erase(source_id); | |
| 702 } | 783 } |
| 703 | 784 |
| 704 void MediaRouterMojoImpl::EnqueueTask(const base::Closure& closure) { | 785 void MediaRouterMojoImpl::EnqueueTask(const base::Closure& closure) { |
| 705 pending_requests_.push_back(closure); | 786 pending_requests_.push_back(closure); |
| 706 if (pending_requests_.size() > kMaxPendingRequests) { | 787 if (pending_requests_.size() > kMaxPendingRequests) { |
| 707 DLOG_WITH_INSTANCE(ERROR) << "Reached max queue size. Dropping oldest " | 788 DLOG_WITH_INSTANCE(ERROR) << "Reached max queue size. Dropping oldest " |
| 708 << "request."; | 789 << "request."; |
| 709 pending_requests_.pop_front(); | 790 pending_requests_.pop_front(); |
| 710 } | 791 } |
| 711 DVLOG_WITH_INSTANCE(2) << "EnqueueTask (queue-length=" | 792 DVLOG_WITH_INSTANCE(2) << "EnqueueTask (queue-length=" |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 780 } | 861 } |
| 781 | 862 |
| 782 void MediaRouterMojoImpl::DrainPendingRequests() { | 863 void MediaRouterMojoImpl::DrainPendingRequests() { |
| 783 DLOG_WITH_INSTANCE(ERROR) | 864 DLOG_WITH_INSTANCE(ERROR) |
| 784 << "Draining request queue. (queue-length=" << pending_requests_.size() | 865 << "Draining request queue. (queue-length=" << pending_requests_.size() |
| 785 << ")"; | 866 << ")"; |
| 786 pending_requests_.clear(); | 867 pending_requests_.clear(); |
| 787 } | 868 } |
| 788 | 869 |
| 789 } // namespace media_router | 870 } // namespace media_router |
| OLD | NEW |