| 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 #include "chrome/browser/media/router/mojo/media_router_mojo_impl.h" | 5 #include "chrome/browser/media/router/mojo/media_router_mojo_impl.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/guid.h" | 12 #include "base/guid.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
| 15 #include "base/memory/scoped_vector.h" | 15 #include "base/memory/scoped_vector.h" |
| 16 #include "base/observer_list.h" | 16 #include "base/observer_list.h" |
| 17 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 18 #include "base/strings/stringprintf.h" | 18 #include "base/strings/stringprintf.h" |
| 19 #include "chrome/browser/media/router/issues_observer.h" | 19 #include "chrome/browser/media/router/issues_observer.h" |
| 20 #include "chrome/browser/media/router/media_router_factory.h" | 20 #include "chrome/browser/media/router/media_router_factory.h" |
| 21 #include "chrome/browser/media/router/media_routes_observer.h" | 21 #include "chrome/browser/media/router/media_routes_observer.h" |
| 22 #include "chrome/browser/media/router/media_sinks_observer.h" | 22 #include "chrome/browser/media/router/media_sinks_observer.h" |
| 23 #include "chrome/browser/media/router/media_source_helper.h" | 23 #include "chrome/browser/media/router/media_source_helper.h" |
| 24 #include "chrome/browser/media/router/mojo/media_remoting_session_impl.h" |
| 24 #include "chrome/browser/media/router/mojo/media_route_provider_util_win.h" | 25 #include "chrome/browser/media/router/mojo/media_route_provider_util_win.h" |
| 25 #include "chrome/browser/media/router/mojo/media_router_mojo_metrics.h" | 26 #include "chrome/browser/media/router/mojo/media_router_mojo_metrics.h" |
| 26 #include "chrome/browser/media/router/mojo/media_router_type_converters.h" | 27 #include "chrome/browser/media/router/mojo/media_router_type_converters.h" |
| 27 #include "chrome/browser/media/router/presentation_session_messages_observer.h" | 28 #include "chrome/browser/media/router/presentation_session_messages_observer.h" |
| 28 #include "chrome/browser/sessions/session_tab_helper.h" | 29 #include "chrome/browser/sessions/session_tab_helper.h" |
| 29 #include "content/public/browser/browser_thread.h" | 30 #include "content/public/browser/browser_thread.h" |
| 30 #include "extensions/browser/process_manager.h" | 31 #include "extensions/browser/process_manager.h" |
| 31 | 32 |
| 32 #define DVLOG_WITH_INSTANCE(level) \ | 33 #define DVLOG_WITH_INSTANCE(level) \ |
| 33 DVLOG(level) << "MR #" << instance_id_ << ": " | 34 DVLOG(level) << "MR #" << instance_id_ << ": " |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 DCHECK(event_page_tracker_); | 95 DCHECK(event_page_tracker_); |
| 95 #if defined(OS_WIN) | 96 #if defined(OS_WIN) |
| 96 CanFirewallUseLocalPorts( | 97 CanFirewallUseLocalPorts( |
| 97 base::Bind(&MediaRouterMojoImpl::OnFirewallCheckComplete, | 98 base::Bind(&MediaRouterMojoImpl::OnFirewallCheckComplete, |
| 98 weak_factory_.GetWeakPtr())); | 99 weak_factory_.GetWeakPtr())); |
| 99 #endif | 100 #endif |
| 100 } | 101 } |
| 101 | 102 |
| 102 MediaRouterMojoImpl::~MediaRouterMojoImpl() { | 103 MediaRouterMojoImpl::~MediaRouterMojoImpl() { |
| 103 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 104 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 105 TerminateAllRemotingSessions("media router shutdown"); |
| 104 } | 106 } |
| 105 | 107 |
| 106 // static | 108 // static |
| 107 void MediaRouterMojoImpl::BindToRequest( | 109 void MediaRouterMojoImpl::BindToRequest( |
| 108 const extensions::Extension* extension, | 110 const extensions::Extension* extension, |
| 109 content::BrowserContext* context, | 111 content::BrowserContext* context, |
| 110 mojo::InterfaceRequest<interfaces::MediaRouter> request) { | 112 mojo::InterfaceRequest<interfaces::MediaRouter> request) { |
| 111 MediaRouterMojoImpl* impl = static_cast<MediaRouterMojoImpl*>( | 113 MediaRouterMojoImpl* impl = static_cast<MediaRouterMojoImpl*>( |
| 112 MediaRouterFactory::GetApiForBrowserContext(context)); | 114 MediaRouterFactory::GetApiForBrowserContext(context)); |
| 113 DCHECK(impl); | 115 DCHECK(impl); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 128 media_route_provider_extension_id_ = extension.id(); | 130 media_route_provider_extension_id_ = extension.id(); |
| 129 if (!provider_version_was_recorded_) { | 131 if (!provider_version_was_recorded_) { |
| 130 MediaRouterMojoMetrics::RecordMediaRouteProviderVersion(extension); | 132 MediaRouterMojoMetrics::RecordMediaRouteProviderVersion(extension); |
| 131 provider_version_was_recorded_ = true; | 133 provider_version_was_recorded_ = true; |
| 132 } | 134 } |
| 133 } | 135 } |
| 134 | 136 |
| 135 void MediaRouterMojoImpl::OnConnectionError() { | 137 void MediaRouterMojoImpl::OnConnectionError() { |
| 136 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 138 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 137 | 139 |
| 140 TerminateAllRemotingSessions("internal connection error"); |
| 138 media_route_provider_.reset(); | 141 media_route_provider_.reset(); |
| 139 binding_.reset(); | 142 binding_.reset(); |
| 140 | 143 |
| 141 // If |OnConnectionError| is invoked while there are pending requests, then | 144 // If |OnConnectionError| is invoked while there are pending requests, then |
| 142 // it means we tried to wake the extension, but weren't able to complete the | 145 // it means we tried to wake the extension, but weren't able to complete the |
| 143 // connection to media route provider. Since we do not know whether the error | 146 // connection to media route provider. Since we do not know whether the error |
| 144 // is transient, reattempt the wakeup. | 147 // is transient, reattempt the wakeup. |
| 145 if (!pending_requests_.empty()) { | 148 if (!pending_requests_.empty()) { |
| 146 DLOG_WITH_INSTANCE(ERROR) << "A connection error while there are pending " | 149 DLOG_WITH_INSTANCE(ERROR) << "A connection error while there are pending " |
| 147 "requests."; | 150 "requests."; |
| (...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 | 804 |
| 802 void MediaRouterMojoImpl::OnPresentationConnectionClosed( | 805 void MediaRouterMojoImpl::OnPresentationConnectionClosed( |
| 803 const mojo::String& route_id, | 806 const mojo::String& route_id, |
| 804 interfaces::MediaRouter::PresentationConnectionCloseReason reason, | 807 interfaces::MediaRouter::PresentationConnectionCloseReason reason, |
| 805 const mojo::String& message) { | 808 const mojo::String& message) { |
| 806 NotifyPresentationConnectionClose( | 809 NotifyPresentationConnectionClose( |
| 807 route_id, mojo::PresentationConnectionCloseReasonFromMojo(reason), | 810 route_id, mojo::PresentationConnectionCloseReasonFromMojo(reason), |
| 808 message); | 811 message); |
| 809 } | 812 } |
| 810 | 813 |
| 814 void MediaRouterMojoImpl::CreateRemotingSession( |
| 815 const mojo::String& media_source, |
| 816 interfaces::MediaRemotingProviderPtr provider, |
| 817 const CreateRemotingSessionCallback& callback) { |
| 818 DVLOG_WITH_INSTANCE(1) |
| 819 << "CreateRemotingSession(media_source=" << media_source << ")"; |
| 820 |
| 821 interfaces::MediaRemotingSessionPtr session_ptr; |
| 822 do { |
| 823 content::WebContents* const source_contents = |
| 824 WebContentsFromMediaSource(MediaSource(media_source)); |
| 825 if (!source_contents) { |
| 826 // Note: This can happen if the tab existed at the time the client called |
| 827 // CreateRemotingSession(), but was closed before this service method was |
| 828 // invoked. |
| 829 DLOG_WITH_INSTANCE(WARNING) |
| 830 << "Cannot find WebContents instance specified by the media source."; |
| 831 break; |
| 832 } |
| 833 |
| 834 if (!provider.is_bound()) { |
| 835 DLOG_WITH_INSTANCE(ERROR) |
| 836 << "Client did not pass a bound MediaRemotingProvider interface."; |
| 837 break; |
| 838 } |
| 839 |
| 840 std::unique_ptr<MediaRemotingSessionImpl>& session = |
| 841 remoting_sessions_[media_source]; |
| 842 if (session) { |
| 843 DLOG_WITH_INSTANCE(ERROR) |
| 844 << "Cannot create multiple MediaRemotingSessions per media source."; |
| 845 break; |
| 846 } |
| 847 session.reset( |
| 848 new AutoTerminatingRemotingSession( |
| 849 source_contents, std::move(provider), GetProxy(&session_ptr), |
| 850 base::Bind(&MediaRouterMojoImpl::OnRemotingSessionTerminated, |
| 851 base::Unretained(this), media_source))); |
| 852 } while (false); |
| 853 |
| 854 callback.Run(std::move(session_ptr)); |
| 855 } |
| 856 |
| 857 void MediaRouterMojoImpl::OnRemotingSessionTerminated( |
| 858 const MediaSource::Id& media_source) { |
| 859 remoting_sessions_.erase(media_source); |
| 860 } |
| 861 |
| 862 void MediaRouterMojoImpl::TerminateAllRemotingSessions( |
| 863 const std::string& error_reason) { |
| 864 // Copy pointers to a separate vector for iteration, since terminating each |
| 865 // session will cause the |remoting_sessions_| map to mutate. |
| 866 std::vector<MediaRemotingSessionImpl*> sessions; |
| 867 for (const auto& entry : remoting_sessions_) |
| 868 sessions.push_back(entry.second.get()); |
| 869 |
| 870 for (MediaRemotingSessionImpl* session : sessions) |
| 871 session->Terminate(error_reason); |
| 872 DCHECK(remoting_sessions_.empty()); |
| 873 } |
| 874 |
| 811 void MediaRouterMojoImpl::DoStartObservingMediaSinks( | 875 void MediaRouterMojoImpl::DoStartObservingMediaSinks( |
| 812 const MediaSource::Id& source_id) { | 876 const MediaSource::Id& source_id) { |
| 813 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaSinks: " << source_id; | 877 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaSinks: " << source_id; |
| 814 // No need to call MRPM if there are no sinks available. | 878 // No need to call MRPM if there are no sinks available. |
| 815 if (availability_ == interfaces::MediaRouter::SinkAvailability::UNAVAILABLE) | 879 if (availability_ == interfaces::MediaRouter::SinkAvailability::UNAVAILABLE) |
| 816 return; | 880 return; |
| 817 | 881 |
| 818 // No need to call MRPM if all observers have been removed in the meantime. | 882 // No need to call MRPM if all observers have been removed in the meantime. |
| 819 auto* sinks_query = sinks_queries_.get(source_id); | 883 auto* sinks_query = sinks_queries_.get(source_id); |
| 820 if (!sinks_query || !sinks_query->observers.might_have_observers()) | 884 if (!sinks_query || !sinks_query->observers.might_have_observers()) |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1013 base::Unretained(this), source_id)); | 1077 base::Unretained(this), source_id)); |
| 1014 } | 1078 } |
| 1015 | 1079 |
| 1016 void MediaRouterMojoImpl::DoUpdateMediaSinks( | 1080 void MediaRouterMojoImpl::DoUpdateMediaSinks( |
| 1017 const MediaSource::Id& source_id) { | 1081 const MediaSource::Id& source_id) { |
| 1018 DVLOG_WITH_INSTANCE(1) << "DoUpdateMediaSinks" << source_id; | 1082 DVLOG_WITH_INSTANCE(1) << "DoUpdateMediaSinks" << source_id; |
| 1019 media_route_provider_->UpdateMediaSinks(source_id); | 1083 media_route_provider_->UpdateMediaSinks(source_id); |
| 1020 } | 1084 } |
| 1021 | 1085 |
| 1022 } // namespace media_router | 1086 } // namespace media_router |
| OLD | NEW |