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

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: Ready for Review 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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) {
221 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.
213 DCHECK(thread_checker_.CalledOnValidThread()); 222 DCHECK(thread_checker_.CalledOnValidThread());
214 223
215 DVLOG_WITH_INSTANCE(1) << "OnRoutesUpdated"; 224 DVLOG_WITH_INSTANCE(1) << "OnRoutesUpdated";
216 225
217 std::vector<MediaRoute> routes_converted; 226 std::vector<MediaRoute> routes_converted;
218 routes_converted.reserve(routes.size()); 227 routes_converted.reserve(routes.size());
219 228
229 std::vector<MediaRoute::Id> joinable_routes_converted;
230 joinable_routes_converted.reserve(joinable_route_ids.size());
231
220 for (size_t i = 0; i < routes.size(); ++i) { 232 for (size_t i = 0; i < routes.size(); ++i) {
221 routes_converted.push_back(routes[i].To<MediaRoute>()); 233 routes_converted.push_back(routes[i].To<MediaRoute>());
222 } 234 }
223 235
224 FOR_EACH_OBSERVER(MediaRoutesObserver, routes_observers_, 236 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.
225 OnRoutesUpdated(routes_converted)); 237 joinable_routes_converted.push_back(joinable_route_ids[i].get());
238 }
239
240 auto it = routes_queries_.find(media_source);
241 if (it == routes_queries_.end() ||
242 !(it->second->observers.might_have_observers())) {
243 DVLOG_WITH_INSTANCE(1)
244 << "Received route list without any active observers: " << media_source;
245 } else {
246 FOR_EACH_OBSERVER(MediaRoutesObserver, it->second->observers,
247 OnRoutesUpdated(routes_converted,
248 joinable_routes_converted));
249 }
226 } 250 }
227 251
228 void MediaRouterMojoImpl::RouteResponseReceived( 252 void MediaRouterMojoImpl::RouteResponseReceived(
229 const std::string& presentation_id, 253 const std::string& presentation_id,
230 const std::vector<MediaRouteResponseCallback>& callbacks, 254 const std::vector<MediaRouteResponseCallback>& callbacks,
231 interfaces::MediaRoutePtr media_route, 255 interfaces::MediaRoutePtr media_route,
232 const mojo::String& error_text) { 256 const mojo::String& error_text) {
233 scoped_ptr<MediaRoute> route; 257 scoped_ptr<MediaRoute> route;
234 std::string actual_presentation_id; 258 std::string actual_presentation_id;
235 std::string error; 259 std::string error;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 return; 324 return;
301 } 325 }
302 326
303 int tab_id = SessionTabHelper::IdForTab(web_contents); 327 int tab_id = SessionTabHelper::IdForTab(web_contents);
304 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoJoinRoute, 328 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoJoinRoute,
305 base::Unretained(this), source_id, presentation_id, 329 base::Unretained(this), source_id, presentation_id,
306 origin.is_empty() ? "" : origin.spec(), tab_id, 330 origin.is_empty() ? "" : origin.spec(), tab_id,
307 callbacks)); 331 callbacks));
308 } 332 }
309 333
334 void MediaRouterMojoImpl::JoinRouteByRouteId(
335 const MediaSource::Id& source_id,
336 const MediaRoute::Id& route_id,
337 const GURL& origin,
338 content::WebContents* web_contents,
339 const std::vector<MediaRouteResponseCallback>& callbacks) {
340 DCHECK(thread_checker_.CalledOnValidThread());
341
342 if (!origin.is_valid()) {
343 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin;
344 for (const MediaRouteResponseCallback& callback : callbacks)
345 callback.Run(nullptr, "", "Invalid origin");
346 return;
347 }
348
349 int tab_id = SessionTabHelper::IdForTab(web_contents);
350 std::string presentation_id("non-local-join_");
351 presentation_id += route_id;
352 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoJoinRoute,
353 base::Unretained(this), source_id, presentation_id,
354 origin.is_empty() ? "" : origin.spec(), tab_id,
355 callbacks));
356 }
357
310 void MediaRouterMojoImpl::CloseRoute(const MediaRoute::Id& route_id) { 358 void MediaRouterMojoImpl::CloseRoute(const MediaRoute::Id& route_id) {
311 DCHECK(thread_checker_.CalledOnValidThread()); 359 DCHECK(thread_checker_.CalledOnValidThread());
312 360
313 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoCloseRoute, 361 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoCloseRoute,
314 base::Unretained(this), route_id)); 362 base::Unretained(this), route_id));
315 } 363 }
316 364
317 void MediaRouterMojoImpl::SendRouteMessage( 365 void MediaRouterMojoImpl::SendRouteMessage(
318 const MediaRoute::Id& route_id, 366 const MediaRoute::Id& route_id,
319 const std::string& message, 367 const std::string& message,
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 base::Unretained(this), source_id)); 455 base::Unretained(this), source_id));
408 } else { 456 } else {
409 sinks_queries_.erase(source_id); 457 sinks_queries_.erase(source_id);
410 } 458 }
411 } 459 }
412 } 460 }
413 461
414 void MediaRouterMojoImpl::RegisterMediaRoutesObserver( 462 void MediaRouterMojoImpl::RegisterMediaRoutesObserver(
415 MediaRoutesObserver* observer) { 463 MediaRoutesObserver* observer) {
416 DCHECK(thread_checker_.CalledOnValidThread()); 464 DCHECK(thread_checker_.CalledOnValidThread());
417 DCHECK(!routes_observers_.HasObserver(observer)); 465 const MediaSource::Id source_id = observer->source_id();
466 auto* routes_query = routes_queries_.get(source_id);
467 if (!routes_query) {
468 routes_query = new MediaRoutesQuery;
469 routes_queries_.add(source_id, make_scoped_ptr(routes_query));
470 } else {
471 DCHECK(!routes_query->observers.HasObserver(observer));
472 }
418 473
474 routes_query->observers.AddObserver(observer);
419 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaRoutes, 475 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaRoutes,
420 base::Unretained(this))); 476 base::Unretained(this), source_id));
421 routes_observers_.AddObserver(observer);
422 } 477 }
423 478
424 void MediaRouterMojoImpl::UnregisterMediaRoutesObserver( 479 void MediaRouterMojoImpl::UnregisterMediaRoutesObserver(
425 MediaRoutesObserver* observer) { 480 MediaRoutesObserver* observer) {
426 if (!routes_observers_.HasObserver(observer)) 481 const MediaSource::Id source_id = observer->source_id();
482 auto* routes_query = routes_queries_.get(source_id);
483 if (!routes_query || !routes_query->observers.HasObserver(observer)) {
427 return; 484 return;
485 }
428 486
429 routes_observers_.RemoveObserver(observer); 487 // If we are removing the final observer for the source, then stop
430 if (!routes_observers_.might_have_observers()) { 488 // observing routes for it.
489 // might_have_observers() is reliable here on the assumption that this call
490 // is not inside the ObserverList iteration.
491 routes_query->observers.RemoveObserver(observer);
492 if (!routes_query->observers.might_have_observers()) {
431 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopObservingMediaRoutes, 493 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopObservingMediaRoutes,
432 base::Unretained(this))); 494 base::Unretained(this), source_id));
433 } 495 }
434 } 496 }
435 497
436 void MediaRouterMojoImpl::RegisterIssuesObserver(IssuesObserver* observer) { 498 void MediaRouterMojoImpl::RegisterIssuesObserver(IssuesObserver* observer) {
437 DCHECK(thread_checker_.CalledOnValidThread()); 499 DCHECK(thread_checker_.CalledOnValidThread());
438 issue_manager_.RegisterObserver(observer); 500 issue_manager_.RegisterObserver(observer);
439 } 501 }
440 502
441 void MediaRouterMojoImpl::UnregisterIssuesObserver(IssuesObserver* observer) { 503 void MediaRouterMojoImpl::UnregisterIssuesObserver(IssuesObserver* observer) {
442 DCHECK(thread_checker_.CalledOnValidThread()); 504 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 if (!sinks_query || !sinks_query->is_active || 746 if (!sinks_query || !sinks_query->is_active ||
685 sinks_query->observers.might_have_observers()) { 747 sinks_query->observers.might_have_observers()) {
686 return; 748 return;
687 } 749 }
688 750
689 DVLOG_WITH_INSTANCE(1) << "MRPM.StopObservingMediaSinks: " << source_id; 751 DVLOG_WITH_INSTANCE(1) << "MRPM.StopObservingMediaSinks: " << source_id;
690 media_route_provider_->StopObservingMediaSinks(source_id); 752 media_route_provider_->StopObservingMediaSinks(source_id);
691 sinks_queries_.erase(source_id); 753 sinks_queries_.erase(source_id);
692 } 754 }
693 755
694 void MediaRouterMojoImpl::DoStartObservingMediaRoutes() { 756 void MediaRouterMojoImpl::DoStartObservingMediaRoutes(
757 const MediaSource::Id& source_id) {
695 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaRoutes"; 758 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaRoutes";
696 media_route_provider_->StartObservingMediaRoutes(); 759
760 // No need to call MRPM if all observers have been removed in the meantime.
761 auto* routes_query = routes_queries_.get(source_id);
762 if (!routes_query || !routes_query->observers.might_have_observers()) {
763 return;
764 }
765
766 DVLOG_WITH_INSTANCE(1) << "MRPM.StartObservingMediaRoutes: " << source_id;
767 media_route_provider_->StartObservingMediaRoutes(source_id);
768 routes_query->is_active = true;
697 } 769 }
698 770
699 void MediaRouterMojoImpl::DoStopObservingMediaRoutes() { 771 void MediaRouterMojoImpl::DoStopObservingMediaRoutes(
772 const MediaSource::Id& source_id) {
700 DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaRoutes"; 773 DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaRoutes";
701 media_route_provider_->StopObservingMediaRoutes(); 774
775 auto* routes_query = routes_queries_.get(source_id);
776 // No need to call MRPM if observers have been added in the meantime,
777 // or StopObservingMediaSinks has already been called.
778 if (!routes_query || !routes_query->is_active ||
779 routes_query->observers.might_have_observers()) {
780 return;
781 }
782
783 DVLOG_WITH_INSTANCE(1) << "MRPM.StopObservingMediaRoutes: " << source_id;
784 media_route_provider_->StopObservingMediaRoutes(source_id);
785 routes_queries_.erase(source_id);
702 } 786 }
703 787
704 void MediaRouterMojoImpl::EnqueueTask(const base::Closure& closure) { 788 void MediaRouterMojoImpl::EnqueueTask(const base::Closure& closure) {
705 pending_requests_.push_back(closure); 789 pending_requests_.push_back(closure);
706 if (pending_requests_.size() > kMaxPendingRequests) { 790 if (pending_requests_.size() > kMaxPendingRequests) {
707 DLOG_WITH_INSTANCE(ERROR) << "Reached max queue size. Dropping oldest " 791 DLOG_WITH_INSTANCE(ERROR) << "Reached max queue size. Dropping oldest "
708 << "request."; 792 << "request.";
709 pending_requests_.pop_front(); 793 pending_requests_.pop_front();
710 } 794 }
711 DVLOG_WITH_INSTANCE(2) << "EnqueueTask (queue-length=" 795 DVLOG_WITH_INSTANCE(2) << "EnqueueTask (queue-length="
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 } 864 }
781 865
782 void MediaRouterMojoImpl::DrainPendingRequests() { 866 void MediaRouterMojoImpl::DrainPendingRequests() {
783 DLOG_WITH_INSTANCE(ERROR) 867 DLOG_WITH_INSTANCE(ERROR)
784 << "Draining request queue. (queue-length=" << pending_requests_.size() 868 << "Draining request queue. (queue-length=" << pending_requests_.size()
785 << ")"; 869 << ")";
786 pending_requests_.clear(); 870 pending_requests_.clear();
787 } 871 }
788 872
789 } // namespace media_router 873 } // namespace media_router
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698