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

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: Added Unit Tests Created 5 years, 1 month 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698