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/location.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/thread_task_runner_handle.h"
17 #include "base/values.h"
18 #include "chromeos/chromeos_switches.h"
19 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "chromeos/dbus/shill_device_client.h"
21 #include "chromeos/dbus/shill_ipconfig_client.h"
22 #include "chromeos/dbus/shill_profile_client.h"
23 #include "chromeos/dbus/shill_property_changed_observer.h"
24 #include "chromeos/dbus/shill_service_client.h"
26 #include "dbus/message.h"
27 #include "dbus/object_path.h"
28 #include "dbus/values_util.h"
29 #include "third_party/cros_system_api/dbus/service_constants.h"
35 // Allow parsed command line option 'tdls_busy' to set the fake busy count.
36 int s_tdls_busy_count
= 0;
37 int s_extra_wifi_networks
= 0;
39 // Used to compare values for finding entries to erase in a ListValue.
40 // (ListValue only implements a const_iterator version of Find).
42 explicit ValueEquals(const base::Value
* first
) : first_(first
) {}
43 bool operator()(const base::Value
* second
) const {
44 return first_
->Equals(second
);
46 const base::Value
* first_
;
49 // Appends string entries from |service_list_in| whose entries in ServiceClient
50 // have Type |match_type| to one of the output lists based on the entry's State.
51 void AppendServicesForType(
52 const base::ListValue
* service_list_in
,
53 const char* match_type
,
54 bool technology_enabled
,
55 std::vector
<std::string
>* active_service_list_out
,
56 std::vector
<std::string
>* inactive_service_list_out
,
57 std::vector
<std::string
>* disabled_service_list_out
) {
58 ShillServiceClient::TestInterface
* service_client
=
59 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
60 for (base::ListValue::const_iterator iter
= service_list_in
->begin();
61 iter
!= service_list_in
->end(); ++iter
) {
62 std::string service_path
;
63 if (!(*iter
)->GetAsString(&service_path
))
65 const base::DictionaryValue
* properties
=
66 service_client
->GetServiceProperties(service_path
);
68 LOG(ERROR
) << "Properties not found for service: " << service_path
;
72 properties
->GetString(shill::kTypeProperty
, &type
);
73 if (type
!= match_type
)
76 if (technology_enabled
)
77 properties
->GetBoolean(shill::kVisibleProperty
, &visible
);
79 disabled_service_list_out
->push_back(service_path
);
83 properties
->GetString(shill::kStateProperty
, &state
);
84 if (state
== shill::kStateOnline
||
85 state
== shill::kStateAssociation
||
86 state
== shill::kStateConfiguration
||
87 state
== shill::kStatePortal
||
88 state
== shill::kStateReady
) {
89 active_service_list_out
->push_back(service_path
);
91 inactive_service_list_out
->push_back(service_path
);
96 void LogErrorCallback(const std::string
& error_name
,
97 const std::string
& error_message
) {
98 LOG(ERROR
) << error_name
<< ": " << error_message
;
101 bool IsConnectedState(const std::string
& state
) {
102 return state
== shill::kStateOnline
|| state
== shill::kStatePortal
||
103 state
== shill::kStateReady
;
106 void UpdatePortaledWifiState(const std::string
& service_path
) {
107 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
108 ->SetServiceProperty(service_path
,
109 shill::kStateProperty
,
110 base::StringValue(shill::kStatePortal
));
113 bool IsCellularTechnology(const std::string
& type
) {
114 return (type
== shill::kNetworkTechnology1Xrtt
||
115 type
== shill::kNetworkTechnologyEvdo
||
116 type
== shill::kNetworkTechnologyGsm
||
117 type
== shill::kNetworkTechnologyGprs
||
118 type
== shill::kNetworkTechnologyEdge
||
119 type
== shill::kNetworkTechnologyUmts
||
120 type
== shill::kNetworkTechnologyHspa
||
121 type
== shill::kNetworkTechnologyHspaPlus
||
122 type
== shill::kNetworkTechnologyLte
||
123 type
== shill::kNetworkTechnologyLteAdvanced
);
126 const char* kTechnologyUnavailable
= "unavailable";
127 const char* kNetworkActivated
= "activated";
128 const char* kNetworkDisabled
= "disabled";
129 const char* kCellularServicePath
= "/service/cellular1";
130 const char* kRoamingRequired
= "required";
135 const char FakeShillManagerClient::kFakeEthernetNetworkGuid
[] = "eth1_guid";
137 FakeShillManagerClient::FakeShillManagerClient()
138 : interactive_delay_(0),
139 cellular_technology_(shill::kNetworkTechnologyGsm
),
140 weak_ptr_factory_(this) {
141 ParseCommandLineSwitch();
144 FakeShillManagerClient::~FakeShillManagerClient() {}
146 // ShillManagerClient overrides.
148 void FakeShillManagerClient::Init(dbus::Bus
* bus
) {}
150 void FakeShillManagerClient::AddPropertyChangedObserver(
151 ShillPropertyChangedObserver
* observer
) {
152 observer_list_
.AddObserver(observer
);
155 void FakeShillManagerClient::RemovePropertyChangedObserver(
156 ShillPropertyChangedObserver
* observer
) {
157 observer_list_
.RemoveObserver(observer
);
160 void FakeShillManagerClient::GetProperties(
161 const DictionaryValueCallback
& callback
) {
162 VLOG(1) << "Manager.GetProperties";
163 base::ThreadTaskRunnerHandle::Get()->PostTask(
164 FROM_HERE
, base::Bind(&FakeShillManagerClient::PassStubProperties
,
165 weak_ptr_factory_
.GetWeakPtr(), callback
));
168 void FakeShillManagerClient::GetNetworksForGeolocation(
169 const DictionaryValueCallback
& callback
) {
170 base::ThreadTaskRunnerHandle::Get()->PostTask(
171 FROM_HERE
, base::Bind(&FakeShillManagerClient::PassStubGeoNetworks
,
172 weak_ptr_factory_
.GetWeakPtr(), callback
));
175 void FakeShillManagerClient::SetProperty(const std::string
& name
,
176 const base::Value
& value
,
177 const base::Closure
& callback
,
178 const ErrorCallback
& error_callback
) {
179 VLOG(2) << "SetProperty: " << name
;
180 stub_properties_
.SetWithoutPathExpansion(name
, value
.DeepCopy());
181 CallNotifyObserversPropertyChanged(name
);
182 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, callback
);
185 void FakeShillManagerClient::RequestScan(const std::string
& type
,
186 const base::Closure
& callback
,
187 const ErrorCallback
& error_callback
) {
188 // For Stub purposes, default to a Wifi scan.
189 std::string device_type
= shill::kTypeWifi
;
192 ShillDeviceClient::TestInterface
* device_client
=
193 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
194 std::string device_path
= device_client
->GetDevicePathForType(device_type
);
195 if (!device_path
.empty()) {
196 device_client
->SetDeviceProperty(
197 device_path
, shill::kScanningProperty
, base::FundamentalValue(true));
199 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
201 base::Bind(&FakeShillManagerClient::ScanCompleted
,
202 weak_ptr_factory_
.GetWeakPtr(), device_path
, callback
),
203 base::TimeDelta::FromSeconds(interactive_delay_
));
206 void FakeShillManagerClient::EnableTechnology(
207 const std::string
& type
,
208 const base::Closure
& callback
,
209 const ErrorCallback
& error_callback
) {
210 base::ListValue
* enabled_list
= NULL
;
211 if (!stub_properties_
.GetListWithoutPathExpansion(
212 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
213 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, callback
);
214 base::ThreadTaskRunnerHandle::Get()->PostTask(
216 base::Bind(error_callback
, "StubError", "Property not found"));
219 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
221 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
222 weak_ptr_factory_
.GetWeakPtr(), type
, callback
, true),
223 base::TimeDelta::FromSeconds(interactive_delay_
));
226 void FakeShillManagerClient::DisableTechnology(
227 const std::string
& type
,
228 const base::Closure
& callback
,
229 const ErrorCallback
& error_callback
) {
230 base::ListValue
* enabled_list
= NULL
;
231 if (!stub_properties_
.GetListWithoutPathExpansion(
232 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
233 base::ThreadTaskRunnerHandle::Get()->PostTask(
235 base::Bind(error_callback
, "StubError", "Property not found"));
238 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
240 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
241 weak_ptr_factory_
.GetWeakPtr(), type
, callback
, false),
242 base::TimeDelta::FromSeconds(interactive_delay_
));
245 void FakeShillManagerClient::ConfigureService(
246 const base::DictionaryValue
& properties
,
247 const ObjectPathCallback
& callback
,
248 const ErrorCallback
& error_callback
) {
249 ShillServiceClient::TestInterface
* service_client
=
250 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
254 if (!properties
.GetString(shill::kGuidProperty
, &guid
) ||
255 !properties
.GetString(shill::kTypeProperty
, &type
)) {
256 LOG(ERROR
) << "ConfigureService requires GUID and Type to be defined";
257 // If the properties aren't filled out completely, then just return an empty
259 base::ThreadTaskRunnerHandle::Get()->PostTask(
260 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
264 // For the purposes of this stub, we're going to assume that the GUID property
265 // is set to the service path because we don't want to re-implement Shill's
266 // property matching magic here.
267 std::string service_path
= guid
;
269 std::string ipconfig_path
;
270 properties
.GetString(shill::kIPConfigProperty
, &ipconfig_path
);
272 // Merge the new properties with existing properties, if any.
273 const base::DictionaryValue
* existing_properties
=
274 service_client
->GetServiceProperties(service_path
);
275 if (!existing_properties
) {
276 // Add a new service to the service client stub because none exists, yet.
277 // This calls AddManagerService.
278 service_client
->AddServiceWithIPConfig(service_path
,
285 existing_properties
= service_client
->GetServiceProperties(service_path
);
288 scoped_ptr
<base::DictionaryValue
> merged_properties(
289 existing_properties
->DeepCopy());
290 merged_properties
->MergeDictionary(&properties
);
292 // Now set all the properties.
293 for (base::DictionaryValue::Iterator
iter(*merged_properties
);
294 !iter
.IsAtEnd(); iter
.Advance()) {
295 service_client
->SetServiceProperty(service_path
, iter
.key(), iter
.value());
298 // If the Profile property is set, add it to ProfileClient.
299 std::string profile_path
;
300 merged_properties
->GetStringWithoutPathExpansion(shill::kProfileProperty
,
302 if (!profile_path
.empty()) {
303 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface()->
304 AddService(profile_path
, service_path
);
307 base::ThreadTaskRunnerHandle::Get()->PostTask(
308 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath(service_path
)));
311 void FakeShillManagerClient::ConfigureServiceForProfile(
312 const dbus::ObjectPath
& profile_path
,
313 const base::DictionaryValue
& properties
,
314 const ObjectPathCallback
& callback
,
315 const ErrorCallback
& error_callback
) {
316 std::string profile_property
;
317 properties
.GetStringWithoutPathExpansion(shill::kProfileProperty
,
319 CHECK(profile_property
== profile_path
.value());
320 ConfigureService(properties
, callback
, error_callback
);
324 void FakeShillManagerClient::GetService(
325 const base::DictionaryValue
& properties
,
326 const ObjectPathCallback
& callback
,
327 const ErrorCallback
& error_callback
) {
328 base::ThreadTaskRunnerHandle::Get()->PostTask(
329 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
332 void FakeShillManagerClient::VerifyDestination(
333 const VerificationProperties
& properties
,
334 const BooleanCallback
& callback
,
335 const ErrorCallback
& error_callback
) {
336 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
337 base::Bind(callback
, true));
340 void FakeShillManagerClient::VerifyAndEncryptCredentials(
341 const VerificationProperties
& properties
,
342 const std::string
& service_path
,
343 const StringCallback
& callback
,
344 const ErrorCallback
& error_callback
) {
345 base::ThreadTaskRunnerHandle::Get()->PostTask(
346 FROM_HERE
, base::Bind(callback
, "encrypted_credentials"));
349 void FakeShillManagerClient::VerifyAndEncryptData(
350 const VerificationProperties
& properties
,
351 const std::string
& data
,
352 const StringCallback
& callback
,
353 const ErrorCallback
& error_callback
) {
354 base::ThreadTaskRunnerHandle::Get()->PostTask(
355 FROM_HERE
, base::Bind(callback
, "encrypted_data"));
358 void FakeShillManagerClient::ConnectToBestServices(
359 const base::Closure
& callback
,
360 const ErrorCallback
& error_callback
) {
361 if (best_service_
.empty()) {
362 VLOG(1) << "No 'best' service set.";
366 DBusThreadManager::Get()->GetShillServiceClient()->Connect(
367 dbus::ObjectPath(best_service_
), callback
, error_callback
);
370 ShillManagerClient::TestInterface
* FakeShillManagerClient::GetTestInterface() {
374 // ShillManagerClient::TestInterface overrides.
376 void FakeShillManagerClient::AddDevice(const std::string
& device_path
) {
377 if (GetListProperty(shill::kDevicesProperty
)
378 ->AppendIfNotPresent(new base::StringValue(device_path
))) {
379 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
383 void FakeShillManagerClient::RemoveDevice(const std::string
& device_path
) {
384 base::StringValue
device_path_value(device_path
);
385 if (GetListProperty(shill::kDevicesProperty
)->Remove(
386 device_path_value
, NULL
)) {
387 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
391 void FakeShillManagerClient::ClearDevices() {
392 GetListProperty(shill::kDevicesProperty
)->Clear();
393 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
396 void FakeShillManagerClient::AddTechnology(const std::string
& type
,
398 if (GetListProperty(shill::kAvailableTechnologiesProperty
)
399 ->AppendIfNotPresent(new base::StringValue(type
))) {
400 CallNotifyObserversPropertyChanged(
401 shill::kAvailableTechnologiesProperty
);
404 GetListProperty(shill::kEnabledTechnologiesProperty
)
405 ->AppendIfNotPresent(new base::StringValue(type
))) {
406 CallNotifyObserversPropertyChanged(
407 shill::kEnabledTechnologiesProperty
);
411 void FakeShillManagerClient::RemoveTechnology(const std::string
& type
) {
412 base::StringValue
type_value(type
);
413 if (GetListProperty(shill::kAvailableTechnologiesProperty
)->Remove(
415 CallNotifyObserversPropertyChanged(
416 shill::kAvailableTechnologiesProperty
);
418 if (GetListProperty(shill::kEnabledTechnologiesProperty
)->Remove(
420 CallNotifyObserversPropertyChanged(
421 shill::kEnabledTechnologiesProperty
);
425 void FakeShillManagerClient::SetTechnologyInitializing(const std::string
& type
,
428 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)
429 ->AppendIfNotPresent(new base::StringValue(type
))) {
430 CallNotifyObserversPropertyChanged(
431 shill::kUninitializedTechnologiesProperty
);
434 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)->Remove(
435 base::StringValue(type
), NULL
)) {
436 CallNotifyObserversPropertyChanged(
437 shill::kUninitializedTechnologiesProperty
);
442 void FakeShillManagerClient::AddGeoNetwork(
443 const std::string
& technology
,
444 const base::DictionaryValue
& network
) {
445 base::ListValue
* list_value
= NULL
;
446 if (!stub_geo_networks_
.GetListWithoutPathExpansion(technology
,
448 list_value
= new base::ListValue
;
449 stub_geo_networks_
.SetWithoutPathExpansion(technology
, list_value
);
451 list_value
->Append(network
.DeepCopy());
454 void FakeShillManagerClient::AddProfile(const std::string
& profile_path
) {
455 const char* key
= shill::kProfilesProperty
;
456 if (GetListProperty(key
)
457 ->AppendIfNotPresent(new base::StringValue(profile_path
))) {
458 CallNotifyObserversPropertyChanged(key
);
462 void FakeShillManagerClient::ClearProperties() {
463 stub_properties_
.Clear();
466 void FakeShillManagerClient::SetManagerProperty(const std::string
& key
,
467 const base::Value
& value
) {
468 SetProperty(key
, value
,
469 base::Bind(&base::DoNothing
), base::Bind(&LogErrorCallback
));
472 void FakeShillManagerClient::AddManagerService(
473 const std::string
& service_path
,
474 bool notify_observers
) {
475 VLOG(2) << "AddManagerService: " << service_path
;
476 GetListProperty(shill::kServiceCompleteListProperty
)
477 ->AppendIfNotPresent(new base::StringValue(service_path
));
478 SortManagerServices(false);
479 if (notify_observers
)
480 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
483 void FakeShillManagerClient::RemoveManagerService(
484 const std::string
& service_path
) {
485 VLOG(2) << "RemoveManagerService: " << service_path
;
486 base::StringValue
service_path_value(service_path
);
487 GetListProperty(shill::kServiceCompleteListProperty
)->Remove(
488 service_path_value
, NULL
);
489 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
492 void FakeShillManagerClient::ClearManagerServices() {
493 VLOG(1) << "ClearManagerServices";
494 GetListProperty(shill::kServiceCompleteListProperty
)->Clear();
495 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
498 void FakeShillManagerClient::ServiceStateChanged(
499 const std::string
& service_path
,
500 const std::string
& state
) {
501 if (service_path
== default_service_
&& !IsConnectedState(state
)) {
502 // Default service is no longer connected; clear.
503 default_service_
.clear();
504 base::StringValue
default_service_value(default_service_
);
505 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
509 void FakeShillManagerClient::SortManagerServices(bool notify
) {
510 VLOG(1) << "SortManagerServices";
511 static const char* ordered_types
[] = {shill::kTypeEthernet
,
512 shill::kTypeEthernetEap
,
514 shill::kTypeCellular
,
518 base::ListValue
* complete_list
=
519 GetListProperty(shill::kServiceCompleteListProperty
);
520 if (complete_list
->empty())
522 scoped_ptr
<base::ListValue
> prev_complete_list(complete_list
->DeepCopy());
524 std::vector
<std::string
> active_services
;
525 std::vector
<std::string
> inactive_services
;
526 std::vector
<std::string
> disabled_services
;
527 for (size_t i
= 0; i
< arraysize(ordered_types
); ++i
) {
528 AppendServicesForType(complete_list
,
530 TechnologyEnabled(ordered_types
[i
]),
535 complete_list
->Clear();
536 for (size_t i
= 0; i
< active_services
.size(); ++i
)
537 complete_list
->AppendString(active_services
[i
]);
538 for (size_t i
= 0; i
< inactive_services
.size(); ++i
)
539 complete_list
->AppendString(inactive_services
[i
]);
540 for (size_t i
= 0; i
< disabled_services
.size(); ++i
)
541 complete_list
->AppendString(disabled_services
[i
]);
543 if (notify
&& !complete_list
->Equals(prev_complete_list
.get()))
544 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
546 // Set the first active service as the Default service.
547 std::string new_default_service
;
548 if (!active_services
.empty()) {
549 ShillServiceClient::TestInterface
* service_client
=
550 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
551 std::string service_path
= active_services
[0];
552 const base::DictionaryValue
* properties
=
553 service_client
->GetServiceProperties(service_path
);
555 LOG(ERROR
) << "Properties not found for service: " << service_path
;
558 properties
->GetString(shill::kStateProperty
, &state
);
559 if (IsConnectedState(state
))
560 new_default_service
= service_path
;
563 if (default_service_
!= new_default_service
) {
564 default_service_
= new_default_service
;
565 base::StringValue
default_service_value(default_service_
);
566 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
570 int FakeShillManagerClient::GetInteractiveDelay() const {
571 return interactive_delay_
;
574 void FakeShillManagerClient::SetBestServiceToConnect(
575 const std::string
& service_path
) {
576 best_service_
= service_path
;
579 void FakeShillManagerClient::SetupDefaultEnvironment() {
580 // Bail out from setup if there is no message loop. This will be the common
581 // case for tests that are not testing Shill.
582 if (!base::ThreadTaskRunnerHandle::IsSet())
585 DBusThreadManager
* dbus_manager
= DBusThreadManager::Get();
586 ShillServiceClient::TestInterface
* services
=
587 dbus_manager
->GetShillServiceClient()->GetTestInterface();
589 ShillProfileClient::TestInterface
* profiles
=
590 dbus_manager
->GetShillProfileClient()->GetTestInterface();
592 ShillDeviceClient::TestInterface
* devices
=
593 dbus_manager
->GetShillDeviceClient()->GetTestInterface();
595 ShillIPConfigClient::TestInterface
* ip_configs
=
596 dbus_manager
->GetShillIPConfigClient()->GetTestInterface();
599 const std::string shared_profile
= ShillProfileClient::GetSharedProfilePath();
600 profiles
->AddProfile(shared_profile
, std::string());
602 const bool add_to_visible
= true;
605 base::DictionaryValue ipconfig_v4_dictionary
;
606 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
607 shill::kAddressProperty
, "100.0.0.1");
608 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
609 shill::kGatewayProperty
, "100.0.0.2");
610 ipconfig_v4_dictionary
.SetIntegerWithoutPathExpansion(
611 shill::kPrefixlenProperty
, 1);
612 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
613 shill::kMethodProperty
, shill::kTypeIPv4
);
614 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
615 shill::kWebProxyAutoDiscoveryUrlProperty
, "http://wpad.com/wpad.dat");
616 ip_configs
->AddIPConfig("ipconfig_v4_path", ipconfig_v4_dictionary
);
617 base::DictionaryValue ipconfig_v6_dictionary
;
618 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
619 shill::kAddressProperty
, "0:0:0:0:100:0:0:1");
620 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
621 shill::kMethodProperty
, shill::kTypeIPv6
);
622 ip_configs
->AddIPConfig("ipconfig_v6_path", ipconfig_v6_dictionary
);
628 state
= GetInitialStateForType(shill::kTypeEthernet
, &enabled
);
629 if (state
== shill::kStateOnline
|| state
== shill::kStateIdle
) {
630 AddTechnology(shill::kTypeEthernet
, enabled
);
632 "/device/eth1", shill::kTypeEthernet
, "stub_eth_device1");
633 devices
->SetDeviceProperty("/device/eth1",
634 shill::kAddressProperty
,
635 base::StringValue("0123456789ab"));
636 base::ListValue eth_ip_configs
;
637 eth_ip_configs
.AppendString("ipconfig_v4_path");
638 eth_ip_configs
.AppendString("ipconfig_v6_path");
639 devices
->SetDeviceProperty("/device/eth1",
640 shill::kIPConfigsProperty
,
642 const std::string kFakeEthernetNetworkPath
= "/service/eth1";
643 services
->AddService(kFakeEthernetNetworkPath
,
644 kFakeEthernetNetworkGuid
,
646 shill::kTypeEthernet
,
649 profiles
->AddService(shared_profile
, kFakeEthernetNetworkPath
);
653 if (s_tdls_busy_count
!= 0) {
654 DBusThreadManager::Get()
655 ->GetShillDeviceClient()
657 ->SetTDLSBusyCount(s_tdls_busy_count
);
660 state
= GetInitialStateForType(shill::kTypeWifi
, &enabled
);
661 if (state
!= kTechnologyUnavailable
) {
662 bool portaled
= false;
663 if (state
== shill::kStatePortal
) {
665 state
= shill::kStateIdle
;
667 AddTechnology(shill::kTypeWifi
, enabled
);
668 devices
->AddDevice("/device/wifi1", shill::kTypeWifi
, "stub_wifi_device1");
669 devices
->SetDeviceProperty("/device/wifi1",
670 shill::kAddressProperty
,
671 base::StringValue("23456789abcd"));
672 base::ListValue wifi_ip_configs
;
673 wifi_ip_configs
.AppendString("ipconfig_v4_path");
674 wifi_ip_configs
.AppendString("ipconfig_v6_path");
675 devices
->SetDeviceProperty("/device/wifi1",
676 shill::kIPConfigsProperty
,
679 const std::string kWifi1Path
= "/service/wifi1";
680 services
->AddService(kWifi1Path
,
686 services
->SetServiceProperty(kWifi1Path
,
687 shill::kSecurityClassProperty
,
688 base::StringValue(shill::kSecurityWep
));
689 services
->SetServiceProperty(kWifi1Path
,
690 shill::kConnectableProperty
,
691 base::FundamentalValue(true));
692 profiles
->AddService(shared_profile
, kWifi1Path
);
694 const std::string kWifi2Path
= "/service/wifi2";
695 services
->AddService(kWifi2Path
,
697 "wifi2_PSK" /* name */,
701 services
->SetServiceProperty(kWifi2Path
,
702 shill::kSecurityClassProperty
,
703 base::StringValue(shill::kSecurityPsk
));
704 services
->SetServiceProperty(
705 kWifi2Path
, shill::kSignalStrengthProperty
, base::FundamentalValue(80));
706 profiles
->AddService(shared_profile
, kWifi2Path
);
708 const std::string kWifi3Path
= "/service/wifi3";
709 services
->AddService(kWifi3Path
,
715 services
->SetServiceProperty(
716 kWifi3Path
, shill::kSignalStrengthProperty
, base::FundamentalValue(40));
719 const std::string kPortaledWifiPath
= "/service/portaled_wifi";
720 services
->AddService(kPortaledWifiPath
, "portaled_wifi_guid",
721 "Portaled Wifi" /* name */, shill::kTypeWifi
,
722 shill::kStateIdle
, add_to_visible
);
723 services
->SetServiceProperty(kPortaledWifiPath
,
724 shill::kSecurityClassProperty
,
725 base::StringValue(shill::kSecurityNone
));
726 services
->SetConnectBehavior(
728 base::Bind(&UpdatePortaledWifiState
, kPortaledWifiPath
));
729 services
->SetServiceProperty(kPortaledWifiPath
,
730 shill::kConnectableProperty
,
731 base::FundamentalValue(true));
732 profiles
->AddService(shared_profile
, kPortaledWifiPath
);
735 for (int i
= 0; i
< s_extra_wifi_networks
; ++i
) {
737 std::string path
= base::StringPrintf("/service/wifi%d", id
);
738 std::string guid
= base::StringPrintf("wifi%d_guid", id
);
739 std::string name
= base::StringPrintf("wifi%d", id
);
740 services
->AddService(path
, guid
, name
, shill::kTypeWifi
,
741 shill::kStateIdle
, add_to_visible
);
746 const std::string kWimaxPath
= "/service/wimax1";
747 state
= GetInitialStateForType(shill::kTypeWimax
, &enabled
);
748 if (state
!= kTechnologyUnavailable
) {
749 AddTechnology(shill::kTypeWimax
, enabled
);
751 "/device/wimax1", shill::kTypeWimax
, "stub_wimax_device1");
753 services
->AddService(kWimaxPath
, "wimax1_guid", "wimax1" /* name */,
754 shill::kTypeWimax
, state
, add_to_visible
);
755 services
->SetServiceProperty(kWimaxPath
, shill::kConnectableProperty
,
756 base::FundamentalValue(true));
757 base::FundamentalValue
strength_value(80);
758 services
->SetServiceProperty(kWimaxPath
, shill::kSignalStrengthProperty
,
760 profiles
->AddService(shared_profile
, kWimaxPath
);
764 state
= GetInitialStateForType(shill::kTypeCellular
, &enabled
);
765 if (state
!= kTechnologyUnavailable
) {
766 bool activated
= false;
767 if (state
== kNetworkActivated
) {
769 state
= shill::kStateIdle
;
771 AddTechnology(shill::kTypeCellular
, enabled
);
773 "/device/cellular1", shill::kTypeCellular
, "stub_cellular_device1");
774 devices
->SetDeviceProperty("/device/cellular1",
775 shill::kCarrierProperty
,
776 base::StringValue(shill::kCarrierSprint
));
777 base::ListValue carrier_list
;
778 carrier_list
.AppendString(shill::kCarrierSprint
);
779 carrier_list
.AppendString(shill::kCarrierGenericUMTS
);
780 devices
->SetDeviceProperty("/device/cellular1",
781 shill::kSupportedCarriersProperty
,
783 devices
->SetDeviceProperty("/device/cellular1",
784 shill::kSupportNetworkScanProperty
,
785 base::FundamentalValue(true));
786 if (roaming_state_
== kRoamingRequired
) {
787 devices
->SetDeviceProperty("/device/cellular1",
788 shill::kProviderRequiresRoamingProperty
,
789 base::FundamentalValue(true));
792 services
->AddService(kCellularServicePath
,
794 "cellular1" /* name */,
795 shill::kTypeCellular
,
798 base::StringValue
technology_value(cellular_technology_
);
799 devices
->SetDeviceProperty("/device/cellular1",
800 shill::kTechnologyFamilyProperty
,
802 services
->SetServiceProperty(kCellularServicePath
,
803 shill::kNetworkTechnologyProperty
,
807 services
->SetServiceProperty(
808 kCellularServicePath
,
809 shill::kActivationStateProperty
,
810 base::StringValue(shill::kActivationStateActivated
));
811 services
->SetServiceProperty(kCellularServicePath
,
812 shill::kConnectableProperty
,
813 base::FundamentalValue(true));
815 services
->SetServiceProperty(
816 kCellularServicePath
,
817 shill::kActivationStateProperty
,
818 base::StringValue(shill::kActivationStateNotActivated
));
821 std::string shill_roaming_state
;
822 if (roaming_state_
== kRoamingRequired
)
823 shill_roaming_state
= shill::kRoamingStateRoaming
;
824 else if (roaming_state_
.empty())
825 shill_roaming_state
= shill::kRoamingStateHome
;
826 else // |roaming_state_| is expected to be a valid Shill state.
827 shill_roaming_state
= roaming_state_
;
828 services
->SetServiceProperty(kCellularServicePath
,
829 shill::kRoamingStateProperty
,
830 base::StringValue(shill_roaming_state
));
832 base::DictionaryValue apn
;
833 apn
.SetStringWithoutPathExpansion(shill::kApnProperty
, "testapn");
834 apn
.SetStringWithoutPathExpansion(shill::kApnNameProperty
, "Test APN");
835 apn
.SetStringWithoutPathExpansion(shill::kApnLocalizedNameProperty
,
836 "Localized Test APN");
837 apn
.SetStringWithoutPathExpansion(shill::kApnUsernameProperty
, "User1");
838 apn
.SetStringWithoutPathExpansion(shill::kApnPasswordProperty
, "password");
839 base::DictionaryValue apn2
;
840 apn2
.SetStringWithoutPathExpansion(shill::kApnProperty
, "testapn2");
841 services
->SetServiceProperty(kCellularServicePath
,
842 shill::kCellularApnProperty
, apn
);
843 services
->SetServiceProperty(kCellularServicePath
,
844 shill::kCellularLastGoodApnProperty
, apn
);
845 base::ListValue apn_list
;
846 apn_list
.Append(apn
.DeepCopy());
847 apn_list
.Append(apn2
.DeepCopy());
848 devices
->SetDeviceProperty("/device/cellular1",
849 shill::kCellularApnListProperty
, apn_list
);
851 profiles
->AddService(shared_profile
, kCellularServicePath
);
855 state
= GetInitialStateForType(shill::kTypeVPN
, &enabled
);
856 if (state
!= kTechnologyUnavailable
) {
857 // Set the "Provider" dictionary properties. Note: when setting these in
858 // Shill, "Provider.Type", etc keys are used, but when reading the values
859 // "Provider" . "Type", etc keys are used. Here we are setting the values
860 // that will be read (by the UI, tests, etc).
861 base::DictionaryValue provider_properties_openvpn
;
862 provider_properties_openvpn
.SetString(shill::kTypeProperty
,
863 shill::kProviderOpenVpn
);
864 provider_properties_openvpn
.SetString(shill::kHostProperty
, "vpn_host");
866 services
->AddService("/service/vpn1",
872 services
->SetServiceProperty(
873 "/service/vpn1", shill::kProviderProperty
, provider_properties_openvpn
);
874 profiles
->AddService(shared_profile
, "/service/vpn1");
876 base::DictionaryValue provider_properties_l2tp
;
877 provider_properties_l2tp
.SetString(shill::kTypeProperty
,
878 shill::kProviderL2tpIpsec
);
879 provider_properties_l2tp
.SetString(shill::kHostProperty
, "vpn_host2");
881 services
->AddService("/service/vpn2",
887 services
->SetServiceProperty(
888 "/service/vpn2", shill::kProviderProperty
, provider_properties_l2tp
);
891 // Additional device states
892 for (DevicePropertyMap::iterator iter1
= shill_device_property_map_
.begin();
893 iter1
!= shill_device_property_map_
.end(); ++iter1
) {
894 std::string device_type
= iter1
->first
;
895 std::string device_path
= devices
->GetDevicePathForType(device_type
);
896 for (ShillPropertyMap::iterator iter2
= iter1
->second
.begin();
897 iter2
!= iter1
->second
.end(); ++iter2
) {
898 devices
->SetDeviceProperty(device_path
, iter2
->first
, *(iter2
->second
));
899 delete iter2
->second
;
903 SortManagerServices(true);
908 void FakeShillManagerClient::PassStubProperties(
909 const DictionaryValueCallback
& callback
) const {
910 scoped_ptr
<base::DictionaryValue
> stub_properties(
911 stub_properties_
.DeepCopy());
912 stub_properties
->SetWithoutPathExpansion(
913 shill::kServiceCompleteListProperty
,
914 GetEnabledServiceList(shill::kServiceCompleteListProperty
));
915 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, *stub_properties
);
918 void FakeShillManagerClient::PassStubGeoNetworks(
919 const DictionaryValueCallback
& callback
) const {
920 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, stub_geo_networks_
);
923 void FakeShillManagerClient::CallNotifyObserversPropertyChanged(
924 const std::string
& property
) {
925 // Avoid unnecessary delayed task if we have no observers (e.g. during
927 if (!observer_list_
.might_have_observers())
929 base::ThreadTaskRunnerHandle::Get()->PostTask(
931 base::Bind(&FakeShillManagerClient::NotifyObserversPropertyChanged
,
932 weak_ptr_factory_
.GetWeakPtr(), property
));
935 void FakeShillManagerClient::NotifyObserversPropertyChanged(
936 const std::string
& property
) {
937 VLOG(1) << "NotifyObserversPropertyChanged: " << property
;
938 base::Value
* value
= NULL
;
939 if (!stub_properties_
.GetWithoutPathExpansion(property
, &value
)) {
940 LOG(ERROR
) << "Notify for unknown property: " << property
;
943 if (property
== shill::kServiceCompleteListProperty
) {
944 scoped_ptr
<base::ListValue
> services(GetEnabledServiceList(property
));
945 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
947 OnPropertyChanged(property
, *(services
.get())));
950 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
952 OnPropertyChanged(property
, *value
));
955 base::ListValue
* FakeShillManagerClient::GetListProperty(
956 const std::string
& property
) {
957 base::ListValue
* list_property
= NULL
;
958 if (!stub_properties_
.GetListWithoutPathExpansion(
959 property
, &list_property
)) {
960 list_property
= new base::ListValue
;
961 stub_properties_
.SetWithoutPathExpansion(property
, list_property
);
963 return list_property
;
966 bool FakeShillManagerClient::TechnologyEnabled(const std::string
& type
) const {
967 if (type
== shill::kTypeVPN
)
968 return true; // VPN is always "enabled" since there is no associated device
969 if (type
== shill::kTypeEthernetEap
)
971 bool enabled
= false;
972 const base::ListValue
* technologies
;
973 if (stub_properties_
.GetListWithoutPathExpansion(
974 shill::kEnabledTechnologiesProperty
, &technologies
)) {
975 base::StringValue
type_value(type
);
976 if (technologies
->Find(type_value
) != technologies
->end())
982 void FakeShillManagerClient::SetTechnologyEnabled(
983 const std::string
& type
,
984 const base::Closure
& callback
,
986 base::ListValue
* enabled_list
=
987 GetListProperty(shill::kEnabledTechnologiesProperty
);
989 enabled_list
->AppendIfNotPresent(new base::StringValue(type
));
991 enabled_list
->Remove(base::StringValue(type
), NULL
);
992 CallNotifyObserversPropertyChanged(
993 shill::kEnabledTechnologiesProperty
);
994 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, callback
);
995 // May affect available services.
996 SortManagerServices(true);
999 base::ListValue
* FakeShillManagerClient::GetEnabledServiceList(
1000 const std::string
& property
) const {
1001 base::ListValue
* new_service_list
= new base::ListValue
;
1002 const base::ListValue
* service_list
;
1003 if (stub_properties_
.GetListWithoutPathExpansion(property
, &service_list
)) {
1004 ShillServiceClient::TestInterface
* service_client
=
1005 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
1006 for (base::ListValue::const_iterator iter
= service_list
->begin();
1007 iter
!= service_list
->end(); ++iter
) {
1008 std::string service_path
;
1009 if (!(*iter
)->GetAsString(&service_path
))
1011 const base::DictionaryValue
* properties
=
1012 service_client
->GetServiceProperties(service_path
);
1014 LOG(ERROR
) << "Properties not found for service: " << service_path
;
1018 properties
->GetString(shill::kTypeProperty
, &type
);
1019 if (TechnologyEnabled(type
))
1020 new_service_list
->Append((*iter
)->DeepCopy());
1023 return new_service_list
;
1026 void FakeShillManagerClient::ScanCompleted(const std::string
& device_path
,
1027 const base::Closure
& callback
) {
1028 if (!device_path
.empty()) {
1029 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
1030 SetDeviceProperty(device_path
,
1031 shill::kScanningProperty
,
1032 base::FundamentalValue(false));
1034 VLOG(2) << "ScanCompleted";
1035 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
1036 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, callback
);
1039 void FakeShillManagerClient::ParseCommandLineSwitch() {
1041 SetInitialNetworkState(shill::kTypeEthernet
, shill::kStateOnline
);
1042 SetInitialNetworkState(shill::kTypeWifi
, shill::kStateOnline
);
1043 SetInitialNetworkState(shill::kTypeCellular
, shill::kStateIdle
);
1044 SetInitialNetworkState(shill::kTypeVPN
, shill::kStateIdle
);
1046 // Parse additional options
1047 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
1048 if (!command_line
->HasSwitch(switches::kShillStub
))
1051 std::string option_str
=
1052 command_line
->GetSwitchValueASCII(switches::kShillStub
);
1053 VLOG(1) << "Parsing command line:" << option_str
;
1054 base::StringPairs string_pairs
;
1055 base::SplitStringIntoKeyValuePairs(option_str
, '=', ',', &string_pairs
);
1056 for (base::StringPairs::iterator iter
= string_pairs
.begin();
1057 iter
!= string_pairs
.end(); ++iter
) {
1058 ParseOption((*iter
).first
, (*iter
).second
);
1062 bool FakeShillManagerClient::ParseOption(const std::string
& arg0
,
1063 const std::string
& arg1
) {
1064 VLOG(1) << "Parsing command line option: '" << arg0
<< "=" << arg1
<< "'";
1065 if ((arg0
== "clear" || arg0
== "reset") && arg1
== "1") {
1066 shill_initial_state_map_
.clear();
1068 } else if (arg0
== "interactive") {
1071 base::StringToInt(arg1
, &seconds
);
1072 interactive_delay_
= seconds
;
1074 } else if (arg0
== "sim_lock") {
1075 bool locked
= (arg1
== "1") ? true : false;
1076 base::DictionaryValue
* simlock_dict
= new base::DictionaryValue
;
1077 simlock_dict
->Set(shill::kSIMLockEnabledProperty
,
1078 new base::FundamentalValue(locked
));
1079 std::string lock_type
= shill::kSIMLockPin
;
1080 simlock_dict
->SetString(shill::kSIMLockTypeProperty
, lock_type
);
1081 simlock_dict
->SetInteger(shill::kSIMLockRetriesLeftProperty
, 5);
1083 shill_device_property_map_
[shill::kTypeCellular
]
1084 [shill::kSIMLockStatusProperty
] = simlock_dict
;
1085 shill_device_property_map_
1086 [shill::kTypeCellular
][shill::kTechnologyFamilyProperty
] =
1087 new base::StringValue(shill::kNetworkTechnologyGsm
);
1089 } else if (arg0
== "tdls_busy") {
1091 base::StringToInt(arg1
, &s_tdls_busy_count
);
1093 s_tdls_busy_count
= 1;
1095 } else if (arg0
== "roaming") {
1096 // "home", "roaming", or "required"
1097 roaming_state_
= arg1
;
1100 return SetInitialNetworkState(arg0
, arg1
);
1103 bool FakeShillManagerClient::SetInitialNetworkState(std::string type_arg
,
1104 std::string state_arg
) {
1105 int state_arg_as_int
= -1;
1106 base::StringToInt(state_arg
, &state_arg_as_int
);
1109 if (state_arg
.empty() || state_arg
== "1" || state_arg
== "on" ||
1110 state_arg
== "enabled" || state_arg
== "connected" ||
1111 state_arg
== "online") {
1112 // Enabled and connected (default value)
1113 state
= shill::kStateOnline
;
1114 } else if (state_arg
== "0" || state_arg
== "off" ||
1115 state_arg
== "inactive" || state_arg
== shill::kStateIdle
) {
1116 // Technology enabled, services are created but are not connected.
1117 state
= shill::kStateIdle
;
1118 } else if (type_arg
== shill::kTypeWifi
&& state_arg_as_int
> 1) {
1119 // Enabled and connected, add extra wifi networks.
1120 state
= shill::kStateOnline
;
1121 s_extra_wifi_networks
= state_arg_as_int
- 1;
1122 } else if (state_arg
== "disabled" || state_arg
== "disconnect") {
1123 // Technology disabled but available, services created but not connected.
1124 state
= kNetworkDisabled
;
1125 } else if (state_arg
== "none" || state_arg
== "offline") {
1126 // Technology not available, do not create services.
1127 state
= kTechnologyUnavailable
;
1128 } else if (state_arg
== "portal") {
1129 // Technology is enabled, a service is connected and in Portal state.
1130 state
= shill::kStatePortal
;
1131 } else if (state_arg
== "active" || state_arg
== "activated") {
1132 // Technology is enabled, a service is connected and Activated.
1133 state
= kNetworkActivated
;
1134 } else if (type_arg
== shill::kTypeCellular
&&
1135 IsCellularTechnology(state_arg
)) {
1136 state
= shill::kStateOnline
;
1137 cellular_technology_
= state_arg
;
1138 } else if (type_arg
== shill::kTypeCellular
&& state_arg
== "LTEAdvanced") {
1139 // Special case, Shill name contains a ' '.
1140 state
= shill::kStateOnline
;
1141 cellular_technology_
= shill::kNetworkTechnologyLteAdvanced
;
1143 LOG(ERROR
) << "Unrecognized initial state: " << type_arg
<< "="
1149 if (type_arg
== "wireless") {
1150 shill_initial_state_map_
[shill::kTypeWifi
] = state
;
1151 shill_initial_state_map_
[shill::kTypeCellular
] = state
;
1154 // Convenience synonyms.
1155 if (type_arg
== "eth")
1156 type_arg
= shill::kTypeEthernet
;
1158 if (type_arg
!= shill::kTypeEthernet
&&
1159 type_arg
!= shill::kTypeWifi
&&
1160 type_arg
!= shill::kTypeCellular
&&
1161 type_arg
!= shill::kTypeWimax
&&
1162 type_arg
!= shill::kTypeVPN
) {
1163 LOG(WARNING
) << "Unrecognized Shill network type: " << type_arg
;
1167 // Disabled ethernet is the same as unavailable.
1168 if (type_arg
== shill::kTypeEthernet
&& state
== kNetworkDisabled
)
1169 state
= kTechnologyUnavailable
;
1171 shill_initial_state_map_
[type_arg
] = state
;
1175 std::string
FakeShillManagerClient::GetInitialStateForType(
1176 const std::string
& type
,
1178 std::map
<std::string
, std::string
>::const_iterator iter
=
1179 shill_initial_state_map_
.find(type
);
1180 if (iter
== shill_initial_state_map_
.end()) {
1182 return kTechnologyUnavailable
;
1184 std::string state
= iter
->second
;
1185 if (state
== kNetworkDisabled
) {
1187 return shill::kStateIdle
;
1190 if ((state
== shill::kStatePortal
&& type
!= shill::kTypeWifi
) ||
1191 (state
== kNetworkActivated
&& type
!= shill::kTypeCellular
)) {
1192 LOG(WARNING
) << "Invalid state: " << state
<< " for " << type
;
1193 return shill::kStateIdle
;
1198 } // namespace chromeos