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

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: address comments. 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
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"
11 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
12 #include "base/synchronization/waitable_event.h" 13 #include "base/synchronization/waitable_event.h"
13 #include "content/common/media/media_stream_messages.h" 14 #include "content/common/media/media_stream_messages.h"
14 #include "content/public/common/content_switches.h" 15 #include "content/public/common/content_switches.h"
15 #include "content/public/common/renderer_preferences.h" 16 #include "content/public/common/renderer_preferences.h"
16 #include "content/renderer/media/media_stream.h" 17 #include "content/renderer/media/media_stream.h"
17 #include "content/renderer/media/media_stream_audio_processor.h" 18 #include "content/renderer/media/media_stream_audio_processor.h"
18 #include "content/renderer/media/media_stream_audio_processor_options.h" 19 #include "content/renderer/media/media_stream_audio_processor_options.h"
19 #include "content/renderer/media/media_stream_audio_source.h" 20 #include "content/renderer/media/media_stream_audio_source.h"
20 #include "content/renderer/media/media_stream_video_source.h" 21 #include "content/renderer/media/media_stream_video_source.h"
21 #include "content/renderer/media/media_stream_video_track.h" 22 #include "content/renderer/media/media_stream_video_track.h"
22 #include "content/renderer/media/peer_connection_identity_store.h" 23 #include "content/renderer/media/peer_connection_identity_store.h"
23 #include "content/renderer/media/rtc_media_constraints.h" 24 #include "content/renderer/media/rtc_media_constraints.h"
24 #include "content/renderer/media/rtc_peer_connection_handler.h" 25 #include "content/renderer/media/rtc_peer_connection_handler.h"
25 #include "content/renderer/media/rtc_video_decoder_factory.h" 26 #include "content/renderer/media/rtc_video_decoder_factory.h"
26 #include "content/renderer/media/rtc_video_encoder_factory.h" 27 #include "content/renderer/media/rtc_video_encoder_factory.h"
27 #include "content/renderer/media/webaudio_capturer_source.h" 28 #include "content/renderer/media/webaudio_capturer_source.h"
28 #include "content/renderer/media/webrtc/stun_field_trial.h" 29 #include "content/renderer/media/webrtc/stun_field_trial.h"
29 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" 30 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h"
30 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" 31 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h"
31 #include "content/renderer/media/webrtc_audio_device_impl.h" 32 #include "content/renderer/media/webrtc_audio_device_impl.h"
32 #include "content/renderer/media/webrtc_local_audio_track.h" 33 #include "content/renderer/media/webrtc_local_audio_track.h"
33 #include "content/renderer/media/webrtc_logging.h" 34 #include "content/renderer/media/webrtc_logging.h"
34 #include "content/renderer/media/webrtc_uma_histograms.h" 35 #include "content/renderer/media/webrtc_uma_histograms.h"
36 #include "content/renderer/p2p/empty_network_manager.h"
37 #include "content/renderer/p2p/filtering_network_manager.h"
35 #include "content/renderer/p2p/ipc_network_manager.h" 38 #include "content/renderer/p2p/ipc_network_manager.h"
36 #include "content/renderer/p2p/ipc_socket_factory.h" 39 #include "content/renderer/p2p/ipc_socket_factory.h"
37 #include "content/renderer/p2p/port_allocator.h" 40 #include "content/renderer/p2p/port_allocator.h"
41 #include "content/renderer/render_frame_impl.h"
38 #include "content/renderer/render_thread_impl.h" 42 #include "content/renderer/render_thread_impl.h"
39 #include "content/renderer/render_view_impl.h" 43 #include "content/renderer/render_view_impl.h"
40 #include "jingle/glue/thread_wrapper.h" 44 #include "jingle/glue/thread_wrapper.h"
45 #include "media/base/media_permission.h"
41 #include "media/renderers/gpu_video_accelerator_factories.h" 46 #include "media/renderers/gpu_video_accelerator_factories.h"
42 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" 47 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
43 #include "third_party/WebKit/public/platform/WebMediaStream.h" 48 #include "third_party/WebKit/public/platform/WebMediaStream.h"
44 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" 49 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
45 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 50 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
46 #include "third_party/WebKit/public/platform/WebURL.h" 51 #include "third_party/WebKit/public/platform/WebURL.h"
47 #include "third_party/WebKit/public/web/WebDocument.h" 52 #include "third_party/WebKit/public/web/WebDocument.h"
48 #include "third_party/WebKit/public/web/WebFrame.h" 53 #include "third_party/WebKit/public/web/WebFrame.h"
49 #include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface .h" 54 #include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface .h"
50 55
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 constraints->AddOptional(kConstraintEffectMap[i].constraint, 104 constraints->AddOptional(kConstraintEffectMap[i].constraint,
100 webrtc::MediaConstraintsInterface::kValueFalse, true); 105 webrtc::MediaConstraintsInterface::kValueFalse, true);
101 } 106 }
102 DVLOG(1) << "Disabling constraint: " 107 DVLOG(1) << "Disabling constraint: "
103 << kConstraintEffectMap[i].constraint; 108 << kConstraintEffectMap[i].constraint;
104 } 109 }
105 } 110 }
106 } 111 }
107 } 112 }
108 113
109 class P2PPortAllocatorFactory : public webrtc::PortAllocatorFactoryInterface { 114 class P2PPortAllocatorFactory : public webrtc::PortAllocatorFactoryInterface {
Sergey Ulanov 2015/09/25 18:19:19 I thinks you can just change this to 'public rtc::
110 public: 115 public:
111 P2PPortAllocatorFactory(P2PSocketDispatcher* socket_dispatcher, 116 // |media_permission| has to be pass as ref to avoid an invocation of copy
112 rtc::NetworkManager* network_manager, 117 // constructor inside rtc::RefCountedObject.
Sergey Ulanov 2015/09/25 00:45:31 Not sure what's the problem here. Passing scoped_p
guoweis_left_chromium 2015/09/25 03:42:20 rtc::RefCountedObject is a template as RefCounte
Sergey Ulanov 2015/09/25 18:19:19 I see. So the problem is that rtc::RefCountedOject
113 rtc::PacketSocketFactory* socket_factory, 118 P2PPortAllocatorFactory(
114 const GURL& origin, 119 scoped_ptr<media::MediaPermission>& media_permission,
115 const P2PPortAllocator::Config& config) 120 const scoped_refptr<P2PSocketDispatcher>& socket_dispatcher,
116 : socket_dispatcher_(socket_dispatcher), 121 rtc::NetworkManager* network_manager,
122 rtc::PacketSocketFactory* socket_factory,
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 network_manager.reset(new FilteringNetworkManager(
157 network_manager_, origin_, media_permission_.Pass()));
158 if (media_permission_) {
159 // Start permission check earlier to reduce any impact to call set up
160 // time.
161 task_runner_->PostTask(
162 FROM_HERE, base::Bind(&FilteringNetworkManager::CheckPermissions,
163 static_cast<FilteringNetworkManager*>(
Sergey Ulanov 2015/09/25 00:45:30 Please don't use static_cast to downcast pointers
guoweis_left_chromium 2015/09/25 03:42:20 Done.
164 network_manager.get())
165 ->GetWeakPtr()));
Sergey Ulanov 2015/09/25 00:45:30 You don't need weak_ptr here. The network manager
guoweis_left_chromium 2015/09/25 03:42:20 Done.
166 }
167 } else {
168 network_manager.reset(new EmptyNetworkManager());
169 }
170
171 return new P2PPortAllocator(socket_dispatcher_, network_manager.Pass(),
172 socket_factory_, config, origin_, task_runner_);
145 } 173 }
146 174
147 protected: 175 protected:
148 ~P2PPortAllocatorFactory() override {} 176 ~P2PPortAllocatorFactory() override {
177 if (media_permission_) {
178 task_runner_->DeleteSoon(FROM_HERE, media_permission_.release());
179 }
180 }
149 181
150 private: 182 private:
151 scoped_refptr<P2PSocketDispatcher> socket_dispatcher_; 183 // Ownership of |media_permission_| will be passed to FilteringNetworkManager
152 // |network_manager_| and |socket_factory_| are a weak references, owned by 184 // during CreatePortAllocator.
153 // PeerConnectionDependencyFactory. 185 scoped_ptr<media::MediaPermission> media_permission_;
186
187 const scoped_refptr<P2PSocketDispatcher>& socket_dispatcher_;
154 rtc::NetworkManager* network_manager_; 188 rtc::NetworkManager* network_manager_;
155 rtc::PacketSocketFactory* socket_factory_; 189 rtc::PacketSocketFactory* socket_factory_;
156 // The origin URL of the WebFrame that created the 190 const P2PPortAllocator::Config& config_;
157 // P2PPortAllocatorFactory. 191 const GURL& origin_;
158 GURL origin_;
159 192
160 // Keep track of configuration common to all PortAllocators created by this 193 // This is the worker thread where |media_permission_| and |network_manager_|
161 // factory; additional, per-allocator configuration is passed into 194 // live on.
162 // CreatePortAllocator. 195 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
163 P2PPortAllocator::Config config_;
164 }; 196 };
165 197
166 PeerConnectionDependencyFactory::PeerConnectionDependencyFactory( 198 PeerConnectionDependencyFactory::PeerConnectionDependencyFactory(
167 P2PSocketDispatcher* p2p_socket_dispatcher) 199 P2PSocketDispatcher* p2p_socket_dispatcher)
168 : network_manager_(NULL), 200 : network_manager_(NULL),
169 p2p_socket_dispatcher_(p2p_socket_dispatcher), 201 p2p_socket_dispatcher_(p2p_socket_dispatcher),
170 signaling_thread_(NULL), 202 signaling_thread_(NULL),
171 worker_thread_(NULL), 203 worker_thread_(NULL),
172 chrome_signaling_thread_("Chrome_libJingle_Signaling"), 204 chrome_signaling_thread_("Chrome_libJingle_Signaling"),
173 chrome_worker_thread_("Chrome_libJingle_WorkerThread") { 205 chrome_worker_thread_("Chrome_libJingle_WorkerThread") {
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 CHECK(web_frame); 427 CHECK(web_frame);
396 CHECK(observer); 428 CHECK(observer);
397 if (!GetPcFactory().get()) 429 if (!GetPcFactory().get())
398 return NULL; 430 return NULL;
399 431
400 rtc::scoped_ptr<PeerConnectionIdentityStore> identity_store( 432 rtc::scoped_ptr<PeerConnectionIdentityStore> identity_store(
401 new PeerConnectionIdentityStore( 433 new PeerConnectionIdentityStore(
402 GURL(web_frame->document().url()), 434 GURL(web_frame->document().url()),
403 GURL(web_frame->document().firstPartyForCookies()))); 435 GURL(web_frame->document().firstPartyForCookies())));
404 436
437 // |media_permission| will be called to check mic/camera permission. If at
438 // least one of them is granted, P2PPortAllocator is allowed to gather local
439 // host IP addresses as ICE candidates.
440 // If the experiment is not enabled, turn off the permission check by
441 // passing nullptr to FilteringNetworkManager constructor.
442 scoped_ptr<media::MediaPermission> media_permission;
443 if (base::FieldTrialList::FindFullName("WebRTC-LocalIPPermissionCheck") ==
444 "Enabled") {
445 RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(web_frame);
446 if (render_frame) {
447 media_permission = render_frame->CreateMediaPermissionProxy(
448 chrome_worker_thread_.task_runner());
449 DCHECK(media_permission);
450 }
451 }
452
405 // Copy the flag from Preference associated with this WebFrame. 453 // Copy the flag from Preference associated with this WebFrame.
406 P2PPortAllocator::Config pref_config; 454 P2PPortAllocator::Config port_config;
407 if (web_frame && web_frame->view()) { 455 if (web_frame && web_frame->view()) {
408 RenderViewImpl* renderer_view_impl = 456 RenderViewImpl* renderer_view_impl =
409 RenderViewImpl::FromWebView(web_frame->view()); 457 RenderViewImpl::FromWebView(web_frame->view());
410 if (renderer_view_impl) { 458 if (renderer_view_impl) {
411 pref_config.enable_multiple_routes = 459 // TODO(guoweis): |enable_multiple_routes| should be renamed to
460 // |request_multiple_routes|. Whether local IP addresses could be
461 // collected depends on if mic/camera permission is granted for this
462 // origin.
463 port_config.enable_multiple_routes =
412 renderer_view_impl->renderer_preferences() 464 renderer_view_impl->renderer_preferences()
413 .enable_webrtc_multiple_routes; 465 .enable_webrtc_multiple_routes;
414 pref_config.enable_nonproxied_udp = 466 port_config.enable_nonproxied_udp =
415 renderer_view_impl->renderer_preferences() 467 renderer_view_impl->renderer_preferences()
416 .enable_webrtc_nonproxied_udp; 468 .enable_webrtc_nonproxied_udp;
417 } 469 }
418 } 470 }
419 471
472 const GURL& requesting_origin =
473 GURL(web_frame->document().url().spec()).GetOrigin();
474
420 scoped_refptr<P2PPortAllocatorFactory> pa_factory = 475 scoped_refptr<P2PPortAllocatorFactory> pa_factory =
421 new rtc::RefCountedObject<P2PPortAllocatorFactory>( 476 new rtc::RefCountedObject<P2PPortAllocatorFactory>(
Sergey Ulanov 2015/09/25 18:19:19 this can be 'new P2PPortAllocatorFactory' if P2PPo
422 p2p_socket_dispatcher_.get(), network_manager_, socket_factory_.get(), 477 media_permission.Pass(), p2p_socket_dispatcher_, network_manager_,
423 GURL(web_frame->document().url().spec()).GetOrigin(), pref_config); 478 socket_factory_.get(), port_config, requesting_origin,
479 chrome_worker_thread_.task_runner());
424 480
425 return GetPcFactory()->CreatePeerConnection(config, 481 return GetPcFactory()->CreatePeerConnection(config,
426 constraints, 482 constraints,
427 pa_factory.get(), 483 pa_factory.get(),
428 identity_store.Pass(), 484 identity_store.Pass(),
429 observer).get(); 485 observer).get();
430 } 486 }
431 487
432 scoped_refptr<webrtc::MediaStreamInterface> 488 scoped_refptr<webrtc::MediaStreamInterface>
433 PeerConnectionDependencyFactory::CreateLocalMediaStream( 489 PeerConnectionDependencyFactory::CreateLocalMediaStream(
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 } 737 }
682 738
683 void PeerConnectionDependencyFactory::EnsureWebRtcAudioDeviceImpl() { 739 void PeerConnectionDependencyFactory::EnsureWebRtcAudioDeviceImpl() {
684 if (audio_device_.get()) 740 if (audio_device_.get())
685 return; 741 return;
686 742
687 audio_device_ = new WebRtcAudioDeviceImpl(); 743 audio_device_ = new WebRtcAudioDeviceImpl();
688 } 744 }
689 745
690 } // namespace content 746 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698