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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/net/network_quality_observer_impl.h"
6
7 #include "base/memory/ptr_util.h"
8 #include "content/browser/renderer_host/render_process_host_impl.h"
9 #include "content/common/view_messages.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/notification_observer.h"
12 #include "content/public/browser/notification_registrar.h"
13 #include "content/public/browser/notification_service.h"
14 #include "content/public/browser/notification_types.h"
15 #include "content/public/browser/render_process_host.h"
16
17 namespace {
18
19 // Returns true if the |current_value| is meaningfully different from the
20 // |past_value|.
21 bool MetricChangedMeaningfully(int32_t past_value, int32_t current_value) {
22 if ((past_value == net::nqe::internal::INVALID_RTT_THROUGHPUT) !=
23 (current_value == net::nqe::internal::INVALID_RTT_THROUGHPUT)) {
24 return true;
25 }
26
27 if (past_value == net::nqe::internal::INVALID_RTT_THROUGHPUT &&
28 current_value == net::nqe::internal::INVALID_RTT_THROUGHPUT) {
29 return false;
30 }
31
32 // Metric has changed meaningfully only if (i) the difference between the two
33 // values exceed the threshold; and, (ii) the ratio of the values also exceeds
34 // the threshold.
35 static const int kMinDifferenceInMetrics = 100;
36 static const float kMinRatio = 1.2f;
37
38 if (std::abs(past_value - current_value) < kMinDifferenceInMetrics) {
39 // The absolute change in the value is not sufficient enough.
40 return false;
41 }
42
43 if (past_value < (kMinRatio * current_value) &&
44 current_value < (kMinRatio * past_value)) {
45 // The relative change in the value is not sufficient enough.
46 return false;
47 }
48
49 return true;
50 }
51
52 } // namespace
53
54 namespace content {
55
56 // UiThreadObserver observes the changes to the network quality on the UI
57 // thread, and notifies the renderers of the change in the network quality.
58 class NetworkQualityObserverImpl::UiThreadObserver
59 : public content::NotificationObserver {
60 public:
61 UiThreadObserver() {}
62
63 ~UiThreadObserver() override {
64 registrar_.Remove(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
65 NotificationService::AllSources());
66 }
67
68 void InitOnUIThread() {
69 DCHECK_CURRENTLY_ON(BrowserThread::UI);
70 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
71 NotificationService::AllSources());
72 }
73
74 void OnRTTOrThroughputEstimatesComputed(
75 const net::nqe::internal::NetworkQuality& network_quality) {
76 DCHECK_CURRENTLY_ON(BrowserThread::UI);
77
78 last_notified_network_quality_ = network_quality;
79
80 // Notify all the existing renderers of the change in the network quality.
81 for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
82 !it.IsAtEnd(); it.Advance()) {
83 it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
84 last_notified_network_quality_.http_rtt().InMilliseconds(),
85 last_notified_network_quality_.transport_rtt().InMilliseconds(),
86 last_notified_network_quality_.downstream_throughput_kbps());
87 }
88 }
89
90 private:
91 // NotificationObserver implementation:
92 void Observe(int type,
93 const NotificationSource& source,
94 const NotificationDetails& details) override {
95 DCHECK_CURRENTLY_ON(BrowserThread::UI);
96 DCHECK_EQ(NOTIFICATION_RENDERER_PROCESS_CREATED, type);
97
98 RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr();
99
100 // Notify the newly created renderer of the current network quality.
101 rph->GetRendererInterface()->OnNetworkQualityChanged(
102 last_notified_network_quality_.http_rtt().InMilliseconds(),
103 last_notified_network_quality_.transport_rtt().InMilliseconds(),
104 last_notified_network_quality_.downstream_throughput_kbps());
105 }
106
107 content::NotificationRegistrar registrar_;
108
109 // The network quality that was last sent to the renderers.
110 net::nqe::internal::NetworkQuality last_notified_network_quality_;
111
112 DISALLOW_COPY_AND_ASSIGN(UiThreadObserver);
113 };
114
115 NetworkQualityObserverImpl::NetworkQualityObserverImpl(
116 net::NetworkQualityEstimator* network_quality_estimator)
117 : network_quality_estimator_(network_quality_estimator) {
118 network_quality_estimator_->AddRTTAndThroughputEstimatesObserver(this);
119
120 ui_thread_observer_ = base::MakeUnique<UiThreadObserver>();
121 BrowserThread::PostTask(
122 BrowserThread::UI, FROM_HERE,
123 base::BindOnce(&UiThreadObserver::InitOnUIThread,
124 base::Unretained(ui_thread_observer_.get())));
125 }
126
127 NetworkQualityObserverImpl::~NetworkQualityObserverImpl() {
128 DCHECK(thread_checker_.CalledOnValidThread());
129 network_quality_estimator_->RemoveRTTAndThroughputEstimatesObserver(this);
130
131 DCHECK(ui_thread_observer_);
132
133 // If possible, delete |ui_thread_observer_| on UI thread.
134 UiThreadObserver* ui_thread_observer_ptr = ui_thread_observer_.release();
135 bool posted = BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE,
136 ui_thread_observer_ptr);
137
138 if (!posted)
139 delete ui_thread_observer_ptr;
140 }
141
142 void NetworkQualityObserverImpl::OnRTTOrThroughputEstimatesComputed(
143 base::TimeDelta http_rtt,
144 base::TimeDelta transport_rtt,
145 int32_t downstream_throughput_kbps) {
146 DCHECK(thread_checker_.CalledOnValidThread());
147
148 // Check if any of the network quality metrics changed meaningfully.
149 bool http_rtt_changed = MetricChangedMeaningfully(
150 last_notified_network_quality_.http_rtt().InMilliseconds(),
151 http_rtt.InMilliseconds());
152
153 bool transport_rtt_changed = MetricChangedMeaningfully(
154 last_notified_network_quality_.transport_rtt().InMilliseconds(),
155 transport_rtt.InMilliseconds());
156 bool kbps_changed = MetricChangedMeaningfully(
157 last_notified_network_quality_.downstream_throughput_kbps(),
158 downstream_throughput_kbps);
159
160 if (!http_rtt_changed && !transport_rtt_changed && !kbps_changed) {
161 // Return since none of the metrics changed meaningfully. This reduces
162 // the number of notifications to the different renderers every time
163 // the network quality is recomputed.
164 return;
165 }
166
167 last_notified_network_quality_ = net::nqe::internal::NetworkQuality(
168 http_rtt, transport_rtt, downstream_throughput_kbps);
169
170 BrowserThread::PostTask(
171 BrowserThread::UI, FROM_HERE,
172 base::BindOnce(&UiThreadObserver::OnRTTOrThroughputEstimatesComputed,
173 base::Unretained(ui_thread_observer_.get()),
174 last_notified_network_quality_));
175 }
176
177 std::unique_ptr<net::NetworkQualityEstimator::RTTAndThroughputEstimatesObserver>
178 CreateNetworkQualityObserver(
179 net::NetworkQualityEstimator* network_quality_estimator) {
180 return base::MakeUnique<NetworkQualityObserverImpl>(
181 network_quality_estimator);
182 }
183
184 } // namespace content
OLDNEW
« 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