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

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

Powered by Google App Engine
This is Rietveld 408576698