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/message_loop/message_loop_proxy.h"
19 #include "base/observer_list.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
,
64 const MediaRouteResponseCallback
& callback
) override
;
65 void CloseRoute(const MediaRoute::Id
& route_id
) override
;
66 void SendRouteMessage(const MediaRoute::Id
& route_id
,
67 const std::string
& message
,
68 const SendRouteMessageCallback
& callback
) override
;
69 void ClearIssue(const Issue::Id
& issue_id
) override
;
70 void RegisterMediaSinksObserver(MediaSinksObserver
* observer
) override
;
71 void UnregisterMediaSinksObserver(MediaSinksObserver
* observer
) override
;
72 void RegisterMediaRoutesObserver(MediaRoutesObserver
* observer
) override
;
73 void UnregisterMediaRoutesObserver(MediaRoutesObserver
* observer
) override
;
74 void AddIssuesObserver(IssuesObserver
* observer
) override
;
75 void RemoveIssuesObserver(IssuesObserver
* observer
) override
;
77 void set_instance_id_for_test(const std::string
& instance_id
) {
78 instance_id_
= instance_id
;
82 friend class MediaRouterMojoImplFactory
;
83 friend class MediaRouterMojoTest
;
85 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest
,
86 DeferredBindingAndSuspension
);
88 // Standard constructor, used by
89 // MediaRouterMojoImplFactory::GetApiForBrowserContext.
90 explicit MediaRouterMojoImpl(
91 extensions::EventPageTracker
* event_page_tracker
);
93 // Binds |this| to a Mojo interface request, so that clients can acquire a
94 // handle to a MediaRouterMojoImpl instance via the Mojo service connector.
95 // Stores the |extension_id| of the component extension.
96 void BindToMojoRequest(
97 mojo::InterfaceRequest
<interfaces::MediaRouterObserver
> request
,
98 const std::string
& extension_id
);
100 // Enqueues a closure for later execution by ExecutePendingRequests().
101 void EnqueueTask(const base::Closure
& closure
);
103 // Runs a closure if the extension monitored by |extension_monitor_| is
104 // active, or defers it for later execution if the extension is suspended.
105 void RunOrDefer(const base::Closure
& request
);
107 // Dispatches the Mojo requests queued in |pending_requests_|.
108 void ExecutePendingRequests();
110 // These calls invoke methods in the component extension via Mojo.
111 void DoCreateRoute(const MediaSource::Id
& source_id
,
112 const MediaSink::Id
& sink_id
,
113 const MediaRouteResponseCallback
& callback
);
114 void DoCloseRoute(const MediaRoute::Id
& route_id
);
115 void DoSendSessionMessage(const MediaRoute::Id
& route_id
,
116 const std::string
& message
,
117 const SendRouteMessageCallback
& callback
);
118 void DoClearIssue(const Issue::Id
& issue_id
);
119 void DoStartObservingMediaSinks(const std::string
& source_id
);
120 void DoStopObservingMediaSinks(const std::string
& source_id
);
121 void DoStartObservingMediaRoutes();
122 void DoStopObservingMediaRoutes();
123 void DoStartObservingIssues();
124 void DoStopObservingIssues();
126 // mojo::ErrorHandler implementation.
127 void OnConnectionError() override
;
129 // interfaces::MediaRouterObserver implementation.
130 void ProvideMediaRouter(
131 interfaces::MediaRouterPtr media_router_ptr
,
132 const interfaces::MediaRouterObserver::ProvideMediaRouterCallback
&
134 void OnMessage(const mojo::String
& route_id
,
135 const mojo::String
& message
) override
;
136 void OnIssue(interfaces::IssuePtr issue
) override
;
137 void OnSinksReceived(const mojo::String
& media_source
,
138 mojo::Array
<interfaces::MediaSinkPtr
> sinks
) override
;
139 void OnRoutesUpdated(mojo::Array
<interfaces::MediaRoutePtr
> routes
) override
;
141 // Pending requests queued to be executed once component extension
143 std::vector
<base::Closure
> pending_requests_
;
145 base::ScopedPtrHashMap
<MediaSource::Id
,
146 scoped_ptr
<base::ObserverList
<MediaSinksObserver
>>>
149 base::ObserverList
<MediaRoutesObserver
> routes_observers_
;
151 // Binds |this| to listen for updates from the component extension Media
153 scoped_ptr
<mojo::Binding
<interfaces::MediaRouterObserver
>> binding_
;
155 // Mojo proxy object for the component extension Media Router.
156 // Set to null initially, and set to the proxy to the component extension
157 // on |ProvideMediaRouter()|. This is set to null again when the component
158 // extension becomes suspended or if there is a connection error.
159 interfaces::MediaRouterPtr mojo_media_router_
;
161 // Id of the component extension. Used for managing its suspend/wake state
162 // via event_page_tracker_.
163 std::string mojo_media_router_extension_id_
;
165 // Allows the extension to be monitored for suspend, and woken.
166 // This is a reference to a BrowserContext keyed service that outlives this
168 extensions::EventPageTracker
* event_page_tracker_
;
170 // GUID unique to each browser run. Component extension uses this to detect
171 // when its persisted state was written by an older browser instance, and is
173 std::string instance_id_
;
175 base::ThreadChecker thread_checker_
;
177 DISALLOW_COPY_AND_ASSIGN(MediaRouterMojoImpl
);
180 } // namespace media_router
182 #endif // CHROME_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_MOJO_IMPL_H_