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

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: 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..8d507d225e0d1cbaac58879af5773e7e352ff2c9
--- /dev/null
+++ b/content/renderer/p2p/filtering_network_manager.cc
@@ -0,0 +1,175 @@
+// 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 "content/renderer/media/media_permission_dispatcher_proxy.h"
Sergey Ulanov 2015/09/21 22:12:58 I don't see this being used anywhere
guoweis_left_chromium 2015/09/22 17:56:56 Done.
+
+namespace content {
+
+FilteringNetworkManager::Params::Params(
+ rtc::NetworkManager* network_manager,
+ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+ const GURL& requesting_origin)
+ : network_manager(network_manager),
+ task_runner(task_runner),
+ requesting_origin(requesting_origin) {}
+
+FilteringNetworkManager::Params::~Params() {}
+
+FilteringNetworkManager::FilteringNetworkManager(
+ const Params& params,
+ scoped_ptr<media::MediaPermission> media_permission)
+ : network_manager_(params.network_manager),
+ task_runner_(params.task_runner),
+ media_permission_(media_permission.Pass()),
+ requesting_origin_(params.requesting_origin) {
+ set_enumeration_permission(ENUMERATION_BLOCKED);
+
+ // If the feature is not enabled, just return ALLOWED as it's requested.
+ if (!media_permission_) {
+ set_enumeration_permission(ENUMERATION_ALLOWED);
+ return;
+ }
+ pending_permission_checks_ = 2;
+ task_runner_->PostTask(FROM_HERE,
Sergey Ulanov 2015/09/21 22:12:58 Is it possible to call CheckPermissions() the firs
guoweis_left_chromium 2015/09/22 17:56:56 Problem with that approach is it serializes the pe
+ base::Bind(&FilteringNetworkManager::CheckPermissions,
+ base::AsWeakPtr(this)));
+}
+
+void FilteringNetworkManager::CheckPermissions() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ // Request for media permission asynchronously.
+ media_permission_->HasPermission(
+ media::MediaPermission::AUDIO_CAPTURE, requesting_origin_,
+ base::Bind(&FilteringNetworkManager::OnPermissionStatus,
+ base::AsWeakPtr(this)));
+ media_permission_->HasPermission(
+ media::MediaPermission::VIDEO_CAPTURE, requesting_origin_,
+ base::Bind(&FilteringNetworkManager::OnPermissionStatus,
+ base::AsWeakPtr(this)));
+}
+
+FilteringNetworkManager::~FilteringNetworkManager() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ // This helps to catch the case if permission never comes back.
+ if (!start_updating_time_.is_null())
+ ReportMetrics(false);
+}
+
+void FilteringNetworkManager::StartUpdating() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+
+ 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(task_runner_->BelongsToCurrentThread());
+ network_manager_->StopUpdating();
+ DCHECK_GT(start_count_, 0);
+ --start_count_;
+}
+
+void FilteringNetworkManager::GetNetworks(NetworkList* networks) const {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ if (!networks)
Sergey Ulanov 2015/09/21 22:12:58 I don't think you need this check. This method is
guoweis_left_chromium 2015/09/22 17:56:56 Done.
+ return;
+
+ networks->clear();
+
+ if (GetIPPermissionStatus() == PERMISSION_GRANTED)
+ network_manager_->GetNetworks(networks);
+}
+
+void FilteringNetworkManager::OnPermissionStatus(bool granted) {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ 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(task_runner_->BelongsToCurrentThread());
+ 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)
+ ReportTimeToUpdateNetwork(base::TimeTicks::Now() - start_updating_time_);
+
+ ReportIPPermissionStatus(GetIPPermissionStatus());
+}
+
+IPPermissionStatus FilteringNetworkManager::GetIPPermissionStatus() const {
+ if (enumeration_permission() == ENUMERATION_ALLOWED)
+ return PERMISSION_GRANTED;
+
+ if (pending_permission_checks_ == 0 &&
+ 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_ == 0)
+ return;
+
+ ReportMetrics(true);
+
+ // Post a task to avoid reentrancy.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&FilteringNetworkManager::SendNetworksChangedSignal,
+ AsWeakPtr()));
+
+ sent_first_update_ = true;
+ received_networks_changed_since_last_firing_ = false;
+}
+
+void FilteringNetworkManager::SendNetworksChangedSignal() {
+ SignalNetworksChanged();
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698