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"
26 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
32 namespace extensions
{
33 class EventPageTracker
;
36 namespace media_router
{
38 // MediaRouter implementation that delegates calls to the component extension.
39 // Also handles the suspension and wakeup of the component extension.
40 class MediaRouterMojoImpl
: public MediaRouter
,
41 public interfaces::MediaRouter
{
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::MediaRouter
> 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.
63 const MediaSource::Id
& source_id
,
64 const MediaSink::Id
& sink_id
,
67 const std::vector
<MediaRouteResponseCallback
>& callbacks
) override
;
69 const MediaSource::Id
& source_id
,
70 const std::string
& presentation_id
,
73 const std::vector
<MediaRouteResponseCallback
>& callbacks
) override
;
74 void CloseRoute(const MediaRoute::Id
& route_id
) override
;
75 void SendRouteMessage(const MediaRoute::Id
& route_id
,
76 const std::string
& message
,
77 const SendRouteMessageCallback
& callback
) override
;
78 void SendRouteBinaryMessage(
79 const MediaRoute::Id
& route_id
,
80 scoped_ptr
<std::vector
<uint8
>> data
,
81 const SendRouteMessageCallback
& callback
) override
;
82 void AddIssue(const Issue
& issue
) override
;
83 void ClearIssue(const Issue::Id
& issue_id
) override
;
84 void OnPresentationSessionDetached(const MediaRoute::Id
& route_id
) override
;
86 const std::string
& media_route_provider_extension_id() const {
87 return media_route_provider_extension_id_
;
90 void set_instance_id_for_test(const std::string
& instance_id
) {
91 instance_id_
= instance_id
;
95 friend class MediaRouterFactory
;
96 friend class MediaRouterMojoExtensionTest
;
97 friend class MediaRouterMojoTest
;
99 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoImplTest
,
100 RegisterAndUnregisterMediaSinksObserver
);
101 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoImplTest
,
102 RegisterAndUnregisterMediaRoutesObserver
);
103 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoImplTest
, HandleIssue
);
104 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest
,
105 DeferredBindingAndSuspension
);
107 // Standard constructor, used by
108 // MediaRouterMojoImplFactory::GetApiForBrowserContext.
109 explicit MediaRouterMojoImpl(
110 extensions::EventPageTracker
* event_page_tracker
);
112 // Binds |this| to a Mojo interface request, so that clients can acquire a
113 // handle to a MediaRouterMojoImpl instance via the Mojo service connector.
114 // Stores the |extension_id| of the component extension.
115 void BindToMojoRequest(
116 mojo::InterfaceRequest
<interfaces::MediaRouter
> request
,
117 const std::string
& extension_id
);
119 // Enqueues a closure for later execution by ExecutePendingRequests().
120 void EnqueueTask(const base::Closure
& closure
);
122 // Runs a closure if the extension monitored by |extension_monitor_| is
123 // active, or defers it for later execution if the extension is suspended.
124 void RunOrDefer(const base::Closure
& request
);
126 // Dispatches the Mojo requests queued in |pending_requests_|.
127 void ExecutePendingRequests();
129 // MediaRouter implementation.
130 void RegisterMediaSinksObserver(MediaSinksObserver
* observer
) override
;
131 void UnregisterMediaSinksObserver(MediaSinksObserver
* observer
) override
;
132 void RegisterMediaRoutesObserver(MediaRoutesObserver
* observer
) override
;
133 void UnregisterMediaRoutesObserver(MediaRoutesObserver
* observer
) override
;
134 void RegisterIssuesObserver(IssuesObserver
* observer
) override
;
135 void UnregisterIssuesObserver(IssuesObserver
* observer
) override
;
136 void RegisterPresentationSessionMessagesObserver(
137 PresentationSessionMessagesObserver
* observer
) override
;
138 void UnregisterPresentationSessionMessagesObserver(
139 PresentationSessionMessagesObserver
* observer
) override
;
141 // These calls invoke methods in the component extension via Mojo.
142 void DoCreateRoute(const MediaSource::Id
& source_id
,
143 const MediaSink::Id
& sink_id
,
144 const std::string
& origin
,
146 const std::vector
<MediaRouteResponseCallback
>& callbacks
);
147 void DoJoinRoute(const MediaSource::Id
& source_id
,
148 const std::string
& presentation_id
,
149 const std::string
& origin
,
151 const std::vector
<MediaRouteResponseCallback
>& callbacks
);
152 void DoCloseRoute(const MediaRoute::Id
& route_id
);
153 void DoSendSessionMessage(const MediaRoute::Id
& route_id
,
154 const std::string
& message
,
155 const SendRouteMessageCallback
& callback
);
156 void DoSendSessionBinaryMessage(const MediaRoute::Id
& route_id
,
157 scoped_ptr
<std::vector
<uint8
>> data
,
158 const SendRouteMessageCallback
& callback
);
159 void DoListenForRouteMessages(const MediaRoute::Id
& route_id
);
160 void DoStopListeningForRouteMessages(const MediaRoute::Id
& route_id
);
161 void DoOnPresentationSessionDetached(const MediaRoute::Id
& route_id
);
162 void DoStartObservingMediaSinks(const MediaSource::Id
& source_id
);
163 void DoStopObservingMediaSinks(const MediaSource::Id
& source_id
);
164 void DoStartObservingMediaRoutes();
165 void DoStopObservingMediaRoutes();
167 // Invoked when the next batch of messages arrives.
168 // |route_id|: ID of route of the messages.
169 // |messages|: A list of messages received.
170 // |error|: true if an error occurred.
171 void OnRouteMessagesReceived(
172 const MediaRoute::Id
& route_id
,
173 mojo::Array
<interfaces::RouteMessagePtr
> messages
,
176 // Error handler callback for |binding_| and |media_route_provider_|.
177 void OnConnectionError();
179 // interfaces::MediaRouter implementation.
180 void RegisterMediaRouteProvider(
181 interfaces::MediaRouteProviderPtr media_route_provider_ptr
,
182 const interfaces::MediaRouter::RegisterMediaRouteProviderCallback
&
184 void OnIssue(interfaces::IssuePtr issue
) override
;
185 void OnSinksReceived(const mojo::String
& media_source
,
186 mojo::Array
<interfaces::MediaSinkPtr
> sinks
) override
;
187 void OnRoutesUpdated(mojo::Array
<interfaces::MediaRoutePtr
> routes
) override
;
189 // Pending requests queued to be executed once component extension
191 std::vector
<base::Closure
> pending_requests_
;
193 base::ScopedPtrHashMap
<MediaSource::Id
,
194 scoped_ptr
<base::ObserverList
<MediaSinksObserver
>>>
197 base::ObserverList
<MediaRoutesObserver
> routes_observers_
;
199 using PresentationSessionMessagesObserverList
=
200 base::ObserverList
<PresentationSessionMessagesObserver
>;
201 base::ScopedPtrHashMap
<MediaRoute::Id
,
202 scoped_ptr
<PresentationSessionMessagesObserverList
>>
204 // IDs of MediaRoutes being listened for messages. Note that this is
205 // different from |message_observers_| because we might be waiting for
206 // |OnRouteMessagesReceived()| to be invoked after all observers for that
207 // route have been removed.
208 std::set
<MediaRoute::Id
> route_ids_listening_for_messages_
;
210 IssueManager issue_manager_
;
212 // Binds |this| to a Mojo connection stub for interfaces::MediaRouter.
213 scoped_ptr
<mojo::Binding
<interfaces::MediaRouter
>> binding_
;
215 // Mojo proxy object for the Media Route Provider Manager.
216 // Set to null initially, and later set to the Provider Manager proxy object
217 // passed in via |RegisterMediaRouteProvider()|.
218 // This is set to null again when the component extension is suspended
219 // if or a Mojo channel error occured.
220 interfaces::MediaRouteProviderPtr media_route_provider_
;
222 // Id of the component extension. Used for managing its suspend/wake state
223 // via event_page_tracker_.
224 std::string media_route_provider_extension_id_
;
226 // Allows the extension to be monitored for suspend, and woken.
227 // This is a reference to a BrowserContext keyed service that outlives this
229 extensions::EventPageTracker
* event_page_tracker_
;
231 // GUID unique to each browser run. Component extension uses this to detect
232 // when its persisted state was written by an older browser instance, and is
234 std::string instance_id_
;
236 base::ThreadChecker thread_checker_
;
238 DISALLOW_COPY_AND_ASSIGN(MediaRouterMojoImpl
);
241 } // namespace media_router
243 #endif // CHROME_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_MOJO_IMPL_H_