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

Unified Diff: content/browser/net/network_quality_observer_impl.cc

Issue 2857093002: Expose changes in the network quality to the renderers (Closed)
Patch Set: isherman comments Created 3 years, 7 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
« no previous file with comments | « content/browser/net/network_quality_observer_impl.h ('k') | content/browser/net_info_browsertest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/net/network_quality_observer_impl.cc
diff --git a/content/browser/net/network_quality_observer_impl.cc b/content/browser/net/network_quality_observer_impl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a92ea1a9a5a20d899cb7847286ee663067dc2885
--- /dev/null
+++ b/content/browser/net/network_quality_observer_impl.cc
@@ -0,0 +1,184 @@
+// Copyright 2017 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/browser/net/network_quality_observer_impl.h"
+
+#include "base/memory/ptr_util.h"
+#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/common/view_messages.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/browser/render_process_host.h"
+
+namespace {
+
+// Returns true if the |current_value| is meaningfully different from the
+// |past_value|.
+bool MetricChangedMeaningfully(int32_t past_value, int32_t current_value) {
+ if ((past_value == net::nqe::internal::INVALID_RTT_THROUGHPUT) !=
+ (current_value == net::nqe::internal::INVALID_RTT_THROUGHPUT)) {
+ return true;
+ }
+
+ if (past_value == net::nqe::internal::INVALID_RTT_THROUGHPUT &&
+ current_value == net::nqe::internal::INVALID_RTT_THROUGHPUT) {
+ return false;
+ }
+
+ // Metric has changed meaningfully only if (i) the difference between the two
+ // values exceed the threshold; and, (ii) the ratio of the values also exceeds
+ // the threshold.
+ static const int kMinDifferenceInMetrics = 100;
+ static const float kMinRatio = 1.2f;
+
+ if (std::abs(past_value - current_value) < kMinDifferenceInMetrics) {
+ // The absolute change in the value is not sufficient enough.
+ return false;
+ }
+
+ if (past_value < (kMinRatio * current_value) &&
+ current_value < (kMinRatio * past_value)) {
+ // The relative change in the value is not sufficient enough.
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace
+
+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() {}
+
+ ~UiThreadObserver() override {
+ 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 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()) {
+ it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
+ last_notified_network_quality_.http_rtt().InMilliseconds(),
+ last_notified_network_quality_.transport_rtt().InMilliseconds(),
+ 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_network_quality_.http_rtt().InMilliseconds(),
+ last_notified_network_quality_.transport_rtt().InMilliseconds(),
+ last_notified_network_quality_.downstream_throughput_kbps());
+ }
+
+ content::NotificationRegistrar registrar_;
+
+ // The network quality that was last sent to the renderers.
+ net::nqe::internal::NetworkQuality last_notified_network_quality_;
+
+ DISALLOW_COPY_AND_ASSIGN(UiThreadObserver);
+};
+
+NetworkQualityObserverImpl::NetworkQualityObserverImpl(
+ net::NetworkQualityEstimator* network_quality_estimator)
+ : network_quality_estimator_(network_quality_estimator) {
+ network_quality_estimator_->AddRTTAndThroughputEstimatesObserver(this);
+
+ ui_thread_observer_ = base::MakeUnique<UiThreadObserver>();
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&UiThreadObserver::InitOnUIThread,
+ base::Unretained(ui_thread_observer_.get())));
+}
+
+NetworkQualityObserverImpl::~NetworkQualityObserverImpl() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ network_quality_estimator_->RemoveRTTAndThroughputEstimatesObserver(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::OnRTTOrThroughputEstimatesComputed(
+ base::TimeDelta http_rtt,
+ base::TimeDelta transport_rtt,
+ int32_t downstream_throughput_kbps) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // Check if any of the network quality metrics changed meaningfully.
+ bool http_rtt_changed = MetricChangedMeaningfully(
+ last_notified_network_quality_.http_rtt().InMilliseconds(),
+ http_rtt.InMilliseconds());
+
+ bool transport_rtt_changed = MetricChangedMeaningfully(
+ last_notified_network_quality_.transport_rtt().InMilliseconds(),
+ transport_rtt.InMilliseconds());
+ bool kbps_changed = MetricChangedMeaningfully(
+ last_notified_network_quality_.downstream_throughput_kbps(),
+ downstream_throughput_kbps);
+
+ if (!http_rtt_changed && !transport_rtt_changed && !kbps_changed) {
+ // Return since none of the metrics changed meaningfully. This reduces
+ // the number of notifications to the different renderers every time
+ // the network quality is recomputed.
+ return;
+ }
+
+ last_notified_network_quality_ = net::nqe::internal::NetworkQuality(
+ http_rtt, transport_rtt, downstream_throughput_kbps);
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&UiThreadObserver::OnRTTOrThroughputEstimatesComputed,
+ base::Unretained(ui_thread_observer_.get()),
+ last_notified_network_quality_));
+}
+
+std::unique_ptr<net::NetworkQualityEstimator::RTTAndThroughputEstimatesObserver>
+CreateNetworkQualityObserver(
+ net::NetworkQualityEstimator* network_quality_estimator) {
+ return base::MakeUnique<NetworkQualityObserverImpl>(
+ network_quality_estimator);
+}
+
+} // namespace content
« no previous file with comments | « content/browser/net/network_quality_observer_impl.h ('k') | content/browser/net_info_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698