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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 67 MediaRouterMediaRoutesObserver(MediaRouterMojoImpl* router) | 67 MediaRouterMediaRoutesObserver(MediaRouterMojoImpl* router) |
| 68 : MediaRoutesObserver(router), | 68 : MediaRoutesObserver(router), |
| 69 router_(router) { | 69 router_(router) { |
| 70 DCHECK(router); | 70 DCHECK(router); |
| 71 } | 71 } |
| 72 | 72 |
| 73 MediaRouterMojoImpl::MediaRouterMediaRoutesObserver:: | 73 MediaRouterMojoImpl::MediaRouterMediaRoutesObserver:: |
| 74 ~MediaRouterMediaRoutesObserver() { | 74 ~MediaRouterMediaRoutesObserver() { |
| 75 } | 75 } |
| 76 | 76 |
| 77 MediaRouterMojoImpl::MediaRoutesQuery::MediaRoutesQuery() = default; | |
| 78 | |
| 79 MediaRouterMojoImpl::MediaRoutesQuery::~MediaRoutesQuery() = default; | |
| 80 | |
| 77 MediaRouterMojoImpl::MediaSinksQuery::MediaSinksQuery() = default; | 81 MediaRouterMojoImpl::MediaSinksQuery::MediaSinksQuery() = default; |
| 78 | 82 |
| 79 MediaRouterMojoImpl::MediaSinksQuery::~MediaSinksQuery() = default; | 83 MediaRouterMojoImpl::MediaSinksQuery::~MediaSinksQuery() = default; |
| 80 | 84 |
| 81 void MediaRouterMojoImpl::MediaRouterMediaRoutesObserver::OnRoutesUpdated( | 85 void MediaRouterMojoImpl::MediaRouterMediaRoutesObserver::OnRoutesUpdated( |
| 82 const std::vector<media_router::MediaRoute>& routes) { | 86 const std::vector<media_router::MediaRoute>& routes, |
| 87 const std::vector<media_router::MediaRoute::Id>& joinable_route_ids) { | |
| 83 bool has_local_display_route = | 88 bool has_local_display_route = |
| 84 std::find_if(routes.begin(), routes.end(), | 89 std::find_if(routes.begin(), routes.end(), |
| 85 [](const media_router::MediaRoute& route) { | 90 [](const media_router::MediaRoute& route) { |
| 86 return route.is_local() && route.for_display(); | 91 return route.is_local() && route.for_display(); |
| 87 }) != routes.end(); | 92 }) != routes.end(); |
| 88 | 93 |
| 89 // |this| will be deleted in UpdateHasLocalDisplayRoute() if | 94 // |this| will be deleted in UpdateHasLocalDisplayRoute() if |
| 90 // |has_local_display_route| is false. Note that ObserverList supports | 95 // |has_local_display_route| is false. Note that ObserverList supports |
| 91 // removing an observer while iterating through it. | 96 // removing an observer while iterating through it. |
| 92 router_->UpdateHasLocalDisplayRoute(has_local_display_route); | 97 router_->UpdateHasLocalDisplayRoute(has_local_display_route); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 185 const Issue& issue_converted = issue.To<Issue>(); | 190 const Issue& issue_converted = issue.To<Issue>(); |
| 186 issue_manager_.AddIssue(issue_converted); | 191 issue_manager_.AddIssue(issue_converted); |
| 187 } | 192 } |
| 188 | 193 |
| 189 void MediaRouterMojoImpl::OnSinksReceived( | 194 void MediaRouterMojoImpl::OnSinksReceived( |
| 190 const mojo::String& media_source, | 195 const mojo::String& media_source, |
| 191 mojo::Array<interfaces::MediaSinkPtr> sinks) { | 196 mojo::Array<interfaces::MediaSinkPtr> sinks) { |
| 192 DCHECK(thread_checker_.CalledOnValidThread()); | 197 DCHECK(thread_checker_.CalledOnValidThread()); |
| 193 | 198 |
| 194 DVLOG_WITH_INSTANCE(1) << "OnSinksReceived"; | 199 DVLOG_WITH_INSTANCE(1) << "OnSinksReceived"; |
| 200 auto it = sinks_queries_.find(media_source); | |
| 201 if (it == sinks_queries_.end() || | |
| 202 !(it->second->observers.might_have_observers())) { | |
| 203 DVLOG_WITH_INSTANCE(1) | |
| 204 << "Received sink list without any active observers: " << media_source; | |
| 205 return; | |
| 206 } | |
| 207 | |
| 195 std::vector<MediaSink> sinks_converted; | 208 std::vector<MediaSink> sinks_converted; |
| 196 sinks_converted.reserve(sinks.size()); | 209 sinks_converted.reserve(sinks.size()); |
| 197 | 210 |
| 198 for (size_t i = 0; i < sinks.size(); ++i) { | 211 for (size_t i = 0; i < sinks.size(); ++i) { |
| 199 sinks_converted.push_back(sinks[i].To<MediaSink>()); | 212 sinks_converted.push_back(sinks[i].To<MediaSink>()); |
| 200 } | 213 } |
| 201 | 214 |
| 202 auto it = sinks_queries_.find(media_source); | 215 FOR_EACH_OBSERVER(MediaSinksObserver, it->second->observers, |
| 203 if (it == sinks_queries_.end() || | 216 OnSinksReceived(sinks_converted)); |
| 204 !(it->second->observers.might_have_observers())) { | |
| 205 DVLOG_WITH_INSTANCE(1) | |
| 206 << "Received sink list without any active observers: " << media_source; | |
| 207 } else { | |
| 208 FOR_EACH_OBSERVER(MediaSinksObserver, it->second->observers, | |
| 209 OnSinksReceived(sinks_converted)); | |
| 210 } | |
| 211 } | 217 } |
| 212 | 218 |
| 213 void MediaRouterMojoImpl::OnRoutesUpdated( | 219 void MediaRouterMojoImpl::OnRoutesUpdated( |
| 214 mojo::Array<interfaces::MediaRoutePtr> routes) { | 220 const mojo::String& media_source, |
| 221 mojo::Array<interfaces::MediaRoutePtr> routes, | |
| 222 mojo::Array<mojo::String> joinable_route_ids) { | |
| 215 DCHECK(thread_checker_.CalledOnValidThread()); | 223 DCHECK(thread_checker_.CalledOnValidThread()); |
| 216 | 224 |
| 217 DVLOG_WITH_INSTANCE(1) << "OnRoutesUpdated"; | 225 DVLOG_WITH_INSTANCE(1) << "OnRoutesUpdated"; |
| 226 auto it = routes_queries_.find(media_source); | |
| 227 if (it == routes_queries_.end() || | |
| 228 !(it->second->observers.might_have_observers())) { | |
| 229 DVLOG_WITH_INSTANCE(1) | |
| 230 << "Received route list without any active observers: " << media_source; | |
| 231 return; | |
| 232 } | |
| 218 | 233 |
| 219 std::vector<MediaRoute> routes_converted; | 234 std::vector<MediaRoute> routes_converted; |
| 220 routes_converted.reserve(routes.size()); | 235 routes_converted.reserve(routes.size()); |
| 221 | 236 |
| 222 for (size_t i = 0; i < routes.size(); ++i) { | 237 std::vector<MediaRoute::Id> joinable_routes_converted; |
| 238 joinable_routes_converted.reserve(joinable_route_ids.size()); | |
| 239 | |
| 240 for (size_t i = 0; i < routes.size(); ++i) | |
| 223 routes_converted.push_back(routes[i].To<MediaRoute>()); | 241 routes_converted.push_back(routes[i].To<MediaRoute>()); |
| 224 } | |
| 225 | 242 |
| 226 FOR_EACH_OBSERVER(MediaRoutesObserver, routes_observers_, | 243 for (size_t i = 0; i < joinable_route_ids.size(); ++i) |
| 227 OnRoutesUpdated(routes_converted)); | 244 joinable_routes_converted.push_back(joinable_route_ids[i]); |
| 245 | |
| 246 FOR_EACH_OBSERVER(MediaRoutesObserver, it->second->observers, | |
| 247 OnRoutesUpdated(routes_converted, | |
| 248 joinable_routes_converted)); | |
| 228 } | 249 } |
| 229 | 250 |
| 230 void MediaRouterMojoImpl::RouteResponseReceived( | 251 void MediaRouterMojoImpl::RouteResponseReceived( |
| 231 const std::string& presentation_id, | 252 const std::string& presentation_id, |
| 232 const std::vector<MediaRouteResponseCallback>& callbacks, | 253 const std::vector<MediaRouteResponseCallback>& callbacks, |
| 233 interfaces::MediaRoutePtr media_route, | 254 interfaces::MediaRoutePtr media_route, |
| 234 const mojo::String& error_text) { | 255 const mojo::String& error_text) { |
| 235 scoped_ptr<MediaRoute> route; | 256 scoped_ptr<MediaRoute> route; |
| 236 std::string actual_presentation_id; | 257 std::string actual_presentation_id; |
| 237 std::string error; | 258 std::string error; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 307 } | 328 } |
| 308 | 329 |
| 309 SetWakeReason(MediaRouteProviderWakeReason::JOIN_ROUTE); | 330 SetWakeReason(MediaRouteProviderWakeReason::JOIN_ROUTE); |
| 310 int tab_id = SessionTabHelper::IdForTab(web_contents); | 331 int tab_id = SessionTabHelper::IdForTab(web_contents); |
| 311 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoJoinRoute, | 332 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoJoinRoute, |
| 312 base::Unretained(this), source_id, presentation_id, | 333 base::Unretained(this), source_id, presentation_id, |
| 313 origin.is_empty() ? "" : origin.spec(), tab_id, | 334 origin.is_empty() ? "" : origin.spec(), tab_id, |
| 314 callbacks)); | 335 callbacks)); |
| 315 } | 336 } |
| 316 | 337 |
| 338 void MediaRouterMojoImpl::JoinRouteByRouteId( | |
| 339 const MediaSource::Id& source_id, | |
| 340 const MediaRoute::Id& route_id, | |
| 341 const GURL& origin, | |
| 342 content::WebContents* web_contents, | |
| 343 const std::vector<MediaRouteResponseCallback>& callbacks) { | |
| 344 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 345 | |
| 346 if (!origin.is_valid()) { | |
| 347 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin; | |
| 348 for (const MediaRouteResponseCallback& callback : callbacks) | |
| 349 callback.Run(nullptr, "", "Invalid origin"); | |
| 350 return; | |
| 351 } | |
| 352 | |
| 353 int tab_id = SessionTabHelper::IdForTab(web_contents); | |
| 354 std::string presentation_id("non-local-join_"); | |
|
mark a. foltz
2015/12/03 19:24:23
What is this for - shouldn't the route_id already
matt.boetger
2015/12/15 19:21:20
Since this is non-local, the route_id contains the
| |
| 355 presentation_id += route_id; | |
| 356 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoJoinRoute, | |
|
mark a. foltz
2015/12/03 19:24:23
I'm not sure DoJoinRoute is the right API to call
matt.boetger
2015/12/15 19:21:20
Yes, the fake presentation id was a way to re-use
| |
| 357 base::Unretained(this), source_id, presentation_id, | |
| 358 origin.is_empty() ? "" : origin.spec(), tab_id, | |
| 359 callbacks)); | |
| 360 } | |
| 361 | |
| 317 void MediaRouterMojoImpl::CloseRoute(const MediaRoute::Id& route_id) { | 362 void MediaRouterMojoImpl::CloseRoute(const MediaRoute::Id& route_id) { |
| 318 DCHECK(thread_checker_.CalledOnValidThread()); | 363 DCHECK(thread_checker_.CalledOnValidThread()); |
| 319 | 364 |
| 320 SetWakeReason(MediaRouteProviderWakeReason::CLOSE_ROUTE); | 365 SetWakeReason(MediaRouteProviderWakeReason::CLOSE_ROUTE); |
| 321 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoCloseRoute, | 366 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoCloseRoute, |
| 322 base::Unretained(this), route_id)); | 367 base::Unretained(this), route_id)); |
| 323 } | 368 } |
| 324 | 369 |
| 325 void MediaRouterMojoImpl::SendRouteMessage( | 370 void MediaRouterMojoImpl::SendRouteMessage( |
| 326 const MediaRoute::Id& route_id, | 371 const MediaRoute::Id& route_id, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 423 base::Unretained(this), source_id)); | 468 base::Unretained(this), source_id)); |
| 424 } else { | 469 } else { |
| 425 sinks_queries_.erase(source_id); | 470 sinks_queries_.erase(source_id); |
| 426 } | 471 } |
| 427 } | 472 } |
| 428 } | 473 } |
| 429 | 474 |
| 430 void MediaRouterMojoImpl::RegisterMediaRoutesObserver( | 475 void MediaRouterMojoImpl::RegisterMediaRoutesObserver( |
| 431 MediaRoutesObserver* observer) { | 476 MediaRoutesObserver* observer) { |
| 432 DCHECK(thread_checker_.CalledOnValidThread()); | 477 DCHECK(thread_checker_.CalledOnValidThread()); |
| 433 DCHECK(!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) { | |
| 481 routes_query = new MediaRoutesQuery; | |
| 482 routes_queries_.add(source_id, make_scoped_ptr(routes_query)); | |
| 483 } else { | |
| 484 DCHECK(!routes_query->observers.HasObserver(observer)); | |
| 485 } | |
| 434 | 486 |
| 487 routes_query->observers.AddObserver(observer); | |
| 435 SetWakeReason(MediaRouteProviderWakeReason::START_OBSERVING_MEDIA_ROUTES); | 488 SetWakeReason(MediaRouteProviderWakeReason::START_OBSERVING_MEDIA_ROUTES); |
| 436 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaRoutes, | 489 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaRoutes, |
| 437 base::Unretained(this))); | 490 base::Unretained(this), source_id)); |
| 438 routes_observers_.AddObserver(observer); | |
| 439 } | 491 } |
| 440 | 492 |
| 441 void MediaRouterMojoImpl::UnregisterMediaRoutesObserver( | 493 void MediaRouterMojoImpl::UnregisterMediaRoutesObserver( |
| 442 MediaRoutesObserver* observer) { | 494 MediaRoutesObserver* observer) { |
| 443 if (!routes_observers_.HasObserver(observer)) | 495 const MediaSource::Id source_id = observer->source_id(); |
| 496 auto* routes_query = routes_queries_.get(source_id); | |
| 497 if (!routes_query || !routes_query->observers.HasObserver(observer)) { | |
| 444 return; | 498 return; |
| 499 } | |
| 445 | 500 |
| 446 routes_observers_.RemoveObserver(observer); | 501 // If we are removing the final observer for the source, then stop |
| 447 if (!routes_observers_.might_have_observers()) { | 502 // observing routes for it. |
| 503 // might_have_observers() is reliable here on the assumption that this call | |
| 504 // is not inside the ObserverList iteration. | |
| 505 routes_query->observers.RemoveObserver(observer); | |
| 506 if (!routes_query->observers.might_have_observers()) { | |
| 448 SetWakeReason(MediaRouteProviderWakeReason::STOP_OBSERVING_MEDIA_ROUTES); | 507 SetWakeReason(MediaRouteProviderWakeReason::STOP_OBSERVING_MEDIA_ROUTES); |
| 449 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopObservingMediaRoutes, | 508 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopObservingMediaRoutes, |
| 450 base::Unretained(this))); | 509 base::Unretained(this), source_id)); |
| 451 } | 510 } |
| 452 } | 511 } |
| 453 | 512 |
| 454 void MediaRouterMojoImpl::RegisterIssuesObserver(IssuesObserver* observer) { | 513 void MediaRouterMojoImpl::RegisterIssuesObserver(IssuesObserver* observer) { |
| 455 DCHECK(thread_checker_.CalledOnValidThread()); | 514 DCHECK(thread_checker_.CalledOnValidThread()); |
| 456 issue_manager_.RegisterObserver(observer); | 515 issue_manager_.RegisterObserver(observer); |
| 457 } | 516 } |
| 458 | 517 |
| 459 void MediaRouterMojoImpl::UnregisterIssuesObserver(IssuesObserver* observer) { | 518 void MediaRouterMojoImpl::UnregisterIssuesObserver(IssuesObserver* observer) { |
| 460 DCHECK(thread_checker_.CalledOnValidThread()); | 519 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 717 if (!sinks_query || !sinks_query->is_active || | 776 if (!sinks_query || !sinks_query->is_active || |
| 718 sinks_query->observers.might_have_observers()) { | 777 sinks_query->observers.might_have_observers()) { |
| 719 return; | 778 return; |
| 720 } | 779 } |
| 721 | 780 |
| 722 DVLOG_WITH_INSTANCE(1) << "MRPM.StopObservingMediaSinks: " << source_id; | 781 DVLOG_WITH_INSTANCE(1) << "MRPM.StopObservingMediaSinks: " << source_id; |
| 723 media_route_provider_->StopObservingMediaSinks(source_id); | 782 media_route_provider_->StopObservingMediaSinks(source_id); |
| 724 sinks_queries_.erase(source_id); | 783 sinks_queries_.erase(source_id); |
| 725 } | 784 } |
| 726 | 785 |
| 727 void MediaRouterMojoImpl::DoStartObservingMediaRoutes() { | 786 void MediaRouterMojoImpl::DoStartObservingMediaRoutes( |
| 787 const MediaSource::Id& source_id) { | |
| 728 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaRoutes"; | 788 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaRoutes"; |
| 729 media_route_provider_->StartObservingMediaRoutes(); | 789 |
| 790 // No need to call MRPM if all observers have been removed in the meantime. | |
| 791 auto* routes_query = routes_queries_.get(source_id); | |
|
mark a. foltz
2015/12/03 19:24:23
This pattern is repeated a couple of times - pleas
matt.boetger
2015/12/15 19:21:20
Done.
| |
| 792 if (!routes_query || !routes_query->observers.might_have_observers()) { | |
| 793 return; | |
| 794 } | |
| 795 | |
| 796 DVLOG_WITH_INSTANCE(1) << "MRPM.StartObservingMediaRoutes: " << source_id; | |
| 797 media_route_provider_->StartObservingMediaRoutes(source_id); | |
| 798 routes_query->is_active = true; | |
| 730 } | 799 } |
| 731 | 800 |
| 732 void MediaRouterMojoImpl::DoStopObservingMediaRoutes() { | 801 void MediaRouterMojoImpl::DoStopObservingMediaRoutes( |
| 802 const MediaSource::Id& source_id) { | |
| 733 DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaRoutes"; | 803 DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaRoutes"; |
| 734 media_route_provider_->StopObservingMediaRoutes(); | 804 |
| 805 auto* routes_query = routes_queries_.get(source_id); | |
| 806 // No need to call MRPM if observers have been added in the meantime, | |
| 807 // or StopObservingMediaSinks has already been called. | |
| 808 if (!routes_query || !routes_query->is_active || | |
| 809 routes_query->observers.might_have_observers()) { | |
| 810 return; | |
| 811 } | |
| 812 | |
| 813 DVLOG_WITH_INSTANCE(1) << "MRPM.StopObservingMediaRoutes: " << source_id; | |
| 814 media_route_provider_->StopObservingMediaRoutes(source_id); | |
| 815 routes_queries_.erase(source_id); | |
| 735 } | 816 } |
| 736 | 817 |
| 737 void MediaRouterMojoImpl::EnqueueTask(const base::Closure& closure) { | 818 void MediaRouterMojoImpl::EnqueueTask(const base::Closure& closure) { |
| 738 pending_requests_.push_back(closure); | 819 pending_requests_.push_back(closure); |
| 739 if (pending_requests_.size() > kMaxPendingRequests) { | 820 if (pending_requests_.size() > kMaxPendingRequests) { |
| 740 DLOG_WITH_INSTANCE(ERROR) << "Reached max queue size. Dropping oldest " | 821 DLOG_WITH_INSTANCE(ERROR) << "Reached max queue size. Dropping oldest " |
| 741 << "request."; | 822 << "request."; |
| 742 pending_requests_.pop_front(); | 823 pending_requests_.pop_front(); |
| 743 } | 824 } |
| 744 DVLOG_WITH_INSTANCE(2) << "EnqueueTask (queue-length=" | 825 DVLOG_WITH_INSTANCE(2) << "EnqueueTask (queue-length=" |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 829 if (current_wake_reason_ == MediaRouteProviderWakeReason::TOTAL_COUNT) | 910 if (current_wake_reason_ == MediaRouteProviderWakeReason::TOTAL_COUNT) |
| 830 current_wake_reason_ = reason; | 911 current_wake_reason_ = reason; |
| 831 } | 912 } |
| 832 | 913 |
| 833 void MediaRouterMojoImpl::ClearWakeReason() { | 914 void MediaRouterMojoImpl::ClearWakeReason() { |
| 834 DCHECK(current_wake_reason_ != MediaRouteProviderWakeReason::TOTAL_COUNT); | 915 DCHECK(current_wake_reason_ != MediaRouteProviderWakeReason::TOTAL_COUNT); |
| 835 current_wake_reason_ = MediaRouteProviderWakeReason::TOTAL_COUNT; | 916 current_wake_reason_ = MediaRouteProviderWakeReason::TOTAL_COUNT; |
| 836 } | 917 } |
| 837 | 918 |
| 838 } // namespace media_router | 919 } // namespace media_router |
| OLD | NEW |