OLD | NEW |
---|---|
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 15 matching lines...) Expand all Loading... | |
77 output->data.reset(new std::vector<uint8_t>); | 55 output->data.reset(new std::vector<uint8_t>); |
78 input->data.Swap(output->data.get()); | 56 input->data.Swap(output->data.get()); |
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 |
65 class MediaRouterMediaRoutesObserver : | |
66 public media_router::MediaRoutesObserver { | |
67 public: | |
68 explicit MediaRouterMediaRoutesObserver(MediaRouterMojoImpl* router) | |
69 : MediaRoutesObserver(router), | |
70 router_(router) { | |
71 DCHECK(router); | |
72 } | |
73 ~MediaRouterMediaRoutesObserver() override {} | |
74 | |
75 // media_router::MediaRoutesObserver: | |
76 void OnRoutesUpdated( | |
77 const std::vector<media_router::MediaRoute>& routes) override { | |
78 bool has_local_route = | |
79 std::find_if(routes.begin(), routes.end(), | |
80 [](const media_router::MediaRoute& route) { | |
81 return route.is_local(); }) != | |
82 routes.end(); | |
83 | |
84 // |this| will be deleted beyond this point if |has_local_route| is false. | |
85 router_->UpdateHasLocalRoute(has_local_route); | |
86 } | |
87 | |
88 private: | |
89 MediaRouterMojoImpl* const router_; | |
90 | |
91 DISALLOW_COPY_AND_ASSIGN(MediaRouterMediaRoutesObserver); | |
92 }; | |
93 | |
87 } // namespace | 94 } // namespace |
88 | 95 |
89 MediaRouterMojoImpl::MediaRouterMojoImpl( | 96 MediaRouterMojoImpl::MediaRouterMojoImpl( |
90 extensions::EventPageTracker* event_page_tracker) | 97 extensions::EventPageTracker* event_page_tracker) |
91 : event_page_tracker_(event_page_tracker), | 98 : event_page_tracker_(event_page_tracker), |
92 instance_id_(base::GenerateGUID()) { | 99 instance_id_(base::GenerateGUID()), |
100 has_local_route_(false) { | |
93 DCHECK(event_page_tracker_); | 101 DCHECK(event_page_tracker_); |
94 } | 102 } |
95 | 103 |
96 MediaRouterMojoImpl::~MediaRouterMojoImpl() { | 104 MediaRouterMojoImpl::~MediaRouterMojoImpl() { |
97 DCHECK(thread_checker_.CalledOnValidThread()); | 105 DCHECK(thread_checker_.CalledOnValidThread()); |
98 } | 106 } |
99 | 107 |
100 // static | 108 // static |
101 void MediaRouterMojoImpl::BindToRequest( | 109 void MediaRouterMojoImpl::BindToRequest( |
102 const std::string& extension_id, | 110 const std::string& extension_id, |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
184 routes_converted.reserve(routes.size()); | 192 routes_converted.reserve(routes.size()); |
185 | 193 |
186 for (size_t i = 0; i < routes.size(); ++i) { | 194 for (size_t i = 0; i < routes.size(); ++i) { |
187 routes_converted.push_back(routes[i].To<MediaRoute>()); | 195 routes_converted.push_back(routes[i].To<MediaRoute>()); |
188 } | 196 } |
189 | 197 |
190 FOR_EACH_OBSERVER(MediaRoutesObserver, routes_observers_, | 198 FOR_EACH_OBSERVER(MediaRoutesObserver, routes_observers_, |
191 OnRoutesUpdated(routes_converted)); | 199 OnRoutesUpdated(routes_converted)); |
192 } | 200 } |
193 | 201 |
202 void MediaRouterMojoImpl::RouteResponseReceived( | |
203 const std::string& presentation_id, | |
204 const std::vector<MediaRouteResponseCallback>& callbacks, | |
205 interfaces::MediaRoutePtr media_route, | |
206 const mojo::String& error_text) { | |
207 scoped_ptr<MediaRoute> route; | |
208 std::string actual_presentation_id; | |
209 std::string error; | |
210 if (media_route.is_null()) { | |
211 // An error occurred. | |
212 DCHECK(!error_text.is_null()); | |
213 error = !error_text.get().empty() ? error_text.get() : "Unknown error."; | |
214 } else { | |
215 route = media_route.To<scoped_ptr<MediaRoute>>(); | |
216 actual_presentation_id = presentation_id; | |
217 | |
218 FOR_EACH_OBSERVER(LocalMediaRoutesObserver, local_routes_observers_, | |
imcheng
2015/10/02 19:54:43
Replace this with UpdateHasLocalRoute(true)
apacible
2015/10/02 20:45:48
Done.
| |
219 OnHasLocalRouteUpdated(true)); | |
220 if (!routes_observer_) | |
221 routes_observer_.reset(new MediaRouterMediaRoutesObserver(this)); | |
222 } | |
223 | |
224 for (const MediaRouteResponseCallback& callback : callbacks) | |
225 callback.Run(route.get(), actual_presentation_id, error); | |
226 } | |
227 | |
194 void MediaRouterMojoImpl::CreateRoute( | 228 void MediaRouterMojoImpl::CreateRoute( |
195 const MediaSource::Id& source_id, | 229 const MediaSource::Id& source_id, |
196 const MediaSink::Id& sink_id, | 230 const MediaSink::Id& sink_id, |
197 const GURL& origin, | 231 const GURL& origin, |
198 int tab_id, | 232 int tab_id, |
199 const std::vector<MediaRouteResponseCallback>& callbacks) { | 233 const std::vector<MediaRouteResponseCallback>& callbacks) { |
200 DCHECK(thread_checker_.CalledOnValidThread()); | 234 DCHECK(thread_checker_.CalledOnValidThread()); |
201 | 235 |
202 if (!origin.is_valid()) { | 236 if (!origin.is_valid()) { |
203 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin; | 237 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin; |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
385 return; | 419 return; |
386 | 420 |
387 observer_list->RemoveObserver(observer); | 421 observer_list->RemoveObserver(observer); |
388 if (!observer_list->might_have_observers()) { | 422 if (!observer_list->might_have_observers()) { |
389 messages_observers_.erase(route_id); | 423 messages_observers_.erase(route_id); |
390 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopListeningForRouteMessages, | 424 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStopListeningForRouteMessages, |
391 base::Unretained(this), route_id)); | 425 base::Unretained(this), route_id)); |
392 } | 426 } |
393 } | 427 } |
394 | 428 |
429 void MediaRouterMojoImpl::RegisterLocalMediaRoutesObserver( | |
imcheng
2015/10/02 19:54:43
we should add a test for this. Maybe in a separate
apacible
2015/10/02 20:45:48
Acknowledged.
| |
430 LocalMediaRoutesObserver* observer) { | |
431 DCHECK(thread_checker_.CalledOnValidThread()); | |
432 DCHECK(observer); | |
433 | |
434 DCHECK(!local_routes_observers_.HasObserver(observer)); | |
435 local_routes_observers_.AddObserver(observer); | |
436 } | |
437 | |
438 void MediaRouterMojoImpl::UnregisterLocalMediaRoutesObserver( | |
439 LocalMediaRoutesObserver* observer) { | |
440 DCHECK(thread_checker_.CalledOnValidThread()); | |
441 DCHECK(observer); | |
442 | |
443 if (!local_routes_observers_.HasObserver(observer)) | |
444 return; | |
445 local_routes_observers_.RemoveObserver(observer); | |
446 } | |
447 | |
395 void MediaRouterMojoImpl::DoCreateRoute( | 448 void MediaRouterMojoImpl::DoCreateRoute( |
396 const MediaSource::Id& source_id, | 449 const MediaSource::Id& source_id, |
397 const MediaSink::Id& sink_id, | 450 const MediaSink::Id& sink_id, |
398 const std::string& origin, | 451 const std::string& origin, |
399 int tab_id, | 452 int tab_id, |
400 const std::vector<MediaRouteResponseCallback>& callbacks) { | 453 const std::vector<MediaRouteResponseCallback>& callbacks) { |
401 std::string presentation_id("mr_"); | 454 std::string presentation_id("mr_"); |
402 presentation_id += base::GenerateGUID(); | 455 presentation_id += base::GenerateGUID(); |
403 DVLOG_WITH_INSTANCE(1) << "DoCreateRoute " << source_id << "=>" << sink_id | 456 DVLOG_WITH_INSTANCE(1) << "DoCreateRoute " << source_id << "=>" << sink_id |
404 << ", presentation ID: " << presentation_id; | 457 << ", presentation ID: " << presentation_id; |
405 media_route_provider_->CreateRoute( | 458 media_route_provider_->CreateRoute( |
406 source_id, sink_id, presentation_id, origin, tab_id, | 459 source_id, sink_id, presentation_id, origin, tab_id, |
407 base::Bind(&RouteResponseReceived, presentation_id, callbacks)); | 460 base::Bind(&MediaRouterMojoImpl::RouteResponseReceived, |
461 base::Unretained(this), presentation_id, callbacks)); | |
408 } | 462 } |
409 | 463 |
410 void MediaRouterMojoImpl::DoJoinRoute( | 464 void MediaRouterMojoImpl::DoJoinRoute( |
411 const MediaSource::Id& source_id, | 465 const MediaSource::Id& source_id, |
412 const std::string& presentation_id, | 466 const std::string& presentation_id, |
413 const std::string& origin, | 467 const std::string& origin, |
414 int tab_id, | 468 int tab_id, |
415 const std::vector<MediaRouteResponseCallback>& callbacks) { | 469 const std::vector<MediaRouteResponseCallback>& callbacks) { |
416 DVLOG_WITH_INSTANCE(1) << "DoJoinRoute " << source_id | 470 DVLOG_WITH_INSTANCE(1) << "DoJoinRoute " << source_id |
417 << ", presentation ID: " << presentation_id; | 471 << ", presentation ID: " << presentation_id; |
418 media_route_provider_->JoinRoute( | 472 media_route_provider_->JoinRoute( |
419 source_id, presentation_id, origin, tab_id, | 473 source_id, presentation_id, origin, tab_id, |
420 base::Bind(&RouteResponseReceived, presentation_id, callbacks)); | 474 base::Bind(&MediaRouterMojoImpl::RouteResponseReceived, |
475 base::Unretained(this), presentation_id, callbacks)); | |
421 } | 476 } |
422 | 477 |
423 void MediaRouterMojoImpl::DoCloseRoute(const MediaRoute::Id& route_id) { | 478 void MediaRouterMojoImpl::DoCloseRoute(const MediaRoute::Id& route_id) { |
424 DVLOG_WITH_INSTANCE(1) << "DoCloseRoute " << route_id; | 479 DVLOG_WITH_INSTANCE(1) << "DoCloseRoute " << route_id; |
425 media_route_provider_->CloseRoute(route_id); | 480 media_route_provider_->CloseRoute(route_id); |
426 } | 481 } |
427 | 482 |
428 void MediaRouterMojoImpl::DoSendSessionMessage( | 483 void MediaRouterMojoImpl::DoSendSessionMessage( |
429 const MediaRoute::Id& route_id, | 484 const MediaRoute::Id& route_id, |
430 const std::string& message, | 485 const std::string& message, |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
510 route_id, base::Bind(&MediaRouterMojoImpl::OnRouteMessagesReceived, | 565 route_id, base::Bind(&MediaRouterMojoImpl::OnRouteMessagesReceived, |
511 base::Unretained(this), route_id)); | 566 base::Unretained(this), route_id)); |
512 } | 567 } |
513 | 568 |
514 void MediaRouterMojoImpl::DoOnPresentationSessionDetached( | 569 void MediaRouterMojoImpl::DoOnPresentationSessionDetached( |
515 const MediaRoute::Id& route_id) { | 570 const MediaRoute::Id& route_id) { |
516 DVLOG_WITH_INSTANCE(1) << "DoOnPresentationSessionDetached " << route_id; | 571 DVLOG_WITH_INSTANCE(1) << "DoOnPresentationSessionDetached " << route_id; |
517 media_route_provider_->OnPresentationSessionDetached(route_id); | 572 media_route_provider_->OnPresentationSessionDetached(route_id); |
518 } | 573 } |
519 | 574 |
575 bool MediaRouterMojoImpl::HasLocalRoute() const { | |
576 return has_local_route_; | |
577 } | |
578 | |
579 void MediaRouterMojoImpl::UpdateHasLocalRoute(bool has_local_route) { | |
580 if (has_local_route_ != has_local_route) { | |
581 if (!has_local_route) | |
582 routes_observer_.reset(); | |
583 | |
584 FOR_EACH_OBSERVER(LocalMediaRoutesObserver, local_routes_observers_, | |
585 OnHasLocalRouteUpdated(has_local_route_)); | |
imcheng
2015/10/02 19:54:43
you would need to have updated has_local_route_ be
apacible
2015/10/02 20:45:48
Done.
| |
586 } | |
587 | |
588 has_local_route_ = has_local_route; | |
589 } | |
590 | |
520 void MediaRouterMojoImpl::DoStartObservingMediaSinks( | 591 void MediaRouterMojoImpl::DoStartObservingMediaSinks( |
521 const MediaSource::Id& source_id) { | 592 const MediaSource::Id& source_id) { |
522 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaSinks: " << source_id; | 593 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaSinks: " << source_id; |
523 media_route_provider_->StartObservingMediaSinks(source_id); | 594 media_route_provider_->StartObservingMediaSinks(source_id); |
524 } | 595 } |
525 | 596 |
526 void MediaRouterMojoImpl::DoStopObservingMediaSinks( | 597 void MediaRouterMojoImpl::DoStopObservingMediaSinks( |
527 const MediaSource::Id& source_id) { | 598 const MediaSource::Id& source_id) { |
528 DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaSinks: " << source_id; | 599 DVLOG_WITH_INSTANCE(1) << "DoStopObservingMediaSinks: " << source_id; |
529 media_route_provider_->StopObservingMediaSinks(source_id); | 600 media_route_provider_->StopObservingMediaSinks(source_id); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
583 return; | 654 return; |
584 } | 655 } |
585 | 656 |
586 for (const auto& next_request : pending_requests_) | 657 for (const auto& next_request : pending_requests_) |
587 next_request.Run(); | 658 next_request.Run(); |
588 | 659 |
589 pending_requests_.clear(); | 660 pending_requests_.clear(); |
590 } | 661 } |
591 | 662 |
592 } // namespace media_router | 663 } // namespace media_router |
OLD | NEW |