1 // Copyright (c) 2012 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.
5 // See network_change_notifier_android.h for design explanations.
7 #include "base/basictypes.h"
9 #include "base/callback.h"
10 #include "base/compiler_specific.h"
11 #include "base/message_loop/message_loop.h"
12 #include "net/android/network_change_notifier_android.h"
13 #include "net/android/network_change_notifier_delegate_android.h"
14 #include "net/base/network_change_notifier.h"
15 #include "net/dns/dns_config_service.h"
16 #include "net/dns/dns_protocol.h"
17 #include "testing/gtest/include/gtest/gtest.h"
23 class NetworkChangeNotifierDelegateAndroidObserver
24 : public NetworkChangeNotifierDelegateAndroid::Observer
{
26 NetworkChangeNotifierDelegateAndroidObserver()
27 : type_notifications_count_(0), max_bandwidth_notifications_count_(0) {}
29 // NetworkChangeNotifierDelegateAndroid::Observer:
30 void OnConnectionTypeChanged() override
{ type_notifications_count_
++; }
32 void OnMaxBandwidthChanged(double max_bandwidth_mbps
) override
{
33 max_bandwidth_notifications_count_
++;
36 int type_notifications_count() const { return type_notifications_count_
; }
37 int bandwidth_notifications_count() const {
38 return max_bandwidth_notifications_count_
;
42 int type_notifications_count_
;
43 int max_bandwidth_notifications_count_
;
46 class NetworkChangeNotifierObserver
47 : public NetworkChangeNotifier::ConnectionTypeObserver
{
49 NetworkChangeNotifierObserver() : notifications_count_(0) {}
51 // NetworkChangeNotifier::Observer:
52 void OnConnectionTypeChanged(
53 NetworkChangeNotifier::ConnectionType connection_type
) override
{
54 notifications_count_
++;
57 int notifications_count() const {
58 return notifications_count_
;
62 int notifications_count_
;
65 class DNSChangeObserver
: public NetworkChangeNotifier::DNSObserver
{
68 : change_notifications_count_(0), initial_notifications_count_(0) {}
70 // NetworkChangeNotifier::DNSObserver:
71 void OnDNSChanged() override
{ change_notifications_count_
++; }
73 void OnInitialDNSConfigRead() override
{
74 initial_notifications_count_
++;
75 base::MessageLoop::current()->Quit();
78 int change_notifications_count() const { return change_notifications_count_
; }
80 int initial_notifications_count() const {
81 return initial_notifications_count_
;
85 int change_notifications_count_
;
86 int initial_notifications_count_
;
91 class BaseNetworkChangeNotifierAndroidTest
: public testing::Test
{
93 typedef NetworkChangeNotifier::ConnectionType ConnectionType
;
95 ~BaseNetworkChangeNotifierAndroidTest() override
{}
98 const base::Callback
<int(void)>& notifications_count_getter
,
99 const base::Callback
<ConnectionType(void)>& connection_type_getter
) {
100 EXPECT_EQ(0, notifications_count_getter
.Run());
101 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN
,
102 connection_type_getter
.Run());
104 // Changing from online to offline should trigger a notification.
106 EXPECT_EQ(1, notifications_count_getter
.Run());
107 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE
,
108 connection_type_getter
.Run());
110 // No notification should be triggered when the offline state hasn't
113 EXPECT_EQ(1, notifications_count_getter
.Run());
114 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE
,
115 connection_type_getter
.Run());
117 // Going from offline to online should trigger a notification.
119 EXPECT_EQ(2, notifications_count_getter
.Run());
120 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN
,
121 connection_type_getter
.Run());
125 delegate_
.SetOnline();
126 // Note that this is needed because ObserverListThreadSafe uses PostTask().
127 base::MessageLoop::current()->RunUntilIdle();
131 delegate_
.SetOffline();
132 // See comment above.
133 base::MessageLoop::current()->RunUntilIdle();
136 NetworkChangeNotifierDelegateAndroid delegate_
;
139 // Tests that NetworkChangeNotifierDelegateAndroid is initialized with the
140 // actual connection type rather than a hardcoded one (e.g.
141 // CONNECTION_UNKNOWN). Initializing the connection type to CONNECTION_UNKNOWN
142 // and relying on the first network change notification to set it correctly can
143 // be problematic in case there is a long delay between the delegate's
144 // construction and the notification.
145 TEST_F(BaseNetworkChangeNotifierAndroidTest
,
146 DelegateIsInitializedWithCurrentConnectionType
) {
148 ASSERT_EQ(NetworkChangeNotifier::CONNECTION_NONE
,
149 delegate_
.GetCurrentConnectionType());
150 // Instantiate another delegate to validate that it uses the actual
151 // connection type at construction.
152 scoped_ptr
<NetworkChangeNotifierDelegateAndroid
> other_delegate(
153 new NetworkChangeNotifierDelegateAndroid());
154 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE
,
155 other_delegate
->GetCurrentConnectionType());
157 // Toggle the global connectivity state and instantiate another delegate
160 ASSERT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN
,
161 delegate_
.GetCurrentConnectionType());
162 other_delegate
.reset(new NetworkChangeNotifierDelegateAndroid());
163 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN
,
164 other_delegate
->GetCurrentConnectionType());
167 class NetworkChangeNotifierDelegateAndroidTest
168 : public BaseNetworkChangeNotifierAndroidTest
{
170 NetworkChangeNotifierDelegateAndroidTest() {
171 delegate_
.AddObserver(&delegate_observer_
);
172 delegate_
.AddObserver(&other_delegate_observer_
);
175 ~NetworkChangeNotifierDelegateAndroidTest() override
{
176 delegate_
.RemoveObserver(&delegate_observer_
);
177 delegate_
.RemoveObserver(&other_delegate_observer_
);
180 NetworkChangeNotifierDelegateAndroidObserver delegate_observer_
;
181 NetworkChangeNotifierDelegateAndroidObserver other_delegate_observer_
;
184 // Tests that the NetworkChangeNotifierDelegateAndroid's observers are notified.
185 // A testing-only observer is used here for testing. In production the
186 // delegate's observers are instances of NetworkChangeNotifierAndroid.
187 TEST_F(NetworkChangeNotifierDelegateAndroidTest
, DelegateObserverNotified
) {
188 // Test the logic with a single observer.
189 RunTest(base::Bind(&NetworkChangeNotifierDelegateAndroidObserver::
190 type_notifications_count
,
191 base::Unretained(&delegate_observer_
)),
193 &NetworkChangeNotifierDelegateAndroid::GetCurrentConnectionType
,
194 base::Unretained(&delegate_
)));
195 // Check that *all* the observers are notified. Both observers should have the
197 EXPECT_EQ(delegate_observer_
.type_notifications_count(),
198 other_delegate_observer_
.type_notifications_count());
201 class NetworkChangeNotifierAndroidTest
202 : public BaseNetworkChangeNotifierAndroidTest
{
204 void SetUp() override
{
205 IPAddressNumber dns_number
;
206 ASSERT_TRUE(ParseIPLiteralToNumber("8.8.8.8", &dns_number
));
207 dns_config_
.nameservers
.push_back(
208 IPEndPoint(dns_number
, dns_protocol::kDefaultPort
));
209 notifier_
.reset(new NetworkChangeNotifierAndroid(&delegate_
, &dns_config_
));
210 NetworkChangeNotifier::AddConnectionTypeObserver(
211 &connection_type_observer_
);
212 NetworkChangeNotifier::AddConnectionTypeObserver(
213 &other_connection_type_observer_
);
216 NetworkChangeNotifierObserver connection_type_observer_
;
217 NetworkChangeNotifierObserver other_connection_type_observer_
;
218 NetworkChangeNotifier::DisableForTest disable_for_test_
;
219 DnsConfig dns_config_
;
220 scoped_ptr
<NetworkChangeNotifierAndroid
> notifier_
;
223 // When a NetworkChangeNotifierAndroid is observing a
224 // NetworkChangeNotifierDelegateAndroid for network state changes, and the
225 // NetworkChangeNotifierDelegateAndroid's connectivity state changes, the
226 // NetworkChangeNotifierAndroid should reflect that state.
227 TEST_F(NetworkChangeNotifierAndroidTest
,
228 NotificationsSentToNetworkChangeNotifierAndroid
) {
229 RunTest(base::Bind(&NetworkChangeNotifierObserver::notifications_count
,
230 base::Unretained(&connection_type_observer_
)),
231 base::Bind(&NetworkChangeNotifierAndroid::GetCurrentConnectionType
,
232 base::Unretained(notifier_
.get())));
235 // When a NetworkChangeNotifierAndroid's connection state changes, it should
236 // notify all of its observers.
237 TEST_F(NetworkChangeNotifierAndroidTest
,
238 NotificationsSentToClientsOfNetworkChangeNotifier
) {
241 &NetworkChangeNotifierObserver::notifications_count
,
242 base::Unretained(&connection_type_observer_
)),
243 base::Bind(&NetworkChangeNotifier::GetConnectionType
));
244 // Check that *all* the observers are notified.
245 EXPECT_EQ(connection_type_observer_
.notifications_count(),
246 other_connection_type_observer_
.notifications_count());
249 TEST_F(NetworkChangeNotifierAndroidTest
, MaxBandwidth
) {
251 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN
,
252 notifier_
->GetConnectionType());
253 EXPECT_EQ(std::numeric_limits
<double>::infinity(),
254 notifier_
->GetMaxBandwidth());
256 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE
,
257 notifier_
->GetConnectionType());
258 EXPECT_EQ(0.0, notifier_
->GetMaxBandwidth());
261 TEST_F(NetworkChangeNotifierDelegateAndroidTest
,
262 MaxBandwidthNotifiedOnConnectionChange
) {
263 EXPECT_EQ(0, delegate_observer_
.bandwidth_notifications_count());
265 EXPECT_EQ(1, delegate_observer_
.bandwidth_notifications_count());
267 EXPECT_EQ(2, delegate_observer_
.bandwidth_notifications_count());
269 EXPECT_EQ(2, delegate_observer_
.bandwidth_notifications_count());
272 TEST_F(NetworkChangeNotifierAndroidTest
, InitialSignal
) {
273 DNSChangeObserver dns_change_observer
;
274 NetworkChangeNotifier::AddDNSObserver(&dns_change_observer
);
275 base::MessageLoop::current()->Run();
276 EXPECT_EQ(1, dns_change_observer
.initial_notifications_count());
277 EXPECT_EQ(0, dns_change_observer
.change_notifications_count());
278 NetworkChangeNotifier::RemoveDNSObserver(&dns_change_observer
);