Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CHROME_BROWSER_MEDIA_ROUTER_MOJO_MEDIA_ROUTER_MOJO_IMPL_H_ | 5 #ifndef CHROME_BROWSER_MEDIA_ROUTER_MOJO_MEDIA_ROUTER_MOJO_IMPL_H_ |
| 6 #define CHROME_BROWSER_MEDIA_ROUTER_MOJO_MEDIA_ROUTER_MOJO_IMPL_H_ | 6 #define CHROME_BROWSER_MEDIA_ROUTER_MOJO_MEDIA_ROUTER_MOJO_IMPL_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <deque> | 10 #include <deque> |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "chrome/common/media_router/route_request_result.h" | 31 #include "chrome/common/media_router/route_request_result.h" |
| 32 #include "content/public/browser/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
| 33 #include "mojo/public/cpp/bindings/binding.h" | 33 #include "mojo/public/cpp/bindings/binding.h" |
| 34 #include "services/service_manager/public/cpp/bind_source_info.h" | 34 #include "services/service_manager/public/cpp/bind_source_info.h" |
| 35 | 35 |
| 36 namespace content { | 36 namespace content { |
| 37 class BrowserContext; | 37 class BrowserContext; |
| 38 } | 38 } |
| 39 | 39 |
| 40 namespace extensions { | 40 namespace extensions { |
| 41 class EventPageTracker; | |
| 42 class Extension; | 41 class Extension; |
| 43 } | 42 } |
| 44 | 43 |
| 45 namespace media_router { | 44 namespace media_router { |
| 46 | 45 |
| 47 enum class MediaRouteProviderWakeReason; | 46 enum class MediaRouteProviderWakeReason; |
| 48 class DialMediaSinkServiceProxy; | 47 class DialMediaSinkServiceProxy; |
| 48 class EventPageRequestManager; | |
| 49 | 49 |
| 50 // MediaRouter implementation that delegates calls to the component extension. | 50 // MediaRouter implementation that delegates calls to the component extension. |
| 51 // Also handles the suspension and wakeup of the component extension. | 51 // Also handles the suspension and wakeup of the component extension. |
| 52 // Lives on the UI thread. | 52 // Lives on the UI thread. |
| 53 class MediaRouterMojoImpl : public MediaRouterBase, | 53 class MediaRouterMojoImpl : public MediaRouterBase, |
| 54 public mojom::MediaRouter { | 54 public mojom::MediaRouter { |
| 55 public: | 55 public: |
| 56 ~MediaRouterMojoImpl() override; | 56 ~MediaRouterMojoImpl() override; |
| 57 | 57 |
| 58 // Sets up the MediaRouterMojoImpl instance owned by |context| to handle | 58 // Sets up the MediaRouterMojoImpl instance owned by |context| to handle |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 107 void SearchSinks(const MediaSink::Id& sink_id, | 107 void SearchSinks(const MediaSink::Id& sink_id, |
| 108 const MediaSource::Id& source_id, | 108 const MediaSource::Id& source_id, |
| 109 const std::string& search_input, | 109 const std::string& search_input, |
| 110 const std::string& domain, | 110 const std::string& domain, |
| 111 MediaSinkSearchResponseCallback sink_callback) override; | 111 MediaSinkSearchResponseCallback sink_callback) override; |
| 112 void ProvideSinks(const std::string& provider_name, | 112 void ProvideSinks(const std::string& provider_name, |
| 113 std::vector<MediaSinkInternal> sinks) override; | 113 std::vector<MediaSinkInternal> sinks) override; |
| 114 scoped_refptr<MediaRouteController> GetRouteController( | 114 scoped_refptr<MediaRouteController> GetRouteController( |
| 115 const MediaRoute::Id& route_id) override; | 115 const MediaRoute::Id& route_id) override; |
| 116 | 116 |
| 117 const std::string& media_route_provider_extension_id() const { | 117 // TODO(crbug.com/597778): Remove this getter. |
| 118 return media_route_provider_extension_id_; | 118 const std::string& media_route_provider_extension_id() const; |
| 119 } | |
| 120 | 119 |
| 121 void set_instance_id_for_test(const std::string& instance_id) { | 120 void set_instance_id_for_test(const std::string& instance_id) { |
| 122 instance_id_ = instance_id; | 121 instance_id_ = instance_id; |
| 123 } | 122 } |
| 124 | 123 |
| 125 private: | 124 private: |
| 126 friend class MediaRouterFactory; | 125 friend class MediaRouterFactory; |
| 127 friend class MediaRouterMojoExtensionTest; | 126 friend class MediaRouterMojoExtensionTest; |
| 128 friend class MediaRouterMojoTest; | 127 friend class MediaRouterMojoTest; |
| 129 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoImplTest, JoinRoute); | 128 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoImplTest, JoinRoute); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 161 DrainPendingRequestQueue); | 160 DrainPendingRequestQueue); |
| 162 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest, | 161 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest, |
| 163 DropOldestPendingRequest); | 162 DropOldestPendingRequest); |
| 164 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest, | 163 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest, |
| 165 AttemptedWakeupTooManyTimes); | 164 AttemptedWakeupTooManyTimes); |
| 166 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest, | 165 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest, |
| 167 WakeupFailedDrainsQueue); | 166 WakeupFailedDrainsQueue); |
| 168 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest, | 167 FRIEND_TEST_ALL_PREFIXES(MediaRouterMojoExtensionTest, |
| 169 SyncStateToMediaRouteProvider); | 168 SyncStateToMediaRouteProvider); |
| 170 | 169 |
| 171 // The max number of pending requests allowed. When number of pending requests | |
| 172 // exceeds this number, the oldest request will be dropped. | |
| 173 static const int kMaxPendingRequests = 30; | |
| 174 | |
| 175 // Max consecutive attempts to wake up the component extension before | |
| 176 // giving up and draining the pending request queue. | |
| 177 static const int kMaxWakeupAttemptCount = 3; | |
| 178 | |
| 179 // Represents a query to the MRPM for media sinks and holds observers for the | 170 // Represents a query to the MRPM for media sinks and holds observers for the |
| 180 // query. | 171 // query. |
| 181 struct MediaSinksQuery { | 172 struct MediaSinksQuery { |
| 182 public: | 173 public: |
| 183 MediaSinksQuery(); | 174 MediaSinksQuery(); |
| 184 ~MediaSinksQuery(); | 175 ~MediaSinksQuery(); |
| 185 | 176 |
| 186 // True if the query has been sent to the MRPM. | 177 // True if the query has been sent to the MRPM. |
| 187 bool is_active = false; | 178 bool is_active = false; |
| 188 | 179 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 214 enum class FirewallCheck { | 205 enum class FirewallCheck { |
| 215 // Skips the firewall check for the benefit of unit tests so they do not | 206 // Skips the firewall check for the benefit of unit tests so they do not |
| 216 // have to depend on the system's firewall configuration. | 207 // have to depend on the system's firewall configuration. |
| 217 SKIP_FOR_TESTING, | 208 SKIP_FOR_TESTING, |
| 218 // Perform the firewall check (default). | 209 // Perform the firewall check (default). |
| 219 RUN, | 210 RUN, |
| 220 }; | 211 }; |
| 221 | 212 |
| 222 // Standard constructor, used by | 213 // Standard constructor, used by |
| 223 // MediaRouterMojoImplFactory::GetApiForBrowserContext. | 214 // MediaRouterMojoImplFactory::GetApiForBrowserContext. |
| 224 MediaRouterMojoImpl(extensions::EventPageTracker* event_page_tracker, | 215 MediaRouterMojoImpl(content::BrowserContext* context, |
| 225 content::BrowserContext* context, | |
| 226 FirewallCheck check_firewall = FirewallCheck::RUN); | 216 FirewallCheck check_firewall = FirewallCheck::RUN); |
| 227 | 217 |
| 228 // Binds |this| to a Mojo interface request, so that clients can acquire a | 218 // Binds |this| to a Mojo interface request, so that clients can acquire a |
| 229 // handle to a MediaRouterMojoImpl instance via the Mojo service connector. | 219 // handle to a MediaRouterMojoImpl instance via the Mojo service connector. |
| 230 // Stores the ID of |extension| in |media_route_provider_extension_id_|. | 220 // Stores the ID of |extension| in |media_route_provider_extension_id_|. |
| 231 void BindToMojoRequest( | 221 void BindToMojoRequest( |
| 232 mojo::InterfaceRequest<mojom::MediaRouter> request, | 222 mojo::InterfaceRequest<mojom::MediaRouter> request, |
| 233 const extensions::Extension& extension); | 223 const extensions::Extension& extension); |
| 234 | 224 |
| 235 // Enqueues a closure for later execution by ExecutePendingRequests(). | |
| 236 void EnqueueTask(base::OnceClosure closure); | |
| 237 | |
| 238 // Runs a closure if the extension monitored by |extension_monitor_| is | |
| 239 // active, or defers it for later execution if the extension is suspended. | |
| 240 void RunOrDefer(base::OnceClosure request); | |
| 241 | |
| 242 // Dispatches the Mojo requests queued in |pending_requests_|. | |
| 243 void ExecutePendingRequests(); | |
| 244 | |
| 245 // Drops all pending requests. Called when we have a connection error to | |
| 246 // component extension and further reattempts are unlikely to help. | |
| 247 void DrainPendingRequests(); | |
| 248 | |
| 249 // MediaRouter implementation. | 225 // MediaRouter implementation. |
| 250 bool RegisterMediaSinksObserver(MediaSinksObserver* observer) override; | 226 bool RegisterMediaSinksObserver(MediaSinksObserver* observer) override; |
| 251 void UnregisterMediaSinksObserver(MediaSinksObserver* observer) override; | 227 void UnregisterMediaSinksObserver(MediaSinksObserver* observer) override; |
| 252 void RegisterMediaRoutesObserver(MediaRoutesObserver* observer) override; | 228 void RegisterMediaRoutesObserver(MediaRoutesObserver* observer) override; |
| 253 void UnregisterMediaRoutesObserver(MediaRoutesObserver* observer) override; | 229 void UnregisterMediaRoutesObserver(MediaRoutesObserver* observer) override; |
| 254 void RegisterIssuesObserver(IssuesObserver* observer) override; | 230 void RegisterIssuesObserver(IssuesObserver* observer) override; |
| 255 void UnregisterIssuesObserver(IssuesObserver* observer) override; | 231 void UnregisterIssuesObserver(IssuesObserver* observer) override; |
| 256 void RegisterRouteMessageObserver(RouteMessageObserver* observer) override; | 232 void RegisterRouteMessageObserver(RouteMessageObserver* observer) override; |
| 257 void UnregisterRouteMessageObserver(RouteMessageObserver* observer) override; | 233 void UnregisterRouteMessageObserver(RouteMessageObserver* observer) override; |
| 258 void DetachRouteController(const MediaRoute::Id& route_id, | 234 void DetachRouteController(const MediaRoute::Id& route_id, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 361 // Converts the callback result of calling Mojo CreateRoute()/JoinRoute() | 337 // Converts the callback result of calling Mojo CreateRoute()/JoinRoute() |
| 362 // into a local callback. | 338 // into a local callback. |
| 363 void RouteResponseReceived(const std::string& presentation_id, | 339 void RouteResponseReceived(const std::string& presentation_id, |
| 364 bool is_incognito, | 340 bool is_incognito, |
| 365 std::vector<MediaRouteResponseCallback> callbacks, | 341 std::vector<MediaRouteResponseCallback> callbacks, |
| 366 bool is_join, | 342 bool is_join, |
| 367 const base::Optional<MediaRoute>& media_route, | 343 const base::Optional<MediaRoute>& media_route, |
| 368 const base::Optional<std::string>& error_text, | 344 const base::Optional<std::string>& error_text, |
| 369 RouteRequestResult::ResultCode result_code); | 345 RouteRequestResult::ResultCode result_code); |
| 370 | 346 |
| 371 // Callback invoked by |event_page_tracker_| after an attempt to wake the | |
| 372 // component extension. If |success| is false, the pending request queue is | |
| 373 // drained. | |
| 374 void EventPageWakeComplete(bool success); | |
| 375 | |
| 376 // Removes all requests from the pending requests queue. Called when there is | |
| 377 // a permanent error connecting to component extension. | |
| 378 void DrainRequestQueue(); | |
| 379 | |
| 380 // Calls to |event_page_tracker_| to wake the component extension. | |
| 381 // |media_route_provider_extension_id_| must not be empty and the extension | |
| 382 // should be currently suspended. | |
| 383 // If there have already been too many wakeup attempts, give up and drain | |
| 384 // the pending request queue. | |
| 385 void AttemptWakeEventPage(); | |
| 386 | |
| 387 // Sets the reason why we are attempting to wake the extension. Since | |
| 388 // multiple tasks may be enqueued for execution each time the extension runs, | |
| 389 // we record the first such reason. | |
| 390 void SetWakeReason(MediaRouteProviderWakeReason reason); | |
| 391 | |
| 392 // Clears the wake reason after the extension has been awoken. | |
| 393 void ClearWakeReason(); | |
| 394 | |
| 395 #if defined(OS_WIN) | 347 #if defined(OS_WIN) |
| 396 // Ensures that mDNS discovery is enabled in the MRPM extension. This can be | 348 // Ensures that mDNS discovery is enabled in the MRPM extension. This can be |
| 397 // called many times but the MRPM will only be called once per registration | 349 // called many times but the MRPM will only be called once per registration |
| 398 // period. | 350 // period. |
| 399 void EnsureMdnsDiscoveryEnabled(); | 351 void EnsureMdnsDiscoveryEnabled(); |
| 400 void DoEnsureMdnsDiscoveryEnabled(); | 352 void DoEnsureMdnsDiscoveryEnabled(); |
| 401 | 353 |
| 402 // Callback used to enabled mDNS in the MRPM if a firewall prompt will not be | 354 // Callback used to enabled mDNS in the MRPM if a firewall prompt will not be |
| 403 // triggered. If a firewall prompt would be triggered, enabling mDNS won't | 355 // triggered. If a firewall prompt would be triggered, enabling mDNS won't |
| 404 // happen until the user is clearly interacting with MR. | 356 // happen until the user is clearly interacting with MR. |
| 405 void OnFirewallCheckComplete(bool firewall_can_use_local_ports); | 357 void OnFirewallCheckComplete(bool firewall_can_use_local_ports); |
| 406 #endif | 358 #endif |
| 407 | 359 |
| 408 // Start browser side sink discovery. | 360 // Start browser side sink discovery. |
| 409 void StartDiscovery(); | 361 void StartDiscovery(); |
| 410 | 362 |
| 411 // Requests MRPM to update media sinks. This allows MRPs that only do | 363 // Requests MRPM to update media sinks. This allows MRPs that only do |
| 412 // discovery on sink queries an opportunity to update discovery results | 364 // discovery on sink queries an opportunity to update discovery results |
| 413 // even if the MRP SinkAvailability is marked UNAVAILABLE. | 365 // even if the MRP SinkAvailability is marked UNAVAILABLE. |
| 414 void UpdateMediaSinks(const MediaSource::Id& source_id); | 366 void UpdateMediaSinks(const MediaSource::Id& source_id); |
| 415 void DoUpdateMediaSinks(const MediaSource::Id& source_id); | 367 void DoUpdateMediaSinks(const MediaSource::Id& source_id); |
| 416 | 368 |
| 417 // Invalidates and removes controllers from |route_controllers_| whose media | 369 // Invalidates and removes controllers from |route_controllers_| whose media |
| 418 // routes do not appear in |routes|. | 370 // routes do not appear in |routes|. |
| 419 void RemoveInvalidRouteControllers(const std::vector<MediaRoute>& routes); | 371 void RemoveInvalidRouteControllers(const std::vector<MediaRoute>& routes); |
| 420 | 372 |
| 421 // Callback called by MRP's CreateMediaRouteController(). | 373 // Callback called by MRP's CreateMediaRouteController(). |
| 422 void OnMediaControllerCreated(const MediaRoute::Id& route_id, bool success); | 374 void OnMediaControllerCreated(const MediaRoute::Id& route_id, bool success); |
| 423 | 375 |
| 424 // Pending requests queued to be executed once component extension | |
| 425 // becomes ready. | |
| 426 std::deque<base::OnceClosure> pending_requests_; | |
| 427 | |
| 428 std::unordered_map<MediaSource::Id, std::unique_ptr<MediaSinksQuery>> | 376 std::unordered_map<MediaSource::Id, std::unique_ptr<MediaSinksQuery>> |
| 429 sinks_queries_; | 377 sinks_queries_; |
| 430 | 378 |
| 431 std::unordered_map<MediaSource::Id, std::unique_ptr<MediaRoutesQuery>> | 379 std::unordered_map<MediaSource::Id, std::unique_ptr<MediaRoutesQuery>> |
| 432 routes_queries_; | 380 routes_queries_; |
| 433 | 381 |
| 434 std::unordered_map<MediaRoute::Id, | 382 std::unordered_map<MediaRoute::Id, |
| 435 std::unique_ptr<base::ObserverList<RouteMessageObserver>>> | 383 std::unique_ptr<base::ObserverList<RouteMessageObserver>>> |
| 436 message_observers_; | 384 message_observers_; |
| 437 | 385 |
| 438 IssueManager issue_manager_; | 386 IssueManager issue_manager_; |
| 439 | 387 |
| 440 // Binds |this| to a Mojo connection stub for mojom::MediaRouter. | 388 // Binds |this| to a Mojo connection stub for mojom::MediaRouter. |
| 441 std::unique_ptr<mojo::Binding<mojom::MediaRouter>> binding_; | 389 std::unique_ptr<mojo::Binding<mojom::MediaRouter>> binding_; |
| 442 | 390 |
| 443 // Mojo proxy object for the Media Route Provider Manager. | 391 // Mojo proxy object for the Media Route Provider Manager. |
| 444 // Set to null initially, and later set to the Provider Manager proxy object | 392 // Set to null initially, and later set to the Provider Manager proxy object |
| 445 // passed in via |RegisterMediaRouteProvider()|. | 393 // passed in via |RegisterMediaRouteProvider()|. |
| 446 // This is set to null again when the component extension is suspended | 394 // This is set to null again when the component extension is suspended |
| 447 // if or a Mojo channel error occured. | 395 // if or a Mojo channel error occured. |
| 448 mojom::MediaRouteProviderPtr media_route_provider_; | 396 mojom::MediaRouteProviderPtr media_route_provider_; |
| 449 | 397 |
| 450 // Id of the component extension. Used for managing its suspend/wake state | |
| 451 // via event_page_tracker_. | |
| 452 std::string media_route_provider_extension_id_; | |
| 453 | |
| 454 // Allows the extension to be monitored for suspend, and woken. | |
| 455 // This is a reference to a BrowserContext keyed service that outlives this | |
| 456 // instance. | |
| 457 extensions::EventPageTracker* event_page_tracker_; | |
| 458 | |
| 459 // GUID unique to each browser run. Component extension uses this to detect | 398 // GUID unique to each browser run. Component extension uses this to detect |
| 460 // when its persisted state was written by an older browser instance, and is | 399 // when its persisted state was written by an older browser instance, and is |
| 461 // therefore stale. | 400 // therefore stale. |
| 462 std::string instance_id_; | 401 std::string instance_id_; |
|
imcheng
2017/06/30 00:17:39
Is the plan to move instance_id_ / provider_versio
takumif
2017/07/01 01:16:45
Yes, given those are used in BindToRequest() and R
| |
| 463 | 402 |
| 464 // The last reported sink availability from the media route provider manager. | 403 // The last reported sink availability from the media route provider manager. |
| 465 mojom::MediaRouter::SinkAvailability availability_; | 404 mojom::MediaRouter::SinkAvailability availability_; |
| 466 | 405 |
| 467 int wakeup_attempt_count_ = 0; | |
| 468 | |
| 469 // Records the current reason the extension is being woken up. Is set to | |
| 470 // MediaRouteProviderWakeReason::TOTAL_COUNT if there is no pending reason. | |
| 471 MediaRouteProviderWakeReason current_wake_reason_; | |
| 472 | |
| 473 // A flag to ensure that we record the provider version once, during the | |
| 474 // initial event page wakeup attempt. | |
| 475 bool provider_version_was_recorded_ = false; | |
| 476 | |
| 477 // Stores route controllers that can be used to send media commands to the | 406 // Stores route controllers that can be used to send media commands to the |
| 478 // extension. | 407 // extension. |
| 479 std::unordered_map<MediaRoute::Id, MediaRouteController*> route_controllers_; | 408 std::unordered_map<MediaRoute::Id, MediaRouteController*> route_controllers_; |
| 480 | 409 |
| 481 // Media sink service for DIAL devices. | 410 // Media sink service for DIAL devices. |
| 482 scoped_refptr<DialMediaSinkServiceProxy> dial_media_sink_service_proxy_; | 411 scoped_refptr<DialMediaSinkServiceProxy> dial_media_sink_service_proxy_; |
| 483 | 412 |
| 484 content::BrowserContext* const context_; | 413 content::BrowserContext* const context_; |
| 485 | 414 |
| 415 // Request manager responsible for waking the component extension and calling | |
| 416 // the requests to it. | |
| 417 EventPageRequestManager* const event_page_request_manager_; | |
| 418 | |
| 419 // A flag to ensure that we record the provider version once, during the | |
| 420 // initial event page wakeup attempt. | |
| 421 bool provider_version_was_recorded_ = false; | |
| 422 | |
| 486 #if defined(OS_WIN) | 423 #if defined(OS_WIN) |
| 487 // A pair of flags to ensure that mDNS discovery is only enabled on Windows | 424 // A pair of flags to ensure that mDNS discovery is only enabled on Windows |
| 488 // when there will be appropriate context for the user to associate a firewall | 425 // when there will be appropriate context for the user to associate a firewall |
| 489 // prompt with Media Router. |should_enable_mdns_discovery_| can only go from | 426 // prompt with Media Router. |should_enable_mdns_discovery_| can only go from |
| 490 // |false| to |true|. On Windows, |is_mdns_enabled_| is set to |false| in | 427 // |false| to |true|. On Windows, |is_mdns_enabled_| is set to |false| in |
| 491 // RegisterMediaRouteProvider and only set to |true| when we successfully call | 428 // RegisterMediaRouteProvider and only set to |true| when we successfully call |
| 492 // the extension to enable mDNS. | 429 // the extension to enable mDNS. |
| 493 bool is_mdns_enabled_ = false; | 430 bool is_mdns_enabled_ = false; |
| 494 bool should_enable_mdns_discovery_ = false; | 431 bool should_enable_mdns_discovery_ = false; |
| 495 #endif | 432 #endif |
| 496 | 433 |
| 497 base::WeakPtrFactory<MediaRouterMojoImpl> weak_factory_; | 434 base::WeakPtrFactory<MediaRouterMojoImpl> weak_factory_; |
| 498 | 435 |
| 499 DISALLOW_COPY_AND_ASSIGN(MediaRouterMojoImpl); | 436 DISALLOW_COPY_AND_ASSIGN(MediaRouterMojoImpl); |
| 500 }; | 437 }; |
| 501 | 438 |
| 502 } // namespace media_router | 439 } // namespace media_router |
| 503 | 440 |
| 504 #endif // CHROME_BROWSER_MEDIA_ROUTER_MOJO_MEDIA_ROUTER_MOJO_IMPL_H_ | 441 #endif // CHROME_BROWSER_MEDIA_ROUTER_MOJO_MEDIA_ROUTER_MOJO_IMPL_H_ |
| OLD | NEW |