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.
8 #include "base/callback.h"
9 #include "base/compiler_specific.h"
10 #include "base/message_loop/message_loop.h"
11 #include "net/android/network_change_notifier_android.h"
12 #include "net/android/network_change_notifier_delegate_android.h"
13 #include "net/base/network_change_notifier.h"
14 #include "net/dns/dns_config_service.h"
15 #include "net/dns/dns_protocol.h"
16 #include "testing/gtest/include/gtest/gtest.h"
22 class NetworkChangeNotifierDelegateAndroidObserver
23 : public NetworkChangeNotifierDelegateAndroid::Observer
{
25 NetworkChangeNotifierDelegateAndroidObserver()
26 : type_notifications_count_(0), max_bandwidth_notifications_count_(0) {}
28 // NetworkChangeNotifierDelegateAndroid::Observer:
29 void OnConnectionTypeChanged() override
{ type_notifications_count_
++; }
31 void OnMaxBandwidthChanged(
32 double max_bandwidth_mbps
,
33 net::NetworkChangeNotifier::ConnectionType type
) override
{
34 max_bandwidth_notifications_count_
++;
37 int type_notifications_count() const { return type_notifications_count_
; }
38 int bandwidth_notifications_count() const {
39 return max_bandwidth_notifications_count_
;
43 int type_notifications_count_
;
44 int max_bandwidth_notifications_count_
;
47 class NetworkChangeNotifierObserver
48 : public NetworkChangeNotifier::ConnectionTypeObserver
{
50 NetworkChangeNotifierObserver() : notifications_count_(0) {}
52 // NetworkChangeNotifier::Observer:
53 void OnConnectionTypeChanged(
54 NetworkChangeNotifier::ConnectionType connection_type
) override
{
55 notifications_count_
++;
58 int notifications_count() const {
59 return notifications_count_
;
63 int notifications_count_
;
66 class DNSChangeObserver
: public NetworkChangeNotifier::DNSObserver
{
69 : change_notifications_count_(0), initial_notifications_count_(0) {}
71 // NetworkChangeNotifier::DNSObserver:
72 void OnDNSChanged() override
{ change_notifications_count_
++; }
74 void OnInitialDNSConfigRead() override
{
75 initial_notifications_count_
++;
76 base::MessageLoop::current()->Quit();
79 int change_notifications_count() const { return change_notifications_count_
; }
81 int initial_notifications_count() const {
82 return initial_notifications_count_
;
86 int change_notifications_count_
;
87 int initial_notifications_count_
;
92 class BaseNetworkChangeNotifierAndroidTest
: public testing::Test
{
94 typedef NetworkChangeNotifier::ConnectionType ConnectionType
;
96 ~BaseNetworkChangeNotifierAndroidTest() override
{}
99 const base::Callback
<int(void)>& notifications_count_getter
,
100 const base::Callback
<ConnectionType(void)>& connection_type_getter
) {
101 EXPECT_EQ(0, notifications_count_getter
.Run());
102 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN
,
103 connection_type_getter
.Run());
105 // Changing from online to offline should trigger a notification.
107 EXPECT_EQ(1, notifications_count_getter
.Run());
108 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE
,
109 connection_type_getter
.Run());
111 // No notification should be triggered when the offline state hasn't
114 EXPECT_EQ(1, notifications_count_getter
.Run());
115 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE
,
116 connection_type_getter
.Run());
118 // Going from offline to online should trigger a notification.
120 EXPECT_EQ(2, notifications_count_getter
.Run());
121 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN
,
122 connection_type_getter
.Run());
126 delegate_
.SetOnline();
127 // Note that this is needed because base::ObserverListThreadSafe uses
129 base::MessageLoop::current()->RunUntilIdle();
133 delegate_
.SetOffline();
134 // See comment above.
135 base::MessageLoop::current()->RunUntilIdle();
138 NetworkChangeNotifierDelegateAndroid delegate_
;
141 // Tests that NetworkChangeNotifierDelegateAndroid is initialized with the
142 // actual connection type rather than a hardcoded one (e.g.
143 // CONNECTION_UNKNOWN). Initializing the connection type to CONNECTION_UNKNOWN
144 // and relying on the first network change notification to set it correctly can
145 // be problematic in case there is a long delay between the delegate's
146 // construction and the notification.
147 TEST_F(BaseNetworkChangeNotifierAndroidTest
,
148 DelegateIsInitializedWithCurrentConnectionType
) {
150 ASSERT_EQ(NetworkChangeNotifier::CONNECTION_NONE
,
151 delegate_
.GetCurrentConnectionType());
152 // Instantiate another delegate to validate that it uses the actual
153 // connection type at construction.
154 scoped_ptr
<NetworkChangeNotifierDelegateAndroid
> other_delegate(
155 new NetworkChangeNotifierDelegateAndroid());
156 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE
,
157 other_delegate
->GetCurrentConnectionType());
159 // Toggle the global connectivity state and instantiate another delegate
162 ASSERT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN
,
163 delegate_
.GetCurrentConnectionType());
164 other_delegate
.reset(new NetworkChangeNotifierDelegateAndroid());
165 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN
,
166 other_delegate
->GetCurrentConnectionType());
169 class NetworkChangeNotifierDelegateAndroidTest
170 : public BaseNetworkChangeNotifierAndroidTest
{
172 NetworkChangeNotifierDelegateAndroidTest() {
173 delegate_
.AddObserver(&delegate_observer_
);
174 delegate_
.AddObserver(&other_delegate_observer_
);
177 ~NetworkChangeNotifierDelegateAndroidTest() override
{
178 delegate_
.RemoveObserver(&delegate_observer_
);
179 delegate_
.RemoveObserver(&other_delegate_observer_
);
182 NetworkChangeNotifierDelegateAndroidObserver delegate_observer_
;
183 NetworkChangeNotifierDelegateAndroidObserver other_delegate_observer_
;
186 // Tests that the NetworkChangeNotifierDelegateAndroid's observers are notified.
187 // A testing-only observer is used here for testing. In production the
188 // delegate's observers are instances of NetworkChangeNotifierAndroid.
189 TEST_F(NetworkChangeNotifierDelegateAndroidTest
, DelegateObserverNotified
) {
190 // Test the logic with a single observer.
191 RunTest(base::Bind(&NetworkChangeNotifierDelegateAndroidObserver::
192 type_notifications_count
,
193 base::Unretained(&delegate_observer_
)),
195 &NetworkChangeNotifierDelegateAndroid::GetCurrentConnectionType
,
196 base::Unretained(&delegate_
)));
197 // Check that *all* the observers are notified. Both observers should have the
199 EXPECT_EQ(delegate_observer_
.type_notifications_count(),
200 other_delegate_observer_
.type_notifications_count());
203 class NetworkChangeNotifierAndroidTest
204 : public BaseNetworkChangeNotifierAndroidTest
{
206 void SetUp() override
{
207 IPAddressNumber dns_number
;
208 ASSERT_TRUE(ParseIPLiteralToNumber("8.8.8.8", &dns_number
));
209 dns_config_
.nameservers
.push_back(
210 IPEndPoint(dns_number
, dns_protocol::kDefaultPort
));
211 notifier_
.reset(new NetworkChangeNotifierAndroid(&delegate_
, &dns_config_
));
212 NetworkChangeNotifier::AddConnectionTypeObserver(
213 &connection_type_observer_
);
214 NetworkChangeNotifier::AddConnectionTypeObserver(
215 &other_connection_type_observer_
);
218 NetworkChangeNotifierObserver connection_type_observer_
;
219 NetworkChangeNotifierObserver other_connection_type_observer_
;
220 NetworkChangeNotifier::DisableForTest disable_for_test_
;
221 DnsConfig dns_config_
;
222 scoped_ptr
<NetworkChangeNotifierAndroid
> notifier_
;
225 // When a NetworkChangeNotifierAndroid is observing a
226 // NetworkChangeNotifierDelegateAndroid for network state changes, and the
227 // NetworkChangeNotifierDelegateAndroid's connectivity state changes, the
228 // NetworkChangeNotifierAndroid should reflect that state.
229 TEST_F(NetworkChangeNotifierAndroidTest
,
230 NotificationsSentToNetworkChangeNotifierAndroid
) {
231 RunTest(base::Bind(&NetworkChangeNotifierObserver::notifications_count
,
232 base::Unretained(&connection_type_observer_
)),
233 base::Bind(&NetworkChangeNotifierAndroid::GetCurrentConnectionType
,
234 base::Unretained(notifier_
.get())));
237 // When a NetworkChangeNotifierAndroid's connection state changes, it should
238 // notify all of its observers.
239 TEST_F(NetworkChangeNotifierAndroidTest
,
240 NotificationsSentToClientsOfNetworkChangeNotifier
) {
243 &NetworkChangeNotifierObserver::notifications_count
,
244 base::Unretained(&connection_type_observer_
)),
245 base::Bind(&NetworkChangeNotifier::GetConnectionType
));
246 // Check that *all* the observers are notified.
247 EXPECT_EQ(connection_type_observer_
.notifications_count(),
248 other_connection_type_observer_
.notifications_count());
251 TEST_F(NetworkChangeNotifierAndroidTest
, MaxBandwidth
) {
253 double max_bandwidth_mbps
= 0.0;
254 NetworkChangeNotifier::ConnectionType connection_type
=
255 NetworkChangeNotifier::CONNECTION_NONE
;
256 notifier_
->GetMaxBandwidthAndConnectionType(&max_bandwidth_mbps
,
258 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN
, connection_type
);
259 EXPECT_EQ(std::numeric_limits
<double>::infinity(), max_bandwidth_mbps
);
261 notifier_
->GetMaxBandwidthAndConnectionType(&max_bandwidth_mbps
,
263 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE
, connection_type
);
264 EXPECT_EQ(0.0, max_bandwidth_mbps
);
267 TEST_F(NetworkChangeNotifierDelegateAndroidTest
,
268 MaxBandwidthNotifiedOnConnectionChange
) {
269 EXPECT_EQ(0, delegate_observer_
.bandwidth_notifications_count());
271 EXPECT_EQ(1, delegate_observer_
.bandwidth_notifications_count());
273 EXPECT_EQ(2, delegate_observer_
.bandwidth_notifications_count());
275 EXPECT_EQ(2, delegate_observer_
.bandwidth_notifications_count());
278 TEST_F(NetworkChangeNotifierAndroidTest
, InitialSignal
) {
279 DNSChangeObserver dns_change_observer
;
280 NetworkChangeNotifier::AddDNSObserver(&dns_change_observer
);
281 base::MessageLoop::current()->Run();
282 EXPECT_EQ(1, dns_change_observer
.initial_notifications_count());
283 EXPECT_EQ(0, dns_change_observer
.change_notifications_count());
284 NetworkChangeNotifier::RemoveDNSObserver(&dns_change_observer
);