Index: chrome/browser/media/router/media_router_mojo_impl.cc |
diff --git a/chrome/browser/media/router/media_router_mojo_impl.cc b/chrome/browser/media/router/media_router_mojo_impl.cc |
index cfdd2b8d355f2b346a4fab1c63550b3c26781c9b..f20a8bf1c5aa7a4e2bad00f92bec0cfdc1b9e002 100644 |
--- a/chrome/browser/media/router/media_router_mojo_impl.cc |
+++ b/chrome/browser/media/router/media_router_mojo_impl.cc |
@@ -11,6 +11,7 @@ |
#include "base/observer_list.h" |
#include "base/strings/stringprintf.h" |
#include "chrome/browser/media/router/issues_observer.h" |
+#include "chrome/browser/media/router/local_media_routes_observer.h" |
#include "chrome/browser/media/router/media_router_factory.h" |
#include "chrome/browser/media/router/media_router_type_converters.h" |
#include "chrome/browser/media/router/media_routes_observer.h" |
@@ -26,29 +27,6 @@ |
namespace media_router { |
namespace { |
-// Converts the callback result of calling Mojo CreateRoute()/JoinRoute() |
-// into a local callback. |
-void RouteResponseReceived( |
- const std::string& presentation_id, |
- const std::vector<MediaRouteResponseCallback>& callbacks, |
- interfaces::MediaRoutePtr media_route, |
- const mojo::String& error_text) { |
- scoped_ptr<MediaRoute> route; |
- std::string actual_presentation_id; |
- std::string error; |
- if (media_route.is_null()) { |
- // An error occurred. |
- DCHECK(!error_text.is_null()); |
- error = !error_text.get().empty() ? error_text.get() : "Unknown error."; |
- } else { |
- route = media_route.To<scoped_ptr<MediaRoute>>(); |
- actual_presentation_id = presentation_id; |
- } |
- |
- for (const MediaRouteResponseCallback& callback : callbacks) |
- callback.Run(route.get(), actual_presentation_id, error); |
-} |
- |
// TODO(imcheng): We should handle failure in this case. One way is to invoke |
// all pending requests with failure. (crbug.com/490787) |
void EventPageWakeComplete(bool success) { |
@@ -84,12 +62,42 @@ ConvertToPresentationSessionMessage(interfaces::RouteMessagePtr input) { |
return output.Pass(); |
} |
+class MediaRouterMediaRoutesObserver : |
+ public media_router::MediaRoutesObserver { |
+ public: |
+ explicit MediaRouterMediaRoutesObserver(MediaRouterMojoImpl* router) |
+ : MediaRoutesObserver(router), |
+ router_(router) { |
+ DCHECK(router); |
+ } |
+ ~MediaRouterMediaRoutesObserver() override {} |
+ |
+ // media_router::MediaRoutesObserver: |
+ void OnRoutesUpdated( |
+ const std::vector<media_router::MediaRoute>& routes) override { |
+ bool has_local_route = |
+ std::find_if(routes.begin(), routes.end(), |
+ [](const media_router::MediaRoute& route) { |
+ return route.is_local(); }) != |
+ routes.end(); |
+ |
+ // |this| will be deleted beyond this point if |has_local_route| is false. |
+ router_->UpdateHasLocalRoute(has_local_route); |
+ } |
+ |
+ private: |
+ MediaRouterMojoImpl* const router_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(MediaRouterMediaRoutesObserver); |
+}; |
+ |
} // namespace |
MediaRouterMojoImpl::MediaRouterMojoImpl( |
extensions::EventPageTracker* event_page_tracker) |
: event_page_tracker_(event_page_tracker), |
- instance_id_(base::GenerateGUID()) { |
+ instance_id_(base::GenerateGUID()), |
+ has_local_route_(false) { |
DCHECK(event_page_tracker_); |
} |
@@ -191,6 +199,32 @@ void MediaRouterMojoImpl::OnRoutesUpdated( |
OnRoutesUpdated(routes_converted)); |
} |
+void MediaRouterMojoImpl::RouteResponseReceived( |
+ const std::string& presentation_id, |
+ const std::vector<MediaRouteResponseCallback>& callbacks, |
+ interfaces::MediaRoutePtr media_route, |
+ const mojo::String& error_text) { |
+ scoped_ptr<MediaRoute> route; |
+ std::string actual_presentation_id; |
+ std::string error; |
+ if (media_route.is_null()) { |
+ // An error occurred. |
+ DCHECK(!error_text.is_null()); |
+ error = !error_text.get().empty() ? error_text.get() : "Unknown error."; |
+ } else { |
+ route = media_route.To<scoped_ptr<MediaRoute>>(); |
+ actual_presentation_id = presentation_id; |
+ |
+ 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.
|
+ OnHasLocalRouteUpdated(true)); |
+ if (!routes_observer_) |
+ routes_observer_.reset(new MediaRouterMediaRoutesObserver(this)); |
+ } |
+ |
+ for (const MediaRouteResponseCallback& callback : callbacks) |
+ callback.Run(route.get(), actual_presentation_id, error); |
+} |
+ |
void MediaRouterMojoImpl::CreateRoute( |
const MediaSource::Id& source_id, |
const MediaSink::Id& sink_id, |
@@ -392,6 +426,25 @@ void MediaRouterMojoImpl::UnregisterPresentationSessionMessagesObserver( |
} |
} |
+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.
|
+ LocalMediaRoutesObserver* observer) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ DCHECK(observer); |
+ |
+ DCHECK(!local_routes_observers_.HasObserver(observer)); |
+ local_routes_observers_.AddObserver(observer); |
+} |
+ |
+void MediaRouterMojoImpl::UnregisterLocalMediaRoutesObserver( |
+ LocalMediaRoutesObserver* observer) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ DCHECK(observer); |
+ |
+ if (!local_routes_observers_.HasObserver(observer)) |
+ return; |
+ local_routes_observers_.RemoveObserver(observer); |
+} |
+ |
void MediaRouterMojoImpl::DoCreateRoute( |
const MediaSource::Id& source_id, |
const MediaSink::Id& sink_id, |
@@ -404,7 +457,8 @@ void MediaRouterMojoImpl::DoCreateRoute( |
<< ", presentation ID: " << presentation_id; |
media_route_provider_->CreateRoute( |
source_id, sink_id, presentation_id, origin, tab_id, |
- base::Bind(&RouteResponseReceived, presentation_id, callbacks)); |
+ base::Bind(&MediaRouterMojoImpl::RouteResponseReceived, |
+ base::Unretained(this), presentation_id, callbacks)); |
} |
void MediaRouterMojoImpl::DoJoinRoute( |
@@ -417,7 +471,8 @@ void MediaRouterMojoImpl::DoJoinRoute( |
<< ", presentation ID: " << presentation_id; |
media_route_provider_->JoinRoute( |
source_id, presentation_id, origin, tab_id, |
- base::Bind(&RouteResponseReceived, presentation_id, callbacks)); |
+ base::Bind(&MediaRouterMojoImpl::RouteResponseReceived, |
+ base::Unretained(this), presentation_id, callbacks)); |
} |
void MediaRouterMojoImpl::DoCloseRoute(const MediaRoute::Id& route_id) { |
@@ -517,6 +572,22 @@ void MediaRouterMojoImpl::DoOnPresentationSessionDetached( |
media_route_provider_->OnPresentationSessionDetached(route_id); |
} |
+bool MediaRouterMojoImpl::HasLocalRoute() const { |
+ return has_local_route_; |
+} |
+ |
+void MediaRouterMojoImpl::UpdateHasLocalRoute(bool has_local_route) { |
+ if (has_local_route_ != has_local_route) { |
+ if (!has_local_route) |
+ routes_observer_.reset(); |
+ |
+ FOR_EACH_OBSERVER(LocalMediaRoutesObserver, local_routes_observers_, |
+ 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.
|
+ } |
+ |
+ has_local_route_ = has_local_route; |
+} |
+ |
void MediaRouterMojoImpl::DoStartObservingMediaSinks( |
const MediaSource::Id& source_id) { |
DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaSinks: " << source_id; |