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 #include "chromeos/network/network_state_handler.h"
11 #include "base/bind.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/values.h"
15 #include "chromeos/dbus/dbus_thread_manager.h"
16 #include "chromeos/dbus/shill_device_client.h"
17 #include "chromeos/dbus/shill_manager_client.h"
18 #include "chromeos/dbus/shill_profile_client.h"
19 #include "chromeos/dbus/shill_service_client.h"
20 #include "chromeos/network/network_state.h"
21 #include "chromeos/network/network_state_handler_observer.h"
22 #include "chromeos/network/shill_property_util.h"
23 #include "dbus/object_path.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "third_party/cros_system_api/dbus/service_constants.h"
29 void ErrorCallbackFunction(const std::string
& error_name
,
30 const std::string
& error_message
) {
31 LOG(ERROR
) << "Shill Error: " << error_name
<< " : " << error_message
;
34 const std::string kShillManagerClientStubDefaultService
= "eth1";
35 const std::string kShillManagerClientStubDefaultWireless
= "wifi1";
36 const std::string kShillManagerClientStubWireless2
= "wifi2";
37 const std::string kShillManagerClientStubCellular
= "cellular1";
39 using chromeos::NetworkState
;
40 using chromeos::NetworkStateHandler
;
42 class TestObserver
: public chromeos::NetworkStateHandlerObserver
{
44 explicit TestObserver(NetworkStateHandler
* handler
)
46 device_list_changed_count_(0),
48 default_network_change_count_(0),
52 virtual ~TestObserver() {
55 virtual void DeviceListChanged() OVERRIDE
{
56 ++device_list_changed_count_
;
59 virtual void NetworkListChanged() OVERRIDE
{
60 NetworkStateHandler::NetworkStateList networks
;
61 handler_
->GetNetworkList(&networks
);
62 network_count_
= networks
.size();
63 if (network_count_
== 0) {
64 default_network_
= "";
65 default_network_connection_state_
= "";
67 NetworkStateHandler::FavoriteStateList favorites
;
68 handler_
->GetFavoriteList(&favorites
);
69 favorite_count_
= favorites
.size();
72 virtual void DefaultNetworkChanged(const NetworkState
* network
) OVERRIDE
{
73 ++default_network_change_count_
;
74 default_network_
= network
? network
->path() : "";
75 default_network_connection_state_
=
76 network
? network
->connection_state() : "";
77 DVLOG(1) << "DefaultNetworkChanged: " << default_network_
78 << " State: " << default_network_connection_state_
;
81 virtual void NetworkConnectionStateChanged(
82 const NetworkState
* network
) OVERRIDE
{
83 network_connection_state_
[network
->path()] = network
->connection_state();
84 connection_state_changes_
[network
->path()]++;
87 virtual void NetworkPropertiesUpdated(const NetworkState
* network
) OVERRIDE
{
89 property_updates_
[network
->path()]++;
92 size_t device_list_changed_count() { return device_list_changed_count_
; }
93 size_t network_count() { return network_count_
; }
94 size_t default_network_change_count() {
95 return default_network_change_count_
;
97 void reset_network_change_count() {
98 DVLOG(1) << "ResetNetworkChangeCount";
99 default_network_change_count_
= 0;
101 std::string
default_network() { return default_network_
; }
102 std::string
default_network_connection_state() {
103 return default_network_connection_state_
;
105 size_t favorite_count() { return favorite_count_
; }
107 int PropertyUpdatesForService(const std::string
& service_path
) {
108 return property_updates_
[service_path
];
111 int ConnectionStateChangesForService(const std::string
& service_path
) {
112 return connection_state_changes_
[service_path
];
115 std::string
NetworkConnectionStateForService(
116 const std::string
& service_path
) {
117 return network_connection_state_
[service_path
];
121 NetworkStateHandler
* handler_
;
122 size_t device_list_changed_count_
;
123 size_t network_count_
;
124 size_t default_network_change_count_
;
125 std::string default_network_
;
126 std::string default_network_connection_state_
;
127 size_t favorite_count_
;
128 std::map
<std::string
, int> property_updates_
;
129 std::map
<std::string
, int> connection_state_changes_
;
130 std::map
<std::string
, std::string
> network_connection_state_
;
132 DISALLOW_COPY_AND_ASSIGN(TestObserver
);
139 class NetworkStateHandlerTest
: public testing::Test
{
141 NetworkStateHandlerTest()
142 : device_test_(NULL
), manager_test_(NULL
), service_test_(NULL
) {}
143 virtual ~NetworkStateHandlerTest() {}
145 virtual void SetUp() OVERRIDE
{
146 // Initialize DBusThreadManager with a stub implementation.
147 DBusThreadManager::InitializeWithStub();
148 SetupNetworkStateHandler();
149 message_loop_
.RunUntilIdle();
152 virtual void TearDown() OVERRIDE
{
153 network_state_handler_
->RemoveObserver(test_observer_
.get(), FROM_HERE
);
154 test_observer_
.reset();
155 network_state_handler_
.reset();
156 DBusThreadManager::Shutdown();
159 void SetupNetworkStateHandler() {
160 SetupDefaultShillState();
161 network_state_handler_
.reset(new NetworkStateHandler
);
162 test_observer_
.reset(new TestObserver(network_state_handler_
.get()));
163 network_state_handler_
->AddObserver(test_observer_
.get(), FROM_HERE
);
164 network_state_handler_
->InitShillPropertyHandler();
168 void SetupDefaultShillState() {
169 message_loop_
.RunUntilIdle(); // Process any pending updates
171 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
172 ASSERT_TRUE(device_test_
);
173 device_test_
->ClearDevices();
174 device_test_
->AddDevice(
175 "/device/stub_wifi_device1", shill::kTypeWifi
, "stub_wifi_device1");
176 device_test_
->AddDevice("/device/stub_cellular_device1",
177 shill::kTypeCellular
,
178 "stub_cellular_device1");
181 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface();
182 ASSERT_TRUE(manager_test_
);
185 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
186 ASSERT_TRUE(service_test_
);
187 service_test_
->ClearServices();
188 const bool add_to_visible
= true;
189 const bool add_to_watchlist
= true;
190 service_test_
->AddService(kShillManagerClientStubDefaultService
,
191 kShillManagerClientStubDefaultService
,
192 shill::kTypeEthernet
,
196 service_test_
->AddService(kShillManagerClientStubDefaultWireless
,
197 kShillManagerClientStubDefaultWireless
,
202 service_test_
->AddService(kShillManagerClientStubWireless2
,
203 kShillManagerClientStubWireless2
,
208 service_test_
->AddService(kShillManagerClientStubCellular
,
209 kShillManagerClientStubCellular
,
210 shill::kTypeCellular
,
216 base::MessageLoopForUI message_loop_
;
217 scoped_ptr
<NetworkStateHandler
> network_state_handler_
;
218 scoped_ptr
<TestObserver
> test_observer_
;
219 ShillDeviceClient::TestInterface
* device_test_
;
220 ShillManagerClient::TestInterface
* manager_test_
;
221 ShillServiceClient::TestInterface
* service_test_
;
224 DISALLOW_COPY_AND_ASSIGN(NetworkStateHandlerTest
);
227 TEST_F(NetworkStateHandlerTest
, NetworkStateHandlerStub
) {
228 // Ensure that the network list is the expected size.
229 const size_t kNumShillManagerClientStubImplServices
= 4;
230 EXPECT_EQ(kNumShillManagerClientStubImplServices
,
231 test_observer_
->network_count());
232 // Ensure that the first stub network is the default network.
233 EXPECT_EQ(kShillManagerClientStubDefaultService
,
234 test_observer_
->default_network());
235 EXPECT_EQ(kShillManagerClientStubDefaultService
,
236 network_state_handler_
->ConnectedNetworkByType(
237 NetworkTypePattern::Default())->path());
238 EXPECT_EQ(kShillManagerClientStubDefaultService
,
239 network_state_handler_
->ConnectedNetworkByType(
240 NetworkTypePattern::Ethernet())->path());
241 EXPECT_EQ(kShillManagerClientStubDefaultWireless
,
242 network_state_handler_
->ConnectedNetworkByType(
243 NetworkTypePattern::Wireless())->path());
244 EXPECT_EQ(kShillManagerClientStubCellular
,
245 network_state_handler_
->FirstNetworkByType(
246 NetworkTypePattern::Mobile())->path());
248 kShillManagerClientStubCellular
,
249 network_state_handler_
->FirstNetworkByType(NetworkTypePattern::Cellular())
251 EXPECT_EQ(shill::kStateOnline
,
252 test_observer_
->default_network_connection_state());
255 TEST_F(NetworkStateHandlerTest
, TechnologyChanged
) {
256 // There may be several manager changes during initialization.
257 size_t initial_changed_count
= test_observer_
->device_list_changed_count();
258 // Disable a technology.
259 network_state_handler_
->SetTechnologyEnabled(
260 NetworkTypePattern::Wimax(), false, network_handler::ErrorCallback());
262 NetworkStateHandler::TECHNOLOGY_ENABLED
,
263 network_state_handler_
->GetTechnologyState(NetworkTypePattern::Wimax()));
264 EXPECT_EQ(initial_changed_count
+ 1,
265 test_observer_
->device_list_changed_count());
266 // Enable a technology.
267 network_state_handler_
->SetTechnologyEnabled(
268 NetworkTypePattern::Wimax(), true, network_handler::ErrorCallback());
269 // The technology state should immediately change to ENABLING and we should
270 // receive a manager changed callback.
271 EXPECT_EQ(initial_changed_count
+ 2,
272 test_observer_
->device_list_changed_count());
274 NetworkStateHandler::TECHNOLOGY_ENABLING
,
275 network_state_handler_
->GetTechnologyState(NetworkTypePattern::Wimax()));
276 message_loop_
.RunUntilIdle();
277 // Ensure we receive 2 manager changed callbacks when the technology becomes
278 // avalable and enabled.
279 EXPECT_EQ(initial_changed_count
+ 4,
280 test_observer_
->device_list_changed_count());
282 NetworkStateHandler::TECHNOLOGY_ENABLED
,
283 network_state_handler_
->GetTechnologyState(NetworkTypePattern::Wimax()));
286 TEST_F(NetworkStateHandlerTest
, TechnologyState
) {
287 manager_test_
->RemoveTechnology(shill::kTypeWimax
);
288 message_loop_
.RunUntilIdle();
290 NetworkStateHandler::TECHNOLOGY_UNAVAILABLE
,
291 network_state_handler_
->GetTechnologyState(NetworkTypePattern::Wimax()));
293 manager_test_
->AddTechnology(shill::kTypeWimax
, false);
294 message_loop_
.RunUntilIdle();
296 NetworkStateHandler::TECHNOLOGY_AVAILABLE
,
297 network_state_handler_
->GetTechnologyState(NetworkTypePattern::Wimax()));
299 manager_test_
->SetTechnologyInitializing(shill::kTypeWimax
, true);
300 message_loop_
.RunUntilIdle();
302 NetworkStateHandler::TECHNOLOGY_UNINITIALIZED
,
303 network_state_handler_
->GetTechnologyState(NetworkTypePattern::Wimax()));
305 manager_test_
->SetTechnologyInitializing(shill::kTypeWimax
, false);
306 network_state_handler_
->SetTechnologyEnabled(
307 NetworkTypePattern::Wimax(), true, network_handler::ErrorCallback());
308 message_loop_
.RunUntilIdle();
310 NetworkStateHandler::TECHNOLOGY_ENABLED
,
311 network_state_handler_
->GetTechnologyState(NetworkTypePattern::Wimax()));
313 manager_test_
->RemoveTechnology(shill::kTypeWimax
);
314 message_loop_
.RunUntilIdle();
316 NetworkStateHandler::TECHNOLOGY_UNAVAILABLE
,
317 network_state_handler_
->GetTechnologyState(NetworkTypePattern::Wimax()));
320 TEST_F(NetworkStateHandlerTest
, ServicePropertyChanged
) {
321 // Set a service property.
322 const std::string eth1
= kShillManagerClientStubDefaultService
;
323 const NetworkState
* ethernet
= network_state_handler_
->GetNetworkState(eth1
);
324 ASSERT_TRUE(ethernet
);
325 EXPECT_EQ("", ethernet
->security());
326 EXPECT_EQ(1, test_observer_
->PropertyUpdatesForService(eth1
));
327 base::StringValue
security_value("TestSecurity");
328 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
329 dbus::ObjectPath(eth1
),
330 shill::kSecurityProperty
, security_value
,
331 base::Bind(&base::DoNothing
), base::Bind(&ErrorCallbackFunction
));
332 message_loop_
.RunUntilIdle();
333 ethernet
= network_state_handler_
->GetNetworkState(eth1
);
334 EXPECT_EQ("TestSecurity", ethernet
->security());
335 EXPECT_EQ(2, test_observer_
->PropertyUpdatesForService(eth1
));
337 // Changing a service to the existing value should not trigger an update.
338 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
339 dbus::ObjectPath(eth1
),
340 shill::kSecurityProperty
, security_value
,
341 base::Bind(&base::DoNothing
), base::Bind(&ErrorCallbackFunction
));
342 message_loop_
.RunUntilIdle();
343 EXPECT_EQ(2, test_observer_
->PropertyUpdatesForService(eth1
));
346 TEST_F(NetworkStateHandlerTest
, FavoriteState
) {
347 // Set the profile entry of a service
348 const std::string wifi1
= kShillManagerClientStubDefaultWireless
;
349 ShillProfileClient::TestInterface
* profile_test
=
350 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
351 EXPECT_TRUE(profile_test
->AddService("/profile/default", wifi1
));
352 message_loop_
.RunUntilIdle();
353 network_state_handler_
->UpdateManagerProperties();
354 message_loop_
.RunUntilIdle();
355 EXPECT_EQ(1u, test_observer_
->favorite_count());
358 TEST_F(NetworkStateHandlerTest
, NetworkConnectionStateChanged
) {
359 // Change a network state.
360 const std::string eth1
= kShillManagerClientStubDefaultService
;
361 base::StringValue
connection_state_idle_value(shill::kStateIdle
);
362 service_test_
->SetServiceProperty(eth1
, shill::kStateProperty
,
363 connection_state_idle_value
);
364 message_loop_
.RunUntilIdle();
365 EXPECT_EQ(shill::kStateIdle
,
366 test_observer_
->NetworkConnectionStateForService(eth1
));
367 EXPECT_EQ(2, test_observer_
->ConnectionStateChangesForService(eth1
));
368 // Confirm that changing the connection state to the same value does *not*
369 // signal the observer.
370 service_test_
->SetServiceProperty(eth1
, shill::kStateProperty
,
371 connection_state_idle_value
);
372 message_loop_
.RunUntilIdle();
373 EXPECT_EQ(2, test_observer_
->ConnectionStateChangesForService(eth1
));
376 TEST_F(NetworkStateHandlerTest
, DefaultServiceDisconnected
) {
377 const std::string eth1
= kShillManagerClientStubDefaultService
;
378 const std::string wifi1
= kShillManagerClientStubDefaultWireless
;
380 // Disconnect ethernet.
381 test_observer_
->reset_network_change_count();
382 base::StringValue
connection_state_idle_value(shill::kStateIdle
);
383 service_test_
->SetServiceProperty(eth1
, shill::kStateProperty
,
384 connection_state_idle_value
);
385 message_loop_
.RunUntilIdle();
386 // Expect two changes: first when eth1 becomes disconnected, second when
387 // wifi1 becomes the default.
388 EXPECT_EQ(2u, test_observer_
->default_network_change_count());
389 EXPECT_EQ(wifi1
, test_observer_
->default_network());
392 test_observer_
->reset_network_change_count();
393 service_test_
->SetServiceProperty(wifi1
, shill::kStateProperty
,
394 connection_state_idle_value
);
395 message_loop_
.RunUntilIdle();
396 EXPECT_EQ(1u, test_observer_
->default_network_change_count());
397 EXPECT_EQ("", test_observer_
->default_network());
400 TEST_F(NetworkStateHandlerTest
, DefaultServiceConnected
) {
401 const std::string eth1
= kShillManagerClientStubDefaultService
;
402 const std::string wifi1
= kShillManagerClientStubDefaultWireless
;
404 // Disconnect ethernet and wifi.
405 base::StringValue
connection_state_idle_value(shill::kStateIdle
);
406 service_test_
->SetServiceProperty(eth1
, shill::kStateProperty
,
407 connection_state_idle_value
);
408 service_test_
->SetServiceProperty(wifi1
, shill::kStateProperty
,
409 connection_state_idle_value
);
410 message_loop_
.RunUntilIdle();
411 EXPECT_EQ(std::string(), test_observer_
->default_network());
413 // Connect ethernet, should become the default network.
414 test_observer_
->reset_network_change_count();
415 base::StringValue
connection_state_ready_value(shill::kStateReady
);
416 service_test_
->SetServiceProperty(eth1
, shill::kStateProperty
,
417 connection_state_ready_value
);
418 message_loop_
.RunUntilIdle();
419 EXPECT_EQ(eth1
, test_observer_
->default_network());
420 EXPECT_EQ(shill::kStateReady
,
421 test_observer_
->default_network_connection_state());
422 EXPECT_EQ(1u, test_observer_
->default_network_change_count());
425 TEST_F(NetworkStateHandlerTest
, DefaultServiceChanged
) {
426 const std::string eth1
= kShillManagerClientStubDefaultService
;
427 // The default service should be eth1.
428 EXPECT_EQ(eth1
, test_observer_
->default_network());
430 // Change the default network by changing Manager.DefaultService.
431 test_observer_
->reset_network_change_count();
432 const std::string wifi1
= kShillManagerClientStubDefaultWireless
;
433 base::StringValue
wifi1_value(wifi1
);
434 manager_test_
->SetManagerProperty(
435 shill::kDefaultServiceProperty
, wifi1_value
);
436 message_loop_
.RunUntilIdle();
437 EXPECT_EQ(wifi1
, test_observer_
->default_network());
438 EXPECT_EQ(1u, test_observer_
->default_network_change_count());
440 // Change the state of the default network.
441 test_observer_
->reset_network_change_count();
442 base::StringValue
connection_state_ready_value(shill::kStateReady
);
443 service_test_
->SetServiceProperty(wifi1
, shill::kStateProperty
,
444 connection_state_ready_value
);
445 message_loop_
.RunUntilIdle();
446 EXPECT_EQ(shill::kStateReady
,
447 test_observer_
->default_network_connection_state());
448 EXPECT_EQ(1u, test_observer_
->default_network_change_count());
450 // Updating a property on the default network should trigger
451 // a default network change.
452 test_observer_
->reset_network_change_count();
453 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
454 dbus::ObjectPath(wifi1
),
455 shill::kSecurityProperty
, base::StringValue("TestSecurity"),
456 base::Bind(&base::DoNothing
), base::Bind(&ErrorCallbackFunction
));
457 message_loop_
.RunUntilIdle();
458 EXPECT_EQ(1u, test_observer_
->default_network_change_count());
460 // No default network updates for signal strength changes.
461 test_observer_
->reset_network_change_count();
462 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
463 dbus::ObjectPath(wifi1
),
464 shill::kSignalStrengthProperty
, base::FundamentalValue(32),
465 base::Bind(&base::DoNothing
), base::Bind(&ErrorCallbackFunction
));
466 message_loop_
.RunUntilIdle();
467 EXPECT_EQ(0u, test_observer_
->default_network_change_count());
470 TEST_F(NetworkStateHandlerTest
, RequestUpdate
) {
471 // Request an update for kShillManagerClientStubDefaultWireless.
472 EXPECT_EQ(1, test_observer_
->PropertyUpdatesForService(
473 kShillManagerClientStubDefaultWireless
));
474 network_state_handler_
->RequestUpdateForNetwork(
475 kShillManagerClientStubDefaultWireless
);
476 message_loop_
.RunUntilIdle();
477 EXPECT_EQ(2, test_observer_
->PropertyUpdatesForService(
478 kShillManagerClientStubDefaultWireless
));
480 // Request an update for all networks.
481 network_state_handler_
->RequestUpdateForAllNetworks();
482 message_loop_
.RunUntilIdle();
483 // kShillManagerClientStubDefaultWireless should now have 3 updates
484 EXPECT_EQ(3, test_observer_
->PropertyUpdatesForService(
485 kShillManagerClientStubDefaultWireless
));
486 // Other networks should have 2 updates (inital + request).
487 EXPECT_EQ(2, test_observer_
->PropertyUpdatesForService(
488 kShillManagerClientStubDefaultService
));
489 EXPECT_EQ(2, test_observer_
->PropertyUpdatesForService(
490 kShillManagerClientStubWireless2
));
491 EXPECT_EQ(2, test_observer_
->PropertyUpdatesForService(
492 kShillManagerClientStubCellular
));
495 } // namespace chromeos