1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "net/nqe/event_creator.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
8*6777b538SAndroid Build Coastguard Worker #include <memory>
9*6777b538SAndroid Build Coastguard Worker #include <utility>
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/values.h"
15*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_capture_mode.h"
16*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_with_source.h"
17*6777b538SAndroid Build Coastguard Worker
18*6777b538SAndroid Build Coastguard Worker namespace net::nqe::internal {
19*6777b538SAndroid Build Coastguard Worker
20*6777b538SAndroid Build Coastguard Worker namespace {
21*6777b538SAndroid Build Coastguard Worker
NetworkQualityChangedNetLogParams(base::TimeDelta http_rtt,base::TimeDelta transport_rtt,int32_t downstream_throughput_kbps,EffectiveConnectionType effective_connection_type)22*6777b538SAndroid Build Coastguard Worker base::Value::Dict NetworkQualityChangedNetLogParams(
23*6777b538SAndroid Build Coastguard Worker base::TimeDelta http_rtt,
24*6777b538SAndroid Build Coastguard Worker base::TimeDelta transport_rtt,
25*6777b538SAndroid Build Coastguard Worker int32_t downstream_throughput_kbps,
26*6777b538SAndroid Build Coastguard Worker EffectiveConnectionType effective_connection_type) {
27*6777b538SAndroid Build Coastguard Worker base::Value::Dict value;
28*6777b538SAndroid Build Coastguard Worker value.Set("http_rtt_ms", static_cast<int>(http_rtt.InMilliseconds()));
29*6777b538SAndroid Build Coastguard Worker value.Set("transport_rtt_ms",
30*6777b538SAndroid Build Coastguard Worker static_cast<int>(transport_rtt.InMilliseconds()));
31*6777b538SAndroid Build Coastguard Worker value.Set("downstream_throughput_kbps", downstream_throughput_kbps);
32*6777b538SAndroid Build Coastguard Worker value.Set("effective_connection_type",
33*6777b538SAndroid Build Coastguard Worker GetNameForEffectiveConnectionType(effective_connection_type));
34*6777b538SAndroid Build Coastguard Worker return value;
35*6777b538SAndroid Build Coastguard Worker }
36*6777b538SAndroid Build Coastguard Worker
MetricChangedMeaningfully(int32_t past_value,int32_t current_value)37*6777b538SAndroid Build Coastguard Worker bool MetricChangedMeaningfully(int32_t past_value, int32_t current_value) {
38*6777b538SAndroid Build Coastguard Worker if ((past_value == INVALID_RTT_THROUGHPUT) !=
39*6777b538SAndroid Build Coastguard Worker (current_value == INVALID_RTT_THROUGHPUT)) {
40*6777b538SAndroid Build Coastguard Worker return true;
41*6777b538SAndroid Build Coastguard Worker }
42*6777b538SAndroid Build Coastguard Worker
43*6777b538SAndroid Build Coastguard Worker if (past_value == INVALID_RTT_THROUGHPUT &&
44*6777b538SAndroid Build Coastguard Worker current_value == INVALID_RTT_THROUGHPUT) {
45*6777b538SAndroid Build Coastguard Worker return false;
46*6777b538SAndroid Build Coastguard Worker }
47*6777b538SAndroid Build Coastguard Worker
48*6777b538SAndroid Build Coastguard Worker // Create a new entry only if (i) the difference between the two values exceed
49*6777b538SAndroid Build Coastguard Worker // the threshold; and, (ii) the ratio of the values also exceeds the
50*6777b538SAndroid Build Coastguard Worker // threshold.
51*6777b538SAndroid Build Coastguard Worker static const int kMinDifferenceInMetrics = 100;
52*6777b538SAndroid Build Coastguard Worker static const float kMinRatio = 1.2f;
53*6777b538SAndroid Build Coastguard Worker
54*6777b538SAndroid Build Coastguard Worker if (std::abs(past_value - current_value) < kMinDifferenceInMetrics) {
55*6777b538SAndroid Build Coastguard Worker // The absolute change in the value is not sufficient enough.
56*6777b538SAndroid Build Coastguard Worker return false;
57*6777b538SAndroid Build Coastguard Worker }
58*6777b538SAndroid Build Coastguard Worker
59*6777b538SAndroid Build Coastguard Worker if (past_value < (kMinRatio * current_value) &&
60*6777b538SAndroid Build Coastguard Worker current_value < (kMinRatio * past_value)) {
61*6777b538SAndroid Build Coastguard Worker // The relative change in the value is not sufficient enough.
62*6777b538SAndroid Build Coastguard Worker return false;
63*6777b538SAndroid Build Coastguard Worker }
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard Worker return true;
66*6777b538SAndroid Build Coastguard Worker }
67*6777b538SAndroid Build Coastguard Worker
68*6777b538SAndroid Build Coastguard Worker } // namespace
69*6777b538SAndroid Build Coastguard Worker
EventCreator(NetLogWithSource net_log)70*6777b538SAndroid Build Coastguard Worker EventCreator::EventCreator(NetLogWithSource net_log) : net_log_(net_log) {}
71*6777b538SAndroid Build Coastguard Worker
~EventCreator()72*6777b538SAndroid Build Coastguard Worker EventCreator::~EventCreator() {
73*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
74*6777b538SAndroid Build Coastguard Worker }
75*6777b538SAndroid Build Coastguard Worker
MaybeAddNetworkQualityChangedEventToNetLog(EffectiveConnectionType effective_connection_type,const NetworkQuality & network_quality)76*6777b538SAndroid Build Coastguard Worker void EventCreator::MaybeAddNetworkQualityChangedEventToNetLog(
77*6777b538SAndroid Build Coastguard Worker EffectiveConnectionType effective_connection_type,
78*6777b538SAndroid Build Coastguard Worker const NetworkQuality& network_quality) {
79*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
80*6777b538SAndroid Build Coastguard Worker
81*6777b538SAndroid Build Coastguard Worker // Check if any of the network quality metrics changed meaningfully.
82*6777b538SAndroid Build Coastguard Worker bool effective_connection_type_changed =
83*6777b538SAndroid Build Coastguard Worker past_effective_connection_type_ != effective_connection_type;
84*6777b538SAndroid Build Coastguard Worker bool http_rtt_changed = MetricChangedMeaningfully(
85*6777b538SAndroid Build Coastguard Worker past_network_quality_.http_rtt().InMilliseconds(),
86*6777b538SAndroid Build Coastguard Worker network_quality.http_rtt().InMilliseconds());
87*6777b538SAndroid Build Coastguard Worker
88*6777b538SAndroid Build Coastguard Worker bool transport_rtt_changed = MetricChangedMeaningfully(
89*6777b538SAndroid Build Coastguard Worker past_network_quality_.transport_rtt().InMilliseconds(),
90*6777b538SAndroid Build Coastguard Worker network_quality.transport_rtt().InMilliseconds());
91*6777b538SAndroid Build Coastguard Worker bool kbps_changed = MetricChangedMeaningfully(
92*6777b538SAndroid Build Coastguard Worker past_network_quality_.downstream_throughput_kbps(),
93*6777b538SAndroid Build Coastguard Worker network_quality.downstream_throughput_kbps());
94*6777b538SAndroid Build Coastguard Worker
95*6777b538SAndroid Build Coastguard Worker if (!effective_connection_type_changed && !http_rtt_changed &&
96*6777b538SAndroid Build Coastguard Worker !transport_rtt_changed && !kbps_changed) {
97*6777b538SAndroid Build Coastguard Worker // Return since none of the metrics changed meaningfully.
98*6777b538SAndroid Build Coastguard Worker return;
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker
101*6777b538SAndroid Build Coastguard Worker past_effective_connection_type_ = effective_connection_type;
102*6777b538SAndroid Build Coastguard Worker past_network_quality_ = network_quality;
103*6777b538SAndroid Build Coastguard Worker
104*6777b538SAndroid Build Coastguard Worker net_log_.AddEvent(NetLogEventType::NETWORK_QUALITY_CHANGED, [&] {
105*6777b538SAndroid Build Coastguard Worker return NetworkQualityChangedNetLogParams(
106*6777b538SAndroid Build Coastguard Worker network_quality.http_rtt(), network_quality.transport_rtt(),
107*6777b538SAndroid Build Coastguard Worker network_quality.downstream_throughput_kbps(),
108*6777b538SAndroid Build Coastguard Worker effective_connection_type);
109*6777b538SAndroid Build Coastguard Worker });
110*6777b538SAndroid Build Coastguard Worker }
111*6777b538SAndroid Build Coastguard Worker
112*6777b538SAndroid Build Coastguard Worker } // namespace net::nqe::internal
113