Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: chrome/browser/media/router/media_router_mojo_impl.cc

Issue 1415103006: Non-Local Join for Media Router and Presentation API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Review Fixes 2 Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698