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

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

Issue 1383653002: MediaRouterAction: Only observe Media Routes when there is a local route. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Changes per imcheng@'s comments. Created 5 years, 2 months 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"
11 #include "base/observer_list.h" 11 #include "base/observer_list.h"
12 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
13 #include "chrome/browser/media/router/issues_observer.h" 13 #include "chrome/browser/media/router/issues_observer.h"
14 #include "chrome/browser/media/router/local_media_routes_observer.h"
14 #include "chrome/browser/media/router/media_router_factory.h" 15 #include "chrome/browser/media/router/media_router_factory.h"
15 #include "chrome/browser/media/router/media_router_type_converters.h" 16 #include "chrome/browser/media/router/media_router_type_converters.h"
16 #include "chrome/browser/media/router/media_routes_observer.h" 17 #include "chrome/browser/media/router/media_routes_observer.h"
17 #include "chrome/browser/media/router/media_sinks_observer.h" 18 #include "chrome/browser/media/router/media_sinks_observer.h"
18 #include "chrome/browser/media/router/presentation_session_messages_observer.h" 19 #include "chrome/browser/media/router/presentation_session_messages_observer.h"
19 #include "extensions/browser/process_manager.h" 20 #include "extensions/browser/process_manager.h"
20 21
21 #define DVLOG_WITH_INSTANCE(level) \ 22 #define DVLOG_WITH_INSTANCE(level) \
22 DVLOG(level) << "MR #" << instance_id_ << ": " 23 DVLOG(level) << "MR #" << instance_id_ << ": "
23 24
24 #define DLOG_WITH_INSTANCE(level) DLOG(level) << "MR #" << instance_id_ << ": " 25 #define DLOG_WITH_INSTANCE(level) DLOG(level) << "MR #" << instance_id_ << ": "
25 26
26 namespace media_router { 27 namespace media_router {
27 namespace { 28 namespace {
28 29
29 // Converts the callback result of calling Mojo CreateRoute()/JoinRoute()
30 // into a local callback.
31 void RouteResponseReceived(
32 const std::string& presentation_id,
33 const std::vector<MediaRouteResponseCallback>& callbacks,
34 interfaces::MediaRoutePtr media_route,
35 const mojo::String& error_text) {
36 scoped_ptr<MediaRoute> route;
37 std::string actual_presentation_id;
38 std::string error;
39 if (media_route.is_null()) {
40 // An error occurred.
41 DCHECK(!error_text.is_null());
42 error = !error_text.get().empty() ? error_text.get() : "Unknown error.";
43 } else {
44 route = media_route.To<scoped_ptr<MediaRoute>>();
45 actual_presentation_id = presentation_id;
46 }
47
48 for (const MediaRouteResponseCallback& callback : callbacks)
49 callback.Run(route.get(), actual_presentation_id, error);
50 }
51
52 // TODO(imcheng): We should handle failure in this case. One way is to invoke 30 // TODO(imcheng): We should handle failure in this case. One way is to invoke
53 // all pending requests with failure. (crbug.com/490787) 31 // all pending requests with failure. (crbug.com/490787)
54 void EventPageWakeComplete(bool success) { 32 void EventPageWakeComplete(bool success) {
55 if (!success) 33 if (!success)
56 LOG(ERROR) << "An error encountered while waking the event page."; 34 LOG(ERROR) << "An error encountered while waking the event page.";
57 } 35 }
58 36
59 scoped_ptr<content::PresentationSessionMessage> 37 scoped_ptr<content::PresentationSessionMessage>
60 ConvertToPresentationSessionMessage(interfaces::RouteMessagePtr input) { 38 ConvertToPresentationSessionMessage(interfaces::RouteMessagePtr input) {
61 DCHECK(!input.is_null()); 39 DCHECK(!input.is_null());
(...skipping 17 matching lines...) Expand all
79 return output.Pass(); 57 return output.Pass();
80 } 58 }
81 } 59 }
82 60
83 NOTREACHED() << "Invalid route message type " << input->type; 61 NOTREACHED() << "Invalid route message type " << input->type;
84 return output.Pass(); 62 return output.Pass();
85 } 63 }
86 64
87 } // namespace 65 } // namespace
88 66
67 MediaRouterMojoImpl::MediaRouterMediaRoutesObserver::
68 MediaRouterMediaRoutesObserver(MediaRouterMojoImpl* router)
69 : MediaRoutesObserver(router),
70 router_(router) {
71 DCHECK(router);
72 }
73
74 MediaRouterMojoImpl::MediaRouterMediaRoutesObserver::
75 ~MediaRouterMediaRoutesObserver() {
76 }
77
78 void MediaRouterMojoImpl::MediaRouterMediaRoutesObserver::OnRoutesUpdated(
79 const std::vector<media_router::MediaRoute>& routes) {
80 bool has_local_route =
81 std::find_if(routes.begin(), routes.end(),
82 [](const media_router::MediaRoute& route) {
83 return route.is_local(); }) !=
84 routes.end();
85
86 // |this| will be deleted beyond this point if |has_local_route| is false.
87 router_->UpdateHasLocalRoute(has_local_route);
88 }
89
89 MediaRouterMojoImpl::MediaRouterMojoImpl( 90 MediaRouterMojoImpl::MediaRouterMojoImpl(
90 extensions::EventPageTracker* event_page_tracker) 91 extensions::EventPageTracker* event_page_tracker)
91 : event_page_tracker_(event_page_tracker), 92 : event_page_tracker_(event_page_tracker),
92 instance_id_(base::GenerateGUID()) { 93 instance_id_(base::GenerateGUID()),
94 has_local_route_(false) {
93 DCHECK(event_page_tracker_); 95 DCHECK(event_page_tracker_);
94 } 96 }
95 97
96 MediaRouterMojoImpl::~MediaRouterMojoImpl() { 98 MediaRouterMojoImpl::~MediaRouterMojoImpl() {
97 DCHECK(thread_checker_.CalledOnValidThread()); 99 DCHECK(thread_checker_.CalledOnValidThread());
98 } 100 }
99 101
100 // static 102 // static
101 void MediaRouterMojoImpl::BindToRequest( 103 void MediaRouterMojoImpl::BindToRequest(
102 const std::string& extension_id, 104 const std::string& extension_id,
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 routes_converted.reserve(routes.size()); 186 routes_converted.reserve(routes.size());
185 187
186 for (size_t i = 0; i < routes.size(); ++i) { 188 for (size_t i = 0; i < routes.size(); ++i) {
187 routes_converted.push_back(routes[i].To<MediaRoute>()); 189 routes_converted.push_back(routes[i].To<MediaRoute>());
188 } 190 }
189 191
190 FOR_EACH_OBSERVER(MediaRoutesObserver, routes_observers_, 192 FOR_EACH_OBSERVER(MediaRoutesObserver, routes_observers_,
191 OnRoutesUpdated(routes_converted)); 193 OnRoutesUpdated(routes_converted));
192 } 194 }
193 195
196 void MediaRouterMojoImpl::RouteResponseReceived(
197 const std::string& presentation_id,
198 const std::vector<MediaRouteResponseCallback>& callbacks,
199 interfaces::MediaRoutePtr media_route,
200 const mojo::String& error_text) {
201 scoped_ptr<MediaRoute> route;
202 std::string actual_presentation_id;
203 std::string error;
204 if (media_route.is_null()) {
205 // An error occurred.
206 DCHECK(!error_text.is_null());
207 error = !error_text.get().empty() ? error_text.get() : "Unknown error.";
208 } else {
209 route = media_route.To<scoped_ptr<MediaRoute>>();
210 actual_presentation_id = presentation_id;
211
212 FOR_EACH_OBSERVER(LocalMediaRoutesObserver, local_routes_observers_,
213 UpdateHasLocalRoute(true));
214 if (!routes_observer_)
215 routes_observer_.reset(new MediaRouterMediaRoutesObserver(this));
216 }
217
218 for (const MediaRouteResponseCallback& callback : callbacks)
219 callback.Run(route.get(), actual_presentation_id, error);
220 }
221
222 void MediaRouterMojoImpl::UpdateHasLocalRoute(bool has_local_route) {
223 has_local_route_ = has_local_route;
imcheng 2015/10/02 17:21:11 Can we skip the logic below if has_local_route_ ==
apacible 2015/10/02 18:48:20 Done.
224
225 if (!has_local_route_)
226 routes_observer_.reset();
227
228 FOR_EACH_OBSERVER(LocalMediaRoutesObserver, local_routes_observers_,
229 UpdateHasLocalRoute(has_local_route_));
230 }
231
194 void MediaRouterMojoImpl::CreateRoute( 232 void MediaRouterMojoImpl::CreateRoute(
195 const MediaSource::Id& source_id, 233 const MediaSource::Id& source_id,
196 const MediaSink::Id& sink_id, 234 const MediaSink::Id& sink_id,
197 const GURL& origin, 235 const GURL& origin,
198 int tab_id, 236 int tab_id,
199 const std::vector<MediaRouteResponseCallback>& callbacks) { 237 const std::vector<MediaRouteResponseCallback>& callbacks) {
200 DCHECK(thread_checker_.CalledOnValidThread()); 238 DCHECK(thread_checker_.CalledOnValidThread());
201 239
202 if (!origin.is_valid()) { 240 if (!origin.is_valid()) {
203 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin; 241 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin;
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 return; 423 return;
386 424
387 observer_list->RemoveObserver(observer); 425 observer_list->RemoveObserver(observer);
388 if (!observer_list->might_have_observers()) { 426 if (!observer_list->might_have_observers()) {
389 messages_observers_.erase(route_id); 427 messages_observers_.erase(route_id);
390 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopListeningForRouteMessages, 428 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopListeningForRouteMessages,
391 base::Unretained(this), route_id)); 429 base::Unretained(this), route_id));
392 } 430 }
393 } 431 }
394 432
433 void MediaRouterMojoImpl::RegisterLocalMediaRoutesObserver(
434 LocalMediaRoutesObserver* observer) {
435 DCHECK(thread_checker_.CalledOnValidThread());
436 DCHECK(observer);
437
438 DCHECK(!local_routes_observers_.HasObserver(observer));
439 local_routes_observers_.AddObserver(observer);
440 }
441
442 void MediaRouterMojoImpl::UnregisterLocalMediaRoutesObserver(
443 LocalMediaRoutesObserver* observer) {
444 DCHECK(thread_checker_.CalledOnValidThread());
445 DCHECK(observer);
446
447 if (!local_routes_observers_.HasObserver(observer))
448 return;
449 local_routes_observers_.RemoveObserver(observer);
450 }
451
395 void MediaRouterMojoImpl::DoCreateRoute( 452 void MediaRouterMojoImpl::DoCreateRoute(
396 const MediaSource::Id& source_id, 453 const MediaSource::Id& source_id,
397 const MediaSink::Id& sink_id, 454 const MediaSink::Id& sink_id,
398 const std::string& origin, 455 const std::string& origin,
399 int tab_id, 456 int tab_id,
400 const std::vector<MediaRouteResponseCallback>& callbacks) { 457 const std::vector<MediaRouteResponseCallback>& callbacks) {
401 std::string presentation_id("mr_"); 458 std::string presentation_id("mr_");
402 presentation_id += base::GenerateGUID(); 459 presentation_id += base::GenerateGUID();
403 DVLOG_WITH_INSTANCE(1) << "DoCreateRoute " << source_id << "=>" << sink_id 460 DVLOG_WITH_INSTANCE(1) << "DoCreateRoute " << source_id << "=>" << sink_id
404 << ", presentation ID: " << presentation_id; 461 << ", presentation ID: " << presentation_id;
405 media_route_provider_->CreateRoute( 462 media_route_provider_->CreateRoute(
406 source_id, sink_id, presentation_id, origin, tab_id, 463 source_id, sink_id, presentation_id, origin, tab_id,
407 base::Bind(&RouteResponseReceived, presentation_id, callbacks)); 464 base::Bind(&MediaRouterMojoImpl::RouteResponseReceived,
465 base::Unretained(this), presentation_id, callbacks));
408 } 466 }
409 467
410 void MediaRouterMojoImpl::DoJoinRoute( 468 void MediaRouterMojoImpl::DoJoinRoute(
411 const MediaSource::Id& source_id, 469 const MediaSource::Id& source_id,
412 const std::string& presentation_id, 470 const std::string& presentation_id,
413 const std::string& origin, 471 const std::string& origin,
414 int tab_id, 472 int tab_id,
415 const std::vector<MediaRouteResponseCallback>& callbacks) { 473 const std::vector<MediaRouteResponseCallback>& callbacks) {
416 DVLOG_WITH_INSTANCE(1) << "DoJoinRoute " << source_id 474 DVLOG_WITH_INSTANCE(1) << "DoJoinRoute " << source_id
417 << ", presentation ID: " << presentation_id; 475 << ", presentation ID: " << presentation_id;
418 media_route_provider_->JoinRoute( 476 media_route_provider_->JoinRoute(
419 source_id, presentation_id, origin, tab_id, 477 source_id, presentation_id, origin, tab_id,
420 base::Bind(&RouteResponseReceived, presentation_id, callbacks)); 478 base::Bind(&MediaRouterMojoImpl::RouteResponseReceived,
479 base::Unretained(this), presentation_id, callbacks));
421 } 480 }
422 481
423 void MediaRouterMojoImpl::DoCloseRoute(const MediaRoute::Id& route_id) { 482 void MediaRouterMojoImpl::DoCloseRoute(const MediaRoute::Id& route_id) {
424 DVLOG_WITH_INSTANCE(1) << "DoCloseRoute " << route_id; 483 DVLOG_WITH_INSTANCE(1) << "DoCloseRoute " << route_id;
425 media_route_provider_->CloseRoute(route_id); 484 media_route_provider_->CloseRoute(route_id);
426 } 485 }
427 486
428 void MediaRouterMojoImpl::DoSendSessionMessage( 487 void MediaRouterMojoImpl::DoSendSessionMessage(
429 const MediaRoute::Id& route_id, 488 const MediaRoute::Id& route_id,
430 const std::string& message, 489 const std::string& message,
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 route_id, base::Bind(&MediaRouterMojoImpl::OnRouteMessagesReceived, 569 route_id, base::Bind(&MediaRouterMojoImpl::OnRouteMessagesReceived,
511 base::Unretained(this), route_id)); 570 base::Unretained(this), route_id));
512 } 571 }
513 572
514 void MediaRouterMojoImpl::DoOnPresentationSessionDetached( 573 void MediaRouterMojoImpl::DoOnPresentationSessionDetached(
515 const MediaRoute::Id& route_id) { 574 const MediaRoute::Id& route_id) {
516 DVLOG_WITH_INSTANCE(1) << "DoOnPresentationSessionDetached " << route_id; 575 DVLOG_WITH_INSTANCE(1) << "DoOnPresentationSessionDetached " << route_id;
517 media_route_provider_->OnPresentationSessionDetached(route_id); 576 media_route_provider_->OnPresentationSessionDetached(route_id);
518 } 577 }
519 578
579 bool MediaRouterMojoImpl::GetHasLocalRoute() {
580 return has_local_route_;
581 }
582
520 void MediaRouterMojoImpl::DoStartObservingMediaSinks( 583 void MediaRouterMojoImpl::DoStartObservingMediaSinks(
521 const MediaSource::Id& source_id) { 584 const MediaSource::Id& source_id) {
522 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaSinks: " << source_id; 585 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaSinks: " << source_id;
523 media_route_provider_->StartObservingMediaSinks(source_id); 586 media_route_provider_->StartObservingMediaSinks(source_id);
524 } 587 }
525 588
526 void MediaRouterMojoImpl::DoStopObservingMediaSinks( 589 void MediaRouterMojoImpl::DoStopObservingMediaSinks(
527 const MediaSource::Id& source_id) { 590 const MediaSource::Id& source_id) {
528 DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaSinks: " << source_id; 591 DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaSinks: " << source_id;
529 media_route_provider_->StopObservingMediaSinks(source_id); 592 media_route_provider_->StopObservingMediaSinks(source_id);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 return; 646 return;
584 } 647 }
585 648
586 for (const auto& next_request : pending_requests_) 649 for (const auto& next_request : pending_requests_)
587 next_request.Run(); 650 next_request.Run();
588 651
589 pending_requests_.clear(); 652 pending_requests_.clear();
590 } 653 }
591 654
592 } // namespace media_router 655 } // namespace media_router
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698