Index: content/renderer/media/webrtc/peer_connection_dependency_factory.cc |
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc |
index 663f61869c45cc70b43a6b0e2931f2af057effe6..7cc5a950cb76e1eae1028a035979d3f4f94e0255 100644 |
--- a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc |
+++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc |
@@ -8,6 +8,8 @@ |
#include "base/command_line.h" |
#include "base/location.h" |
+#include "base/metrics/field_trial.h" |
+#include "base/strings/string_util.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/synchronization/waitable_event.h" |
#include "content/common/media/media_stream_messages.h" |
@@ -32,12 +34,16 @@ |
#include "content/renderer/media/webrtc_local_audio_track.h" |
#include "content/renderer/media/webrtc_logging.h" |
#include "content/renderer/media/webrtc_uma_histograms.h" |
+#include "content/renderer/p2p/empty_network_manager.h" |
+#include "content/renderer/p2p/filtering_network_manager.h" |
#include "content/renderer/p2p/ipc_network_manager.h" |
#include "content/renderer/p2p/ipc_socket_factory.h" |
#include "content/renderer/p2p/port_allocator.h" |
+#include "content/renderer/render_frame_impl.h" |
#include "content/renderer/render_thread_impl.h" |
#include "content/renderer/render_view_impl.h" |
#include "jingle/glue/thread_wrapper.h" |
+#include "media/base/media_permission.h" |
#include "media/renderers/gpu_video_accelerator_factories.h" |
#include "third_party/WebKit/public/platform/WebMediaConstraints.h" |
#include "third_party/WebKit/public/platform/WebMediaStream.h" |
@@ -106,18 +112,24 @@ void HarmonizeConstraintsAndEffects(RTCMediaConstraints* constraints, |
} |
} |
-class P2PPortAllocatorFactory : public webrtc::PortAllocatorFactoryInterface { |
+class P2PPortAllocatorFactory |
+ : public rtc::RefCountedObject<webrtc::PortAllocatorFactoryInterface> { |
public: |
- P2PPortAllocatorFactory(P2PSocketDispatcher* socket_dispatcher, |
- rtc::NetworkManager* network_manager, |
- rtc::PacketSocketFactory* socket_factory, |
- const GURL& origin, |
- const P2PPortAllocator::Config& config) |
- : socket_dispatcher_(socket_dispatcher), |
+ P2PPortAllocatorFactory( |
+ scoped_ptr<media::MediaPermission> media_permission, |
+ const scoped_refptr<P2PSocketDispatcher>& socket_dispatcher, |
+ rtc::NetworkManager* network_manager, |
+ rtc::PacketSocketFactory* socket_factory, |
+ const P2PPortAllocator::Config& config, |
+ const GURL& origin, |
+ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) |
+ : media_permission_(media_permission.Pass()), |
+ socket_dispatcher_(socket_dispatcher), |
network_manager_(network_manager), |
socket_factory_(socket_factory), |
+ config_(config), |
origin_(origin), |
- config_(config) {} |
+ task_runner_(task_runner) {} |
cricket::PortAllocator* CreatePortAllocator( |
const std::vector<StunConfiguration>& stun_servers, |
@@ -139,28 +151,46 @@ class P2PPortAllocatorFactory : public webrtc::PortAllocatorFactoryInterface { |
config.relays.push_back(relay_config); |
} |
- return new P2PPortAllocator( |
- socket_dispatcher_.get(), network_manager_, |
- socket_factory_, config, origin_); |
+ scoped_ptr<rtc::NetworkManager> network_manager; |
+ if (config.enable_multiple_routes) { |
+ media::MediaPermission* media_permission = media_permission_.get(); |
+ FilteringNetworkManager* filtering_network_manager = |
+ new FilteringNetworkManager(network_manager_, origin_, |
+ media_permission_.Pass()); |
+ if (media_permission) { |
+ // Start permission check earlier to reduce any impact to call set up |
+ // time. It's safe to use Unretained here since both destructor and |
+ // Initialize can only be called on the worker thread. |
+ task_runner_->PostTask( |
+ FROM_HERE, base::Bind(&FilteringNetworkManager::Initialize, |
+ base::Unretained(filtering_network_manager))); |
+ } |
+ network_manager.reset(filtering_network_manager); |
+ } else { |
+ network_manager.reset(new EmptyNetworkManager()); |
+ } |
+ |
+ return new P2PPortAllocator(socket_dispatcher_, network_manager.Pass(), |
+ socket_factory_, config, origin_, task_runner_); |
} |
protected: |
~P2PPortAllocatorFactory() override {} |
private: |
+ // Ownership of |media_permission_| will be passed to FilteringNetworkManager |
+ // during CreatePortAllocator. |
+ scoped_ptr<media::MediaPermission> media_permission_; |
+ |
scoped_refptr<P2PSocketDispatcher> socket_dispatcher_; |
- // |network_manager_| and |socket_factory_| are a weak references, owned by |
- // PeerConnectionDependencyFactory. |
rtc::NetworkManager* network_manager_; |
rtc::PacketSocketFactory* socket_factory_; |
- // The origin URL of the WebFrame that created the |
- // P2PPortAllocatorFactory. |
+ P2PPortAllocator::Config config_; |
GURL origin_; |
- // Keep track of configuration common to all PortAllocators created by this |
- // factory; additional, per-allocator configuration is passed into |
- // CreatePortAllocator. |
- P2PPortAllocator::Config config_; |
+ // This is the worker thread where |media_permission_| and |network_manager_| |
+ // live on. |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
}; |
PeerConnectionDependencyFactory::PeerConnectionDependencyFactory( |
@@ -403,24 +433,50 @@ PeerConnectionDependencyFactory::CreatePeerConnection( |
GURL(web_frame->document().firstPartyForCookies()))); |
// Copy the flag from Preference associated with this WebFrame. |
- P2PPortAllocator::Config pref_config; |
+ P2PPortAllocator::Config port_config; |
if (web_frame && web_frame->view()) { |
RenderViewImpl* renderer_view_impl = |
RenderViewImpl::FromWebView(web_frame->view()); |
if (renderer_view_impl) { |
- pref_config.enable_multiple_routes = |
+ // TODO(guoweis): |enable_multiple_routes| should be renamed to |
+ // |request_multiple_routes|. Whether local IP addresses could be |
+ // collected depends on if mic/camera permission is granted for this |
+ // origin. |
+ port_config.enable_multiple_routes = |
renderer_view_impl->renderer_preferences() |
.enable_webrtc_multiple_routes; |
- pref_config.enable_nonproxied_udp = |
+ port_config.enable_nonproxied_udp = |
renderer_view_impl->renderer_preferences() |
.enable_webrtc_nonproxied_udp; |
} |
} |
+ // |media_permission| will be called to check mic/camera permission. If at |
+ // least one of them is granted, P2PPortAllocator is allowed to gather local |
+ // host IP addresses as ICE candidates. |
+ // If the experiment is not enabled, turn off the permission check by |
+ // passing nullptr to FilteringNetworkManager constructor. |
+ scoped_ptr<media::MediaPermission> media_permission; |
+ const std::string group_name = |
+ base::FieldTrialList::FindFullName("WebRTC-LocalIPPermissionCheck"); |
+ if (StartsWith(group_name, "Enabled", base::CompareCase::SENSITIVE) && |
+ port_config.enable_multiple_routes) { |
+ RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(web_frame); |
+ if (render_frame) { |
+ media_permission = render_frame->CreateMediaPermissionProxy( |
+ chrome_worker_thread_.task_runner()); |
+ DCHECK(media_permission); |
+ } |
+ } |
+ |
+ const GURL& requesting_origin = |
+ GURL(web_frame->document().url().spec()).GetOrigin(); |
+ |
scoped_refptr<P2PPortAllocatorFactory> pa_factory = |
- new rtc::RefCountedObject<P2PPortAllocatorFactory>( |
- p2p_socket_dispatcher_.get(), network_manager_, socket_factory_.get(), |
- GURL(web_frame->document().url().spec()).GetOrigin(), pref_config); |
+ new P2PPortAllocatorFactory( |
+ media_permission.Pass(), p2p_socket_dispatcher_, network_manager_, |
+ socket_factory_.get(), port_config, requesting_origin, |
+ chrome_worker_thread_.task_runner()); |
return GetPcFactory()->CreatePeerConnection(config, |
constraints, |