Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 | |
| OLD | NEW |