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 |