1 // Copyright 2013 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/dbus/fake_shill_manager_client.h"
8 #include "base/command_line.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_split.h"
12 #include "base/strings/string_util.h"
13 #include "base/values.h"
14 #include "chromeos/chromeos_switches.h"
15 #include "chromeos/dbus/dbus_thread_manager.h"
16 #include "chromeos/dbus/shill_device_client.h"
17 #include "chromeos/dbus/shill_ipconfig_client.h"
18 #include "chromeos/dbus/shill_profile_client.h"
19 #include "chromeos/dbus/shill_property_changed_observer.h"
20 #include "chromeos/dbus/shill_service_client.h"
22 #include "dbus/message.h"
23 #include "dbus/object_path.h"
24 #include "dbus/values_util.h"
25 #include "third_party/cros_system_api/dbus/service_constants.h"
31 // Used to compare values for finding entries to erase in a ListValue.
32 // (ListValue only implements a const_iterator version of Find).
34 explicit ValueEquals(const base::Value
* first
) : first_(first
) {}
35 bool operator()(const base::Value
* second
) const {
36 return first_
->Equals(second
);
38 const base::Value
* first_
;
41 // Appends string entries from |service_list_in| whose entries in ServiceClient
42 // have Type |match_type| to one of the output lists based on the entry's State.
43 void AppendServicesForType(
44 const base::ListValue
* service_list_in
,
45 const char* match_type
,
46 bool technology_enabled
,
47 std::vector
<std::string
>* active_service_list_out
,
48 std::vector
<std::string
>* inactive_service_list_out
,
49 std::vector
<std::string
>* disabled_service_list_out
) {
50 ShillServiceClient::TestInterface
* service_client
=
51 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
52 for (base::ListValue::const_iterator iter
= service_list_in
->begin();
53 iter
!= service_list_in
->end(); ++iter
) {
54 std::string service_path
;
55 if (!(*iter
)->GetAsString(&service_path
))
57 const base::DictionaryValue
* properties
=
58 service_client
->GetServiceProperties(service_path
);
60 LOG(ERROR
) << "Properties not found for service: " << service_path
;
64 properties
->GetString(shill::kTypeProperty
, &type
);
65 if (type
!= match_type
)
68 if (technology_enabled
)
69 properties
->GetBoolean(shill::kVisibleProperty
, &visible
);
71 disabled_service_list_out
->push_back(service_path
);
75 properties
->GetString(shill::kStateProperty
, &state
);
76 if (state
== shill::kStateOnline
||
77 state
== shill::kStateAssociation
||
78 state
== shill::kStateConfiguration
||
79 state
== shill::kStatePortal
||
80 state
== shill::kStateReady
) {
81 active_service_list_out
->push_back(service_path
);
83 inactive_service_list_out
->push_back(service_path
);
88 void LogErrorCallback(const std::string
& error_name
,
89 const std::string
& error_message
) {
90 LOG(ERROR
) << error_name
<< ": " << error_message
;
93 bool IsConnectedState(const std::string
& state
) {
94 return state
== shill::kStateOnline
|| state
== shill::kStatePortal
||
95 state
== shill::kStateReady
;
98 void UpdatePortaledWifiState(const std::string
& service_path
) {
99 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
100 ->SetServiceProperty(service_path
,
101 shill::kStateProperty
,
102 base::StringValue(shill::kStatePortal
));
105 const char* kTechnologyUnavailable
= "unavailable";
106 const char* kNetworkActivated
= "activated";
107 const char* kNetworkDisabled
= "disabled";
108 const char* kCellularServicePath
= "/service/cellular1";
113 const char FakeShillManagerClient::kFakeEthernetNetworkGuid
[] = "eth1_guid";
115 FakeShillManagerClient::FakeShillManagerClient()
116 : interactive_delay_(0),
117 weak_ptr_factory_(this) {
118 ParseCommandLineSwitch();
121 FakeShillManagerClient::~FakeShillManagerClient() {}
123 // ShillManagerClient overrides.
125 void FakeShillManagerClient::Init(dbus::Bus
* bus
) {}
127 void FakeShillManagerClient::AddPropertyChangedObserver(
128 ShillPropertyChangedObserver
* observer
) {
129 observer_list_
.AddObserver(observer
);
132 void FakeShillManagerClient::RemovePropertyChangedObserver(
133 ShillPropertyChangedObserver
* observer
) {
134 observer_list_
.RemoveObserver(observer
);
137 void FakeShillManagerClient::GetProperties(
138 const DictionaryValueCallback
& callback
) {
139 DVLOG(1) << "Manager.GetProperties";
140 base::MessageLoop::current()->PostTask(
141 FROM_HERE
, base::Bind(
142 &FakeShillManagerClient::PassStubProperties
,
143 weak_ptr_factory_
.GetWeakPtr(),
147 void FakeShillManagerClient::GetNetworksForGeolocation(
148 const DictionaryValueCallback
& callback
) {
149 base::MessageLoop::current()->PostTask(
150 FROM_HERE
, base::Bind(
151 &FakeShillManagerClient::PassStubGeoNetworks
,
152 weak_ptr_factory_
.GetWeakPtr(),
156 void FakeShillManagerClient::SetProperty(const std::string
& name
,
157 const base::Value
& value
,
158 const base::Closure
& callback
,
159 const ErrorCallback
& error_callback
) {
160 DVLOG(2) << "SetProperty: " << name
;
161 stub_properties_
.SetWithoutPathExpansion(name
, value
.DeepCopy());
162 CallNotifyObserversPropertyChanged(name
);
163 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
166 void FakeShillManagerClient::RequestScan(const std::string
& type
,
167 const base::Closure
& callback
,
168 const ErrorCallback
& error_callback
) {
169 // For Stub purposes, default to a Wifi scan.
170 std::string device_type
= shill::kTypeWifi
;
173 ShillDeviceClient::TestInterface
* device_client
=
174 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
175 std::string device_path
= device_client
->GetDevicePathForType(device_type
);
176 if (!device_path
.empty()) {
177 device_client
->SetDeviceProperty(
178 device_path
, shill::kScanningProperty
, base::FundamentalValue(true));
180 base::MessageLoop::current()->PostDelayedTask(
182 base::Bind(&FakeShillManagerClient::ScanCompleted
,
183 weak_ptr_factory_
.GetWeakPtr(),
186 base::TimeDelta::FromSeconds(interactive_delay_
));
189 void FakeShillManagerClient::EnableTechnology(
190 const std::string
& type
,
191 const base::Closure
& callback
,
192 const ErrorCallback
& error_callback
) {
193 base::ListValue
* enabled_list
= NULL
;
194 if (!stub_properties_
.GetListWithoutPathExpansion(
195 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
196 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
197 base::MessageLoop::current()->PostTask(
199 base::Bind(error_callback
, "StubError", "Property not found"));
202 base::MessageLoop::current()->PostDelayedTask(
204 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
205 weak_ptr_factory_
.GetWeakPtr(),
209 base::TimeDelta::FromSeconds(interactive_delay_
));
212 void FakeShillManagerClient::DisableTechnology(
213 const std::string
& type
,
214 const base::Closure
& callback
,
215 const ErrorCallback
& error_callback
) {
216 base::ListValue
* enabled_list
= NULL
;
217 if (!stub_properties_
.GetListWithoutPathExpansion(
218 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
219 base::MessageLoop::current()->PostTask(
221 base::Bind(error_callback
, "StubError", "Property not found"));
224 base::MessageLoop::current()->PostDelayedTask(
226 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
227 weak_ptr_factory_
.GetWeakPtr(),
231 base::TimeDelta::FromSeconds(interactive_delay_
));
234 void FakeShillManagerClient::ConfigureService(
235 const base::DictionaryValue
& properties
,
236 const ObjectPathCallback
& callback
,
237 const ErrorCallback
& error_callback
) {
238 ShillServiceClient::TestInterface
* service_client
=
239 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
243 if (!properties
.GetString(shill::kGuidProperty
, &guid
) ||
244 !properties
.GetString(shill::kTypeProperty
, &type
)) {
245 LOG(ERROR
) << "ConfigureService requires GUID and Type to be defined";
246 // If the properties aren't filled out completely, then just return an empty
248 base::MessageLoop::current()->PostTask(
249 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
253 // For the purposes of this stub, we're going to assume that the GUID property
254 // is set to the service path because we don't want to re-implement Shill's
255 // property matching magic here.
256 std::string service_path
= guid
;
258 std::string ipconfig_path
;
259 properties
.GetString(shill::kIPConfigProperty
, &ipconfig_path
);
261 // Merge the new properties with existing properties, if any.
262 const base::DictionaryValue
* existing_properties
=
263 service_client
->GetServiceProperties(service_path
);
264 if (!existing_properties
) {
265 // Add a new service to the service client stub because none exists, yet.
266 // This calls AddManagerService.
267 service_client
->AddServiceWithIPConfig(service_path
,
274 existing_properties
= service_client
->GetServiceProperties(service_path
);
277 scoped_ptr
<base::DictionaryValue
> merged_properties(
278 existing_properties
->DeepCopy());
279 merged_properties
->MergeDictionary(&properties
);
281 // Now set all the properties.
282 for (base::DictionaryValue::Iterator
iter(*merged_properties
);
283 !iter
.IsAtEnd(); iter
.Advance()) {
284 service_client
->SetServiceProperty(service_path
, iter
.key(), iter
.value());
287 // If the Profile property is set, add it to ProfileClient.
288 std::string profile_path
;
289 merged_properties
->GetStringWithoutPathExpansion(shill::kProfileProperty
,
291 if (!profile_path
.empty()) {
292 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface()->
293 AddService(profile_path
, service_path
);
296 base::MessageLoop::current()->PostTask(
297 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath(service_path
)));
300 void FakeShillManagerClient::ConfigureServiceForProfile(
301 const dbus::ObjectPath
& profile_path
,
302 const base::DictionaryValue
& properties
,
303 const ObjectPathCallback
& callback
,
304 const ErrorCallback
& error_callback
) {
305 std::string profile_property
;
306 properties
.GetStringWithoutPathExpansion(shill::kProfileProperty
,
308 CHECK(profile_property
== profile_path
.value());
309 ConfigureService(properties
, callback
, error_callback
);
313 void FakeShillManagerClient::GetService(
314 const base::DictionaryValue
& properties
,
315 const ObjectPathCallback
& callback
,
316 const ErrorCallback
& error_callback
) {
317 base::MessageLoop::current()->PostTask(
318 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
321 void FakeShillManagerClient::VerifyDestination(
322 const VerificationProperties
& properties
,
323 const BooleanCallback
& callback
,
324 const ErrorCallback
& error_callback
) {
325 base::MessageLoop::current()->PostTask(FROM_HERE
, base::Bind(callback
, true));
328 void FakeShillManagerClient::VerifyAndEncryptCredentials(
329 const VerificationProperties
& properties
,
330 const std::string
& service_path
,
331 const StringCallback
& callback
,
332 const ErrorCallback
& error_callback
) {
333 base::MessageLoop::current()->PostTask(
334 FROM_HERE
, base::Bind(callback
, "encrypted_credentials"));
337 void FakeShillManagerClient::VerifyAndEncryptData(
338 const VerificationProperties
& properties
,
339 const std::string
& data
,
340 const StringCallback
& callback
,
341 const ErrorCallback
& error_callback
) {
342 base::MessageLoop::current()->PostTask(
343 FROM_HERE
, base::Bind(callback
, "encrypted_data"));
346 void FakeShillManagerClient::ConnectToBestServices(
347 const base::Closure
& callback
,
348 const ErrorCallback
& error_callback
) {
349 if (best_service_
.empty()) {
350 VLOG(1) << "No 'best' service set.";
354 DBusThreadManager::Get()->GetShillServiceClient()->Connect(
355 dbus::ObjectPath(best_service_
), callback
, error_callback
);
358 void FakeShillManagerClient::AddWakeOnPacketConnection(
359 const net::IPEndPoint
& ip_endpoint
,
360 const base::Closure
& callback
,
361 const ErrorCallback
& error_callback
) {
364 void FakeShillManagerClient::RemoveWakeOnPacketConnection(
365 const net::IPEndPoint
& ip_endpoint
,
366 const base::Closure
& callback
,
367 const ErrorCallback
& error_callback
) {
370 void FakeShillManagerClient::RemoveAllWakeOnPacketConnections(
371 const base::Closure
& callback
,
372 const ErrorCallback
& error_callback
) {
375 ShillManagerClient::TestInterface
* FakeShillManagerClient::GetTestInterface() {
379 // ShillManagerClient::TestInterface overrides.
381 void FakeShillManagerClient::AddDevice(const std::string
& device_path
) {
382 if (GetListProperty(shill::kDevicesProperty
)
383 ->AppendIfNotPresent(new base::StringValue(device_path
))) {
384 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
388 void FakeShillManagerClient::RemoveDevice(const std::string
& device_path
) {
389 base::StringValue
device_path_value(device_path
);
390 if (GetListProperty(shill::kDevicesProperty
)->Remove(
391 device_path_value
, NULL
)) {
392 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
396 void FakeShillManagerClient::ClearDevices() {
397 GetListProperty(shill::kDevicesProperty
)->Clear();
398 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
401 void FakeShillManagerClient::AddTechnology(const std::string
& type
,
403 if (GetListProperty(shill::kAvailableTechnologiesProperty
)
404 ->AppendIfNotPresent(new base::StringValue(type
))) {
405 CallNotifyObserversPropertyChanged(
406 shill::kAvailableTechnologiesProperty
);
409 GetListProperty(shill::kEnabledTechnologiesProperty
)
410 ->AppendIfNotPresent(new base::StringValue(type
))) {
411 CallNotifyObserversPropertyChanged(
412 shill::kEnabledTechnologiesProperty
);
416 void FakeShillManagerClient::RemoveTechnology(const std::string
& type
) {
417 base::StringValue
type_value(type
);
418 if (GetListProperty(shill::kAvailableTechnologiesProperty
)->Remove(
420 CallNotifyObserversPropertyChanged(
421 shill::kAvailableTechnologiesProperty
);
423 if (GetListProperty(shill::kEnabledTechnologiesProperty
)->Remove(
425 CallNotifyObserversPropertyChanged(
426 shill::kEnabledTechnologiesProperty
);
430 void FakeShillManagerClient::SetTechnologyInitializing(const std::string
& type
,
433 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)
434 ->AppendIfNotPresent(new base::StringValue(type
))) {
435 CallNotifyObserversPropertyChanged(
436 shill::kUninitializedTechnologiesProperty
);
439 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)->Remove(
440 base::StringValue(type
), NULL
)) {
441 CallNotifyObserversPropertyChanged(
442 shill::kUninitializedTechnologiesProperty
);
447 void FakeShillManagerClient::AddGeoNetwork(
448 const std::string
& technology
,
449 const base::DictionaryValue
& network
) {
450 base::ListValue
* list_value
= NULL
;
451 if (!stub_geo_networks_
.GetListWithoutPathExpansion(technology
,
453 list_value
= new base::ListValue
;
454 stub_geo_networks_
.SetWithoutPathExpansion(technology
, list_value
);
456 list_value
->Append(network
.DeepCopy());
459 void FakeShillManagerClient::AddProfile(const std::string
& profile_path
) {
460 const char* key
= shill::kProfilesProperty
;
461 if (GetListProperty(key
)
462 ->AppendIfNotPresent(new base::StringValue(profile_path
))) {
463 CallNotifyObserversPropertyChanged(key
);
467 void FakeShillManagerClient::ClearProperties() {
468 stub_properties_
.Clear();
471 void FakeShillManagerClient::SetManagerProperty(const std::string
& key
,
472 const base::Value
& value
) {
473 SetProperty(key
, value
,
474 base::Bind(&base::DoNothing
), base::Bind(&LogErrorCallback
));
477 void FakeShillManagerClient::AddManagerService(
478 const std::string
& service_path
,
479 bool notify_observers
) {
480 DVLOG(2) << "AddManagerService: " << service_path
;
481 GetListProperty(shill::kServiceCompleteListProperty
)
482 ->AppendIfNotPresent(new base::StringValue(service_path
));
483 SortManagerServices(false);
484 if (notify_observers
)
485 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
488 void FakeShillManagerClient::RemoveManagerService(
489 const std::string
& service_path
) {
490 DVLOG(2) << "RemoveManagerService: " << service_path
;
491 base::StringValue
service_path_value(service_path
);
492 GetListProperty(shill::kServiceCompleteListProperty
)->Remove(
493 service_path_value
, NULL
);
494 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
497 void FakeShillManagerClient::ClearManagerServices() {
498 DVLOG(1) << "ClearManagerServices";
499 GetListProperty(shill::kServiceCompleteListProperty
)->Clear();
500 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
503 void FakeShillManagerClient::ServiceStateChanged(
504 const std::string
& service_path
,
505 const std::string
& state
) {
506 if (service_path
== default_service_
&& !IsConnectedState(state
)) {
507 // Default service is no longer connected; clear.
508 default_service_
.clear();
509 base::StringValue
default_service_value(default_service_
);
510 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
514 void FakeShillManagerClient::SortManagerServices(bool notify
) {
515 DVLOG(1) << "SortManagerServices";
516 static const char* ordered_types
[] = {shill::kTypeEthernet
,
517 shill::kTypeEthernetEap
,
519 shill::kTypeCellular
,
523 base::ListValue
* complete_list
=
524 GetListProperty(shill::kServiceCompleteListProperty
);
525 if (complete_list
->empty())
527 scoped_ptr
<base::ListValue
> prev_complete_list(complete_list
->DeepCopy());
529 std::vector
<std::string
> active_services
;
530 std::vector
<std::string
> inactive_services
;
531 std::vector
<std::string
> disabled_services
;
532 for (size_t i
= 0; i
< arraysize(ordered_types
); ++i
) {
533 AppendServicesForType(complete_list
,
535 TechnologyEnabled(ordered_types
[i
]),
540 complete_list
->Clear();
541 for (size_t i
= 0; i
< active_services
.size(); ++i
)
542 complete_list
->AppendString(active_services
[i
]);
543 for (size_t i
= 0; i
< inactive_services
.size(); ++i
)
544 complete_list
->AppendString(inactive_services
[i
]);
545 for (size_t i
= 0; i
< disabled_services
.size(); ++i
)
546 complete_list
->AppendString(disabled_services
[i
]);
548 if (notify
&& !complete_list
->Equals(prev_complete_list
.get()))
549 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
551 // Set the first active service as the Default service.
552 std::string new_default_service
;
553 if (!active_services
.empty()) {
554 ShillServiceClient::TestInterface
* service_client
=
555 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
556 std::string service_path
= active_services
[0];
557 const base::DictionaryValue
* properties
=
558 service_client
->GetServiceProperties(service_path
);
560 LOG(ERROR
) << "Properties not found for service: " << service_path
;
563 properties
->GetString(shill::kStateProperty
, &state
);
564 if (IsConnectedState(state
))
565 new_default_service
= service_path
;
568 if (default_service_
!= new_default_service
) {
569 default_service_
= new_default_service
;
570 base::StringValue
default_service_value(default_service_
);
571 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
575 int FakeShillManagerClient::GetInteractiveDelay() const {
576 return interactive_delay_
;
579 void FakeShillManagerClient::SetBestServiceToConnect(
580 const std::string
& service_path
) {
581 best_service_
= service_path
;
584 void FakeShillManagerClient::SetupDefaultEnvironment() {
585 // Bail out from setup if there is no message loop. This will be the common
586 // case for tests that are not testing Shill.
587 if (!base::MessageLoop::current())
590 DBusThreadManager
* dbus_manager
= DBusThreadManager::Get();
591 ShillServiceClient::TestInterface
* services
=
592 dbus_manager
->GetShillServiceClient()->GetTestInterface();
594 ShillProfileClient::TestInterface
* profiles
=
595 dbus_manager
->GetShillProfileClient()->GetTestInterface();
597 ShillDeviceClient::TestInterface
* devices
=
598 dbus_manager
->GetShillDeviceClient()->GetTestInterface();
600 ShillIPConfigClient::TestInterface
* ip_configs
=
601 dbus_manager
->GetShillIPConfigClient()->GetTestInterface();
604 const std::string shared_profile
= ShillProfileClient::GetSharedProfilePath();
605 profiles
->AddProfile(shared_profile
, std::string());
607 const bool add_to_visible
= true;
610 base::DictionaryValue ipconfig_v4_dictionary
;
611 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
612 shill::kAddressProperty
, "0.0.0.0");
613 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
614 shill::kGatewayProperty
, "0.0.0.1");
615 ipconfig_v4_dictionary
.SetIntegerWithoutPathExpansion(
616 shill::kPrefixlenProperty
, 0);
617 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
618 shill::kMethodProperty
, shill::kTypeIPv4
);
619 ip_configs
->AddIPConfig("ipconfig_v4_path", ipconfig_v4_dictionary
);
620 base::DictionaryValue ipconfig_v6_dictionary
;
621 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
622 shill::kAddressProperty
, "0:0:0:0:0:0:0:0");
623 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
624 shill::kMethodProperty
, shill::kTypeIPv6
);
625 ip_configs
->AddIPConfig("ipconfig_v6_path", ipconfig_v6_dictionary
);
631 state
= GetInitialStateForType(shill::kTypeEthernet
, &enabled
);
632 if (state
== shill::kStateOnline
) {
633 AddTechnology(shill::kTypeEthernet
, enabled
);
635 "/device/eth1", shill::kTypeEthernet
, "stub_eth_device1");
636 devices
->SetDeviceProperty("/device/eth1",
637 shill::kAddressProperty
,
638 base::StringValue("0123456789ab"));
639 base::ListValue eth_ip_configs
;
640 eth_ip_configs
.AppendString("ipconfig_v4_path");
641 eth_ip_configs
.AppendString("ipconfig_v6_path");
642 devices
->SetDeviceProperty("/device/eth1",
643 shill::kIPConfigsProperty
,
645 const std::string kFakeEthernetNetworkPath
= "/service/eth1";
646 services
->AddService(kFakeEthernetNetworkPath
,
647 kFakeEthernetNetworkGuid
,
649 shill::kTypeEthernet
,
652 profiles
->AddService(shared_profile
, kFakeEthernetNetworkPath
);
656 state
= GetInitialStateForType(shill::kTypeWifi
, &enabled
);
657 if (state
!= kTechnologyUnavailable
) {
658 bool portaled
= false;
659 if (state
== shill::kStatePortal
) {
661 state
= shill::kStateIdle
;
663 AddTechnology(shill::kTypeWifi
, enabled
);
664 devices
->AddDevice("/device/wifi1", shill::kTypeWifi
, "stub_wifi_device1");
665 devices
->SetDeviceProperty("/device/wifi1",
666 shill::kAddressProperty
,
667 base::StringValue("23456789abc"));
668 base::ListValue wifi_ip_configs
;
669 wifi_ip_configs
.AppendString("ipconfig_v4_path");
670 wifi_ip_configs
.AppendString("ipconfig_v6_path");
671 devices
->SetDeviceProperty("/device/wifi1",
672 shill::kIPConfigsProperty
,
675 const std::string kWifi1Path
= "/service/wifi1";
676 services
->AddService(kWifi1Path
,
682 services
->SetServiceProperty(kWifi1Path
,
683 shill::kSecurityProperty
,
684 base::StringValue(shill::kSecurityWep
));
685 services
->SetServiceProperty(kWifi1Path
,
686 shill::kConnectableProperty
,
687 base::FundamentalValue(true));
688 profiles
->AddService(shared_profile
, kWifi1Path
);
690 const std::string kWifi2Path
= "/service/wifi2";
691 services
->AddService(kWifi2Path
,
693 "wifi2_PSK" /* name */,
697 services
->SetServiceProperty(kWifi2Path
,
698 shill::kSecurityProperty
,
699 base::StringValue(shill::kSecurityPsk
));
701 base::FundamentalValue
strength_value(80);
702 services
->SetServiceProperty(
703 kWifi2Path
, shill::kSignalStrengthProperty
, strength_value
);
704 profiles
->AddService(shared_profile
, kWifi2Path
);
707 const std::string kPortaledWifiPath
= "/service/portaled_wifi";
708 services
->AddService(kPortaledWifiPath
,
709 "portaled_wifi_guid",
710 "Portaled Wifi" /* name */,
714 services
->SetServiceProperty(kPortaledWifiPath
,
715 shill::kSecurityProperty
,
716 base::StringValue(shill::kSecurityNone
));
717 services
->SetConnectBehavior(kPortaledWifiPath
,
718 base::Bind(&UpdatePortaledWifiState
,
720 services
->SetServiceProperty(kPortaledWifiPath
,
721 shill::kConnectableProperty
,
722 base::FundamentalValue(true));
723 profiles
->AddService(shared_profile
, kPortaledWifiPath
);
728 state
= GetInitialStateForType(shill::kTypeWimax
, &enabled
);
729 if (state
!= kTechnologyUnavailable
) {
730 AddTechnology(shill::kTypeWimax
, enabled
);
732 "/device/wimax1", shill::kTypeWimax
, "stub_wimax_device1");
734 services
->AddService("/service/wimax1",
740 services
->SetServiceProperty("/service/wimax1",
741 shill::kConnectableProperty
,
742 base::FundamentalValue(true));
743 base::FundamentalValue
strength_value(80);
744 services
->SetServiceProperty(
745 "/service/wimax1", shill::kSignalStrengthProperty
, strength_value
);
746 base::StringValue
identity_value("test.identity");
747 services
->SetServiceProperty(
748 "/service/wimax1", shill::kEapIdentityProperty
, identity_value
);
752 state
= GetInitialStateForType(shill::kTypeCellular
, &enabled
);
753 if (state
!= kTechnologyUnavailable
) {
754 bool activated
= false;
755 if (state
== kNetworkActivated
) {
757 state
= shill::kStateIdle
;
759 AddTechnology(shill::kTypeCellular
, enabled
);
761 "/device/cellular1", shill::kTypeCellular
, "stub_cellular_device1");
762 devices
->SetDeviceProperty("/device/cellular1",
763 shill::kCarrierProperty
,
764 base::StringValue(shill::kCarrierSprint
));
765 base::ListValue carrier_list
;
766 carrier_list
.AppendString(shill::kCarrierSprint
);
767 carrier_list
.AppendString(shill::kCarrierGenericUMTS
);
768 devices
->SetDeviceProperty("/device/cellular1",
769 shill::kSupportedCarriersProperty
,
772 services
->AddService(kCellularServicePath
,
774 "cellular1" /* name */,
775 shill::kTypeCellular
,
778 base::StringValue
technology_value(shill::kNetworkTechnologyGsm
);
779 services
->SetServiceProperty(kCellularServicePath
,
780 shill::kNetworkTechnologyProperty
,
784 services
->SetServiceProperty(
785 kCellularServicePath
,
786 shill::kActivationStateProperty
,
787 base::StringValue(shill::kActivationStateActivated
));
788 services
->SetServiceProperty(kCellularServicePath
,
789 shill::kConnectableProperty
,
790 base::FundamentalValue(true));
792 services
->SetServiceProperty(
793 kCellularServicePath
,
794 shill::kActivationStateProperty
,
795 base::StringValue(shill::kActivationStateNotActivated
));
798 services
->SetServiceProperty(kCellularServicePath
,
799 shill::kRoamingStateProperty
,
800 base::StringValue(shill::kRoamingStateHome
));
804 state
= GetInitialStateForType(shill::kTypeVPN
, &enabled
);
805 if (state
!= kTechnologyUnavailable
) {
806 // Set the "Provider" dictionary properties. Note: when setting these in
807 // Shill, "Provider.Type", etc keys are used, but when reading the values
808 // "Provider" . "Type", etc keys are used. Here we are setting the values
809 // that will be read (by the UI, tests, etc).
810 base::DictionaryValue provider_properties_openvpn
;
811 provider_properties_openvpn
.SetString(shill::kTypeProperty
,
812 shill::kProviderOpenVpn
);
813 provider_properties_openvpn
.SetString(shill::kHostProperty
, "vpn_host");
815 services
->AddService("/service/vpn1",
821 services
->SetServiceProperty(
822 "/service/vpn1", shill::kProviderProperty
, provider_properties_openvpn
);
823 profiles
->AddService(shared_profile
, "/service/vpn1");
825 base::DictionaryValue provider_properties_l2tp
;
826 provider_properties_l2tp
.SetString(shill::kTypeProperty
,
827 shill::kProviderL2tpIpsec
);
828 provider_properties_l2tp
.SetString(shill::kHostProperty
, "vpn_host2");
830 services
->AddService("/service/vpn2",
836 services
->SetServiceProperty(
837 "/service/vpn2", shill::kProviderProperty
, provider_properties_l2tp
);
840 // Additional device states
841 for (DevicePropertyMap::iterator iter1
= shill_device_property_map_
.begin();
842 iter1
!= shill_device_property_map_
.end(); ++iter1
) {
843 std::string device_type
= iter1
->first
;
844 std::string device_path
= devices
->GetDevicePathForType(device_type
);
845 for (ShillPropertyMap::iterator iter2
= iter1
->second
.begin();
846 iter2
!= iter1
->second
.end(); ++iter2
) {
847 devices
->SetDeviceProperty(device_path
, iter2
->first
, *(iter2
->second
));
848 delete iter2
->second
;
852 SortManagerServices(true);
857 void FakeShillManagerClient::PassStubProperties(
858 const DictionaryValueCallback
& callback
) const {
859 scoped_ptr
<base::DictionaryValue
> stub_properties(
860 stub_properties_
.DeepCopy());
861 stub_properties
->SetWithoutPathExpansion(
862 shill::kServiceCompleteListProperty
,
863 GetEnabledServiceList(shill::kServiceCompleteListProperty
));
864 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, *stub_properties
);
867 void FakeShillManagerClient::PassStubGeoNetworks(
868 const DictionaryValueCallback
& callback
) const {
869 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, stub_geo_networks_
);
872 void FakeShillManagerClient::CallNotifyObserversPropertyChanged(
873 const std::string
& property
) {
874 // Avoid unnecessary delayed task if we have no observers (e.g. during
876 if (!observer_list_
.might_have_observers())
878 base::MessageLoop::current()->PostTask(
880 base::Bind(&FakeShillManagerClient::NotifyObserversPropertyChanged
,
881 weak_ptr_factory_
.GetWeakPtr(),
885 void FakeShillManagerClient::NotifyObserversPropertyChanged(
886 const std::string
& property
) {
887 DVLOG(1) << "NotifyObserversPropertyChanged: " << property
;
888 base::Value
* value
= NULL
;
889 if (!stub_properties_
.GetWithoutPathExpansion(property
, &value
)) {
890 LOG(ERROR
) << "Notify for unknown property: " << property
;
893 if (property
== shill::kServiceCompleteListProperty
) {
894 scoped_ptr
<base::ListValue
> services(GetEnabledServiceList(property
));
895 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
897 OnPropertyChanged(property
, *(services
.get())));
900 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
902 OnPropertyChanged(property
, *value
));
905 base::ListValue
* FakeShillManagerClient::GetListProperty(
906 const std::string
& property
) {
907 base::ListValue
* list_property
= NULL
;
908 if (!stub_properties_
.GetListWithoutPathExpansion(
909 property
, &list_property
)) {
910 list_property
= new base::ListValue
;
911 stub_properties_
.SetWithoutPathExpansion(property
, list_property
);
913 return list_property
;
916 bool FakeShillManagerClient::TechnologyEnabled(const std::string
& type
) const {
917 if (type
== shill::kTypeVPN
)
918 return true; // VPN is always "enabled" since there is no associated device
919 if (type
== shill::kTypeEthernetEap
)
921 bool enabled
= false;
922 const base::ListValue
* technologies
;
923 if (stub_properties_
.GetListWithoutPathExpansion(
924 shill::kEnabledTechnologiesProperty
, &technologies
)) {
925 base::StringValue
type_value(type
);
926 if (technologies
->Find(type_value
) != technologies
->end())
932 void FakeShillManagerClient::SetTechnologyEnabled(
933 const std::string
& type
,
934 const base::Closure
& callback
,
936 base::ListValue
* enabled_list
=
937 GetListProperty(shill::kEnabledTechnologiesProperty
);
939 enabled_list
->AppendIfNotPresent(new base::StringValue(type
));
941 enabled_list
->Remove(base::StringValue(type
), NULL
);
942 CallNotifyObserversPropertyChanged(
943 shill::kEnabledTechnologiesProperty
);
944 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
945 // May affect available services.
946 SortManagerServices(true);
949 base::ListValue
* FakeShillManagerClient::GetEnabledServiceList(
950 const std::string
& property
) const {
951 base::ListValue
* new_service_list
= new base::ListValue
;
952 const base::ListValue
* service_list
;
953 if (stub_properties_
.GetListWithoutPathExpansion(property
, &service_list
)) {
954 ShillServiceClient::TestInterface
* service_client
=
955 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
956 for (base::ListValue::const_iterator iter
= service_list
->begin();
957 iter
!= service_list
->end(); ++iter
) {
958 std::string service_path
;
959 if (!(*iter
)->GetAsString(&service_path
))
961 const base::DictionaryValue
* properties
=
962 service_client
->GetServiceProperties(service_path
);
964 LOG(ERROR
) << "Properties not found for service: " << service_path
;
968 properties
->GetString(shill::kTypeProperty
, &type
);
969 if (TechnologyEnabled(type
))
970 new_service_list
->Append((*iter
)->DeepCopy());
973 return new_service_list
;
976 void FakeShillManagerClient::ScanCompleted(const std::string
& device_path
,
977 const base::Closure
& callback
) {
978 if (!device_path
.empty()) {
979 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
980 SetDeviceProperty(device_path
,
981 shill::kScanningProperty
,
982 base::FundamentalValue(false));
984 DVLOG(2) << "ScanCompleted";
985 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
986 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
989 void FakeShillManagerClient::ParseCommandLineSwitch() {
991 SetInitialNetworkState(shill::kTypeEthernet
, shill::kStateOnline
);
992 SetInitialNetworkState(shill::kTypeWifi
, shill::kStateOnline
);
993 SetInitialNetworkState(shill::kTypeCellular
, shill::kStateIdle
);
994 SetInitialNetworkState(shill::kTypeVPN
, shill::kStateIdle
);
996 // Parse additional options
997 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
998 if (!command_line
->HasSwitch(switches::kShillStub
))
1001 std::string option_str
=
1002 command_line
->GetSwitchValueASCII(switches::kShillStub
);
1003 VLOG(1) << "Parsing command line:" << option_str
;
1004 base::StringPairs string_pairs
;
1005 base::SplitStringIntoKeyValuePairs(option_str
, '=', ',', &string_pairs
);
1006 for (base::StringPairs::iterator iter
= string_pairs
.begin();
1007 iter
!= string_pairs
.end(); ++iter
) {
1008 ParseOption((*iter
).first
, (*iter
).second
);
1012 bool FakeShillManagerClient::ParseOption(const std::string
& arg0
,
1013 const std::string
& arg1
) {
1014 VLOG(1) << "Parsing command line option: '" << arg0
<< "=" << arg1
<< "'";
1015 if ((arg0
== "clear" || arg0
== "reset") && arg1
== "1") {
1016 shill_initial_state_map_
.clear();
1018 } else if (arg0
== "interactive") {
1021 base::StringToInt(arg1
, &seconds
);
1022 interactive_delay_
= seconds
;
1024 } else if (arg0
== "sim_lock") {
1025 bool locked
= (arg1
== "1") ? true : false;
1026 base::DictionaryValue
* simlock_dict
= new base::DictionaryValue
;
1027 simlock_dict
->Set(shill::kSIMLockEnabledProperty
,
1028 new base::FundamentalValue(locked
));
1029 // TODO(stevenjb): Investigate why non-empty value breaks UI.
1030 std::string lock_type
= ""; // shill::kSIMLockPin
1031 simlock_dict
->SetString(shill::kSIMLockTypeProperty
, lock_type
);
1032 simlock_dict
->SetInteger(shill::kSIMLockRetriesLeftProperty
, 5);
1034 shill_device_property_map_
1035 [shill::kTypeCellular
][shill::kSIMLockStatusProperty
] = simlock_dict
;
1036 shill_device_property_map_
1037 [shill::kTypeCellular
][shill::kTechnologyFamilyProperty
] =
1038 new base::StringValue(shill::kNetworkTechnologyGsm
);
1041 return SetInitialNetworkState(arg0
, arg1
);
1044 bool FakeShillManagerClient::SetInitialNetworkState(std::string type_arg
,
1045 std::string state_arg
) {
1047 state_arg
= base::StringToLowerASCII(state_arg
);
1048 if (state_arg
.empty() || state_arg
== "1" || state_arg
== "on" ||
1049 state_arg
== "enabled" || state_arg
== "connected" ||
1050 state_arg
== "online") {
1051 // Enabled and connected (default value)
1052 state
= shill::kStateOnline
;
1053 } else if (state_arg
== "0" || state_arg
== "off" ||
1054 state_arg
== "inactive" || state_arg
== shill::kStateIdle
) {
1055 // Technology enabled, services are created but are not connected.
1056 state
= shill::kStateIdle
;
1057 } else if (state_arg
== "disabled" || state_arg
== "disconnect") {
1058 // Technology disabled but available, services created but not connected.
1059 state
= kNetworkDisabled
;
1060 } else if (state_arg
== "none" || state_arg
== "offline") {
1061 // Technology not available, do not create services.
1062 state
= kTechnologyUnavailable
;
1063 } else if (state_arg
== "portal") {
1064 // Technology is enabled, a service is connected and in Portal state.
1065 state
= shill::kStatePortal
;
1066 } else if (state_arg
== "active" || state_arg
== "activated") {
1067 // Technology is enabled, a service is connected and Activated.
1068 state
= kNetworkActivated
;
1070 LOG(ERROR
) << "Unrecognized initial state: " << state_arg
;
1074 type_arg
= base::StringToLowerASCII(type_arg
);
1076 if (type_arg
== "wireless") {
1077 shill_initial_state_map_
[shill::kTypeWifi
] = state
;
1078 shill_initial_state_map_
[shill::kTypeCellular
] = state
;
1081 // Convenience synonyms.
1082 if (type_arg
== "eth")
1083 type_arg
= shill::kTypeEthernet
;
1085 if (type_arg
!= shill::kTypeEthernet
&&
1086 type_arg
!= shill::kTypeWifi
&&
1087 type_arg
!= shill::kTypeCellular
&&
1088 type_arg
!= shill::kTypeWimax
&&
1089 type_arg
!= shill::kTypeVPN
) {
1090 LOG(WARNING
) << "Unrecognized Shill network type: " << type_arg
;
1094 // Unconnected or disabled ethernet is the same as unavailable.
1095 if (type_arg
== shill::kTypeEthernet
&&
1096 (state
== shill::kStateIdle
|| state
== kNetworkDisabled
)) {
1097 state
= kTechnologyUnavailable
;
1100 shill_initial_state_map_
[type_arg
] = state
;
1104 std::string
FakeShillManagerClient::GetInitialStateForType(
1105 const std::string
& type
,
1107 std::map
<std::string
, std::string
>::const_iterator iter
=
1108 shill_initial_state_map_
.find(type
);
1109 if (iter
== shill_initial_state_map_
.end()) {
1111 return kTechnologyUnavailable
;
1113 std::string state
= iter
->second
;
1114 if (state
== kNetworkDisabled
) {
1116 return shill::kStateIdle
;
1119 if ((state
== shill::kStatePortal
&& type
!= shill::kTypeWifi
) ||
1120 (state
== kNetworkActivated
&& type
!= shill::kTypeCellular
)) {
1121 LOG(WARNING
) << "Invalid state: " << state
<< " for " << type
;
1122 return shill::kStateIdle
;
1127 } // namespace chromeos