UMA Metric for reporting network problem while connected.
Added a UMA metric for reporting network problem while connected to
a network. Network problem is detected by TrafficMonitor. Max of one
network problem will be reported per connection.
BUG=chromium:374274
TEST=unit tests, manual
Manual Test:
1. Connect a chrome device an AP without internet access.
2. Wait for few minutes, then browse to "chrome://histograms", and verify
there is a histogram for Network.Shill.Wifi.NetworkProblemDetected".
Change-Id: Iad019d147feebcd429445c687a7c37d8e1e281f9
Reviewed-on: https://chromium-review.googlesource.com/200469
Reviewed-by: Peter Qiu <zqiu@chromium.org>
Commit-Queue: Peter Qiu <zqiu@chromium.org>
Tested-by: Peter Qiu <zqiu@chromium.org>
diff --git a/active_passive_out_of_credits_detector.cc b/active_passive_out_of_credits_detector.cc
index 9a3b99e..ea02fd0 100644
--- a/active_passive_out_of_credits_detector.cc
+++ b/active_passive_out_of_credits_detector.cc
@@ -31,7 +31,7 @@
traffic_monitor_(
new TrafficMonitor(service->cellular(), dispatcher)) {
ResetDetector();
- traffic_monitor_->set_tcp_out_traffic_not_routed_callback(
+ traffic_monitor_->set_network_problem_detected_callback(
Bind(&ActivePassiveOutOfCreditsDetector::OnNoNetworkRouting,
weak_ptr_factory_.GetWeakPtr()));
}
@@ -102,7 +102,7 @@
traffic_monitor_->Stop();
}
-void ActivePassiveOutOfCreditsDetector::OnNoNetworkRouting() {
+void ActivePassiveOutOfCreditsDetector::OnNoNetworkRouting(int reason) {
SLOG(Cellular, 2) << "Service " << service()->friendly_name()
<< ": Traffic Monitor detected network congestion.";
SLOG(Cellular, 2) << "Requesting active probe for out-of-credit detection.";
diff --git a/active_passive_out_of_credits_detector.h b/active_passive_out_of_credits_detector.h
index 3843e52..b49b7fa 100644
--- a/active_passive_out_of_credits_detector.h
+++ b/active_passive_out_of_credits_detector.h
@@ -58,7 +58,7 @@
void StopTrafficMonitor();
// Responds to a TrafficMonitor no-network-routing failure.
- void OnNoNetworkRouting();
+ void OnNoNetworkRouting(int reason);
// Initializes and configures the connection health checker.
void SetupConnectionHealthChecker();
diff --git a/active_passive_out_of_credits_detector_unittest.cc b/active_passive_out_of_credits_detector_unittest.cc
index b7dec85..de1e23c 100644
--- a/active_passive_out_of_credits_detector_unittest.cc
+++ b/active_passive_out_of_credits_detector_unittest.cc
@@ -282,7 +282,7 @@
Unretained(this)));
SetConnectionHealthChecker(health_checker); // Passes ownership.
EXPECT_CALL(*health_checker, Start());
- out_of_credits_detector_->OnNoNetworkRouting();
+ out_of_credits_detector_->OnNoNetworkRouting(0);
EXPECT_FALSE(out_of_credits_detector_->out_of_credits());
Mock::VerifyAndClearExpectations(health_checker);
@@ -291,7 +291,7 @@
EXPECT_CALL(*health_checker, health_check_in_progress())
.WillOnce(Return(true));
EXPECT_CALL(*health_checker, Start()).Times(0);
- out_of_credits_detector_->OnNoNetworkRouting();
+ out_of_credits_detector_->OnNoNetworkRouting(0);
}
TEST_F(ActivePassiveOutOfCreditsDetectorTest,
diff --git a/device.cc b/device.cc
index 3482747..b8a3a46 100644
--- a/device.cc
+++ b/device.cc
@@ -43,6 +43,7 @@
#include "shill/store_interface.h"
#include "shill/technology.h"
#include "shill/tethering.h"
+#include "shill/traffic_monitor.h"
using base::Bind;
using base::FilePath;
@@ -566,6 +567,7 @@
StartPortalDetection();
}
StartLinkMonitor();
+ StartTrafficMonitor();
UpdateIPConfigsProperty();
}
@@ -656,6 +658,7 @@
void Device::DestroyConnection() {
SLOG(Device, 2) << __func__ << " on " << link_name_;
+ StopTrafficMonitor();
StopPortalDetection();
StopLinkMonitor();
if (selected_service_.get()) {
@@ -684,6 +687,7 @@
// Just in case the Device subclass has not already done so, make
// sure the previously selected service has its connection removed.
selected_service_->SetConnection(NULL);
+ StopTrafficMonitor();
StopLinkMonitor();
StopPortalDetection();
}
@@ -914,6 +918,65 @@
fallback_dns_test_client_.reset();
}
+void Device::set_traffic_monitor(TrafficMonitor *traffic_monitor) {
+ traffic_monitor_.reset(traffic_monitor);
+}
+
+bool Device::IsTrafficMonitorEnabled() const {
+ return false;
+}
+
+void Device::StartTrafficMonitor() {
+ // Return if traffic monitor is not enabled for this device.
+ if (!IsTrafficMonitorEnabled()) {
+ return;
+ }
+
+ SLOG(Device, 2) << "Device " << FriendlyName()
+ << ": Traffic Monitor starting.";
+ if (!traffic_monitor_.get()) {
+ traffic_monitor_.reset(new TrafficMonitor(this, dispatcher_));
+ traffic_monitor_->set_network_problem_detected_callback(
+ Bind(&Device::OnEncounterNetworkProblem,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+ traffic_monitor_->Start();
+}
+
+void Device::StopTrafficMonitor() {
+ // Return if traffic monitor is not enabled for this device.
+ if (!IsTrafficMonitorEnabled()) {
+ return;
+ }
+
+ if (traffic_monitor_.get()) {
+ SLOG(Device, 2) << "Device " << FriendlyName()
+ << ": Traffic Monitor stopping.";
+ traffic_monitor_->Stop();
+ }
+ traffic_monitor_.reset();
+}
+
+void Device::OnEncounterNetworkProblem(int reason) {
+ int metric_code;
+ switch (reason) {
+ case TrafficMonitor::kNetworkProblemCongestedTxQueue:
+ metric_code = Metrics::kNetworkProblemCongestedTCPTxQueue;
+ break;
+ case TrafficMonitor::kNetworkProblemDNSFailure:
+ metric_code = Metrics::kNetworkProblemDNSFailure;
+ break;
+ default:
+ LOG(ERROR) << "Invalid network problem code: " << reason;
+ return;
+ }
+
+ metrics()->NotifyNetworkProblemDetected(technology_, metric_code);
+ // Stop the traffic monitor, only report the first network problem detected
+ // on the connection for now.
+ StopTrafficMonitor();
+}
+
void Device::SetServiceConnectedState(Service::ConnectState state) {
DCHECK(selected_service_.get());
diff --git a/device.h b/device.h
index 34500aa..e1408db 100644
--- a/device.h
+++ b/device.h
@@ -436,6 +436,23 @@
// Respond to a LinkMonitor gateway's MAC address found/change event.
virtual void OnLinkMonitorGatewayChange();
+ // Returns true if traffic monitor is enabled on this device. The default
+ // implementation will return false, which can be overridden by a derived
+ // class.
+ virtual bool IsTrafficMonitorEnabled() const;
+
+ // Initiates traffic monitoring on the device if traffic monitor is enabled.
+ void StartTrafficMonitor();
+
+ // Stops traffic monitoring on the device if traffic monitor is enabled.
+ void StopTrafficMonitor();
+
+ // Called by the Traffic Monitor when it detects a network problem. Device
+ // subclasses that want to roam to a different network when encountering
+ // network problems can override this method in order to do so. The parent
+ // implementation handles the metric reporting of the network problem.
+ virtual void OnEncounterNetworkProblem(int reason);
+
// Set the state of the selected service, with checks to make sure
// the service is already in a connected state before doing so.
void SetServiceConnectedState(Service::ConnectState state);
@@ -469,6 +486,8 @@
Manager *manager() const { return manager_; }
const LinkMonitor *link_monitor() const { return link_monitor_.get(); }
void set_link_monitor(LinkMonitor *link_monitor);
+ // Use for unit test.
+ void set_traffic_monitor(TrafficMonitor *traffic_monitor);
private:
friend class CellularCapabilityTest;
@@ -593,6 +612,7 @@
portal_detector_callback_;
base::Callback<void(const Error &, const IPAddress &)>
dns_client_callback_;
+ scoped_ptr<TrafficMonitor> traffic_monitor_;
Technology::Identifier technology_;
// The number of portal detection attempts from Connected to Online state.
// This includes all failure/timeout attempts and the final successful
diff --git a/device_unittest.cc b/device_unittest.cc
index 468408b..bc5ad9b 100644
--- a/device_unittest.cc
+++ b/device_unittest.cc
@@ -92,6 +92,9 @@
.WillByDefault(Invoke(this, &TestDevice::DeviceIsIPv6Allowed));
ON_CALL(*this, SetIPFlag(_, _, _))
.WillByDefault(Invoke(this, &TestDevice::DeviceSetIPFlag));
+ ON_CALL(*this, IsTrafficMonitorEnabled())
+ .WillByDefault(Invoke(this,
+ &TestDevice::DeviceIsTrafficMonitorEnabled));
}
~TestDevice() {}
@@ -107,6 +110,7 @@
}
MOCK_CONST_METHOD0(IsIPv6Allowed, bool());
+ MOCK_CONST_METHOD0(IsTrafficMonitorEnabled, bool());
MOCK_METHOD3(SetIPFlag, bool(IPAddress::Family family,
const std::string &flag,
@@ -116,6 +120,10 @@
return Device::IsIPv6Allowed();
}
+ virtual bool DeviceIsTrafficMonitorEnabled() const {
+ return Device::IsTrafficMonitorEnabled();
+ }
+
virtual bool DeviceSetIPFlag(IPAddress::Family family,
const std::string &flag,
const std::string &value) {
@@ -192,6 +200,22 @@
return device_->GetLinkMonitorResponseTime(error);
}
+ void SetTrafficMonitor(TrafficMonitor *traffic_monitor) {
+ device_->set_traffic_monitor(traffic_monitor); // Passes ownership.
+ }
+
+ void StartTrafficMonitor() {
+ device_->StartTrafficMonitor();
+ }
+
+ void StopTrafficMonitor() {
+ device_->StopTrafficMonitor();
+ }
+
+ void NetworkProblemDetected(int reason) {
+ device_->OnEncounterNetworkProblem(reason);
+ }
+
DeviceMockAdaptor *GetDeviceMockAdaptor() {
return dynamic_cast<DeviceMockAdaptor *>(device_->adaptor_.get());
}
@@ -696,6 +720,73 @@
EXPECT_FALSE(HasLinkMonitor());
}
+TEST_F(DeviceTest, TrafficMonitor) {
+ scoped_refptr<MockConnection> connection(
+ new StrictMock<MockConnection>(&device_info_));
+ MockManager manager(control_interface(),
+ dispatcher(),
+ metrics(),
+ glib());
+ scoped_refptr<MockService> service(
+ new StrictMock<MockService>(control_interface(),
+ dispatcher(),
+ metrics(),
+ &manager));
+ SelectService(service);
+ SetConnection(connection.get());
+ MockTrafficMonitor *traffic_monitor = new StrictMock<MockTrafficMonitor>();
+ SetTrafficMonitor(traffic_monitor); // Passes ownership.
+ SetManager(&manager);
+
+ EXPECT_CALL(*device_, IsTrafficMonitorEnabled()).WillRepeatedly(Return(true));
+ EXPECT_CALL(*traffic_monitor, Start());
+ StartTrafficMonitor();
+ EXPECT_CALL(*traffic_monitor, Stop());
+ StopTrafficMonitor();
+ Mock::VerifyAndClearExpectations(traffic_monitor);
+
+ EXPECT_CALL(metrics_, NotifyNetworkProblemDetected(_,
+ Metrics::kNetworkProblemDNSFailure)).Times(1);
+ NetworkProblemDetected(TrafficMonitor::kNetworkProblemDNSFailure);
+
+ // Verify traffic monitor not running when it is disabled.
+ traffic_monitor = new StrictMock<MockTrafficMonitor>();
+ SetTrafficMonitor(traffic_monitor);
+ EXPECT_CALL(*device_, IsTrafficMonitorEnabled())
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(*traffic_monitor, Start()).Times(0);
+ StartTrafficMonitor();
+ EXPECT_CALL(*traffic_monitor, Stop()).Times(0);
+ StopTrafficMonitor();
+
+}
+
+TEST_F(DeviceTest, TrafficMonitorCancelledOnSelectService) {
+ scoped_refptr<MockConnection> connection(
+ new StrictMock<MockConnection>(&device_info_));
+ MockManager manager(control_interface(),
+ dispatcher(),
+ metrics(),
+ glib());
+ scoped_refptr<MockService> service(
+ new StrictMock<MockService>(control_interface(),
+ dispatcher(),
+ metrics(),
+ &manager));
+ SelectService(service);
+ SetConnection(connection.get());
+ MockTrafficMonitor *traffic_monitor = new StrictMock<MockTrafficMonitor>();
+ SetTrafficMonitor(traffic_monitor); // Passes ownership.
+ EXPECT_CALL(*device_, IsTrafficMonitorEnabled()).WillRepeatedly(Return(true));
+ SetManager(&manager);
+ EXPECT_CALL(*service, state())
+ .WillOnce(Return(Service::kStateIdle));
+ EXPECT_CALL(*service, SetState(_));
+ EXPECT_CALL(*service, SetConnection(_));
+ EXPECT_CALL(*traffic_monitor, Stop());
+ SelectService(NULL);
+}
+
TEST_F(DeviceTest, ShouldUseArpGateway) {
EXPECT_FALSE(device_->ShouldUseArpGateway());
}
diff --git a/metrics.cc b/metrics.cc
index a6c91c9..d42e2b3 100644
--- a/metrics.cc
+++ b/metrics.cc
@@ -304,6 +304,10 @@
const char Metrics::kMetricFallbackDNSTestResult[] =
"Network.Shill.FallbackDNSTestResult";
+// static
+const char Metrics::kMetricNetworkProblemDetectedSuffix[] =
+ "NetworkProblemDetected";
+
Metrics::Metrics(EventDispatcher *dispatcher)
: dispatcher_(dispatcher),
library_(&metrics_library_),
@@ -1134,6 +1138,15 @@
kDNSTestResultMax);
}
+void Metrics::NotifyNetworkProblemDetected(Technology::Identifier technology_id,
+ int reason) {
+ string histogram = GetFullMetricName(kMetricNetworkProblemDetectedSuffix,
+ technology_id);
+ SendEnumToUMA(histogram,
+ reason,
+ kNetworkProblemMax);
+}
+
bool Metrics::SendEnumToUMA(const string &name, int sample, int max) {
SLOG(Metrics, 5)
<< "Sending enum " << name << " with value " << sample << ".";
diff --git a/metrics.h b/metrics.h
index 58ea4fd..9abdd0e 100644
--- a/metrics.h
+++ b/metrics.h
@@ -291,6 +291,13 @@
kDNSTestResultMax
};
+ // Network problem detected by traffic monitor.
+ enum NetworkProblem {
+ kNetworkProblemCongestedTCPTxQueue = 0,
+ kNetworkProblemDNSFailure,
+ kNetworkProblemMax
+ };
+
static const char kMetricDisconnectSuffix[];
static const int kMetricDisconnectMax;
static const int kMetricDisconnectMin;
@@ -494,6 +501,9 @@
// DNS test result.
static const char kMetricFallbackDNSTestResult[];
+ // Network problem detected by traffic monitor
+ static const char kMetricNetworkProblemDetectedSuffix[];
+
explicit Metrics(EventDispatcher *dispatcher);
virtual ~Metrics();
@@ -683,6 +693,11 @@
// Notifies this object about the result of the fallback DNS test.
virtual void NotifyFallbackDNSTestResult(int result);
+ // Notifies this object about a network problem detected on the currently
+ // connected network.
+ virtual void NotifyNetworkProblemDetected(
+ Technology::Identifier technology_id, int reason);
+
// Sends linear histogram data to UMA.
virtual bool SendEnumToUMA(const std::string &name, int sample, int max);
diff --git a/metrics_unittest.cc b/metrics_unittest.cc
index a32b2fc..111d8a4 100644
--- a/metrics_unittest.cc
+++ b/metrics_unittest.cc
@@ -799,6 +799,15 @@
metrics_.NotifyFallbackDNSTestResult(Metrics::kDNSTestResultSuccess);
}
+TEST_F(MetricsTest, NotifyNetworkProblemDetected) {
+ EXPECT_CALL(library_,
+ SendEnumToUMA("Network.Shill.Wifi.NetworkProblemDetected",
+ Metrics::kNetworkProblemDNSFailure,
+ Metrics::kNetworkProblemMax));
+ metrics_.NotifyNetworkProblemDetected(Technology::kWifi,
+ Metrics::kNetworkProblemDNSFailure);
+}
+
#ifndef NDEBUG
typedef MetricsTest MetricsDeathTest;
diff --git a/mock_metrics.h b/mock_metrics.h
index e050a59..35087d7 100644
--- a/mock_metrics.h
+++ b/mock_metrics.h
@@ -50,6 +50,8 @@
MOCK_METHOD2(NotifyUserInitiatedConnectionResult,
void(const std::string &name, int result));
MOCK_METHOD1(NotifyFallbackDNSTestResult, void(int result));
+ MOCK_METHOD2(NotifyNetworkProblemDetected,
+ void(Technology::Identifier technology_id, int reason));
private:
DISALLOW_COPY_AND_ASSIGN(MockMetrics);
diff --git a/traffic_monitor.cc b/traffic_monitor.cc
index 4bca373..1b623a3 100644
--- a/traffic_monitor.cc
+++ b/traffic_monitor.cc
@@ -190,20 +190,22 @@
void TrafficMonitor::SampleTraffic() {
SLOG(Link, 3) << __func__;
+ // Schedule the sample callback first, so it is possible for the network
+ // problem callback to stop the traffic monitor.
+ dispatcher_->PostDelayedTask(sample_traffic_callback_.callback(),
+ kSamplingIntervalMilliseconds);
+
if (IsCongestedTxQueues() &&
accummulated_congested_tx_queues_samples_ ==
kMinimumFailedSamplesToTrigger) {
LOG(WARNING) << "Congested tx queues detected, out-of-credits?";
- outgoing_tcp_packets_not_routed_callback_.Run();
+ network_problem_detected_callback_.Run(kNetworkProblemCongestedTxQueue);
} else if (IsDnsFailing() &&
accummulated_dns_failures_samples_ ==
kMinimumFailedSamplesToTrigger) {
LOG(WARNING) << "DNS queries failing, out-of-credits?";
- outgoing_tcp_packets_not_routed_callback_.Run();
+ network_problem_detected_callback_.Run(kNetworkProblemDNSFailure);
}
-
- dispatcher_->PostDelayedTask(sample_traffic_callback_.callback(),
- kSamplingIntervalMilliseconds);
}
} // namespace shill
diff --git a/traffic_monitor.h b/traffic_monitor.h
index 2f19876..4a6ba1a 100644
--- a/traffic_monitor.h
+++ b/traffic_monitor.h
@@ -25,7 +25,14 @@
// and notifies an observer of various scenarios via callbacks.
class TrafficMonitor {
public:
- typedef base::Closure TcpOutTrafficNotRoutedCallback;
+ // Network problem detected by traffic monitor.
+ enum NetworkProblem {
+ kNetworkProblemCongestedTxQueue=0,
+ kNetworkProblemDNSFailure,
+ kNetworkProblemMax
+ };
+
+ typedef base::Callback<void(int)> NetworkProblemDetectedCallback;
TrafficMonitor(const DeviceRefPtr &device, EventDispatcher *dispatcher);
virtual ~TrafficMonitor();
@@ -36,11 +43,12 @@
// Stops traffic monitoring on the selected device.
virtual void Stop();
- // Sets the callback to invoke, if the traffic monitor detects that too many
- // packets are failing to get transmitted over a TCP connection.
- void set_tcp_out_traffic_not_routed_callback(
- const TcpOutTrafficNotRoutedCallback &callback) {
- outgoing_tcp_packets_not_routed_callback_ = callback;
+ // Sets the callback to invoke, if the traffic monitor detects a network
+ // problem, either too many packets are failing to get transmitted over a
+ // TCP connection or DNS is failing.
+ void set_network_problem_detected_callback(
+ const NetworkProblemDetectedCallback &callback) {
+ network_problem_detected_callback_ = callback;
}
private:
@@ -121,9 +129,11 @@
// of the network interface.
base::CancelableClosure sample_traffic_callback_;
- // Callback to invoke when we detect that the send queue has been increasing
- // on an ESTABLISHED TCP connection through the network interface.
- TcpOutTrafficNotRoutedCallback outgoing_tcp_packets_not_routed_callback_;
+ // Callback to invoke when we detect a network problem. Possible network
+ // problems that can be detected are congested TCP TX queue and DNS failure.
+ // Refer to enum NetworkProblem for all possible network problems that can be
+ // detected by Traffic Monitor.
+ NetworkProblemDetectedCallback network_problem_detected_callback_;
// Reads and parses socket information from the system.
scoped_ptr<SocketInfoReader> socket_info_reader_;
diff --git a/traffic_monitor_unittest.cc b/traffic_monitor_unittest.cc
index e4ee9a5..225f289 100644
--- a/traffic_monitor_unittest.cc
+++ b/traffic_monitor_unittest.cc
@@ -63,7 +63,7 @@
remote_addr_.SetAddressFromString(kRemoteIpAddr);
}
- MOCK_METHOD0(OnNoOutgoingPackets, void());
+ MOCK_METHOD1(OnNoOutgoingPackets, void(int));
protected:
virtual void SetUp() {
@@ -314,20 +314,21 @@
0,
SocketInfo::kTimerStateRetransmitTimerPending));
SetupMockSocketInfos(socket_infos);
- monitor_.set_tcp_out_traffic_not_routed_callback(
+ monitor_.set_network_problem_detected_callback(
Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
monitor_.SampleTraffic();
Mock::VerifyAndClearExpectations(this);
// Mimic same queue length by using same mock socket info.
- EXPECT_CALL(*this, OnNoOutgoingPackets());
+ EXPECT_CALL(*this, OnNoOutgoingPackets(
+ TrafficMonitor::kNetworkProblemCongestedTxQueue));
monitor_.SampleTraffic();
Mock::VerifyAndClearExpectations(this);
// Perform another sampling pass and make sure the callback is only
// triggered once.
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
monitor_.SampleTraffic();
}
@@ -343,9 +344,9 @@
0,
SocketInfo::kTimerStateRetransmitTimerPending));
SetupMockSocketInfos(socket_infos);
- monitor_.set_tcp_out_traffic_not_routed_callback(
+ monitor_.set_network_problem_detected_callback(
Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
monitor_.SampleTraffic();
Mock::VerifyAndClearExpectations(this);
@@ -360,7 +361,8 @@
0,
SocketInfo::kTimerStateRetransmitTimerPending));
SetupMockSocketInfos(socket_infos);
- EXPECT_CALL(*this, OnNoOutgoingPackets());
+ EXPECT_CALL(*this, OnNoOutgoingPackets(
+ TrafficMonitor::kNetworkProblemCongestedTxQueue));
monitor_.SampleTraffic();
}
@@ -376,9 +378,9 @@
0,
SocketInfo::kTimerStateRetransmitTimerPending));
SetupMockSocketInfos(socket_infos);
- monitor_.set_tcp_out_traffic_not_routed_callback(
+ monitor_.set_network_problem_detected_callback(
Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
monitor_.SampleTraffic();
Mock::VerifyAndClearExpectations(this);
@@ -393,7 +395,7 @@
0,
SocketInfo::kTimerStateRetransmitTimerPending));
SetupMockSocketInfos(socket_infos);
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
monitor_.SampleTraffic();
Mock::VerifyAndClearExpectations(this);
@@ -408,7 +410,8 @@
0,
SocketInfo::kTimerStateRetransmitTimerPending));
SetupMockSocketInfos(socket_infos);
- EXPECT_CALL(*this, OnNoOutgoingPackets());
+ EXPECT_CALL(*this, OnNoOutgoingPackets(
+ TrafficMonitor::kNetworkProblemCongestedTxQueue));
monitor_.SampleTraffic();
}
@@ -424,9 +427,9 @@
0,
SocketInfo::kTimerStateRetransmitTimerPending));
SetupMockSocketInfos(socket_infos);
- monitor_.set_tcp_out_traffic_not_routed_callback(
+ monitor_.set_network_problem_detected_callback(
Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
monitor_.SampleTraffic();
socket_infos.clear();
@@ -456,9 +459,9 @@
0,
SocketInfo::kTimerStateRetransmitTimerPending));
SetupMockSocketInfos(socket_infos);
- monitor_.set_tcp_out_traffic_not_routed_callback(
+ monitor_.set_network_problem_detected_callback(
Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
monitor_.SampleTraffic();
socket_infos.clear();
@@ -479,9 +482,9 @@
0,
SocketInfo::kTimerStateRetransmitTimerPending));
SetupMockSocketInfos(socket_infos);
- monitor_.set_tcp_out_traffic_not_routed_callback(
+ monitor_.set_network_problem_detected_callback(
Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
monitor_.SampleTraffic();
socket_infos.clear();
@@ -509,11 +512,11 @@
remote_addr_, TrafficMonitor::kDnsPort,
local_addr_, TrafficMonitorTest::kLocalPort1));
SetupMockConnectionInfos(connection_infos);
- monitor_.set_tcp_out_traffic_not_routed_callback(
+ monitor_.set_network_problem_detected_callback(
Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
// Make sure the no routing event is not fired before the threshold is
// exceeded.
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
for (int count = 1; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
++count) {
monitor_.SampleTraffic();
@@ -521,12 +524,13 @@
Mock::VerifyAndClearExpectations(this);
// This call should cause the threshold to exceed.
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(1);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(
+ TrafficMonitor::kNetworkProblemDNSFailure)).Times(1);
monitor_.SampleTraffic();
Mock::VerifyAndClearExpectations(this);
// Make sure the event is only fired once.
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
monitor_.SampleTraffic();
}
@@ -540,9 +544,9 @@
remote_addr_, TrafficMonitor::kDnsPort,
local_addr_, TrafficMonitorTest::kLocalPort1));
SetupMockConnectionInfos(connection_infos);
- monitor_.set_tcp_out_traffic_not_routed_callback(
+ monitor_.set_network_problem_detected_callback(
Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
++count) {
monitor_.SampleTraffic();
@@ -559,9 +563,9 @@
remote_addr_, TrafficMonitor::kDnsPort,
local_addr_, TrafficMonitorTest::kLocalPort1));
SetupMockConnectionInfos(connection_infos);
- monitor_.set_tcp_out_traffic_not_routed_callback(
+ monitor_.set_network_problem_detected_callback(
Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
for (int count = 1; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
++count) {
monitor_.SampleTraffic();
@@ -578,9 +582,9 @@
remote_addr_, TrafficMonitor::kDnsPort,
local_addr_, TrafficMonitorTest::kLocalPort1));
SetupMockConnectionInfos(connection_infos);
- monitor_.set_tcp_out_traffic_not_routed_callback(
+ monitor_.set_network_problem_detected_callback(
Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
for (int count = 1; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
++count) {
monitor_.SampleTraffic();
@@ -596,7 +600,7 @@
remote_addr_, TrafficMonitor::kDnsPort,
local_addr_, TrafficMonitorTest::kLocalPort1));
SetupMockConnectionInfos(connection_infos);
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
monitor_.SampleTraffic();
EXPECT_EQ(0, monitor_.accummulated_dns_failures_samples_);
}
@@ -611,9 +615,9 @@
remote_addr_, TrafficMonitor::kDnsPort,
local_addr_, TrafficMonitorTest::kLocalPort1));
SetupMockConnectionInfos(connection_infos);
- monitor_.set_tcp_out_traffic_not_routed_callback(
+ monitor_.set_network_problem_detected_callback(
Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
++count) {
monitor_.SampleTraffic();
@@ -630,9 +634,9 @@
remote_addr_, TrafficMonitor::kDnsPort,
remote_addr_, TrafficMonitorTest::kLocalPort1));
SetupMockConnectionInfos(connection_infos);
- monitor_.set_tcp_out_traffic_not_routed_callback(
+ monitor_.set_network_problem_detected_callback(
Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
++count) {
monitor_.SampleTraffic();
@@ -650,9 +654,9 @@
remote_addr_, TrafficMonitor::kDnsPort,
remote_addr_, TrafficMonitorTest::kLocalPort1));
SetupMockConnectionInfos(connection_infos);
- monitor_.set_tcp_out_traffic_not_routed_callback(
+ monitor_.set_network_problem_detected_callback(
Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
++count) {
monitor_.SampleTraffic();
@@ -670,9 +674,9 @@
remote_addr_, kNonDnsPort,
local_addr_, TrafficMonitorTest::kLocalPort1));
SetupMockConnectionInfos(connection_infos);
- monitor_.set_tcp_out_traffic_not_routed_callback(
+ monitor_.set_network_problem_detected_callback(
Bind(&TrafficMonitorTest::OnNoOutgoingPackets, Unretained(this)));
- EXPECT_CALL(*this, OnNoOutgoingPackets()).Times(0);
+ EXPECT_CALL(*this, OnNoOutgoingPackets(_)).Times(0);
for (int count = 0; count < TrafficMonitor::kMinimumFailedSamplesToTrigger;
++count) {
monitor_.SampleTraffic();
diff --git a/wifi.cc b/wifi.cc
index 51b05c7..8e5dcc1 100644
--- a/wifi.cc
+++ b/wifi.cc
@@ -2581,6 +2581,11 @@
return "";
}
+// Traffic monitor is enabled for wifi.
+bool WiFi::IsTrafficMonitorEnabled() const {
+ return true;
+}
+
bool WiFi::ResolvePeerMacAddress(const string &input, string *output,
Error *error) {
if (!WiFiEndpoint::MakeHardwareAddressFromString(input).empty()) {
diff --git a/wifi.h b/wifi.h
index 1747676..440e61d 100644
--- a/wifi.h
+++ b/wifi.h
@@ -216,6 +216,10 @@
virtual std::string PerformTDLSOperation(const std::string &operation,
const std::string &peer,
Error *error) override;
+
+ // Overridden from Device superclass.
+ virtual bool IsTrafficMonitorEnabled() const override;
+
private:
enum ScanMethod {
kScanMethodNone,