Commit 86b39222 authored by Tarun Bansal's avatar Tarun Bansal Committed by Commit Bot

Network servicification of NQE in content.

Servicify Network Quality Estimator (NQE) in content. This CL
replaces NQE APIs by Network Quality Tracker (NQT). The
latter works with network servicification enabled as well.

The NQE/NQT APIs in content are used to send network quality change
notifications to the renderer process. These are eventually
consumed by Blink as well as exposed to Web via NetInfo.

This CL also adds a Chrome browser test for the NetInfo API.

Cq-Include-Trybots: luci.chromium.try:linux_mojo
Change-Id: Ib8c0f9b1742d3c1eb3dbefe8d891c06c4e986492
Bug: 883010
Reviewed-on: https://chromium-review.googlesource.com/1214603Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Reviewed-by: default avatarRyan Sturm <ryansturm@chromium.org>
Commit-Queue: Tarun Bansal <tbansal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593051}
parent 17dd68a5
...@@ -118,6 +118,7 @@ ...@@ -118,6 +118,7 @@
#include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/network_quality_observer_factory.h"
#include "content/public/browser/network_service_instance.h" #include "content/public/browser/network_service_instance.h"
#include "content/public/browser/notification_details.h" #include "content/public/browser/notification_details.h"
#include "content/public/browser/plugin_service.h" #include "content/public/browser/plugin_service.h"
...@@ -135,7 +136,6 @@ ...@@ -135,7 +136,6 @@
#include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_context_getter.h"
#include "ppapi/buildflags/buildflags.h" #include "ppapi/buildflags/buildflags.h"
#include "printing/buildflags/buildflags.h" #include "printing/buildflags/buildflags.h"
#include "services/network/public/cpp/network_quality_tracker.h"
#include "services/network/public/cpp/network_switches.h" #include "services/network/public/cpp/network_switches.h"
#include "services/preferences/public/cpp/in_process_service_factory.h" #include "services/preferences/public/cpp/in_process_service_factory.h"
#include "ui/base/idle/idle.h" #include "ui/base/idle/idle.h"
...@@ -1084,6 +1084,13 @@ void BrowserProcessImpl::OnKeepAliveStateChanged(bool is_keeping_alive) { ...@@ -1084,6 +1084,13 @@ void BrowserProcessImpl::OnKeepAliveStateChanged(bool is_keeping_alive) {
Unpin(); Unpin();
} }
void BrowserProcessImpl::CreateNetworkQualityObserver() {
DCHECK(!network_quality_observer_);
network_quality_observer_ =
content::CreateNetworkQualityObserver(network_quality_tracker());
DCHECK(network_quality_observer_);
}
void BrowserProcessImpl::OnKeepAliveRestartStateChanged(bool can_restart) {} void BrowserProcessImpl::OnKeepAliveRestartStateChanged(bool can_restart) {}
void BrowserProcessImpl::CreateWatchdogThread() { void BrowserProcessImpl::CreateWatchdogThread() {
...@@ -1228,6 +1235,8 @@ void BrowserProcessImpl::PreMainMessageLoopRun() { ...@@ -1228,6 +1235,8 @@ void BrowserProcessImpl::PreMainMessageLoopRun() {
base::WrapUnique(new base::DefaultTickClock()), local_state(), base::WrapUnique(new base::DefaultTickClock()), local_state(),
system_network_context_manager()->GetSharedURLLoaderFactory()); system_network_context_manager()->GetSharedURLLoaderFactory());
} }
CreateNetworkQualityObserver();
} }
void BrowserProcessImpl::CreateIconManager() { void BrowserProcessImpl::CreateIconManager() {
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "media/media_buildflags.h" #include "media/media_buildflags.h"
#include "ppapi/buildflags/buildflags.h" #include "ppapi/buildflags/buildflags.h"
#include "printing/buildflags/buildflags.h" #include "printing/buildflags/buildflags.h"
#include "services/network/public/cpp/network_quality_tracker.h"
#include "services/network/public/mojom/network_service.mojom.h" #include "services/network/public/mojom/network_service.mojom.h"
class ChromeChildProcessWatcher; class ChromeChildProcessWatcher;
...@@ -199,6 +200,10 @@ class BrowserProcessImpl : public BrowserProcess, ...@@ -199,6 +200,10 @@ class BrowserProcessImpl : public BrowserProcess,
void OnKeepAliveStateChanged(bool is_keeping_alive) override; void OnKeepAliveStateChanged(bool is_keeping_alive) override;
void OnKeepAliveRestartStateChanged(bool can_restart) override; void OnKeepAliveRestartStateChanged(bool can_restart) override;
// Create network quality observer so that it can propagate network quality
// changes to the render process.
void CreateNetworkQualityObserver();
void CreateWatchdogThread(); void CreateWatchdogThread();
void CreateProfileManager(); void CreateProfileManager();
void CreateLocalState(); void CreateLocalState();
...@@ -255,6 +260,12 @@ class BrowserProcessImpl : public BrowserProcess, ...@@ -255,6 +260,12 @@ class BrowserProcessImpl : public BrowserProcess,
std::unique_ptr<network::NetworkQualityTracker> network_quality_tracker_; std::unique_ptr<network::NetworkQualityTracker> network_quality_tracker_;
// Listens to NetworkQualityTracker and sends network quality updates to the
// renderer.
std::unique_ptr<
network::NetworkQualityTracker::RTTAndThroughputEstimatesObserver>
network_quality_observer_;
bool created_icon_manager_ = false; bool created_icon_manager_ = false;
std::unique_ptr<IconManager> icon_manager_; std::unique_ptr<IconManager> icon_manager_;
......
...@@ -52,7 +52,6 @@ ...@@ -52,7 +52,6 @@
#include "components/version_info/version_info.h" #include "components/version_info/version_info.h"
#include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/network_quality_observer_factory.h"
#include "content/public/browser/network_service_instance.h" #include "content/public/browser/network_service_instance.h"
#include "content/public/common/content_features.h" #include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
...@@ -487,11 +486,6 @@ void IOThread::ConstructSystemRequestContext() { ...@@ -487,11 +486,6 @@ void IOThread::ConstructSystemRequestContext() {
network_service->ConfigureStubHostResolver( network_service->ConfigureStubHostResolver(
stub_resolver_enabled_, std::move(dns_over_https_servers_)); stub_resolver_enabled_, std::move(dns_over_https_servers_));
} }
// TODO(mmenke): This class currently requires an in-process
// NetworkQualityEstimator. Fix that.
globals_->network_quality_observer = content::CreateNetworkQualityObserver(
globals_->system_request_context->network_quality_estimator());
} }
metrics::UpdateUsagePrefCallbackType IOThread::GetMetricsDataUseForwarder() { metrics::UpdateUsagePrefCallbackType IOThread::GetMetricsDataUseForwarder() {
......
...@@ -53,7 +53,6 @@ namespace net { ...@@ -53,7 +53,6 @@ namespace net {
class CertVerifier; class CertVerifier;
class HostResolver; class HostResolver;
class NetworkQualityEstimator; class NetworkQualityEstimator;
class RTTAndThroughputEstimatesObserver;
class URLRequestContext; class URLRequestContext;
class URLRequestContextGetter; class URLRequestContextGetter;
} // namespace net } // namespace net
...@@ -109,9 +108,6 @@ class IOThread : public content::BrowserThreadDelegate { ...@@ -109,9 +108,6 @@ class IOThread : public content::BrowserThreadDelegate {
// URLRequestContext when network service is enabled. // URLRequestContext when network service is enabled.
std::unique_ptr<net::HostResolver> deprecated_host_resolver; std::unique_ptr<net::HostResolver> deprecated_host_resolver;
std::unique_ptr<net::RTTAndThroughputEstimatesObserver>
network_quality_observer;
// When the network service is enabled, this holds on to a // When the network service is enabled, this holds on to a
// content::NetworkContext class that owns |system_request_context|. // content::NetworkContext class that owns |system_request_context|.
std::unique_ptr<network::mojom::NetworkContext> system_network_context; std::unique_ptr<network::mojom::NetworkContext> system_network_context;
......
file://net/OWNERS file://net/OWNERS
per-file disk_cache_dir_policy_handler*=atwilson@chromium.org per-file disk_cache_dir_policy_handler*=atwilson@chromium.org
per-file network_quality*=file://net/nqe/OWNERS
# COMPONENT: Internals>Network # COMPONENT: Internals>Network
...@@ -129,6 +129,22 @@ class NetInfoNetworkQualityEstimatorHoldbackBrowserTest ...@@ -129,6 +129,22 @@ class NetInfoNetworkQualityEstimatorHoldbackBrowserTest
if (network_service_enabled_) { if (network_service_enabled_) {
g_browser_process->network_quality_tracker() g_browser_process->network_quality_tracker()
->ReportEffectiveConnectionTypeForTesting(type); ->ReportEffectiveConnectionTypeForTesting(type);
// Values taken from net/nqe/network_quality_estimator_params.h.
// TODO(tbansal): Declare the values in a common place, and read
// them directly.
if (type == net::EFFECTIVE_CONNECTION_TYPE_3G) {
g_browser_process->network_quality_tracker()
->ReportRTTsAndThroughputForTesting(
base::TimeDelta::FromMilliseconds(450), 400);
} else if (type == net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G) {
g_browser_process->network_quality_tracker()
->ReportRTTsAndThroughputForTesting(
base::TimeDelta::FromMilliseconds(3600), 40);
} else {
NOTREACHED();
}
return;
} }
base::PostTaskWithTraits( base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::IO}, FROM_HERE, {content::BrowserThread::IO},
......
// Copyright 2018 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 <string>
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_base.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "net/nqe/effective_connection_type.h"
#include "services/network/test/test_network_quality_tracker.h"
namespace {
void VerifyDownlinkKbps(double expected_kbps, double got_kbps) {
// First verify that |got_kbps| is a multiple of 50.
int quotient = static_cast<int>(got_kbps / 50);
// |mod| is the remainder left after dividing |got_kbps| by 50 while
// restricting the quotient to integer. For example, if |got_kbps| is
// 1050, then mod will be 0. If |got_kbps| is 1030, mod will be 30.
double mod = got_kbps - 50 * quotient;
EXPECT_LE(0.0, mod);
EXPECT_GT(50.0, mod);
// It is possible that |mod| is not exactly 0 because of floating point
// computations. e.g., |got_kbps| may be 99.999999, in which case |mod|
// will be 49.999999.
EXPECT_TRUE(mod < (1e-5) || (50 - mod) < 1e-5) << " got_kbps=" << got_kbps;
if (expected_kbps > 10000)
expected_kbps = 10000;
// The difference between the actual and the estimate value should be within
// 10%. Add 50 (bucket size used in Blink) to account for the cases when the
// sample may spill over to the next bucket due to the added noise of 10%.
// For example, if sample is 300 kbps, after adding noise, it may become 330,
// and after rounding off, it would spill over to the next bucket of 350 kbps.
EXPECT_GE((expected_kbps * 0.1) + 50, std::abs(expected_kbps - got_kbps))
<< " expected_kbps=" << expected_kbps << " got_kbps=" << got_kbps;
}
} // namespace
class NetInfoBrowserTest : public InProcessBrowserTest {
public:
network::NetworkQualityTracker* GetNetworkQualityTracker() const {
return g_browser_process->network_quality_tracker();
}
protected:
void SetUpOnMainThread() override {}
// Runs |script| repeatedly until the |script| returns |expected_value|.
void RunScriptUntilExpectedStringValueMet(const std::string& script,
const std::string& expected_value) {
while (true) {
if (RunScriptExtractString(script) == expected_value)
return;
base::RunLoop().RunUntilIdle();
}
}
// Repeatedly runs NetInfo JavaScript API to get RTT until it returns
// |expected_rtt|.
void RunGetRttUntilExpectedValueReached(base::TimeDelta expected_rtt) {
if (expected_rtt > base::TimeDelta::FromMilliseconds(3000))
expected_rtt = base::TimeDelta::FromMilliseconds(3000);
while (true) {
int32_t got_rtt_milliseconds = RunScriptExtractInt("getRtt()");
EXPECT_EQ(0, got_rtt_milliseconds % 50)
<< " got_rtt_milliseconds=" << got_rtt_milliseconds;
// The difference between the actual and the estimate value should be
// within 10%. Add 50 (bucket size used in Blink) to account for the cases
// when the sample may spill over to the next bucket due to the added
// noise of 10%. For example, if sample is 300 msec, after adding noise,
// it may become 330, and after rounding off, it would spill over to the
// next bucket of 350 msec.
if (expected_rtt.InMilliseconds() * 0.1 + 50 >=
std::abs(expected_rtt.InMilliseconds() - got_rtt_milliseconds)) {
return;
}
}
}
double RunScriptExtractDouble(const std::string& script) {
double data = 0.0;
EXPECT_TRUE(ExecuteScriptAndExtractDouble(
browser()->tab_strip_model()->GetActiveWebContents(), script, &data));
return data;
}
private:
std::string RunScriptExtractString(const std::string& script) {
std::string data;
EXPECT_TRUE(ExecuteScriptAndExtractString(
browser()->tab_strip_model()->GetActiveWebContents(), script, &data));
return data;
}
int RunScriptExtractInt(const std::string& script) {
int data = 0;
EXPECT_TRUE(ExecuteScriptAndExtractInt(
browser()->tab_strip_model()->GetActiveWebContents(), script, &data));
return data;
}
};
// Make sure the changes in the effective connection type are notified to the
// render thread.
IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest,
EffectiveConnectionTypeChangeNotfied) {
embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
EXPECT_TRUE(embedded_test_server()->Start());
ui_test_utils::NavigateToURL(
browser(), embedded_test_server()->GetURL("/net_info.html"));
// Change effective connection type so that the renderer process is notified.
// Changing the effective connection type from 2G to 3G is guaranteed to
// generate the notification to the renderers, irrespective of the current
// effective connection type.
GetNetworkQualityTracker()->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_2G);
RunScriptUntilExpectedStringValueMet("getEffectiveType()", "2g");
GetNetworkQualityTracker()->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_3G);
RunScriptUntilExpectedStringValueMet("getEffectiveType()", "3g");
}
// Make sure the changes in the network quality are notified to the render
// thread, and the changed network quality is accessible via Javascript API.
IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityChangeNotified) {
GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
base::TimeDelta::FromSeconds(1), 300);
embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
EXPECT_TRUE(embedded_test_server()->Start());
ui_test_utils::NavigateToURL(
browser(), embedded_test_server()->GetURL("/net_info.html"));
RunGetRttUntilExpectedValueReached(base::TimeDelta::FromSeconds(1));
// If the updated RTT is available via JavaScript, then downlink must have
// been updated too.
VerifyDownlinkKbps(300, RunScriptExtractDouble("getDownlink()") * 1000);
// Verify that the network quality change is accessible via Javascript API.
GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
base::TimeDelta::FromSeconds(10), 3000);
RunGetRttUntilExpectedValueReached(base::TimeDelta::FromSeconds(10));
VerifyDownlinkKbps(3000, RunScriptExtractDouble("getDownlink()") * 1000);
}
...@@ -666,6 +666,7 @@ test("browser_tests") { ...@@ -666,6 +666,7 @@ test("browser_tests") {
"../browser/net/netinfo_network_quality_estimator_holdback_browsertest.cc", "../browser/net/netinfo_network_quality_estimator_holdback_browsertest.cc",
"../browser/net/network_connection_tracker_browsertest.cc", "../browser/net/network_connection_tracker_browsertest.cc",
"../browser/net/network_context_configuration_browsertest.cc", "../browser/net/network_context_configuration_browsertest.cc",
"../browser/net/network_quality_netinfo_browsertest.cc",
"../browser/net/network_quality_tracker_browsertest.cc", "../browser/net/network_quality_tracker_browsertest.cc",
"../browser/net/network_request_metrics_browsertest.cc", "../browser/net/network_request_metrics_browsertest.cc",
"../browser/net/nqe/ui_network_quality_estimator_service_browsertest.cc", "../browser/net/nqe/ui_network_quality_estimator_service_browsertest.cc",
......
...@@ -5,17 +5,14 @@ ...@@ -5,17 +5,14 @@
#include "content/browser/net/network_quality_observer_impl.h" #include "content/browser/net/network_quality_observer_impl.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/task/post_task.h" #include "content/common/renderer.mojom.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/common/view_messages.h" #include "content/common/view_messages.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_observer.h" #include "content/public/browser/network_quality_observer_factory.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h" #include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h" #include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "net/nqe/network_quality_estimator.h"
namespace { namespace {
...@@ -59,121 +56,22 @@ bool MetricChangedMeaningfully(int32_t past_value, int32_t current_value) { ...@@ -59,121 +56,22 @@ bool MetricChangedMeaningfully(int32_t past_value, int32_t current_value) {
namespace content { namespace content {
// UiThreadObserver observes the changes to the network quality on the UI
// thread, and notifies the renderers of the change in the network quality.
class NetworkQualityObserverImpl::UiThreadObserver
: public content::NotificationObserver {
public:
UiThreadObserver()
: last_notified_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) {}
~UiThreadObserver() override {
if (!registrar_.IsRegistered(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
NotificationService::AllSources())) {
return;
}
registrar_.Remove(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
NotificationService::AllSources());
}
void InitOnUIThread() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
NotificationService::AllSources());
}
void OnEffectiveConnectionTypeChanged(net::EffectiveConnectionType type) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (last_notified_type_ == type)
return;
last_notified_type_ = type;
// Notify all the existing renderers of the change in the network quality.
for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
!it.IsAtEnd(); it.Advance()) {
if (it.GetCurrentValue()->IsInitializedAndNotDead()) {
it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
last_notified_type_, last_notified_network_quality_.http_rtt(),
last_notified_network_quality_.transport_rtt(),
last_notified_network_quality_.downstream_throughput_kbps());
}
}
}
void OnRTTOrThroughputEstimatesComputed(
const net::nqe::internal::NetworkQuality& network_quality) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
last_notified_network_quality_ = network_quality;
// Notify all the existing renderers of the change in the network quality.
for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
!it.IsAtEnd(); it.Advance()) {
if (it.GetCurrentValue()->IsInitializedAndNotDead()) {
it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
last_notified_type_, last_notified_network_quality_.http_rtt(),
last_notified_network_quality_.transport_rtt(),
last_notified_network_quality_.downstream_throughput_kbps());
}
}
}
private:
// NotificationObserver implementation:
void Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) override {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(NOTIFICATION_RENDERER_PROCESS_CREATED, type);
RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr();
// Notify the newly created renderer of the current network quality.
rph->GetRendererInterface()->OnNetworkQualityChanged(
last_notified_type_, last_notified_network_quality_.http_rtt(),
last_notified_network_quality_.transport_rtt(),
last_notified_network_quality_.downstream_throughput_kbps());
}
content::NotificationRegistrar registrar_;
// The network quality that was last sent to the renderers.
net::EffectiveConnectionType last_notified_type_;
net::nqe::internal::NetworkQuality last_notified_network_quality_;
DISALLOW_COPY_AND_ASSIGN(UiThreadObserver);
};
NetworkQualityObserverImpl::NetworkQualityObserverImpl( NetworkQualityObserverImpl::NetworkQualityObserverImpl(
net::NetworkQualityEstimator* network_quality_estimator) network::NetworkQualityTracker* network_quality_tracker)
: network_quality_estimator_(network_quality_estimator), : network_quality_tracker_(network_quality_tracker),
last_notified_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) { last_notified_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) {
network_quality_estimator_->AddRTTAndThroughputEstimatesObserver(this); DCHECK_CURRENTLY_ON(BrowserThread::UI);
network_quality_estimator_->AddEffectiveConnectionTypeObserver(this);
registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
ui_thread_observer_ = std::make_unique<UiThreadObserver>(); NotificationService::AllSources());
base::PostTaskWithTraits( network_quality_tracker_->AddRTTAndThroughputEstimatesObserver(this);
FROM_HERE, {BrowserThread::UI}, network_quality_tracker_->AddEffectiveConnectionTypeObserver(this);
base::BindOnce(&UiThreadObserver::InitOnUIThread,
base::Unretained(ui_thread_observer_.get())));
} }
NetworkQualityObserverImpl::~NetworkQualityObserverImpl() { NetworkQualityObserverImpl::~NetworkQualityObserverImpl() {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
network_quality_estimator_->RemoveRTTAndThroughputEstimatesObserver(this); network_quality_tracker_->RemoveRTTAndThroughputEstimatesObserver(this);
network_quality_estimator_->RemoveEffectiveConnectionTypeObserver(this); network_quality_tracker_->RemoveEffectiveConnectionTypeObserver(this);
DCHECK(ui_thread_observer_);
// If possible, delete |ui_thread_observer_| on UI thread.
UiThreadObserver* ui_thread_observer_ptr = ui_thread_observer_.release();
bool posted = BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE,
ui_thread_observer_ptr);
if (!posted)
delete ui_thread_observer_ptr;
} }
void NetworkQualityObserverImpl::OnEffectiveConnectionTypeChanged( void NetworkQualityObserverImpl::OnEffectiveConnectionTypeChanged(
...@@ -185,11 +83,31 @@ void NetworkQualityObserverImpl::OnEffectiveConnectionTypeChanged( ...@@ -185,11 +83,31 @@ void NetworkQualityObserverImpl::OnEffectiveConnectionTypeChanged(
last_notified_type_ = type; last_notified_type_ = type;
base::PostTaskWithTraits( // Notify all the existing renderers of the change in the network quality.
FROM_HERE, {BrowserThread::UI}, for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
base::BindOnce(&UiThreadObserver::OnEffectiveConnectionTypeChanged, !it.IsAtEnd(); it.Advance()) {
base::Unretained(ui_thread_observer_.get()), if (it.GetCurrentValue()->IsInitializedAndNotDead()) {
last_notified_type_)); it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
last_notified_type_, last_notified_network_quality_.http_rtt(),
last_notified_network_quality_.transport_rtt(),
last_notified_network_quality_.downstream_throughput_kbps());
}
}
}
void NetworkQualityObserverImpl::Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK_EQ(NOTIFICATION_RENDERER_PROCESS_CREATED, type);
RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr();
// Notify the newly created renderer of the current network quality.
rph->GetRendererInterface()->OnNetworkQualityChanged(
last_notified_type_, last_notified_network_quality_.http_rtt(),
last_notified_network_quality_.transport_rtt(),
last_notified_network_quality_.downstream_throughput_kbps());
} }
void NetworkQualityObserverImpl::OnRTTOrThroughputEstimatesComputed( void NetworkQualityObserverImpl::OnRTTOrThroughputEstimatesComputed(
...@@ -225,18 +143,23 @@ void NetworkQualityObserverImpl::OnRTTOrThroughputEstimatesComputed( ...@@ -225,18 +143,23 @@ void NetworkQualityObserverImpl::OnRTTOrThroughputEstimatesComputed(
last_notified_network_quality_ = net::nqe::internal::NetworkQuality( last_notified_network_quality_ = net::nqe::internal::NetworkQuality(
http_rtt, transport_rtt, downstream_throughput_kbps); http_rtt, transport_rtt, downstream_throughput_kbps);
base::PostTaskWithTraits( // Notify all the existing renderers of the change in the network quality.
FROM_HERE, {BrowserThread::UI}, for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
base::BindOnce(&UiThreadObserver::OnRTTOrThroughputEstimatesComputed, !it.IsAtEnd(); it.Advance()) {
base::Unretained(ui_thread_observer_.get()), if (it.GetCurrentValue()->IsInitializedAndNotDead()) {
last_notified_network_quality_)); it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
last_notified_type_, last_notified_network_quality_.http_rtt(),
last_notified_network_quality_.transport_rtt(),
last_notified_network_quality_.downstream_throughput_kbps());
}
}
} }
std::unique_ptr<net::RTTAndThroughputEstimatesObserver> std::unique_ptr<
network::NetworkQualityTracker::RTTAndThroughputEstimatesObserver>
CreateNetworkQualityObserver( CreateNetworkQualityObserver(
net::NetworkQualityEstimator* network_quality_estimator) { network::NetworkQualityTracker* network_quality_tracker) {
return std::make_unique<NetworkQualityObserverImpl>( return std::make_unique<NetworkQualityObserverImpl>(network_quality_tracker);
network_quality_estimator);
} }
} // namespace content } // namespace content
\ No newline at end of file
...@@ -13,31 +13,31 @@ ...@@ -13,31 +13,31 @@
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/public/browser/network_quality_observer_factory.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "net/nqe/effective_connection_type.h" #include "net/nqe/effective_connection_type.h"
#include "net/nqe/effective_connection_type_observer.h"
#include "net/nqe/network_quality.h" #include "net/nqe/network_quality.h"
#include "net/nqe/rtt_throughput_estimates_observer.h" #include "services/network/public/cpp/network_quality_tracker.h"
namespace net {
class NetworkQualityEstimator;
}
namespace content { namespace content {
// Listens for changes to the network quality and manages sending updates to // Listens for changes to the network quality and manages sending updates to
// each RenderProcess via mojo. // each RenderProcess via mojo.
class CONTENT_EXPORT NetworkQualityObserverImpl class CONTENT_EXPORT NetworkQualityObserverImpl
: public net::EffectiveConnectionTypeObserver, : public network::NetworkQualityTracker::EffectiveConnectionTypeObserver,
public net::RTTAndThroughputEstimatesObserver { public network::NetworkQualityTracker::RTTAndThroughputEstimatesObserver,
public content::NotificationObserver {
public: public:
explicit NetworkQualityObserverImpl( explicit NetworkQualityObserverImpl(
net::NetworkQualityEstimator* network_quality_estimator); network::NetworkQualityTracker* network_quality_tracker);
~NetworkQualityObserverImpl() override; ~NetworkQualityObserverImpl() override;
private: private:
class UiThreadObserver; // content::NotificationObserver:
void Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) override;
// net::EffectiveConnectionTypeObserver implementation: // net::EffectiveConnectionTypeObserver implementation:
void OnEffectiveConnectionTypeChanged( void OnEffectiveConnectionTypeChanged(
...@@ -49,20 +49,16 @@ class CONTENT_EXPORT NetworkQualityObserverImpl ...@@ -49,20 +49,16 @@ class CONTENT_EXPORT NetworkQualityObserverImpl
base::TimeDelta transport_rtt, base::TimeDelta transport_rtt,
int32_t downstream_throughput_kbps) override; int32_t downstream_throughput_kbps) override;
// |ui_thread_observer_| is owned by |this|, and interacts with // |network_quality_tracker_| is guaranteed to be non-null during the
// the render processes. It is created on the IO thread but afterwards, should
// only be accessed on the UI thread. |ui_thread_observer_| is guaranteed to
// be non-null during the lifetime of |this|.
std::unique_ptr<UiThreadObserver> ui_thread_observer_;
// |network_quality_estimator_| is guaranteed to be non-null during the
// lifetime of |this|. // lifetime of |this|.
net::NetworkQualityEstimator* network_quality_estimator_; network::NetworkQualityTracker* network_quality_tracker_;
// The network quality when the |ui_thread_observer_| was last notified. // The network quality when the |ui_thread_observer_| was last notified.
net::EffectiveConnectionType last_notified_type_; net::EffectiveConnectionType last_notified_type_;
net::nqe::internal::NetworkQuality last_notified_network_quality_; net::nqe::internal::NetworkQuality last_notified_network_quality_;
content::NotificationRegistrar registrar_;
base::ThreadChecker thread_checker_; base::ThreadChecker thread_checker_;
DISALLOW_COPY_AND_ASSIGN(NetworkQualityObserverImpl); DISALLOW_COPY_AND_ASSIGN(NetworkQualityObserverImpl);
...@@ -70,4 +66,4 @@ class CONTENT_EXPORT NetworkQualityObserverImpl ...@@ -70,4 +66,4 @@ class CONTENT_EXPORT NetworkQualityObserverImpl
} // namespace content } // namespace content
#endif // CONTENT_BROWSER_NET_NETWORK_QUALITY_OBSERVER_IMPL_H_ #endif // CONTENT_BROWSER_NET_NETWORK_QUALITY_OBSERVER_IMPL_H_
\ No newline at end of file
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_browser_thread_bundle.h"
#include "net/nqe/effective_connection_type.h" #include "net/nqe/effective_connection_type.h"
#include "net/nqe/network_quality_estimator_test_util.h" #include "services/network/test/test_network_quality_tracker.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace content { namespace content {
...@@ -19,25 +19,32 @@ TEST(NetworkQualityObserverImplTest, TestObserverNotified) { ...@@ -19,25 +19,32 @@ TEST(NetworkQualityObserverImplTest, TestObserverNotified) {
content::TestBrowserThreadBundle thread_bundle( content::TestBrowserThreadBundle thread_bundle(
content::TestBrowserThreadBundle::Options::IO_MAINLOOP); content::TestBrowserThreadBundle::Options::IO_MAINLOOP);
net::TestNetworkQualityEstimator estimator; network::TestNetworkQualityTracker test_network_quality_tracker;
estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(1));
NetworkQualityObserverImpl impl(&test_network_quality_tracker);
test_network_quality_tracker.ReportRTTsAndThroughputForTesting(
base::TimeDelta::FromMilliseconds(1), 100);
NetworkQualityObserverImpl observer(&estimator);
// Give a chance for |observer| to register with the |estimator|.
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
base::HistogramTester histogram_tester; base::HistogramTester histogram_tester;
estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(500));
test_network_quality_tracker.ReportRTTsAndThroughputForTesting(
base::TimeDelta::FromMilliseconds(500), 100);
// RTT changed from 1 msec to 500 msec. // RTT changed from 1 msec to 500 msec.
histogram_tester.ExpectBucketCount( histogram_tester.ExpectBucketCount(
"NQE.ContentObserver.NetworkQualityMeaningfullyChanged", 1, 1); "NQE.ContentObserver.NetworkQualityMeaningfullyChanged", 1, 1);
estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(625)); test_network_quality_tracker.ReportRTTsAndThroughputForTesting(
base::TimeDelta::FromMilliseconds(625), 100);
// RTT changed from 500 msec to 625 msec. // RTT changed from 500 msec to 625 msec.
histogram_tester.ExpectBucketCount( histogram_tester.ExpectBucketCount(
"NQE.ContentObserver.NetworkQualityMeaningfullyChanged", 1, 2); "NQE.ContentObserver.NetworkQualityMeaningfullyChanged", 1, 2);
estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(626)); test_network_quality_tracker.ReportRTTsAndThroughputForTesting(
base::TimeDelta::FromMilliseconds(626), 100);
// RTT changed from 625 msec to 626 msec which is not a meaningful change. // RTT changed from 625 msec to 626 msec which is not a meaningful change.
histogram_tester.ExpectBucketCount( histogram_tester.ExpectBucketCount(
"NQE.ContentObserver.NetworkQualityMeaningfullyChanged", 1, 2); "NQE.ContentObserver.NetworkQualityMeaningfullyChanged", 1, 2);
......
This diff is collapsed.
...@@ -14,18 +14,19 @@ ...@@ -14,18 +14,19 @@
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "net/nqe/rtt_throughput_estimates_observer.h" #include "net/nqe/rtt_throughput_estimates_observer.h"
namespace net { namespace network {
class NetworkQualityEstimator; class NetworkQualityTracker;
} }
namespace content { namespace content {
// Creates network quality observer that listens for changes to the network // Creates network quality observer that listens for changes to the network
// quality and manages sending updates to each RenderProcess. // quality and manages sending updates to each RenderProcess.
CONTENT_EXPORT std::unique_ptr<net::RTTAndThroughputEstimatesObserver> CONTENT_EXPORT std::unique_ptr<
network::NetworkQualityTracker::RTTAndThroughputEstimatesObserver>
CreateNetworkQualityObserver( CreateNetworkQualityObserver(
net::NetworkQualityEstimator* network_quality_estimator); network::NetworkQualityTracker* network_quality_tracker);
} // namespace content } // namespace content
#endif // CONTENT_PUBLIC_BROWSER_NETWORK_QUALITY_OBSERVER_FACTORY_H_ #endif // CONTENT_PUBLIC_BROWSER_NETWORK_QUALITY_OBSERVER_FACTORY_H_
\ No newline at end of file
...@@ -16,6 +16,7 @@ NetworkQualityTracker::NetworkQualityTracker( ...@@ -16,6 +16,7 @@ NetworkQualityTracker::NetworkQualityTracker(
: get_network_service_callback_(callback), : get_network_service_callback_(callback),
effective_connection_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN), effective_connection_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
downlink_bandwidth_kbps_(std::numeric_limits<int32_t>::max()), downlink_bandwidth_kbps_(std::numeric_limits<int32_t>::max()),
network_quality_overridden_for_testing_(false),
binding_(this) { binding_(this) {
InitializeMojoChannel(); InitializeMojoChannel();
DCHECK(binding_.is_bound()); DCHECK(binding_.is_bound());
...@@ -76,9 +77,12 @@ void NetworkQualityTracker::ReportEffectiveConnectionTypeForTesting( ...@@ -76,9 +77,12 @@ void NetworkQualityTracker::ReportEffectiveConnectionTypeForTesting(
net::EffectiveConnectionType effective_connection_type) { net::EffectiveConnectionType effective_connection_type) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
network_quality_overridden_for_testing_ = true;
effective_connection_type_ = effective_connection_type; effective_connection_type_ = effective_connection_type;
for (auto& observer : effective_connection_type_observer_list_) for (auto& observer : effective_connection_type_observer_list_) {
observer.OnEffectiveConnectionTypeChanged(effective_connection_type); observer.OnEffectiveConnectionTypeChanged(effective_connection_type);
}
} }
void NetworkQualityTracker::ReportRTTsAndThroughputForTesting( void NetworkQualityTracker::ReportRTTsAndThroughputForTesting(
...@@ -86,6 +90,8 @@ void NetworkQualityTracker::ReportRTTsAndThroughputForTesting( ...@@ -86,6 +90,8 @@ void NetworkQualityTracker::ReportRTTsAndThroughputForTesting(
int32_t downstream_throughput_kbps) { int32_t downstream_throughput_kbps) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
network_quality_overridden_for_testing_ = true;
http_rtt_ = http_rtt; http_rtt_ = http_rtt;
downlink_bandwidth_kbps_ = downstream_throughput_kbps; downlink_bandwidth_kbps_ = downstream_throughput_kbps;
...@@ -108,6 +114,9 @@ void NetworkQualityTracker::OnNetworkQualityChanged( ...@@ -108,6 +114,9 @@ void NetworkQualityTracker::OnNetworkQualityChanged(
int32_t bandwidth_kbps) { int32_t bandwidth_kbps) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (network_quality_overridden_for_testing_)
return;
// If the RTT values are unavailable, set them to value 0. // If the RTT values are unavailable, set them to value 0.
if (http_rtt < base::TimeDelta()) if (http_rtt < base::TimeDelta())
http_rtt = base::TimeDelta(); http_rtt = base::TimeDelta();
......
...@@ -128,12 +128,14 @@ class COMPONENT_EXPORT(NETWORK_CPP) NetworkQualityTracker ...@@ -128,12 +128,14 @@ class COMPONENT_EXPORT(NETWORK_CPP) NetworkQualityTracker
// Changes effective connection type estimate to the provided value, and // Changes effective connection type estimate to the provided value, and
// reports |effective_connection_type| to all // reports |effective_connection_type| to all
// EffectiveConnectionTypeObservers. // EffectiveConnectionTypeObservers. Calling this also disables all organic
// notifications sent to observers.
void ReportEffectiveConnectionTypeForTesting( void ReportEffectiveConnectionTypeForTesting(
net::EffectiveConnectionType effective_connection_type); net::EffectiveConnectionType effective_connection_type);
// Changes RTT and throughput estimate to the provided estimates, and // Changes RTT and throughput estimate to the provided estimates, and
// reports it to all RTTAndThroughputEstimatesObservers. // reports it to all RTTAndThroughputEstimatesObservers. Calling this also
// disables all organic notifications sent to observers.
void ReportRTTsAndThroughputForTesting(base::TimeDelta http_rtt, void ReportRTTsAndThroughputForTesting(base::TimeDelta http_rtt,
int32_t downstream_throughput_kbps); int32_t downstream_throughput_kbps);
...@@ -167,6 +169,10 @@ class COMPONENT_EXPORT(NETWORK_CPP) NetworkQualityTracker ...@@ -167,6 +169,10 @@ class COMPONENT_EXPORT(NETWORK_CPP) NetworkQualityTracker
base::TimeDelta transport_rtt_; base::TimeDelta transport_rtt_;
int32_t downlink_bandwidth_kbps_; int32_t downlink_bandwidth_kbps_;
// True if network quality has been overridden by tests. If set to true, it
// disables all organic notifications sent to observers.
bool network_quality_overridden_for_testing_;
base::ObserverList<EffectiveConnectionTypeObserver>::Unchecked base::ObserverList<EffectiveConnectionTypeObserver>::Unchecked
effective_connection_type_observer_list_; effective_connection_type_observer_list_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment