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

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: ryansturm, nasko 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
65 void InitOnUIThread() {
66 DCHECK_CURRENTLY_ON(BrowserThread::UI);
67 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
nasko 2017/05/09 20:27:47 Shouldn't there be a Remove couterpart of this cal
tbansal1 2017/05/09 21:37:18 Done.
68 NotificationService::AllSources());
69 }
70
71 void OnRTTOrThroughputEstimatesComputed(
72 const net::nqe::internal::NetworkQuality& network_quality) {
73 DCHECK_CURRENTLY_ON(BrowserThread::UI);
74
75 last_notified_network_quality_ = network_quality;
76
77 // Notify all the existing renderers of the change in the network quality.
78 for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
79 !it.IsAtEnd(); it.Advance()) {
80 it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
81 last_notified_network_quality_.http_rtt().InMilliseconds(),
82 last_notified_network_quality_.transport_rtt().InMilliseconds(),
83 last_notified_network_quality_.downstream_throughput_kbps());
84 }
85 }
86
87 private:
88 // NotificationObserver implementation:
89 void Observe(int type,
90 const NotificationSource& source,
91 const NotificationDetails& details) override {
92 DCHECK_CURRENTLY_ON(BrowserThread::UI);
93 DCHECK_EQ(NOTIFICATION_RENDERER_PROCESS_CREATED, type);
94
95 RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr();
96
97 // Notify the newly created renderer of the current network quality.
98 rph->GetRendererInterface()->OnNetworkQualityChanged(
99 last_notified_network_quality_.http_rtt().InMilliseconds(),
100 last_notified_network_quality_.transport_rtt().InMilliseconds(),
101 last_notified_network_quality_.downstream_throughput_kbps());
102 }
103
104 content::NotificationRegistrar registrar_;
105
106 // The network quality that was last notified to the renderers.
nasko 2017/05/09 20:27:47 nit: s/notified/sent/
tbansal1 2017/05/09 21:37:18 Done.
107 net::nqe::internal::NetworkQuality last_notified_network_quality_;
108
109 DISALLOW_COPY_AND_ASSIGN(UiThreadObserver);
110 };
111
112 NetworkQualityObserverImpl::NetworkQualityObserverImpl(
113 net::NetworkQualityEstimator* network_quality_estimator)
114 : network_quality_estimator_(network_quality_estimator) {
115 network_quality_estimator_->AddRTTAndThroughputEstimatesObserver(this);
116
117 ui_thread_observer_ = base::MakeUnique<UiThreadObserver>();
118 BrowserThread::PostTask(
119 BrowserThread::UI, FROM_HERE,
120 base::BindOnce(&UiThreadObserver::InitOnUIThread,
121 base::Unretained(ui_thread_observer_.get())));
122 }
123
124 NetworkQualityObserverImpl::~NetworkQualityObserverImpl() {
125 DCHECK(thread_checker_.CalledOnValidThread());
126 network_quality_estimator_->RemoveRTTAndThroughputEstimatesObserver(this);
127
128 if (!ui_thread_observer_)
129 return;
130
131 // |ui_thread_observer_| must be deleted on UI thread.
132 BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE,
133 ui_thread_observer_.release());
nasko 2017/05/09 20:27:47 You probably want to check the return value of Del
tbansal1 2017/05/09 21:37:18 Done.
134 }
135
136 void NetworkQualityObserverImpl::OnRTTOrThroughputEstimatesComputed(
137 base::TimeDelta http_rtt,
138 base::TimeDelta transport_rtt,
139 int32_t downstream_throughput_kbps) {
140 DCHECK(thread_checker_.CalledOnValidThread());
141
142 // Check if any of the network quality metrics changed meaningfully.
143 bool http_rtt_changed = MetricChangedMeaningfully(
144 last_notified_network_quality_.http_rtt().InMilliseconds(),
145 http_rtt.InMilliseconds());
146
147 bool transport_rtt_changed = MetricChangedMeaningfully(
148 last_notified_network_quality_.transport_rtt().InMilliseconds(),
149 transport_rtt.InMilliseconds());
150 bool kbps_changed = MetricChangedMeaningfully(
151 last_notified_network_quality_.downstream_throughput_kbps(),
152 downstream_throughput_kbps);
153
154 if (!http_rtt_changed && !transport_rtt_changed && !kbps_changed) {
155 // Return since none of the metrics changed meaningfully. This reduces
156 // the number of notifications to the different renderers every time
157 // the network quality is recomputed.
158 return;
159 }
160
161 last_notified_network_quality_ = net::nqe::internal::NetworkQuality(
162 http_rtt, transport_rtt, downstream_throughput_kbps);
163
164 BrowserThread::PostTask(
165 BrowserThread::UI, FROM_HERE,
166 base::BindOnce(&UiThreadObserver::OnRTTOrThroughputEstimatesComputed,
167 base::Unretained(ui_thread_observer_.get()),
168 last_notified_network_quality_));
169 }
170
171 std::unique_ptr<net::NetworkQualityEstimator::RTTAndThroughputEstimatesObserver>
172 CreateNetworkQualityObserver(
173 net::NetworkQualityEstimator* network_quality_estimator) {
174 return base::MakeUnique<NetworkQualityObserverImpl>(
175 network_quality_estimator);
176 }
177
178 } // 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