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