Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: chrome/browser/media/router/media_router_mojo_impl.h

Issue 1826403002: [Media Router] Moves mojo-specific code into mojo/ folder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #ifndef CHROME_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_MOJO_IMPL_H_
6 #define CHROME_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_MOJO_IMPL_H_
7
8 #include <stdint.h>
9
10 #include <deque>
11 #include <map>
12 #include <set>
13 #include <string>
14 #include <vector>
15
16 #include "base/containers/hash_tables.h"
17 #include "base/containers/scoped_ptr_hash_map.h"
18 #include "base/gtest_prod_util.h"
19 #include "base/macros.h"
20 #include "base/memory/scoped_ptr.h"
21 #include "base/memory/weak_ptr.h"
22 #include "base/observer_list.h"
23 #include "base/thread_task_runner_handle.h"
24 #include "chrome/browser/media/router/issue.h"
25 #include "chrome/browser/media/router/issue_manager.h"
26 #include "chrome/browser/media/router/media_router.mojom.h"
27 #include "chrome/browser/media/router/media_router_base.h"
28 #include "chrome/browser/media/router/media_routes_observer.h"
29 #include "mojo/public/cpp/bindings/binding.h"
30
31 namespace content {
32 class BrowserContext;
33 }
34
35 namespace extensions {
36 class EventPageTracker;
37 class Extension;
38 }
39
40 namespace media_router {
41
42 enum class MediaRouteProviderWakeReason;
43
44 // MediaRouter implementation that delegates calls to the component extension.
45 // Also handles the suspension and wakeup of the component extension.
46 class MediaRouterMojoImpl : public MediaRouterBase,
47 public interfaces::MediaRouter {
48 public:
49 ~MediaRouterMojoImpl() override;
50
51 // Sets up the MediaRouterMojoImpl instance owned by |context| to handle
52 // MediaRouterObserver requests from the component extension given by
53 // |extension|. Creates the MediaRouterMojoImpl instance if it does not
54 // exist.
55 // Called by the Mojo module registry.
56 // |extension|: The component extension, used for querying
57 // suspension state.
58 // |context|: The BrowserContext which owns the extension process.
59 // |request|: The Mojo connection request used for binding.
60 static void BindToRequest(
61 const extensions::Extension* extension,
62 content::BrowserContext* context,
63 mojo::InterfaceRequest<interfaces::MediaRouter> request);
64
65 // MediaRouter implementation.
66 // Execution of the requests is delegated to the Do* methods, which can be
67 // enqueued for later use if the extension is temporarily suspended.
68 void CreateRoute(const MediaSource::Id& source_id,
69 const MediaSink::Id& sink_id,
70 const GURL& origin,
71 content::WebContents* web_contents,
72 const std::vector<MediaRouteResponseCallback>& callbacks,
73 base::TimeDelta timeout,
74 bool off_the_record) override;
75 void JoinRoute(const MediaSource::Id& source_id,
76 const std::string& presentation_id,
77 const GURL& origin,
78 content::WebContents* web_contents,
79 const std::vector<MediaRouteResponseCallback>& callbacks,
80 base::TimeDelta timeout,
81 bool off_the_record) override;
82 void ConnectRouteByRouteId(
83 const MediaSource::Id& source,
84 const MediaRoute::Id& route_id,
85 const GURL& origin,
86 content::WebContents* web_contents,
87 const std::vector<MediaRouteResponseCallback>& callbacks,
88 base::TimeDelta timeout,
89 bool off_the_record) override;
90 void TerminateRoute(const MediaRoute::Id& route_id) override;
91 void DetachRoute(const MediaRoute::Id& route_id) override;
92 void SendRouteMessage(const MediaRoute::Id& route_id,
93 const std::string& message,
94 const SendRouteMessageCallback& callback) override;
95 void SendRouteBinaryMessage(
96 const MediaRoute::Id& route_id,
97 scoped_ptr<std::vector<uint8_t>> data,
98 const SendRouteMessageCallback& callback) override;
99 void AddIssue(const Issue& issue) override;
100 void ClearIssue(const Issue::Id& issue_id) override;
101
102 const std::string& media_route_provider_extension_id() const {
103 return media_route_provider_extension_id_;
104 }
105
106 void set_instance_id_for_test(const std::string& instance_id) {
107 instance_id_ = instance_id;
108 }
109
110 private:
111 friend class MediaRouterFactory;
112 friend class MediaRouterMojoExtensionTest;
113 friend class MediaRouterMojoTest;
114 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoImplTest,
115 RegisterAndUnregisterMediaSinksObserver);
116 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoImplTest,
117 RegisterMediaSinksObserverWithAvailabilityChange);
118 FRIEND_TEST_ALL_PREFIXES(
119 MediaRouterMojoImplTest,
120 RegisterAndUnregisterMediaSinksObserverWithAvailabilityChange);
121 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoImplTest,
122 RegisterAndUnregisterMediaRoutesObserver);
123 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoImplTest, HandleIssue);
124 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest,
125 DeferredBindingAndSuspension);
126 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest,
127 DrainPendingRequestQueue);
128 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest,
129 DropOldestPendingRequest);
130 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest,
131 AttemptedWakeupTooManyTimes);
132 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest,
133 WakeupFailedDrainsQueue);
134
135 // The max number of pending requests allowed. When number of pending requests
136 // exceeds this number, the oldest request will be dropped.
137 static const int kMaxPendingRequests = 30;
138
139 // Max consecutive attempts to wake up the component extension before
140 // giving up and draining the pending request queue.
141 static const int kMaxWakeupAttemptCount = 3;
142
143 // Represents a query to the MRPM for media sinks and holds observers for the
144 // query.
145 struct MediaSinksQuery {
146 public:
147 MediaSinksQuery();
148 ~MediaSinksQuery();
149
150 // True if the query has been sent to the MRPM.
151 bool is_active = false;
152
153 // True if cached result is available.
154 bool has_cached_result = false;
155
156 // Cached list of sinks for the query, if |has_cached_result| is true.
157 // Empty otherwise.
158 std::vector<MediaSink> cached_sink_list;
159 std::vector<GURL> origins;
160 base::ObserverList<MediaSinksObserver> observers;
161
162 private:
163 DISALLOW_COPY_AND_ASSIGN(MediaSinksQuery);
164 };
165
166 struct MediaRoutesQuery {
167 public:
168 MediaRoutesQuery();
169 ~MediaRoutesQuery();
170
171 // True if the query has been sent to the MRPM. False otherwise.
172 bool is_active = false;
173 base::ObserverList<MediaRoutesObserver> observers;
174
175 private:
176 DISALLOW_COPY_AND_ASSIGN(MediaRoutesQuery);
177 };
178
179 // Standard constructor, used by
180 // MediaRouterMojoImplFactory::GetApiForBrowserContext.
181 explicit MediaRouterMojoImpl(
182 extensions::EventPageTracker* event_page_tracker);
183
184 // Binds |this| to a Mojo interface request, so that clients can acquire a
185 // handle to a MediaRouterMojoImpl instance via the Mojo service connector.
186 // Stores the ID of |extension| in |media_route_provider_extension_id_|.
187 void BindToMojoRequest(
188 mojo::InterfaceRequest<interfaces::MediaRouter> request,
189 const extensions::Extension& extension);
190
191 // Enqueues a closure for later execution by ExecutePendingRequests().
192 void EnqueueTask(const base::Closure& closure);
193
194 // Runs a closure if the extension monitored by |extension_monitor_| is
195 // active, or defers it for later execution if the extension is suspended.
196 void RunOrDefer(const base::Closure& request);
197
198 // Dispatches the Mojo requests queued in |pending_requests_|.
199 void ExecutePendingRequests();
200
201 // Drops all pending requests. Called when we have a connection error to
202 // component extension and further reattempts are unlikely to help.
203 void DrainPendingRequests();
204
205 // MediaRouter implementation.
206 bool RegisterMediaSinksObserver(MediaSinksObserver* observer) override;
207 void UnregisterMediaSinksObserver(MediaSinksObserver* observer) override;
208 void RegisterMediaRoutesObserver(MediaRoutesObserver* observer) override;
209 void UnregisterMediaRoutesObserver(MediaRoutesObserver* observer) override;
210 void RegisterIssuesObserver(IssuesObserver* observer) override;
211 void UnregisterIssuesObserver(IssuesObserver* observer) override;
212 void RegisterPresentationSessionMessagesObserver(
213 PresentationSessionMessagesObserver* observer) override;
214 void UnregisterPresentationSessionMessagesObserver(
215 PresentationSessionMessagesObserver* observer) override;
216
217 // These calls invoke methods in the component extension via Mojo.
218 void DoCreateRoute(const MediaSource::Id& source_id,
219 const MediaSink::Id& sink_id,
220 const std::string& origin,
221 int tab_id,
222 const std::vector<MediaRouteResponseCallback>& callbacks,
223 base::TimeDelta timeout,
224 bool off_the_record);
225 void DoJoinRoute(const MediaSource::Id& source_id,
226 const std::string& presentation_id,
227 const std::string& origin,
228 int tab_id,
229 const std::vector<MediaRouteResponseCallback>& callbacks,
230 base::TimeDelta timeout,
231 bool off_the_record);
232 void DoConnectRouteByRouteId(
233 const MediaSource::Id& source_id,
234 const MediaRoute::Id& route_id,
235 const std::string& origin,
236 int tab_id,
237 const std::vector<MediaRouteResponseCallback>& callbacks,
238 base::TimeDelta timeout,
239 bool off_the_record);
240 void DoTerminateRoute(const MediaRoute::Id& route_id);
241 void DoDetachRoute(const MediaRoute::Id& route_id);
242 void DoSendSessionMessage(const MediaRoute::Id& route_id,
243 const std::string& message,
244 const SendRouteMessageCallback& callback);
245 void DoSendSessionBinaryMessage(const MediaRoute::Id& route_id,
246 scoped_ptr<std::vector<uint8_t>> data,
247 const SendRouteMessageCallback& callback);
248 void DoListenForRouteMessages(const MediaRoute::Id& route_id);
249 void DoStopListeningForRouteMessages(const MediaRoute::Id& route_id);
250 void DoStartObservingMediaSinks(const MediaSource::Id& source_id);
251 void DoStopObservingMediaSinks(const MediaSource::Id& source_id);
252 void DoStartObservingMediaRoutes(const MediaSource::Id& source_id);
253 void DoStopObservingMediaRoutes(const MediaSource::Id& source_id);
254
255 // Invoked when the next batch of messages arrives.
256 // |route_id|: ID of route of the messages.
257 // |messages|: A list of messages received.
258 // |error|: true if an error occurred.
259 void OnRouteMessagesReceived(
260 const MediaRoute::Id& route_id,
261 mojo::Array<interfaces::RouteMessagePtr> messages,
262 bool error);
263
264 // Error handler callback for |binding_| and |media_route_provider_|.
265 void OnConnectionError();
266
267 // interfaces::MediaRouter implementation.
268 void RegisterMediaRouteProvider(
269 interfaces::MediaRouteProviderPtr media_route_provider_ptr,
270 const interfaces::MediaRouter::RegisterMediaRouteProviderCallback&
271 callback) override;
272 void OnIssue(interfaces::IssuePtr issue) override;
273 void OnSinksReceived(const mojo::String& media_source,
274 mojo::Array<interfaces::MediaSinkPtr> sinks,
275 mojo::Array<mojo::String> origins) override;
276 void OnRoutesUpdated(mojo::Array<interfaces::MediaRoutePtr> routes,
277 const mojo::String& media_source,
278 mojo::Array<mojo::String> joinable_route_ids) override;
279 void OnSinkAvailabilityUpdated(
280 interfaces::MediaRouter::SinkAvailability availability) override;
281 void OnPresentationConnectionStateChanged(
282 const mojo::String& route_id,
283 interfaces::MediaRouter::PresentationConnectionState state) override;
284 void OnPresentationConnectionClosed(
285 const mojo::String& route_id,
286 interfaces::MediaRouter::PresentationConnectionCloseReason reason,
287 const mojo::String& message) override;
288
289 // Converts the callback result of calling Mojo CreateRoute()/JoinRoute()
290 // into a local callback.
291 void RouteResponseReceived(
292 const std::string& presentation_id,
293 bool off_the_record,
294 const std::vector<MediaRouteResponseCallback>& callbacks,
295 interfaces::MediaRoutePtr media_route,
296 const mojo::String& error_text,
297 interfaces::RouteRequestResultCode result_code);
298
299 // Callback invoked by |event_page_tracker_| after an attempt to wake the
300 // component extension. If |success| is false, the pending request queue is
301 // drained.
302 void EventPageWakeComplete(bool success);
303
304 // Removes all requests from the pending requests queue. Called when there is
305 // a permanent error connecting to component extension.
306 void DrainRequestQueue();
307
308 // Calls to |event_page_tracker_| to wake the component extension.
309 // |media_route_provider_extension_id_| must not be empty and the extension
310 // should be currently suspended.
311 // If there have already been too many wakeup attempts, give up and drain
312 // the pending request queue.
313 void AttemptWakeEventPage();
314
315 // Sets the reason why we are attempting to wake the extension. Since
316 // multiple tasks may be enqueued for execution each time the extension runs,
317 // we record the first such reason.
318 void SetWakeReason(MediaRouteProviderWakeReason reason);
319
320 // Clears the wake reason after the extension has been awoken.
321 void ClearWakeReason();
322
323 // Pending requests queued to be executed once component extension
324 // becomes ready.
325 std::deque<base::Closure> pending_requests_;
326
327 base::ScopedPtrHashMap<MediaSource::Id, scoped_ptr<MediaSinksQuery>>
328 sinks_queries_;
329
330 base::ScopedPtrHashMap<MediaSource::Id, scoped_ptr<MediaRoutesQuery>>
331 routes_queries_;
332
333 using PresentationSessionMessagesObserverList =
334 base::ObserverList<PresentationSessionMessagesObserver>;
335 base::ScopedPtrHashMap<MediaRoute::Id,
336 scoped_ptr<PresentationSessionMessagesObserverList>>
337 messages_observers_;
338
339 // IDs of MediaRoutes being listened for messages. Note that this is
340 // different from |message_observers_| because we might be waiting for
341 // |OnRouteMessagesReceived()| to be invoked after all observers for that
342 // route have been removed.
343 std::set<MediaRoute::Id> route_ids_listening_for_messages_;
344
345 IssueManager issue_manager_;
346
347 // Binds |this| to a Mojo connection stub for interfaces::MediaRouter.
348 scoped_ptr<mojo::Binding<interfaces::MediaRouter>> binding_;
349
350 // Mojo proxy object for the Media Route Provider Manager.
351 // Set to null initially, and later set to the Provider Manager proxy object
352 // passed in via |RegisterMediaRouteProvider()|.
353 // This is set to null again when the component extension is suspended
354 // if or a Mojo channel error occured.
355 interfaces::MediaRouteProviderPtr media_route_provider_;
356
357 // Id of the component extension. Used for managing its suspend/wake state
358 // via event_page_tracker_.
359 std::string media_route_provider_extension_id_;
360
361 // Allows the extension to be monitored for suspend, and woken.
362 // This is a reference to a BrowserContext keyed service that outlives this
363 // instance.
364 extensions::EventPageTracker* event_page_tracker_;
365
366 // GUID unique to each browser run. Component extension uses this to detect
367 // when its persisted state was written by an older browser instance, and is
368 // therefore stale.
369 std::string instance_id_;
370
371 // The last reported sink availability from the media route provider manager.
372 interfaces::MediaRouter::SinkAvailability availability_;
373
374 int wakeup_attempt_count_ = 0;
375
376 // Records the current reason the extension is being woken up. Is set to
377 // MediaRouteProviderWakeReason::TOTAL_COUNT if there is no pending reason.
378 MediaRouteProviderWakeReason current_wake_reason_;
379
380 // A flag to ensure that we record the provider version once, during the
381 // initial event page wakeup attempt.
382 bool provider_version_was_recorded_ = false;
383
384 base::WeakPtrFactory<MediaRouterMojoImpl> weak_factory_;
385
386 DISALLOW_COPY_AND_ASSIGN(MediaRouterMojoImpl);
387 };
388
389 } // namespace media_router
390
391 #endif // CHROME_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_MOJO_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698