Chromium Code Reviews| 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..54c07730d84a4ed0ce6bbfe44c1e16e91772deab |
| --- /dev/null |
| +++ b/content/renderer/p2p/filtering_network_manager.cc |
| @@ -0,0 +1,166 @@ |
| +// 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" |
| + |
| +namespace content { |
| + |
| +FilteringNetworkManager::FilteringNetworkManager( |
| + rtc::NetworkManager* network_manager, |
| + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| + const GURL& requesting_origin, |
| + scoped_ptr<media::MediaPermission> media_permission) |
| + : network_manager_(network_manager), |
| + task_runner_(task_runner), |
| + media_permission_(media_permission.Pass()), |
| + requesting_origin_(requesting_origin), |
| + weak_ptr_factory_(this) { |
| + 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; |
| + } |
| + |
| + // Start permission check earlier to reduce any impact to call set up time. |
| + pending_permission_checks_ = 2; |
|
Sergey Ulanov
2015/09/24 19:37:28
best to move this to CheckPermissions() where the
guoweis_left_chromium
2015/09/24 23:06:00
This line above (setting the pending checks to 2)
Sergey Ulanov
2015/09/25 00:45:30
StartUpdating() must be called on the same thread
|
| + task_runner_->PostTask(FROM_HERE, |
| + base::Bind(&FilteringNetworkManager::CheckPermissions, |
|
Sergey Ulanov
2015/09/24 19:37:28
Maybe rename CheckPermission() to Initialize() and
guoweis_left_chromium
2015/09/24 23:06:00
I kept the name. Let me know if you feel strong ab
|
| + weak_ptr_factory_.GetWeakPtr())); |
| +} |
| + |
| +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, |
| + weak_ptr_factory_.GetWeakPtr())); |
| + media_permission_->HasPermission( |
| + media::MediaPermission::VIDEO_CAPTURE, requesting_origin_, |
| + base::Bind(&FilteringNetworkManager::OnPermissionStatus, |
| + weak_ptr_factory_.GetWeakPtr())); |
| +} |
| + |
| +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()); |
| + 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 && |
|
Sergey Ulanov
2015/09/24 19:37:28
nit: !pending_permission_checks_
guoweis_left_chromium
2015/09/24 23:06:00
Done.
|
| + 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, |
| + weak_ptr_factory_.GetWeakPtr())); |
| + |
| + sent_first_update_ = true; |
| + received_networks_changed_since_last_firing_ = false; |
| +} |
| + |
| +void FilteringNetworkManager::SendNetworksChangedSignal() { |
| + SignalNetworksChanged(); |
| +} |
| + |
| +} // namespace content |