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_
13 #include "base/containers/hash_tables.h"
14 #include "base/containers/scoped_ptr_hash_map.h"
15 #include "base/macros.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/memory/weak_ptr.h"
19 #include "base/observer_list.h"
20 #include "base/thread_task_runner_handle.h"
21 #include "base/threading/thread_checker.h"
22 #include "chrome/browser/media/router/issue.h"
23 #include "chrome/browser/media/router/issue_manager.h"
24 #include "chrome/browser/media/router/media_router.h"
25 #include "chrome/browser/media/router/media_router.mojom.h"
31 namespace extensions
{
32 class EventPageTracker
;
35 namespace media_router
{
37 // MediaRouter implementation that delegates calls to the component extension.
38 // Also handles the suspension and wakeup of the component extension.
39 class MediaRouterMojoImpl
: public MediaRouter
,
40 public interfaces::MediaRouter
{
42 ~MediaRouterMojoImpl() override
;
44 // Sets up the MediaRouterMojoImpl instance owned by |context| to handle
45 // MediaRouterObserver requests from the component extension given by
46 // |extension_id|. Creates the MediaRouterMojoImpl instance if it does not
48 // Called by the Mojo module registry.
49 // |extension_id|: The ID of the component extension, used for querying
51 // |context|: The BrowserContext which owns the extension process.
52 // |request|: The Mojo connection request used for binding.
53 static void BindToRequest(
54 const std::string
& extension_id
,
55 content::BrowserContext
* context
,
56 mojo::InterfaceRequest
<interfaces::MediaRouter
> request
);
58 // MediaRouter implementation.
59 // Execution of the requests is delegated to the Do* methods, which can be
60 // enqueued for later use if the extension is temporarily suspended.
62 const MediaSource::Id
& source_id
,
63 const MediaSink::Id
& sink_id
,
66 const std::vector
<MediaRouteResponseCallback
>& callbacks
) override
;
68 const MediaSource::Id
& source_id
,
69 const std::string
& presentation_id
,
72 const std::vector
<MediaRouteResponseCallback
>& callbacks
) override
;
73 void CloseRoute(const MediaRoute::Id
& route_id
) override
;
74 void SendRouteMessage(const MediaRoute::Id
& route_id
,
75 const std::string
& message
,
76 const SendRouteMessageCallback
& callback
) override
;
77 void SendRouteBinaryMessage(
78 const MediaRoute::Id
& route_id
,
79 scoped_ptr
<std::vector
<uint8
>> data
,
80 const SendRouteMessageCallback
& callback
) override
;
81 void ClearIssue(const Issue::Id
& issue_id
) override
;
82 void OnPresentationSessionDetached(const MediaRoute::Id
& route_id
) override
;
84 const std::string
& media_route_provider_extension_id() const {
85 return media_route_provider_extension_id_
;
88 void set_instance_id_for_test(const std::string
& instance_id
) {
89 instance_id_
= instance_id
;
93 friend class MediaRouterFactory
;
94 friend class MediaRouterMojoTest
;
96 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoImplTest
,
97 RegisterAndUnregisterMediaSinksObserver
);
98 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoImplTest
,
99 RegisterAndUnregisterMediaRoutesObserver
);
100 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoImplTest
, HandleIssue
);
101 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest
,
102 DeferredBindingAndSuspension
);
104 // Standard constructor, used by
105 // MediaRouterMojoImplFactory::GetApiForBrowserContext.
106 explicit MediaRouterMojoImpl(
107 extensions::EventPageTracker
* event_page_tracker
);
109 // Binds |this| to a Mojo interface request, so that clients can acquire a
110 // handle to a MediaRouterMojoImpl instance via the Mojo service connector.
111 // Stores the |extension_id| of the component extension.
112 void BindToMojoRequest(
113 mojo::InterfaceRequest
<interfaces::MediaRouter
> request
,
114 const std::string
& extension_id
);
116 // Enqueues a closure for later execution by ExecutePendingRequests().
117 void EnqueueTask(const base::Closure
& closure
);
119 // Runs a closure if the extension monitored by |extension_monitor_| is
120 // active, or defers it for later execution if the extension is suspended.
121 void RunOrDefer(const base::Closure
& request
);
123 // Dispatches the Mojo requests queued in |pending_requests_|.
124 void ExecutePendingRequests();
126 // MediaRouter implementation.
127 void RegisterMediaSinksObserver(MediaSinksObserver
* observer
) override
;
128 void UnregisterMediaSinksObserver(MediaSinksObserver
* observer
) override
;
129 void RegisterMediaRoutesObserver(MediaRoutesObserver
* observer
) override
;
130 void UnregisterMediaRoutesObserver(MediaRoutesObserver
* observer
) override
;
131 void RegisterIssuesObserver(IssuesObserver
* observer
) override
;
132 void UnregisterIssuesObserver(IssuesObserver
* observer
) override
;
133 void RegisterPresentationSessionMessagesObserver(
134 PresentationSessionMessagesObserver
* observer
) override
;
135 void UnregisterPresentationSessionMessagesObserver(
136 PresentationSessionMessagesObserver
* observer
) override
;
138 // These calls invoke methods in the component extension via Mojo.
139 void DoCreateRoute(const MediaSource::Id
& source_id
,
140 const MediaSink::Id
& sink_id
,
141 const std::string
& origin
,
143 const std::vector
<MediaRouteResponseCallback
>& callbacks
);
144 void DoJoinRoute(const MediaSource::Id
& source_id
,
145 const std::string
& presentation_id
,
146 const std::string
& origin
,
148 const std::vector
<MediaRouteResponseCallback
>& callbacks
);
149 void DoCloseRoute(const MediaRoute::Id
& route_id
);
150 void DoSendSessionMessage(const MediaRoute::Id
& route_id
,
151 const std::string
& message
,
152 const SendRouteMessageCallback
& callback
);
153 void DoSendSessionBinaryMessage(const MediaRoute::Id
& route_id
,
154 scoped_ptr
<std::vector
<uint8
>> data
,
155 const SendRouteMessageCallback
& callback
);
156 void DoListenForRouteMessages(const MediaRoute::Id
& route_id
);
157 void DoStopListeningForRouteMessages(const MediaRoute::Id
& route_id
);
158 void DoClearIssue(const Issue::Id
& issue_id
);
159 void DoOnPresentationSessionDetached(const MediaRoute::Id
& route_id
);
160 void DoStartObservingMediaSinks(const MediaSource::Id
& source_id
);
161 void DoStopObservingMediaSinks(const MediaSource::Id
& source_id
);
162 void DoStartObservingMediaRoutes();
163 void DoStopObservingMediaRoutes();
165 // Invoked when the next batch of messages arrives.
166 // |route_id|: ID of route of the messages.
167 // |messages|: A list of messages received.
168 // |error|: true if an error occurred.
169 void OnRouteMessagesReceived(
170 const MediaRoute::Id
& route_id
,
171 mojo::Array
<interfaces::RouteMessagePtr
> messages
,
174 // Error handler callback for |binding_| and |media_route_provider_|.
175 void OnConnectionError();
177 // interfaces::MediaRouter implementation.
178 void RegisterMediaRouteProvider(
179 interfaces::MediaRouteProviderPtr media_route_provider_ptr
,
180 const interfaces::MediaRouter::RegisterMediaRouteProviderCallback
&
182 void OnIssue(interfaces::IssuePtr issue
) override
;
183 void OnSinksReceived(const mojo::String
& media_source
,
184 mojo::Array
<interfaces::MediaSinkPtr
> sinks
) override
;
185 void OnRoutesUpdated(mojo::Array
<interfaces::MediaRoutePtr
> routes
) override
;
187 // Pending requests queued to be executed once component extension
189 std::vector
<base::Closure
> pending_requests_
;
191 base::ScopedPtrHashMap
<MediaSource::Id
,
192 scoped_ptr
<base::ObserverList
<MediaSinksObserver
>>>
195 base::ObserverList
<MediaRoutesObserver
> routes_observers_
;
197 using PresentationSessionMessagesObserverList
=
198 base::ObserverList
<PresentationSessionMessagesObserver
>;
199 base::ScopedPtrHashMap
<MediaRoute::Id
,
200 scoped_ptr
<PresentationSessionMessagesObserverList
>>
202 // IDs of MediaRoutes being listened for messages. Note that this is
203 // different from |message_observers_| because we might be waiting for
204 // |OnRouteMessagesReceived()| to be invoked after all observers for that
205 // route have been removed.
206 std::set
<MediaRoute::Id
> route_ids_listening_for_messages_
;
208 IssueManager issue_manager_
;
210 // Binds |this| to a Mojo connection stub for interfaces::MediaRouter.
211 scoped_ptr
<mojo::Binding
<interfaces::MediaRouter
>> binding_
;
213 // Mojo proxy object for the Media Route Provider Manager.
214 // Set to null initially, and later set to the Provider Manager proxy object
215 // passed in via |RegisterMediaRouteProvider()|.
216 // This is set to null again when the component extension is suspended
217 // if or a Mojo channel error occured.
218 interfaces::MediaRouteProviderPtr media_route_provider_
;
220 // Id of the component extension. Used for managing its suspend/wake state
221 // via event_page_tracker_.
222 std::string media_route_provider_extension_id_
;
224 // Allows the extension to be monitored for suspend, and woken.
225 // This is a reference to a BrowserContext keyed service that outlives this
227 extensions::EventPageTracker
* event_page_tracker_
;
229 // GUID unique to each browser run. Component extension uses this to detect
230 // when its persisted state was written by an older browser instance, and is
232 std::string instance_id_
;
234 base::ThreadChecker thread_checker_
;
236 DISALLOW_COPY_AND_ASSIGN(MediaRouterMojoImpl
);
239 } // namespace media_router
241 #endif // CHROME_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_MOJO_IMPL_H_