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
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_MOJO_IMPL_H_
6 #define CHROME_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_MOJO_IMPL_H_
12 #include "base/containers/hash_tables.h"
13 #include "base/containers/scoped_ptr_hash_map.h"
14 #include "base/macros.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/memory/weak_ptr.h"
18 #include "base/observer_list.h"
19 #include "base/thread_task_runner_handle.h"
20 #include "base/threading/thread_checker.h"
21 #include "chrome/browser/media/router/issue.h"
22 #include "chrome/browser/media/router/media_router.h"
23 #include "chrome/browser/media/router/media_router.mojom.h"
24 #include "components/keyed_service/core/keyed_service.h"
30 namespace extensions
{
31 class EventPageTracker
;
34 namespace media_router
{
36 // MediaRouter implementation that delegates calls to the component extension.
37 // Also handles the suspension and wakeup of the component extension.
38 class MediaRouterMojoImpl
: public MediaRouter
,
39 public interfaces::MediaRouterObserver
,
40 public mojo::ErrorHandler
,
43 ~MediaRouterMojoImpl() override
;
45 // Sets up the MediaRouterMojoImpl instance owned by |context| to handle
46 // MediaRouterObserver requests from the component extension given by
47 // |extension_id|. Creates the MediaRouterMojoImpl instance if it does not
49 // Called by the Mojo module registry.
50 // |extension_id|: The ID of the component extension, used for querying
52 // |context|: The BrowserContext which owns the extension process.
53 // |request|: The Mojo connection request used for binding.
54 static void BindToRequest(
55 const std::string
& extension_id
,
56 content::BrowserContext
* context
,
57 mojo::InterfaceRequest
<interfaces::MediaRouterObserver
> request
);
59 // MediaRouter implementation.
60 // Execution of the requests is delegated to the Do* methods, which can be
61 // enqueued for later use if the extension is temporarily suspended.
62 void CreateRoute(const MediaSource::Id
& source_id
,
63 const MediaSink::Id
& sink_id
,
66 const MediaRouteResponseCallback
& callback
) override
;
67 void JoinRoute(const MediaSource::Id
& source_id
,
68 const std::string
& presentation_id
,
71 const MediaRouteResponseCallback
& callback
) override
;
72 void CloseRoute(const MediaRoute::Id
& route_id
) override
;
73 void SendRouteMessage(const MediaRoute::Id
& route_id
,
74 const std::string
& message
,
75 const SendRouteMessageCallback
& callback
) override
;
76 void ListenForRouteMessages(
77 const std::vector
<MediaRoute::Id
>& route_ids
,
78 const PresentationSessionMessageCallback
& message_cb
) override
;
79 void ClearIssue(const Issue::Id
& issue_id
) override
;
80 void RegisterMediaSinksObserver(MediaSinksObserver
* observer
) override
;
81 void UnregisterMediaSinksObserver(MediaSinksObserver
* observer
) override
;
82 void RegisterMediaRoutesObserver(MediaRoutesObserver
* observer
) override
;
83 void UnregisterMediaRoutesObserver(MediaRoutesObserver
* observer
) override
;
84 void RegisterIssuesObserver(IssuesObserver
* observer
) override
;
85 void UnregisterIssuesObserver(IssuesObserver
* observer
) override
;
87 void set_instance_id_for_test(const std::string
& instance_id
) {
88 instance_id_
= instance_id
;
92 friend class MediaRouterMojoImplFactory
;
93 friend class MediaRouterMojoTest
;
95 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest
,
96 DeferredBindingAndSuspension
);
98 // Standard constructor, used by
99 // MediaRouterMojoImplFactory::GetApiForBrowserContext.
100 explicit MediaRouterMojoImpl(
101 extensions::EventPageTracker
* event_page_tracker
);
103 // Binds |this| to a Mojo interface request, so that clients can acquire a
104 // handle to a MediaRouterMojoImpl instance via the Mojo service connector.
105 // Stores the |extension_id| of the component extension.
106 void BindToMojoRequest(
107 mojo::InterfaceRequest
<interfaces::MediaRouterObserver
> request
,
108 const std::string
& extension_id
);
110 // Enqueues a closure for later execution by ExecutePendingRequests().
111 void EnqueueTask(const base::Closure
& closure
);
113 // Runs a closure if the extension monitored by |extension_monitor_| is
114 // active, or defers it for later execution if the extension is suspended.
115 void RunOrDefer(const base::Closure
& request
);
117 // Dispatches the Mojo requests queued in |pending_requests_|.
118 void ExecutePendingRequests();
120 // These calls invoke methods in the component extension via Mojo.
121 void DoCreateRoute(const MediaSource::Id
& source_id
,
122 const MediaSink::Id
& sink_id
,
123 const std::string
& origin
,
125 const MediaRouteResponseCallback
& callback
);
126 void DoJoinRoute(const MediaSource::Id
& source_id
,
127 const std::string
& presentation_id
,
128 const std::string
& origin
,
130 const MediaRouteResponseCallback
& callback
);
131 void DoCloseRoute(const MediaRoute::Id
& route_id
);
132 void DoSendSessionMessage(const MediaRoute::Id
& route_id
,
133 const std::string
& message
,
134 const SendRouteMessageCallback
& callback
);
135 void DoListenForRouteMessages(
136 const std::vector
<MediaRoute::Id
>& route_ids
,
137 const PresentationSessionMessageCallback
& message_cb
);
138 void DoClearIssue(const Issue::Id
& issue_id
);
139 void DoStartObservingMediaSinks(const MediaSource::Id
& source_id
);
140 void DoStopObservingMediaSinks(const MediaSource::Id
& source_id
);
141 void DoStartObservingMediaRoutes();
142 void DoStopObservingMediaRoutes();
143 void DoStartObservingIssues();
144 void DoStopObservingIssues();
146 // Invoked when the next batch of messages arrives.
147 // |messages|: A list of messages received.
148 // |message_cb|: The callback to invoke to pass on the messages received.
149 void OnRouteMessageReceived(
150 const PresentationSessionMessageCallback
& message_cb
,
151 mojo::Array
<interfaces::RouteMessagePtr
> messages
);
153 // mojo::ErrorHandler implementation.
154 void OnConnectionError() override
;
156 // interfaces::MediaRouterObserver implementation.
157 void ProvideMediaRouter(
158 interfaces::MediaRouterPtr media_router_ptr
,
159 const interfaces::MediaRouterObserver::ProvideMediaRouterCallback
&
161 void OnIssue(interfaces::IssuePtr issue
) override
;
162 void OnSinksReceived(const mojo::String
& media_source
,
163 mojo::Array
<interfaces::MediaSinkPtr
> sinks
) override
;
164 void OnRoutesUpdated(mojo::Array
<interfaces::MediaRoutePtr
> routes
) override
;
166 // Pending requests queued to be executed once component extension
168 std::vector
<base::Closure
> pending_requests_
;
170 base::ScopedPtrHashMap
<MediaSource::Id
,
171 scoped_ptr
<base::ObserverList
<MediaSinksObserver
>>>
174 base::ObserverList
<MediaRoutesObserver
> routes_observers_
;
176 // Binds |this| to listen for updates from the component extension Media
178 scoped_ptr
<mojo::Binding
<interfaces::MediaRouterObserver
>> binding_
;
180 // Mojo proxy object for the component extension Media Router.
181 // Set to null initially, and set to the proxy to the component extension
182 // on |ProvideMediaRouter()|. This is set to null again when the component
183 // extension becomes suspended or if there is a connection error.
184 interfaces::MediaRouterPtr mojo_media_router_
;
186 // Id of the component extension. Used for managing its suspend/wake state
187 // via event_page_tracker_.
188 std::string mojo_media_router_extension_id_
;
190 // Allows the extension to be monitored for suspend, and woken.
191 // This is a reference to a BrowserContext keyed service that outlives this
193 extensions::EventPageTracker
* event_page_tracker_
;
195 // GUID unique to each browser run. Component extension uses this to detect
196 // when its persisted state was written by an older browser instance, and is
198 std::string instance_id_
;
200 base::ThreadChecker thread_checker_
;
202 DISALLOW_COPY_AND_ASSIGN(MediaRouterMojoImpl
);
205 } // namespace media_router
207 #endif // CHROME_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_MOJO_IMPL_H_