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 // Allow parsed command line option 'tdls_busy' to set the fake busy count.
32 int s_tdls_busy_count
= 0;
34 // Used to compare values for finding entries to erase in a ListValue.
35 // (ListValue only implements a const_iterator version of Find).
37 explicit ValueEquals(const base::Value
* first
) : first_(first
) {}
38 bool operator()(const base::Value
* second
) const {
39 return first_
->Equals(second
);
41 const base::Value
* first_
;
44 // Appends string entries from |service_list_in| whose entries in ServiceClient
45 // have Type |match_type| to one of the output lists based on the entry's State.
46 void AppendServicesForType(
47 const base::ListValue
* service_list_in
,
48 const char* match_type
,
49 bool technology_enabled
,
50 std::vector
<std::string
>* active_service_list_out
,
51 std::vector
<std::string
>* inactive_service_list_out
,
52 std::vector
<std::string
>* disabled_service_list_out
) {
53 ShillServiceClient::TestInterface
* service_client
=
54 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
55 for (base::ListValue::const_iterator iter
= service_list_in
->begin();
56 iter
!= service_list_in
->end(); ++iter
) {
57 std::string service_path
;
58 if (!(*iter
)->GetAsString(&service_path
))
60 const base::DictionaryValue
* properties
=
61 service_client
->GetServiceProperties(service_path
);
63 LOG(ERROR
) << "Properties not found for service: " << service_path
;
67 properties
->GetString(shill::kTypeProperty
, &type
);
68 if (type
!= match_type
)
71 if (technology_enabled
)
72 properties
->GetBoolean(shill::kVisibleProperty
, &visible
);
74 disabled_service_list_out
->push_back(service_path
);
78 properties
->GetString(shill::kStateProperty
, &state
);
79 if (state
== shill::kStateOnline
||
80 state
== shill::kStateAssociation
||
81 state
== shill::kStateConfiguration
||
82 state
== shill::kStatePortal
||
83 state
== shill::kStateReady
) {
84 active_service_list_out
->push_back(service_path
);
86 inactive_service_list_out
->push_back(service_path
);
91 void LogErrorCallback(const std::string
& error_name
,
92 const std::string
& error_message
) {
93 LOG(ERROR
) << error_name
<< ": " << error_message
;
96 bool IsConnectedState(const std::string
& state
) {
97 return state
== shill::kStateOnline
|| state
== shill::kStatePortal
||
98 state
== shill::kStateReady
;
101 void UpdatePortaledWifiState(const std::string
& service_path
) {
102 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
103 ->SetServiceProperty(service_path
,
104 shill::kStateProperty
,
105 base::StringValue(shill::kStatePortal
));
108 bool IsCellularTechnology(const std::string
& type
) {
109 return (type
== shill::kNetworkTechnology1Xrtt
||
110 type
== shill::kNetworkTechnologyEvdo
||
111 type
== shill::kNetworkTechnologyGsm
||
112 type
== shill::kNetworkTechnologyGprs
||
113 type
== shill::kNetworkTechnologyEdge
||
114 type
== shill::kNetworkTechnologyUmts
||
115 type
== shill::kNetworkTechnologyHspa
||
116 type
== shill::kNetworkTechnologyHspaPlus
||
117 type
== shill::kNetworkTechnologyLte
||
118 type
== shill::kNetworkTechnologyLteAdvanced
);
121 const char* kTechnologyUnavailable
= "unavailable";
122 const char* kNetworkActivated
= "activated";
123 const char* kNetworkDisabled
= "disabled";
124 const char* kCellularServicePath
= "/service/cellular1";
125 const char* kRoamingRequired
= "required";
130 const char FakeShillManagerClient::kFakeEthernetNetworkGuid
[] = "eth1_guid";
132 FakeShillManagerClient::FakeShillManagerClient()
133 : interactive_delay_(0),
134 cellular_technology_(shill::kNetworkTechnologyGsm
),
135 weak_ptr_factory_(this) {
136 ParseCommandLineSwitch();
139 FakeShillManagerClient::~FakeShillManagerClient() {}
141 // ShillManagerClient overrides.
143 void FakeShillManagerClient::Init(dbus::Bus
* bus
) {}
145 void FakeShillManagerClient::AddPropertyChangedObserver(
146 ShillPropertyChangedObserver
* observer
) {
147 observer_list_
.AddObserver(observer
);
150 void FakeShillManagerClient::RemovePropertyChangedObserver(
151 ShillPropertyChangedObserver
* observer
) {
152 observer_list_
.RemoveObserver(observer
);
155 void FakeShillManagerClient::GetProperties(
156 const DictionaryValueCallback
& callback
) {
157 VLOG(1) << "Manager.GetProperties";
158 base::MessageLoop::current()->PostTask(
159 FROM_HERE
, base::Bind(
160 &FakeShillManagerClient::PassStubProperties
,
161 weak_ptr_factory_
.GetWeakPtr(),
165 void FakeShillManagerClient::GetNetworksForGeolocation(
166 const DictionaryValueCallback
& callback
) {
167 base::MessageLoop::current()->PostTask(
168 FROM_HERE
, base::Bind(
169 &FakeShillManagerClient::PassStubGeoNetworks
,
170 weak_ptr_factory_
.GetWeakPtr(),
174 void FakeShillManagerClient::SetProperty(const std::string
& name
,
175 const base::Value
& value
,
176 const base::Closure
& callback
,
177 const ErrorCallback
& error_callback
) {
178 VLOG(2) << "SetProperty: " << name
;
179 stub_properties_
.SetWithoutPathExpansion(name
, value
.DeepCopy());
180 CallNotifyObserversPropertyChanged(name
);
181 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
184 void FakeShillManagerClient::RequestScan(const std::string
& type
,
185 const base::Closure
& callback
,
186 const ErrorCallback
& error_callback
) {
187 // For Stub purposes, default to a Wifi scan.
188 std::string device_type
= shill::kTypeWifi
;
191 ShillDeviceClient::TestInterface
* device_client
=
192 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
193 std::string device_path
= device_client
->GetDevicePathForType(device_type
);
194 if (!device_path
.empty()) {
195 device_client
->SetDeviceProperty(
196 device_path
, shill::kScanningProperty
, base::FundamentalValue(true));
198 base::MessageLoop::current()->PostDelayedTask(
200 base::Bind(&FakeShillManagerClient::ScanCompleted
,
201 weak_ptr_factory_
.GetWeakPtr(),
204 base::TimeDelta::FromSeconds(interactive_delay_
));
207 void FakeShillManagerClient::EnableTechnology(
208 const std::string
& type
,
209 const base::Closure
& callback
,
210 const ErrorCallback
& error_callback
) {
211 base::ListValue
* enabled_list
= NULL
;
212 if (!stub_properties_
.GetListWithoutPathExpansion(
213 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
214 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
215 base::MessageLoop::current()->PostTask(
217 base::Bind(error_callback
, "StubError", "Property not found"));
220 base::MessageLoop::current()->PostDelayedTask(
222 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
223 weak_ptr_factory_
.GetWeakPtr(),
227 base::TimeDelta::FromSeconds(interactive_delay_
));
230 void FakeShillManagerClient::DisableTechnology(
231 const std::string
& type
,
232 const base::Closure
& callback
,
233 const ErrorCallback
& error_callback
) {
234 base::ListValue
* enabled_list
= NULL
;
235 if (!stub_properties_
.GetListWithoutPathExpansion(
236 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
237 base::MessageLoop::current()->PostTask(
239 base::Bind(error_callback
, "StubError", "Property not found"));
242 base::MessageLoop::current()->PostDelayedTask(
244 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
245 weak_ptr_factory_
.GetWeakPtr(),
249 base::TimeDelta::FromSeconds(interactive_delay_
));
252 void FakeShillManagerClient::ConfigureService(
253 const base::DictionaryValue
& properties
,
254 const ObjectPathCallback
& callback
,
255 const ErrorCallback
& error_callback
) {
256 ShillServiceClient::TestInterface
* service_client
=
257 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
261 if (!properties
.GetString(shill::kGuidProperty
, &guid
) ||
262 !properties
.GetString(shill::kTypeProperty
, &type
)) {
263 LOG(ERROR
) << "ConfigureService requires GUID and Type to be defined";
264 // If the properties aren't filled out completely, then just return an empty
266 base::MessageLoop::current()->PostTask(
267 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
271 // For the purposes of this stub, we're going to assume that the GUID property
272 // is set to the service path because we don't want to re-implement Shill's
273 // property matching magic here.
274 std::string service_path
= guid
;
276 std::string ipconfig_path
;
277 properties
.GetString(shill::kIPConfigProperty
, &ipconfig_path
);
279 // Merge the new properties with existing properties, if any.
280 const base::DictionaryValue
* existing_properties
=
281 service_client
->GetServiceProperties(service_path
);
282 if (!existing_properties
) {
283 // Add a new service to the service client stub because none exists, yet.
284 // This calls AddManagerService.
285 service_client
->AddServiceWithIPConfig(service_path
,
292 existing_properties
= service_client
->GetServiceProperties(service_path
);
295 scoped_ptr
<base::DictionaryValue
> merged_properties(
296 existing_properties
->DeepCopy());
297 merged_properties
->MergeDictionary(&properties
);
299 // Now set all the properties.
300 for (base::DictionaryValue::Iterator
iter(*merged_properties
);
301 !iter
.IsAtEnd(); iter
.Advance()) {
302 service_client
->SetServiceProperty(service_path
, iter
.key(), iter
.value());
305 // If the Profile property is set, add it to ProfileClient.
306 std::string profile_path
;
307 merged_properties
->GetStringWithoutPathExpansion(shill::kProfileProperty
,
309 if (!profile_path
.empty()) {
310 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface()->
311 AddService(profile_path
, service_path
);
314 base::MessageLoop::current()->PostTask(
315 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath(service_path
)));
318 void FakeShillManagerClient::ConfigureServiceForProfile(
319 const dbus::ObjectPath
& profile_path
,
320 const base::DictionaryValue
& properties
,
321 const ObjectPathCallback
& callback
,
322 const ErrorCallback
& error_callback
) {
323 std::string profile_property
;
324 properties
.GetStringWithoutPathExpansion(shill::kProfileProperty
,
326 CHECK(profile_property
== profile_path
.value());
327 ConfigureService(properties
, callback
, error_callback
);
331 void FakeShillManagerClient::GetService(
332 const base::DictionaryValue
& properties
,
333 const ObjectPathCallback
& callback
,
334 const ErrorCallback
& error_callback
) {
335 base::MessageLoop::current()->PostTask(
336 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
339 void FakeShillManagerClient::VerifyDestination(
340 const VerificationProperties
& properties
,
341 const BooleanCallback
& callback
,
342 const ErrorCallback
& error_callback
) {
343 base::MessageLoop::current()->PostTask(FROM_HERE
, base::Bind(callback
, true));
346 void FakeShillManagerClient::VerifyAndEncryptCredentials(
347 const VerificationProperties
& properties
,
348 const std::string
& service_path
,
349 const StringCallback
& callback
,
350 const ErrorCallback
& error_callback
) {
351 base::MessageLoop::current()->PostTask(
352 FROM_HERE
, base::Bind(callback
, "encrypted_credentials"));
355 void FakeShillManagerClient::VerifyAndEncryptData(
356 const VerificationProperties
& properties
,
357 const std::string
& data
,
358 const StringCallback
& callback
,
359 const ErrorCallback
& error_callback
) {
360 base::MessageLoop::current()->PostTask(
361 FROM_HERE
, base::Bind(callback
, "encrypted_data"));
364 void FakeShillManagerClient::ConnectToBestServices(
365 const base::Closure
& callback
,
366 const ErrorCallback
& error_callback
) {
367 if (best_service_
.empty()) {
368 VLOG(1) << "No 'best' service set.";
372 DBusThreadManager::Get()->GetShillServiceClient()->Connect(
373 dbus::ObjectPath(best_service_
), callback
, error_callback
);
376 ShillManagerClient::TestInterface
* FakeShillManagerClient::GetTestInterface() {
380 // ShillManagerClient::TestInterface overrides.
382 void FakeShillManagerClient::AddDevice(const std::string
& device_path
) {
383 if (GetListProperty(shill::kDevicesProperty
)
384 ->AppendIfNotPresent(new base::StringValue(device_path
))) {
385 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
389 void FakeShillManagerClient::RemoveDevice(const std::string
& device_path
) {
390 base::StringValue
device_path_value(device_path
);
391 if (GetListProperty(shill::kDevicesProperty
)->Remove(
392 device_path_value
, NULL
)) {
393 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
397 void FakeShillManagerClient::ClearDevices() {
398 GetListProperty(shill::kDevicesProperty
)->Clear();
399 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
402 void FakeShillManagerClient::AddTechnology(const std::string
& type
,
404 if (GetListProperty(shill::kAvailableTechnologiesProperty
)
405 ->AppendIfNotPresent(new base::StringValue(type
))) {
406 CallNotifyObserversPropertyChanged(
407 shill::kAvailableTechnologiesProperty
);
410 GetListProperty(shill::kEnabledTechnologiesProperty
)
411 ->AppendIfNotPresent(new base::StringValue(type
))) {
412 CallNotifyObserversPropertyChanged(
413 shill::kEnabledTechnologiesProperty
);
417 void FakeShillManagerClient::RemoveTechnology(const std::string
& type
) {
418 base::StringValue
type_value(type
);
419 if (GetListProperty(shill::kAvailableTechnologiesProperty
)->Remove(
421 CallNotifyObserversPropertyChanged(
422 shill::kAvailableTechnologiesProperty
);
424 if (GetListProperty(shill::kEnabledTechnologiesProperty
)->Remove(
426 CallNotifyObserversPropertyChanged(
427 shill::kEnabledTechnologiesProperty
);
431 void FakeShillManagerClient::SetTechnologyInitializing(const std::string
& type
,
434 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)
435 ->AppendIfNotPresent(new base::StringValue(type
))) {
436 CallNotifyObserversPropertyChanged(
437 shill::kUninitializedTechnologiesProperty
);
440 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)->Remove(
441 base::StringValue(type
), NULL
)) {
442 CallNotifyObserversPropertyChanged(
443 shill::kUninitializedTechnologiesProperty
);
448 void FakeShillManagerClient::AddGeoNetwork(
449 const std::string
& technology
,
450 const base::DictionaryValue
& network
) {
451 base::ListValue
* list_value
= NULL
;
452 if (!stub_geo_networks_
.GetListWithoutPathExpansion(technology
,
454 list_value
= new base::ListValue
;
455 stub_geo_networks_
.SetWithoutPathExpansion(technology
, list_value
);
457 list_value
->Append(network
.DeepCopy());
460 void FakeShillManagerClient::AddProfile(const std::string
& profile_path
) {
461 const char* key
= shill::kProfilesProperty
;
462 if (GetListProperty(key
)
463 ->AppendIfNotPresent(new base::StringValue(profile_path
))) {
464 CallNotifyObserversPropertyChanged(key
);
468 void FakeShillManagerClient::ClearProperties() {
469 stub_properties_
.Clear();
472 void FakeShillManagerClient::SetManagerProperty(const std::string
& key
,
473 const base::Value
& value
) {
474 SetProperty(key
, value
,
475 base::Bind(&base::DoNothing
), base::Bind(&LogErrorCallback
));
478 void FakeShillManagerClient::AddManagerService(
479 const std::string
& service_path
,
480 bool notify_observers
) {
481 VLOG(2) << "AddManagerService: " << service_path
;
482 GetListProperty(shill::kServiceCompleteListProperty
)
483 ->AppendIfNotPresent(new base::StringValue(service_path
));
484 SortManagerServices(false);
485 if (notify_observers
)
486 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
489 void FakeShillManagerClient::RemoveManagerService(
490 const std::string
& service_path
) {
491 VLOG(2) << "RemoveManagerService: " << service_path
;
492 base::StringValue
service_path_value(service_path
);
493 GetListProperty(shill::kServiceCompleteListProperty
)->Remove(
494 service_path_value
, NULL
);
495 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
498 void FakeShillManagerClient::ClearManagerServices() {
499 VLOG(1) << "ClearManagerServices";
500 GetListProperty(shill::kServiceCompleteListProperty
)->Clear();
501 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
504 void FakeShillManagerClient::ServiceStateChanged(
505 const std::string
& service_path
,
506 const std::string
& state
) {
507 if (service_path
== default_service_
&& !IsConnectedState(state
)) {
508 // Default service is no longer connected; clear.
509 default_service_
.clear();
510 base::StringValue
default_service_value(default_service_
);
511 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
515 void FakeShillManagerClient::SortManagerServices(bool notify
) {
516 VLOG(1) << "SortManagerServices";
517 static const char* ordered_types
[] = {shill::kTypeEthernet
,
518 shill::kTypeEthernetEap
,
520 shill::kTypeCellular
,
524 base::ListValue
* complete_list
=
525 GetListProperty(shill::kServiceCompleteListProperty
);
526 if (complete_list
->empty())
528 scoped_ptr
<base::ListValue
> prev_complete_list(complete_list
->DeepCopy());
530 std::vector
<std::string
> active_services
;
531 std::vector
<std::string
> inactive_services
;
532 std::vector
<std::string
> disabled_services
;
533 for (size_t i
= 0; i
< arraysize(ordered_types
); ++i
) {
534 AppendServicesForType(complete_list
,
536 TechnologyEnabled(ordered_types
[i
]),
541 complete_list
->Clear();
542 for (size_t i
= 0; i
< active_services
.size(); ++i
)
543 complete_list
->AppendString(active_services
[i
]);
544 for (size_t i
= 0; i
< inactive_services
.size(); ++i
)
545 complete_list
->AppendString(inactive_services
[i
]);
546 for (size_t i
= 0; i
< disabled_services
.size(); ++i
)
547 complete_list
->AppendString(disabled_services
[i
]);
549 if (notify
&& !complete_list
->Equals(prev_complete_list
.get()))
550 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
552 // Set the first active service as the Default service.
553 std::string new_default_service
;
554 if (!active_services
.empty()) {
555 ShillServiceClient::TestInterface
* service_client
=
556 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
557 std::string service_path
= active_services
[0];
558 const base::DictionaryValue
* properties
=
559 service_client
->GetServiceProperties(service_path
);
561 LOG(ERROR
) << "Properties not found for service: " << service_path
;
564 properties
->GetString(shill::kStateProperty
, &state
);
565 if (IsConnectedState(state
))
566 new_default_service
= service_path
;
569 if (default_service_
!= new_default_service
) {
570 default_service_
= new_default_service
;
571 base::StringValue
default_service_value(default_service_
);
572 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
576 int FakeShillManagerClient::GetInteractiveDelay() const {
577 return interactive_delay_
;
580 void FakeShillManagerClient::SetBestServiceToConnect(
581 const std::string
& service_path
) {
582 best_service_
= service_path
;
585 void FakeShillManagerClient::SetupDefaultEnvironment() {
586 // Bail out from setup if there is no message loop. This will be the common
587 // case for tests that are not testing Shill.
588 if (!base::MessageLoop::current())
591 DBusThreadManager
* dbus_manager
= DBusThreadManager::Get();
592 ShillServiceClient::TestInterface
* services
=
593 dbus_manager
->GetShillServiceClient()->GetTestInterface();
595 ShillProfileClient::TestInterface
* profiles
=
596 dbus_manager
->GetShillProfileClient()->GetTestInterface();
598 ShillDeviceClient::TestInterface
* devices
=
599 dbus_manager
->GetShillDeviceClient()->GetTestInterface();
601 ShillIPConfigClient::TestInterface
* ip_configs
=
602 dbus_manager
->GetShillIPConfigClient()->GetTestInterface();
605 const std::string shared_profile
= ShillProfileClient::GetSharedProfilePath();
606 profiles
->AddProfile(shared_profile
, std::string());
608 const bool add_to_visible
= true;
611 base::DictionaryValue ipconfig_v4_dictionary
;
612 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
613 shill::kAddressProperty
, "100.0.0.1");
614 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
615 shill::kGatewayProperty
, "100.0.0.2");
616 ipconfig_v4_dictionary
.SetIntegerWithoutPathExpansion(
617 shill::kPrefixlenProperty
, 1);
618 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
619 shill::kMethodProperty
, shill::kTypeIPv4
);
620 ip_configs
->AddIPConfig("ipconfig_v4_path", ipconfig_v4_dictionary
);
621 base::DictionaryValue ipconfig_v6_dictionary
;
622 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
623 shill::kAddressProperty
, "0:0:0:0:100:0:0:1");
624 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
625 shill::kMethodProperty
, shill::kTypeIPv6
);
626 ip_configs
->AddIPConfig("ipconfig_v6_path", ipconfig_v6_dictionary
);
632 state
= GetInitialStateForType(shill::kTypeEthernet
, &enabled
);
633 if (state
== shill::kStateOnline
) {
634 AddTechnology(shill::kTypeEthernet
, enabled
);
636 "/device/eth1", shill::kTypeEthernet
, "stub_eth_device1");
637 devices
->SetDeviceProperty("/device/eth1",
638 shill::kAddressProperty
,
639 base::StringValue("0123456789ab"));
640 base::ListValue eth_ip_configs
;
641 eth_ip_configs
.AppendString("ipconfig_v4_path");
642 eth_ip_configs
.AppendString("ipconfig_v6_path");
643 devices
->SetDeviceProperty("/device/eth1",
644 shill::kIPConfigsProperty
,
646 const std::string kFakeEthernetNetworkPath
= "/service/eth1";
647 services
->AddService(kFakeEthernetNetworkPath
,
648 kFakeEthernetNetworkGuid
,
650 shill::kTypeEthernet
,
653 profiles
->AddService(shared_profile
, kFakeEthernetNetworkPath
);
657 if (s_tdls_busy_count
!= 0) {
658 DBusThreadManager::Get()
659 ->GetShillDeviceClient()
661 ->SetTDLSBusyCount(s_tdls_busy_count
);
664 state
= GetInitialStateForType(shill::kTypeWifi
, &enabled
);
665 if (state
!= kTechnologyUnavailable
) {
666 bool portaled
= false;
667 if (state
== shill::kStatePortal
) {
669 state
= shill::kStateIdle
;
671 AddTechnology(shill::kTypeWifi
, enabled
);
672 devices
->AddDevice("/device/wifi1", shill::kTypeWifi
, "stub_wifi_device1");
673 devices
->SetDeviceProperty("/device/wifi1",
674 shill::kAddressProperty
,
675 base::StringValue("23456789abcd"));
676 base::ListValue wifi_ip_configs
;
677 wifi_ip_configs
.AppendString("ipconfig_v4_path");
678 wifi_ip_configs
.AppendString("ipconfig_v6_path");
679 devices
->SetDeviceProperty("/device/wifi1",
680 shill::kIPConfigsProperty
,
683 const std::string kWifi1Path
= "/service/wifi1";
684 services
->AddService(kWifi1Path
,
690 services
->SetServiceProperty(kWifi1Path
,
691 shill::kSecurityClassProperty
,
692 base::StringValue(shill::kSecurityWep
));
693 services
->SetServiceProperty(kWifi1Path
,
694 shill::kConnectableProperty
,
695 base::FundamentalValue(true));
696 profiles
->AddService(shared_profile
, kWifi1Path
);
698 const std::string kWifi2Path
= "/service/wifi2";
699 services
->AddService(kWifi2Path
,
701 "wifi2_PSK" /* name */,
705 services
->SetServiceProperty(kWifi2Path
,
706 shill::kSecurityClassProperty
,
707 base::StringValue(shill::kSecurityPsk
));
708 services
->SetServiceProperty(
709 kWifi2Path
, shill::kSignalStrengthProperty
, base::FundamentalValue(80));
710 profiles
->AddService(shared_profile
, kWifi2Path
);
712 const std::string kWifi3Path
= "/service/wifi3";
713 services
->AddService(kWifi3Path
,
719 services
->SetServiceProperty(
720 kWifi3Path
, shill::kSignalStrengthProperty
, base::FundamentalValue(40));
723 const std::string kPortaledWifiPath
= "/service/portaled_wifi";
724 services
->AddService(kPortaledWifiPath
,
725 "portaled_wifi_guid",
726 "Portaled Wifi" /* name */,
730 services
->SetServiceProperty(kPortaledWifiPath
,
731 shill::kSecurityClassProperty
,
732 base::StringValue(shill::kSecurityNone
));
733 services
->SetConnectBehavior(kPortaledWifiPath
,
734 base::Bind(&UpdatePortaledWifiState
,
736 services
->SetServiceProperty(kPortaledWifiPath
,
737 shill::kConnectableProperty
,
738 base::FundamentalValue(true));
739 profiles
->AddService(shared_profile
, kPortaledWifiPath
);
744 const std::string kWimaxPath
= "/service/wimax1";
745 state
= GetInitialStateForType(shill::kTypeWimax
, &enabled
);
746 if (state
!= kTechnologyUnavailable
) {
747 AddTechnology(shill::kTypeWimax
, enabled
);
749 "/device/wimax1", shill::kTypeWimax
, "stub_wimax_device1");
751 services
->AddService(kWimaxPath
, "wimax1_guid", "wimax1" /* name */,
752 shill::kTypeWimax
, state
, add_to_visible
);
753 services
->SetServiceProperty(kWimaxPath
, shill::kConnectableProperty
,
754 base::FundamentalValue(true));
755 base::FundamentalValue
strength_value(80);
756 services
->SetServiceProperty(kWimaxPath
, shill::kSignalStrengthProperty
,
758 profiles
->AddService(shared_profile
, kWimaxPath
);
762 state
= GetInitialStateForType(shill::kTypeCellular
, &enabled
);
763 if (state
!= kTechnologyUnavailable
) {
764 bool activated
= false;
765 if (state
== kNetworkActivated
) {
767 state
= shill::kStateIdle
;
769 AddTechnology(shill::kTypeCellular
, enabled
);
771 "/device/cellular1", shill::kTypeCellular
, "stub_cellular_device1");
772 devices
->SetDeviceProperty("/device/cellular1",
773 shill::kCarrierProperty
,
774 base::StringValue(shill::kCarrierSprint
));
775 base::ListValue carrier_list
;
776 carrier_list
.AppendString(shill::kCarrierSprint
);
777 carrier_list
.AppendString(shill::kCarrierGenericUMTS
);
778 devices
->SetDeviceProperty("/device/cellular1",
779 shill::kSupportedCarriersProperty
,
781 if (roaming_state_
== kRoamingRequired
) {
782 devices
->SetDeviceProperty("/device/cellular1",
783 shill::kProviderRequiresRoamingProperty
,
784 base::FundamentalValue(true));
787 services
->AddService(kCellularServicePath
,
789 "cellular1" /* name */,
790 shill::kTypeCellular
,
793 base::StringValue
technology_value(cellular_technology_
);
794 devices
->SetDeviceProperty("/device/cellular1",
795 shill::kTechnologyFamilyProperty
,
797 services
->SetServiceProperty(kCellularServicePath
,
798 shill::kNetworkTechnologyProperty
,
802 services
->SetServiceProperty(
803 kCellularServicePath
,
804 shill::kActivationStateProperty
,
805 base::StringValue(shill::kActivationStateActivated
));
806 services
->SetServiceProperty(kCellularServicePath
,
807 shill::kConnectableProperty
,
808 base::FundamentalValue(true));
810 services
->SetServiceProperty(
811 kCellularServicePath
,
812 shill::kActivationStateProperty
,
813 base::StringValue(shill::kActivationStateNotActivated
));
816 std::string shill_roaming_state
;
817 if (roaming_state_
== kRoamingRequired
)
818 shill_roaming_state
= shill::kRoamingStateRoaming
;
819 else if (roaming_state_
.empty())
820 shill_roaming_state
= shill::kRoamingStateHome
;
821 else // |roaming_state_| is expected to be a valid Shill state.
822 shill_roaming_state
= roaming_state_
;
823 services
->SetServiceProperty(kCellularServicePath
,
824 shill::kRoamingStateProperty
,
825 base::StringValue(shill_roaming_state
));
826 profiles
->AddService(shared_profile
, kCellularServicePath
);
830 state
= GetInitialStateForType(shill::kTypeVPN
, &enabled
);
831 if (state
!= kTechnologyUnavailable
) {
832 // Set the "Provider" dictionary properties. Note: when setting these in
833 // Shill, "Provider.Type", etc keys are used, but when reading the values
834 // "Provider" . "Type", etc keys are used. Here we are setting the values
835 // that will be read (by the UI, tests, etc).
836 base::DictionaryValue provider_properties_openvpn
;
837 provider_properties_openvpn
.SetString(shill::kTypeProperty
,
838 shill::kProviderOpenVpn
);
839 provider_properties_openvpn
.SetString(shill::kHostProperty
, "vpn_host");
841 services
->AddService("/service/vpn1",
847 services
->SetServiceProperty(
848 "/service/vpn1", shill::kProviderProperty
, provider_properties_openvpn
);
849 profiles
->AddService(shared_profile
, "/service/vpn1");
851 base::DictionaryValue provider_properties_l2tp
;
852 provider_properties_l2tp
.SetString(shill::kTypeProperty
,
853 shill::kProviderL2tpIpsec
);
854 provider_properties_l2tp
.SetString(shill::kHostProperty
, "vpn_host2");
856 services
->AddService("/service/vpn2",
862 services
->SetServiceProperty(
863 "/service/vpn2", shill::kProviderProperty
, provider_properties_l2tp
);
866 // Additional device states
867 for (DevicePropertyMap::iterator iter1
= shill_device_property_map_
.begin();
868 iter1
!= shill_device_property_map_
.end(); ++iter1
) {
869 std::string device_type
= iter1
->first
;
870 std::string device_path
= devices
->GetDevicePathForType(device_type
);
871 for (ShillPropertyMap::iterator iter2
= iter1
->second
.begin();
872 iter2
!= iter1
->second
.end(); ++iter2
) {
873 devices
->SetDeviceProperty(device_path
, iter2
->first
, *(iter2
->second
));
874 delete iter2
->second
;
878 SortManagerServices(true);
883 void FakeShillManagerClient::PassStubProperties(
884 const DictionaryValueCallback
& callback
) const {
885 scoped_ptr
<base::DictionaryValue
> stub_properties(
886 stub_properties_
.DeepCopy());
887 stub_properties
->SetWithoutPathExpansion(
888 shill::kServiceCompleteListProperty
,
889 GetEnabledServiceList(shill::kServiceCompleteListProperty
));
890 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, *stub_properties
);
893 void FakeShillManagerClient::PassStubGeoNetworks(
894 const DictionaryValueCallback
& callback
) const {
895 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, stub_geo_networks_
);
898 void FakeShillManagerClient::CallNotifyObserversPropertyChanged(
899 const std::string
& property
) {
900 // Avoid unnecessary delayed task if we have no observers (e.g. during
902 if (!observer_list_
.might_have_observers())
904 base::MessageLoop::current()->PostTask(
906 base::Bind(&FakeShillManagerClient::NotifyObserversPropertyChanged
,
907 weak_ptr_factory_
.GetWeakPtr(),
911 void FakeShillManagerClient::NotifyObserversPropertyChanged(
912 const std::string
& property
) {
913 VLOG(1) << "NotifyObserversPropertyChanged: " << property
;
914 base::Value
* value
= NULL
;
915 if (!stub_properties_
.GetWithoutPathExpansion(property
, &value
)) {
916 LOG(ERROR
) << "Notify for unknown property: " << property
;
919 if (property
== shill::kServiceCompleteListProperty
) {
920 scoped_ptr
<base::ListValue
> services(GetEnabledServiceList(property
));
921 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
923 OnPropertyChanged(property
, *(services
.get())));
926 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
928 OnPropertyChanged(property
, *value
));
931 base::ListValue
* FakeShillManagerClient::GetListProperty(
932 const std::string
& property
) {
933 base::ListValue
* list_property
= NULL
;
934 if (!stub_properties_
.GetListWithoutPathExpansion(
935 property
, &list_property
)) {
936 list_property
= new base::ListValue
;
937 stub_properties_
.SetWithoutPathExpansion(property
, list_property
);
939 return list_property
;
942 bool FakeShillManagerClient::TechnologyEnabled(const std::string
& type
) const {
943 if (type
== shill::kTypeVPN
)
944 return true; // VPN is always "enabled" since there is no associated device
945 if (type
== shill::kTypeEthernetEap
)
947 bool enabled
= false;
948 const base::ListValue
* technologies
;
949 if (stub_properties_
.GetListWithoutPathExpansion(
950 shill::kEnabledTechnologiesProperty
, &technologies
)) {
951 base::StringValue
type_value(type
);
952 if (technologies
->Find(type_value
) != technologies
->end())
958 void FakeShillManagerClient::SetTechnologyEnabled(
959 const std::string
& type
,
960 const base::Closure
& callback
,
962 base::ListValue
* enabled_list
=
963 GetListProperty(shill::kEnabledTechnologiesProperty
);
965 enabled_list
->AppendIfNotPresent(new base::StringValue(type
));
967 enabled_list
->Remove(base::StringValue(type
), NULL
);
968 CallNotifyObserversPropertyChanged(
969 shill::kEnabledTechnologiesProperty
);
970 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
971 // May affect available services.
972 SortManagerServices(true);
975 base::ListValue
* FakeShillManagerClient::GetEnabledServiceList(
976 const std::string
& property
) const {
977 base::ListValue
* new_service_list
= new base::ListValue
;
978 const base::ListValue
* service_list
;
979 if (stub_properties_
.GetListWithoutPathExpansion(property
, &service_list
)) {
980 ShillServiceClient::TestInterface
* service_client
=
981 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
982 for (base::ListValue::const_iterator iter
= service_list
->begin();
983 iter
!= service_list
->end(); ++iter
) {
984 std::string service_path
;
985 if (!(*iter
)->GetAsString(&service_path
))
987 const base::DictionaryValue
* properties
=
988 service_client
->GetServiceProperties(service_path
);
990 LOG(ERROR
) << "Properties not found for service: " << service_path
;
994 properties
->GetString(shill::kTypeProperty
, &type
);
995 if (TechnologyEnabled(type
))
996 new_service_list
->Append((*iter
)->DeepCopy());
999 return new_service_list
;
1002 void FakeShillManagerClient::ScanCompleted(const std::string
& device_path
,
1003 const base::Closure
& callback
) {
1004 if (!device_path
.empty()) {
1005 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
1006 SetDeviceProperty(device_path
,
1007 shill::kScanningProperty
,
1008 base::FundamentalValue(false));
1010 VLOG(2) << "ScanCompleted";
1011 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
1012 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
1015 void FakeShillManagerClient::ParseCommandLineSwitch() {
1017 SetInitialNetworkState(shill::kTypeEthernet
, shill::kStateOnline
);
1018 SetInitialNetworkState(shill::kTypeWifi
, shill::kStateOnline
);
1019 SetInitialNetworkState(shill::kTypeCellular
, shill::kStateIdle
);
1020 SetInitialNetworkState(shill::kTypeVPN
, shill::kStateIdle
);
1022 // Parse additional options
1023 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
1024 if (!command_line
->HasSwitch(switches::kShillStub
))
1027 std::string option_str
=
1028 command_line
->GetSwitchValueASCII(switches::kShillStub
);
1029 VLOG(1) << "Parsing command line:" << option_str
;
1030 base::StringPairs string_pairs
;
1031 base::SplitStringIntoKeyValuePairs(option_str
, '=', ',', &string_pairs
);
1032 for (base::StringPairs::iterator iter
= string_pairs
.begin();
1033 iter
!= string_pairs
.end(); ++iter
) {
1034 ParseOption((*iter
).first
, (*iter
).second
);
1038 bool FakeShillManagerClient::ParseOption(const std::string
& arg0
,
1039 const std::string
& arg1
) {
1040 VLOG(1) << "Parsing command line option: '" << arg0
<< "=" << arg1
<< "'";
1041 if ((arg0
== "clear" || arg0
== "reset") && arg1
== "1") {
1042 shill_initial_state_map_
.clear();
1044 } else if (arg0
== "interactive") {
1047 base::StringToInt(arg1
, &seconds
);
1048 interactive_delay_
= seconds
;
1050 } else if (arg0
== "sim_lock") {
1051 bool locked
= (arg1
== "1") ? true : false;
1052 base::DictionaryValue
* simlock_dict
= new base::DictionaryValue
;
1053 simlock_dict
->Set(shill::kSIMLockEnabledProperty
,
1054 new base::FundamentalValue(locked
));
1055 // TODO(stevenjb): Investigate why non-empty value breaks UI.
1056 std::string lock_type
= ""; // shill::kSIMLockPin
1057 simlock_dict
->SetString(shill::kSIMLockTypeProperty
, lock_type
);
1058 simlock_dict
->SetInteger(shill::kSIMLockRetriesLeftProperty
, 5);
1060 shill_device_property_map_
[shill::kTypeCellular
]
1061 [shill::kSIMLockStatusProperty
] = simlock_dict
;
1062 shill_device_property_map_
1063 [shill::kTypeCellular
][shill::kTechnologyFamilyProperty
] =
1064 new base::StringValue(shill::kNetworkTechnologyGsm
);
1066 } else if (arg0
== "tdls_busy") {
1068 base::StringToInt(arg1
, &s_tdls_busy_count
);
1070 s_tdls_busy_count
= 1;
1072 } else if (arg0
== "roaming") {
1073 // "home", "roaming", or "required"
1074 roaming_state_
= arg1
;
1077 return SetInitialNetworkState(arg0
, arg1
);
1080 bool FakeShillManagerClient::SetInitialNetworkState(std::string type_arg
,
1081 std::string state_arg
) {
1083 if (state_arg
.empty() || state_arg
== "1" || state_arg
== "on" ||
1084 state_arg
== "enabled" || state_arg
== "connected" ||
1085 state_arg
== "online") {
1086 // Enabled and connected (default value)
1087 state
= shill::kStateOnline
;
1088 } else if (state_arg
== "0" || state_arg
== "off" ||
1089 state_arg
== "inactive" || state_arg
== shill::kStateIdle
) {
1090 // Technology enabled, services are created but are not connected.
1091 state
= shill::kStateIdle
;
1092 } else if (state_arg
== "disabled" || state_arg
== "disconnect") {
1093 // Technology disabled but available, services created but not connected.
1094 state
= kNetworkDisabled
;
1095 } else if (state_arg
== "none" || state_arg
== "offline") {
1096 // Technology not available, do not create services.
1097 state
= kTechnologyUnavailable
;
1098 } else if (state_arg
== "portal") {
1099 // Technology is enabled, a service is connected and in Portal state.
1100 state
= shill::kStatePortal
;
1101 } else if (state_arg
== "active" || state_arg
== "activated") {
1102 // Technology is enabled, a service is connected and Activated.
1103 state
= kNetworkActivated
;
1104 } else if (type_arg
== shill::kTypeCellular
&&
1105 IsCellularTechnology(state_arg
)) {
1106 state
= shill::kStateOnline
;
1107 cellular_technology_
= state_arg
;
1108 } else if (type_arg
== shill::kTypeCellular
&& state_arg
== "LTEAdvanced") {
1109 // Special case, Shill name contains a ' '.
1110 state
= shill::kStateOnline
;
1111 cellular_technology_
= shill::kNetworkTechnologyLteAdvanced
;
1113 LOG(ERROR
) << "Unrecognized initial state: " << type_arg
<< "="
1119 if (type_arg
== "wireless") {
1120 shill_initial_state_map_
[shill::kTypeWifi
] = state
;
1121 shill_initial_state_map_
[shill::kTypeCellular
] = state
;
1124 // Convenience synonyms.
1125 if (type_arg
== "eth")
1126 type_arg
= shill::kTypeEthernet
;
1128 if (type_arg
!= shill::kTypeEthernet
&&
1129 type_arg
!= shill::kTypeWifi
&&
1130 type_arg
!= shill::kTypeCellular
&&
1131 type_arg
!= shill::kTypeWimax
&&
1132 type_arg
!= shill::kTypeVPN
) {
1133 LOG(WARNING
) << "Unrecognized Shill network type: " << type_arg
;
1137 // Unconnected or disabled ethernet is the same as unavailable.
1138 if (type_arg
== shill::kTypeEthernet
&&
1139 (state
== shill::kStateIdle
|| state
== kNetworkDisabled
)) {
1140 state
= kTechnologyUnavailable
;
1143 shill_initial_state_map_
[type_arg
] = state
;
1147 std::string
FakeShillManagerClient::GetInitialStateForType(
1148 const std::string
& type
,
1150 std::map
<std::string
, std::string
>::const_iterator iter
=
1151 shill_initial_state_map_
.find(type
);
1152 if (iter
== shill_initial_state_map_
.end()) {
1154 return kTechnologyUnavailable
;
1156 std::string state
= iter
->second
;
1157 if (state
== kNetworkDisabled
) {
1159 return shill::kStateIdle
;
1162 if ((state
== shill::kStatePortal
&& type
!= shill::kTypeWifi
) ||
1163 (state
== kNetworkActivated
&& type
!= shill::kTypeCellular
)) {
1164 LOG(WARNING
) << "Invalid state: " << state
<< " for " << type
;
1165 return shill::kStateIdle
;
1170 } // namespace chromeos