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

Unified Diff: content/renderer/p2p/filtering_network_manager.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: rebase, fix test issue, fix windows build issue. Created 5 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: content/renderer/p2p/filtering_network_manager.cc
diff --git a/content/renderer/p2p/filtering_network_manager.cc b/content/renderer/p2p/filtering_network_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..23c10c28c202c676c03feb7d79a46b115ae92abf
--- /dev/null
+++ b/content/renderer/p2p/filtering_network_manager.cc
@@ -0,0 +1,170 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/p2p/filtering_network_manager.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/thread_task_runner_handle.h"
+#include "media/base/media_permission.h"
+
+namespace content {
+
+FilteringNetworkManager::FilteringNetworkManager(
+ rtc::NetworkManager* network_manager,
+ const GURL& requesting_origin,
+ scoped_ptr<media::MediaPermission> media_permission)
+ : network_manager_(network_manager),
+ media_permission_(media_permission.Pass()),
+ requesting_origin_(requesting_origin),
+ weak_ptr_factory_(this) {
+ thread_checker_.DetachFromThread();
+ set_enumeration_permission(ENUMERATION_BLOCKED);
+
+ // If the feature is not enabled, just return ALLOWED as it's requested.
+ if (!media_permission_) {
+ initialized_ = true;
+ set_enumeration_permission(ENUMERATION_ALLOWED);
+ return;
+ }
+}
+
+void FilteringNetworkManager::Initialize() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!initialized_);
+
+ initialized_ = true;
+ pending_permission_checks_ = 2;
+
+ // Request for media permission asynchronously.
+ media_permission_->HasPermission(
+ media::MediaPermission::AUDIO_CAPTURE, requesting_origin_,
+ base::Bind(&FilteringNetworkManager::OnPermissionStatus, GetWeakPtr()));
+ media_permission_->HasPermission(
+ media::MediaPermission::VIDEO_CAPTURE, requesting_origin_,
+ base::Bind(&FilteringNetworkManager::OnPermissionStatus, GetWeakPtr()));
+}
+
+FilteringNetworkManager::~FilteringNetworkManager() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ // This helps to catch the case if permission never comes back.
+ if (!start_updating_time_.is_null())
+ ReportMetrics(false);
+}
+
+base::WeakPtr<FilteringNetworkManager> FilteringNetworkManager::GetWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
+}
+
+void FilteringNetworkManager::StartUpdating() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(initialized_);
+
+ if (start_updating_time_.is_null()) {
+ start_updating_time_ = base::TimeTicks::Now();
+ network_manager_->SignalNetworksChanged.connect(
+ this, &FilteringNetworkManager::OnNetworksChanged);
+ }
+
+ network_manager_->StartUpdating();
+ ++start_count_;
+
+ if (sent_first_update_ || should_fire_event())
+ FireEventIfStarted();
+}
+
+void FilteringNetworkManager::StopUpdating() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ network_manager_->StopUpdating();
+ DCHECK_GT(start_count_, 0);
+ --start_count_;
+}
+
+void FilteringNetworkManager::GetNetworks(NetworkList* networks) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ networks->clear();
+
+ if (GetIPPermissionStatus() == PERMISSION_GRANTED)
+ network_manager_->GetNetworks(networks);
+}
+
+void FilteringNetworkManager::OnPermissionStatus(bool granted) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_GT(pending_permission_checks_, 0);
+
+ --pending_permission_checks_;
+
+ if (granted)
+ set_enumeration_permission(ENUMERATION_ALLOWED);
+
+ if (should_fire_event())
+ FireEventIfStarted();
+}
+
+void FilteringNetworkManager::OnNetworksChanged() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ received_networks_changed_since_last_firing_ = true;
+ if (GetIPPermissionStatus() == PERMISSION_GRANTED)
+ FireEventIfStarted();
+}
+
+void FilteringNetworkManager::ReportMetrics(bool report_start_latency) {
+ if (sent_first_update_)
+ return;
+
+ if (report_start_latency)
+ ReportTimeToUpdateNetworkList(base::TimeTicks::Now() -
+ start_updating_time_);
+
+ ReportIPPermissionStatus(GetIPPermissionStatus());
+}
+
+IPPermissionStatus FilteringNetworkManager::GetIPPermissionStatus() const {
+ if (enumeration_permission() == ENUMERATION_ALLOWED)
+ return PERMISSION_GRANTED;
+
+ if (!pending_permission_checks_ &&
+ enumeration_permission() == ENUMERATION_BLOCKED) {
+ return PERMISSION_DENIED;
+ }
+
+ return PERMISSION_UNKNOWN;
+}
+
+bool FilteringNetworkManager::should_fire_event() const {
+ // We should signal network changes when the permisison is denied and we have
+ // never fired any SignalNetworksChanged. Or 2) permission is granted and we
+ // have received new SignalNetworksChanged from |network_manager_| yet to
+ // be broadcast.
+ bool permission_blocked_but_never_fired =
+ (GetIPPermissionStatus() == PERMISSION_DENIED) && !sent_first_update_;
+ bool permission_allowed_pending_networks_update =
+ (GetIPPermissionStatus() == PERMISSION_GRANTED) &&
+ received_networks_changed_since_last_firing_;
+
+ return permission_blocked_but_never_fired ||
+ permission_allowed_pending_networks_update;
+}
+
+void FilteringNetworkManager::FireEventIfStarted() {
+ if (!start_count_)
+ return;
+
+ ReportMetrics(true);
+
+ // Post a task to avoid reentrancy.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&FilteringNetworkManager::SendNetworksChangedSignal,
+ GetWeakPtr()));
+
+ sent_first_update_ = true;
+ received_networks_changed_since_last_firing_ = false;
+}
+
+void FilteringNetworkManager::SendNetworksChangedSignal() {
+ SignalNetworksChanged();
+}
+
+} // namespace content
« no previous file with comments | « content/renderer/p2p/filtering_network_manager.h ('k') | content/renderer/p2p/filtering_network_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698