Chromium Code Reviews| Index: chrome/browser/media/router/media_router_mojo_impl.cc |
| diff --git a/chrome/browser/media/router/media_router_mojo_impl.cc b/chrome/browser/media/router/media_router_mojo_impl.cc |
| index 9fdd6fd14a59c4d9d3f67c011bae75ea6b788239..befe00fe930356e252825d740ba298112e2747a8 100644 |
| --- a/chrome/browser/media/router/media_router_mojo_impl.cc |
| +++ b/chrome/browser/media/router/media_router_mojo_impl.cc |
| @@ -73,12 +73,18 @@ MediaRouterMojoImpl::MediaRouterMediaRoutesObserver:: |
| ~MediaRouterMediaRoutesObserver() { |
| } |
| +MediaRouterMojoImpl::MediaRoutesQuery::MediaRoutesQuery() = default; |
| + |
| +MediaRouterMojoImpl::MediaRoutesQuery::~MediaRoutesQuery() = default; |
| + |
| MediaRouterMojoImpl::MediaSinksQuery::MediaSinksQuery() = default; |
| MediaRouterMojoImpl::MediaSinksQuery::~MediaSinksQuery() = default; |
| void MediaRouterMojoImpl::MediaRouterMediaRoutesObserver::OnRoutesUpdated( |
| - const std::vector<media_router::MediaRoute>& routes) { |
| + const std::vector<media_router::MediaRoute>& routes, |
| + const std::vector<media_router::MediaRoute::Id>& joinable_route_ids) { |
| + |
| bool has_local_route = |
| std::find_if(routes.begin(), routes.end(), |
| [](const media_router::MediaRoute& route) { |
| @@ -209,7 +215,10 @@ void MediaRouterMojoImpl::OnSinksReceived( |
| } |
| void MediaRouterMojoImpl::OnRoutesUpdated( |
| - mojo::Array<interfaces::MediaRoutePtr> routes) { |
| + const mojo::String& media_source, |
| + mojo::Array<interfaces::MediaRoutePtr> routes, |
| + mojo::Array<mojo::String> joinable_route_ids) { |
| + DCHECK(!media_source.is_null()); |
|
imcheng
2015/11/26 00:49:46
This DCHECK is not needed since its non-nullness i
matt.boetger
2015/12/01 01:26:56
Done.
|
| DCHECK(thread_checker_.CalledOnValidThread()); |
| DVLOG_WITH_INSTANCE(1) << "OnRoutesUpdated"; |
| @@ -217,12 +226,27 @@ void MediaRouterMojoImpl::OnRoutesUpdated( |
| std::vector<MediaRoute> routes_converted; |
| routes_converted.reserve(routes.size()); |
| + std::vector<MediaRoute::Id> joinable_routes_converted; |
| + joinable_routes_converted.reserve(joinable_route_ids.size()); |
| + |
| for (size_t i = 0; i < routes.size(); ++i) { |
| routes_converted.push_back(routes[i].To<MediaRoute>()); |
| } |
| - FOR_EACH_OBSERVER(MediaRoutesObserver, routes_observers_, |
| - OnRoutesUpdated(routes_converted)); |
| + for (size_t i = 0; i < joinable_route_ids.size(); ++i) { |
|
imcheng
2015/11/26 00:49:45
nit: rm brace in this for loop and above
matt.boetger
2015/12/01 01:26:56
Done.
|
| + joinable_routes_converted.push_back(joinable_route_ids[i].get()); |
| + } |
| + |
| + auto it = routes_queries_.find(media_source); |
| + if (it == routes_queries_.end() || |
| + !(it->second->observers.might_have_observers())) { |
| + DVLOG_WITH_INSTANCE(1) |
| + << "Received route list without any active observers: " << media_source; |
| + } else { |
| + FOR_EACH_OBSERVER(MediaRoutesObserver, it->second->observers, |
| + OnRoutesUpdated(routes_converted, |
| + joinable_routes_converted)); |
| + } |
| } |
| void MediaRouterMojoImpl::RouteResponseReceived( |
| @@ -307,6 +331,30 @@ void MediaRouterMojoImpl::JoinRoute( |
| callbacks)); |
| } |
| +void MediaRouterMojoImpl::JoinRouteByRouteId( |
| + const MediaSource::Id& source_id, |
| + const MediaRoute::Id& route_id, |
| + const GURL& origin, |
| + content::WebContents* web_contents, |
| + const std::vector<MediaRouteResponseCallback>& callbacks) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + |
| + if (!origin.is_valid()) { |
| + DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin; |
| + for (const MediaRouteResponseCallback& callback : callbacks) |
| + callback.Run(nullptr, "", "Invalid origin"); |
| + return; |
| + } |
| + |
| + int tab_id = SessionTabHelper::IdForTab(web_contents); |
| + std::string presentation_id("non-local-join_"); |
| + presentation_id += route_id; |
| + RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoJoinRoute, |
| + base::Unretained(this), source_id, presentation_id, |
| + origin.is_empty() ? "" : origin.spec(), tab_id, |
| + callbacks)); |
| +} |
| + |
| void MediaRouterMojoImpl::CloseRoute(const MediaRoute::Id& route_id) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| @@ -414,22 +462,36 @@ void MediaRouterMojoImpl::UnregisterMediaSinksObserver( |
| void MediaRouterMojoImpl::RegisterMediaRoutesObserver( |
| MediaRoutesObserver* observer) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(!routes_observers_.HasObserver(observer)); |
| + const MediaSource::Id source_id = observer->source_id(); |
| + auto* routes_query = routes_queries_.get(source_id); |
| + if (!routes_query) { |
| + routes_query = new MediaRoutesQuery; |
| + routes_queries_.add(source_id, make_scoped_ptr(routes_query)); |
| + } else { |
| + DCHECK(!routes_query->observers.HasObserver(observer)); |
| + } |
| + routes_query->observers.AddObserver(observer); |
| RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaRoutes, |
| - base::Unretained(this))); |
| - routes_observers_.AddObserver(observer); |
| + base::Unretained(this), source_id)); |
| } |
| void MediaRouterMojoImpl::UnregisterMediaRoutesObserver( |
| MediaRoutesObserver* observer) { |
| - if (!routes_observers_.HasObserver(observer)) |
| + const MediaSource::Id source_id = observer->source_id(); |
| + auto* routes_query = routes_queries_.get(source_id); |
| + if (!routes_query || !routes_query->observers.HasObserver(observer)) { |
| return; |
| + } |
| - routes_observers_.RemoveObserver(observer); |
| - if (!routes_observers_.might_have_observers()) { |
| + // If we are removing the final observer for the source, then stop |
| + // observing routes for it. |
| + // might_have_observers() is reliable here on the assumption that this call |
| + // is not inside the ObserverList iteration. |
| + routes_query->observers.RemoveObserver(observer); |
| + if (!routes_query->observers.might_have_observers()) { |
| RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopObservingMediaRoutes, |
| - base::Unretained(this))); |
| + base::Unretained(this), source_id)); |
| } |
| } |
| @@ -691,14 +753,36 @@ void MediaRouterMojoImpl::DoStopObservingMediaSinks( |
| sinks_queries_.erase(source_id); |
| } |
| -void MediaRouterMojoImpl::DoStartObservingMediaRoutes() { |
| +void MediaRouterMojoImpl::DoStartObservingMediaRoutes( |
| + const MediaSource::Id& source_id) { |
| DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaRoutes"; |
| - media_route_provider_->StartObservingMediaRoutes(); |
| + |
| + // No need to call MRPM if all observers have been removed in the meantime. |
| + auto* routes_query = routes_queries_.get(source_id); |
| + if (!routes_query || !routes_query->observers.might_have_observers()) { |
| + return; |
| + } |
| + |
| + DVLOG_WITH_INSTANCE(1) << "MRPM.StartObservingMediaRoutes: " << source_id; |
| + media_route_provider_->StartObservingMediaRoutes(source_id); |
| + routes_query->is_active = true; |
| } |
| -void MediaRouterMojoImpl::DoStopObservingMediaRoutes() { |
| +void MediaRouterMojoImpl::DoStopObservingMediaRoutes( |
| + const MediaSource::Id& source_id) { |
| DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaRoutes"; |
| - media_route_provider_->StopObservingMediaRoutes(); |
| + |
| + auto* routes_query = routes_queries_.get(source_id); |
| + // No need to call MRPM if observers have been added in the meantime, |
| + // or StopObservingMediaSinks has already been called. |
| + if (!routes_query || !routes_query->is_active || |
| + routes_query->observers.might_have_observers()) { |
| + return; |
| + } |
| + |
| + DVLOG_WITH_INSTANCE(1) << "MRPM.StopObservingMediaRoutes: " << source_id; |
| + media_route_provider_->StopObservingMediaRoutes(source_id); |
| + routes_queries_.erase(source_id); |
| } |
| void MediaRouterMojoImpl::EnqueueTask(const base::Closure& closure) { |