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

Side by Side Diff: content/renderer/media/webrtc/peer_connection_dependency_factory.cc

Issue 1349823004: Check media permissions (mic/camera) before exposing local addresses to WebRTC. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 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
« no previous file with comments | « content/content_tests.gypi ('k') | content/renderer/p2p/empty_network_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "content/renderer/media/webrtc/peer_connection_dependency_factory.h" 5 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/location.h" 10 #include "base/location.h"
11 #include "base/metrics/field_trial.h"
12 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
12 #include "base/synchronization/waitable_event.h" 14 #include "base/synchronization/waitable_event.h"
13 #include "content/common/media/media_stream_messages.h" 15 #include "content/common/media/media_stream_messages.h"
14 #include "content/public/common/content_switches.h" 16 #include "content/public/common/content_switches.h"
15 #include "content/public/common/renderer_preferences.h" 17 #include "content/public/common/renderer_preferences.h"
16 #include "content/renderer/media/media_stream.h" 18 #include "content/renderer/media/media_stream.h"
17 #include "content/renderer/media/media_stream_audio_processor.h" 19 #include "content/renderer/media/media_stream_audio_processor.h"
18 #include "content/renderer/media/media_stream_audio_processor_options.h" 20 #include "content/renderer/media/media_stream_audio_processor_options.h"
19 #include "content/renderer/media/media_stream_audio_source.h" 21 #include "content/renderer/media/media_stream_audio_source.h"
20 #include "content/renderer/media/media_stream_video_source.h" 22 #include "content/renderer/media/media_stream_video_source.h"
21 #include "content/renderer/media/media_stream_video_track.h" 23 #include "content/renderer/media/media_stream_video_track.h"
22 #include "content/renderer/media/peer_connection_identity_store.h" 24 #include "content/renderer/media/peer_connection_identity_store.h"
23 #include "content/renderer/media/rtc_media_constraints.h" 25 #include "content/renderer/media/rtc_media_constraints.h"
24 #include "content/renderer/media/rtc_peer_connection_handler.h" 26 #include "content/renderer/media/rtc_peer_connection_handler.h"
25 #include "content/renderer/media/rtc_video_decoder_factory.h" 27 #include "content/renderer/media/rtc_video_decoder_factory.h"
26 #include "content/renderer/media/rtc_video_encoder_factory.h" 28 #include "content/renderer/media/rtc_video_encoder_factory.h"
27 #include "content/renderer/media/webaudio_capturer_source.h" 29 #include "content/renderer/media/webaudio_capturer_source.h"
28 #include "content/renderer/media/webrtc/stun_field_trial.h" 30 #include "content/renderer/media/webrtc/stun_field_trial.h"
29 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" 31 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h"
30 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" 32 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h"
31 #include "content/renderer/media/webrtc_audio_device_impl.h" 33 #include "content/renderer/media/webrtc_audio_device_impl.h"
32 #include "content/renderer/media/webrtc_local_audio_track.h" 34 #include "content/renderer/media/webrtc_local_audio_track.h"
33 #include "content/renderer/media/webrtc_logging.h" 35 #include "content/renderer/media/webrtc_logging.h"
34 #include "content/renderer/media/webrtc_uma_histograms.h" 36 #include "content/renderer/media/webrtc_uma_histograms.h"
37 #include "content/renderer/p2p/empty_network_manager.h"
38 #include "content/renderer/p2p/filtering_network_manager.h"
35 #include "content/renderer/p2p/ipc_network_manager.h" 39 #include "content/renderer/p2p/ipc_network_manager.h"
36 #include "content/renderer/p2p/ipc_socket_factory.h" 40 #include "content/renderer/p2p/ipc_socket_factory.h"
37 #include "content/renderer/p2p/port_allocator.h" 41 #include "content/renderer/p2p/port_allocator.h"
42 #include "content/renderer/render_frame_impl.h"
38 #include "content/renderer/render_thread_impl.h" 43 #include "content/renderer/render_thread_impl.h"
39 #include "content/renderer/render_view_impl.h" 44 #include "content/renderer/render_view_impl.h"
40 #include "jingle/glue/thread_wrapper.h" 45 #include "jingle/glue/thread_wrapper.h"
46 #include "media/base/media_permission.h"
41 #include "media/renderers/gpu_video_accelerator_factories.h" 47 #include "media/renderers/gpu_video_accelerator_factories.h"
42 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" 48 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
43 #include "third_party/WebKit/public/platform/WebMediaStream.h" 49 #include "third_party/WebKit/public/platform/WebMediaStream.h"
44 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" 50 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
45 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 51 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
46 #include "third_party/WebKit/public/platform/WebURL.h" 52 #include "third_party/WebKit/public/platform/WebURL.h"
47 #include "third_party/WebKit/public/web/WebDocument.h" 53 #include "third_party/WebKit/public/web/WebDocument.h"
48 #include "third_party/WebKit/public/web/WebFrame.h" 54 #include "third_party/WebKit/public/web/WebFrame.h"
49 #include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface .h" 55 #include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface .h"
50 56
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 constraints->AddOptional(kConstraintEffectMap[i].constraint, 105 constraints->AddOptional(kConstraintEffectMap[i].constraint,
100 webrtc::MediaConstraintsInterface::kValueFalse, true); 106 webrtc::MediaConstraintsInterface::kValueFalse, true);
101 } 107 }
102 DVLOG(1) << "Disabling constraint: " 108 DVLOG(1) << "Disabling constraint: "
103 << kConstraintEffectMap[i].constraint; 109 << kConstraintEffectMap[i].constraint;
104 } 110 }
105 } 111 }
106 } 112 }
107 } 113 }
108 114
109 class P2PPortAllocatorFactory : public webrtc::PortAllocatorFactoryInterface { 115 class P2PPortAllocatorFactory
116 : public rtc::RefCountedObject<webrtc::PortAllocatorFactoryInterface> {
110 public: 117 public:
111 P2PPortAllocatorFactory(P2PSocketDispatcher* socket_dispatcher, 118 P2PPortAllocatorFactory(
112 rtc::NetworkManager* network_manager, 119 scoped_ptr<media::MediaPermission> media_permission,
113 rtc::PacketSocketFactory* socket_factory, 120 const scoped_refptr<P2PSocketDispatcher> socket_dispatcher,
Sergey Ulanov 2015/09/25 19:11:44 it's fine to pass scoped_refptr<> as const-ref (th
114 const GURL& origin, 121 rtc::NetworkManager* network_manager,
115 const P2PPortAllocator::Config& config) 122 rtc::PacketSocketFactory* socket_factory,
116 : socket_dispatcher_(socket_dispatcher), 123 const P2PPortAllocator::Config& config,
124 const GURL& origin,
125 const scoped_refptr<base::SingleThreadTaskRunner> task_runner)
126 : media_permission_(media_permission.Pass()),
127 socket_dispatcher_(socket_dispatcher),
117 network_manager_(network_manager), 128 network_manager_(network_manager),
118 socket_factory_(socket_factory), 129 socket_factory_(socket_factory),
130 config_(config),
119 origin_(origin), 131 origin_(origin),
120 config_(config) {} 132 task_runner_(task_runner) {}
121 133
122 cricket::PortAllocator* CreatePortAllocator( 134 cricket::PortAllocator* CreatePortAllocator(
123 const std::vector<StunConfiguration>& stun_servers, 135 const std::vector<StunConfiguration>& stun_servers,
124 const std::vector<TurnConfiguration>& turn_configurations) override { 136 const std::vector<TurnConfiguration>& turn_configurations) override {
125 P2PPortAllocator::Config config = config_; 137 P2PPortAllocator::Config config = config_;
126 for (size_t i = 0; i < stun_servers.size(); ++i) { 138 for (size_t i = 0; i < stun_servers.size(); ++i) {
127 config.stun_servers.insert(rtc::SocketAddress( 139 config.stun_servers.insert(rtc::SocketAddress(
128 stun_servers[i].server.hostname(), 140 stun_servers[i].server.hostname(),
129 stun_servers[i].server.port())); 141 stun_servers[i].server.port()));
130 } 142 }
131 for (size_t i = 0; i < turn_configurations.size(); ++i) { 143 for (size_t i = 0; i < turn_configurations.size(); ++i) {
132 P2PPortAllocator::Config::RelayServerConfig relay_config; 144 P2PPortAllocator::Config::RelayServerConfig relay_config;
133 relay_config.server_address = turn_configurations[i].server.hostname(); 145 relay_config.server_address = turn_configurations[i].server.hostname();
134 relay_config.port = turn_configurations[i].server.port(); 146 relay_config.port = turn_configurations[i].server.port();
135 relay_config.username = turn_configurations[i].username; 147 relay_config.username = turn_configurations[i].username;
136 relay_config.password = turn_configurations[i].password; 148 relay_config.password = turn_configurations[i].password;
137 relay_config.transport_type = turn_configurations[i].transport_type; 149 relay_config.transport_type = turn_configurations[i].transport_type;
138 relay_config.secure = turn_configurations[i].secure; 150 relay_config.secure = turn_configurations[i].secure;
139 config.relays.push_back(relay_config); 151 config.relays.push_back(relay_config);
140 } 152 }
141 153
142 return new P2PPortAllocator( 154 scoped_ptr<rtc::NetworkManager> network_manager;
143 socket_dispatcher_.get(), network_manager_, 155 if (config.enable_multiple_routes) {
144 socket_factory_, config, origin_); 156 FilteringNetworkManager* filtering_network_manager =
157 new FilteringNetworkManager(network_manager_, origin_,
158 media_permission_.Pass());
159 if (media_permission_) {
160 // Start permission check earlier to reduce any impact to call set up
161 // time. It's safe to use Unretained here since both destructor and
162 // Initialize can only be called on the worker thread.
163 task_runner_->PostTask(
164 FROM_HERE, base::Bind(&FilteringNetworkManager::Initialize,
165 base::Unretained(filtering_network_manager)));
166 }
167 network_manager.reset(filtering_network_manager);
168 } else {
169 network_manager.reset(new EmptyNetworkManager());
170 }
171
172 return new P2PPortAllocator(socket_dispatcher_, network_manager.Pass(),
173 socket_factory_, config, origin_, task_runner_);
145 } 174 }
146 175
147 protected: 176 protected:
148 ~P2PPortAllocatorFactory() override {} 177 ~P2PPortAllocatorFactory() override {}
149 178
150 private: 179 private:
151 scoped_refptr<P2PSocketDispatcher> socket_dispatcher_; 180 // Ownership of |media_permission_| will be passed to FilteringNetworkManager
152 // |network_manager_| and |socket_factory_| are a weak references, owned by 181 // during CreatePortAllocator.
153 // PeerConnectionDependencyFactory. 182 scoped_ptr<media::MediaPermission> media_permission_;
183
184 const scoped_refptr<P2PSocketDispatcher> socket_dispatcher_;
Sergey Ulanov 2015/09/25 19:11:44 nit: don't need const
154 rtc::NetworkManager* network_manager_; 185 rtc::NetworkManager* network_manager_;
155 rtc::PacketSocketFactory* socket_factory_; 186 rtc::PacketSocketFactory* socket_factory_;
156 // The origin URL of the WebFrame that created the 187 const P2PPortAllocator::Config& config_;
Sergey Ulanov 2015/09/25 19:11:44 This shouldn't be a reference. Never store referen
157 // P2PPortAllocatorFactory. 188 const GURL& origin_;
158 GURL origin_;
159 189
160 // Keep track of configuration common to all PortAllocators created by this 190 // This is the worker thread where |media_permission_| and |network_manager_|
161 // factory; additional, per-allocator configuration is passed into 191 // live on.
162 // CreatePortAllocator. 192 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
163 P2PPortAllocator::Config config_;
164 }; 193 };
165 194
166 PeerConnectionDependencyFactory::PeerConnectionDependencyFactory( 195 PeerConnectionDependencyFactory::PeerConnectionDependencyFactory(
167 P2PSocketDispatcher* p2p_socket_dispatcher) 196 P2PSocketDispatcher* p2p_socket_dispatcher)
168 : network_manager_(NULL), 197 : network_manager_(NULL),
169 p2p_socket_dispatcher_(p2p_socket_dispatcher), 198 p2p_socket_dispatcher_(p2p_socket_dispatcher),
170 signaling_thread_(NULL), 199 signaling_thread_(NULL),
171 worker_thread_(NULL), 200 worker_thread_(NULL),
172 chrome_signaling_thread_("Chrome_libJingle_Signaling"), 201 chrome_signaling_thread_("Chrome_libJingle_Signaling"),
173 chrome_worker_thread_("Chrome_libJingle_WorkerThread") { 202 chrome_worker_thread_("Chrome_libJingle_WorkerThread") {
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 CHECK(observer); 425 CHECK(observer);
397 if (!GetPcFactory().get()) 426 if (!GetPcFactory().get())
398 return NULL; 427 return NULL;
399 428
400 rtc::scoped_ptr<PeerConnectionIdentityStore> identity_store( 429 rtc::scoped_ptr<PeerConnectionIdentityStore> identity_store(
401 new PeerConnectionIdentityStore( 430 new PeerConnectionIdentityStore(
402 GURL(web_frame->document().url()), 431 GURL(web_frame->document().url()),
403 GURL(web_frame->document().firstPartyForCookies()))); 432 GURL(web_frame->document().firstPartyForCookies())));
404 433
405 // Copy the flag from Preference associated with this WebFrame. 434 // Copy the flag from Preference associated with this WebFrame.
406 P2PPortAllocator::Config pref_config; 435 P2PPortAllocator::Config port_config;
407 if (web_frame && web_frame->view()) { 436 if (web_frame && web_frame->view()) {
408 RenderViewImpl* renderer_view_impl = 437 RenderViewImpl* renderer_view_impl =
409 RenderViewImpl::FromWebView(web_frame->view()); 438 RenderViewImpl::FromWebView(web_frame->view());
410 if (renderer_view_impl) { 439 if (renderer_view_impl) {
411 pref_config.enable_multiple_routes = 440 // TODO(guoweis): |enable_multiple_routes| should be renamed to
441 // |request_multiple_routes|. Whether local IP addresses could be
442 // collected depends on if mic/camera permission is granted for this
443 // origin.
444 port_config.enable_multiple_routes =
412 renderer_view_impl->renderer_preferences() 445 renderer_view_impl->renderer_preferences()
413 .enable_webrtc_multiple_routes; 446 .enable_webrtc_multiple_routes;
414 pref_config.enable_nonproxied_udp = 447 port_config.enable_nonproxied_udp =
415 renderer_view_impl->renderer_preferences() 448 renderer_view_impl->renderer_preferences()
416 .enable_webrtc_nonproxied_udp; 449 .enable_webrtc_nonproxied_udp;
417 } 450 }
418 } 451 }
419 452
453 // |media_permission| will be called to check mic/camera permission. If at
454 // least one of them is granted, P2PPortAllocator is allowed to gather local
455 // host IP addresses as ICE candidates.
456 // If the experiment is not enabled, turn off the permission check by
457 // passing nullptr to FilteringNetworkManager constructor.
458 scoped_ptr<media::MediaPermission> media_permission;
459 const std::string group_name =
460 base::FieldTrialList::FindFullName("WebRTC-LocalIPPermissionCheck");
461 if (StartsWith(group_name, "Enabled", base::CompareCase::SENSITIVE) &&
462 port_config.enable_multiple_routes) {
463 RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(web_frame);
464 if (render_frame) {
465 media_permission = render_frame->CreateMediaPermissionProxy(
466 chrome_worker_thread_.task_runner());
467 DCHECK(media_permission);
468 }
469 }
470
471 const GURL& requesting_origin =
472 GURL(web_frame->document().url().spec()).GetOrigin();
473
420 scoped_refptr<P2PPortAllocatorFactory> pa_factory = 474 scoped_refptr<P2PPortAllocatorFactory> pa_factory =
421 new rtc::RefCountedObject<P2PPortAllocatorFactory>( 475 new P2PPortAllocatorFactory(
422 p2p_socket_dispatcher_.get(), network_manager_, socket_factory_.get(), 476 media_permission.Pass(), p2p_socket_dispatcher_, network_manager_,
423 GURL(web_frame->document().url().spec()).GetOrigin(), pref_config); 477 socket_factory_.get(), port_config, requesting_origin,
478 chrome_worker_thread_.task_runner());
424 479
425 return GetPcFactory()->CreatePeerConnection(config, 480 return GetPcFactory()->CreatePeerConnection(config,
426 constraints, 481 constraints,
427 pa_factory.get(), 482 pa_factory.get(),
428 identity_store.Pass(), 483 identity_store.Pass(),
429 observer).get(); 484 observer).get();
430 } 485 }
431 486
432 scoped_refptr<webrtc::MediaStreamInterface> 487 scoped_refptr<webrtc::MediaStreamInterface>
433 PeerConnectionDependencyFactory::CreateLocalMediaStream( 488 PeerConnectionDependencyFactory::CreateLocalMediaStream(
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 } 736 }
682 737
683 void PeerConnectionDependencyFactory::EnsureWebRtcAudioDeviceImpl() { 738 void PeerConnectionDependencyFactory::EnsureWebRtcAudioDeviceImpl() {
684 if (audio_device_.get()) 739 if (audio_device_.get())
685 return; 740 return;
686 741
687 audio_device_ = new WebRtcAudioDeviceImpl(); 742 audio_device_ = new WebRtcAudioDeviceImpl();
688 } 743 }
689 744
690 } // namespace content 745 } // namespace content
OLDNEW
« no previous file with comments | « content/content_tests.gypi ('k') | content/renderer/p2p/empty_network_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698