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/fake_shill_device_client.h"
21 #include "chromeos/dbus/shill_device_client.h"
22 #include "chromeos/dbus/shill_ipconfig_client.h"
23 #include "chromeos/dbus/shill_profile_client.h"
24 #include "chromeos/dbus/shill_property_changed_observer.h"
25 #include "chromeos/dbus/shill_service_client.h"
27 #include "dbus/message.h"
28 #include "dbus/object_path.h"
29 #include "dbus/values_util.h"
30 #include "third_party/cros_system_api/dbus/service_constants.h"
36 // Allow parsed command line option 'tdls_busy' to set the fake busy count.
37 int s_tdls_busy_count
= 0;
38 int s_extra_wifi_networks
= 0;
40 // Used to compare values for finding entries to erase in a ListValue.
41 // (ListValue only implements a const_iterator version of Find).
43 explicit ValueEquals(const base::Value
* first
) : first_(first
) {}
44 bool operator()(const base::Value
* second
) const {
45 return first_
->Equals(second
);
47 const base::Value
* first_
;
50 // Appends string entries from |service_list_in| whose entries in ServiceClient
51 // have Type |match_type| to one of the output lists based on the entry's State.
52 void AppendServicesForType(
53 const base::ListValue
* service_list_in
,
54 const char* match_type
,
55 bool technology_enabled
,
56 std::vector
<std::string
>* active_service_list_out
,
57 std::vector
<std::string
>* inactive_service_list_out
,
58 std::vector
<std::string
>* disabled_service_list_out
) {
59 ShillServiceClient::TestInterface
* service_client
=
60 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
61 for (base::ListValue::const_iterator iter
= service_list_in
->begin();
62 iter
!= service_list_in
->end(); ++iter
) {
63 std::string service_path
;
64 if (!(*iter
)->GetAsString(&service_path
))
66 const base::DictionaryValue
* properties
=
67 service_client
->GetServiceProperties(service_path
);
69 LOG(ERROR
) << "Properties not found for service: " << service_path
;
73 properties
->GetString(shill::kTypeProperty
, &type
);
74 if (type
!= match_type
)
77 if (technology_enabled
)
78 properties
->GetBoolean(shill::kVisibleProperty
, &visible
);
80 disabled_service_list_out
->push_back(service_path
);
84 properties
->GetString(shill::kStateProperty
, &state
);
85 if (state
== shill::kStateOnline
||
86 state
== shill::kStateAssociation
||
87 state
== shill::kStateConfiguration
||
88 state
== shill::kStatePortal
||
89 state
== shill::kStateReady
) {
90 active_service_list_out
->push_back(service_path
);
92 inactive_service_list_out
->push_back(service_path
);
97 void LogErrorCallback(const std::string
& error_name
,
98 const std::string
& error_message
) {
99 LOG(ERROR
) << error_name
<< ": " << error_message
;
102 bool IsConnectedState(const std::string
& state
) {
103 return state
== shill::kStateOnline
|| state
== shill::kStatePortal
||
104 state
== shill::kStateReady
;
107 void UpdatePortaledWifiState(const std::string
& service_path
) {
108 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
109 ->SetServiceProperty(service_path
,
110 shill::kStateProperty
,
111 base::StringValue(shill::kStatePortal
));
114 bool IsCellularTechnology(const std::string
& type
) {
115 return (type
== shill::kNetworkTechnology1Xrtt
||
116 type
== shill::kNetworkTechnologyEvdo
||
117 type
== shill::kNetworkTechnologyGsm
||
118 type
== shill::kNetworkTechnologyGprs
||
119 type
== shill::kNetworkTechnologyEdge
||
120 type
== shill::kNetworkTechnologyUmts
||
121 type
== shill::kNetworkTechnologyHspa
||
122 type
== shill::kNetworkTechnologyHspaPlus
||
123 type
== shill::kNetworkTechnologyLte
||
124 type
== shill::kNetworkTechnologyLteAdvanced
);
127 const char* kTechnologyUnavailable
= "unavailable";
128 const char* kNetworkActivated
= "activated";
129 const char* kNetworkDisabled
= "disabled";
130 const char* kCellularServicePath
= "/service/cellular1";
131 const char* kRoamingRequired
= "required";
136 const char FakeShillManagerClient::kFakeEthernetNetworkGuid
[] = "eth1_guid";
138 FakeShillManagerClient::FakeShillManagerClient()
139 : interactive_delay_(0),
140 cellular_technology_(shill::kNetworkTechnologyGsm
),
141 weak_ptr_factory_(this) {
142 ParseCommandLineSwitch();
145 FakeShillManagerClient::~FakeShillManagerClient() {}
147 // ShillManagerClient overrides.
149 void FakeShillManagerClient::Init(dbus::Bus
* bus
) {}
151 void FakeShillManagerClient::AddPropertyChangedObserver(
152 ShillPropertyChangedObserver
* observer
) {
153 observer_list_
.AddObserver(observer
);
156 void FakeShillManagerClient::RemovePropertyChangedObserver(
157 ShillPropertyChangedObserver
* observer
) {
158 observer_list_
.RemoveObserver(observer
);
161 void FakeShillManagerClient::GetProperties(
162 const DictionaryValueCallback
& callback
) {
163 VLOG(1) << "Manager.GetProperties";
164 base::ThreadTaskRunnerHandle::Get()->PostTask(
165 FROM_HERE
, base::Bind(&FakeShillManagerClient::PassStubProperties
,
166 weak_ptr_factory_
.GetWeakPtr(), callback
));
169 void FakeShillManagerClient::GetNetworksForGeolocation(
170 const DictionaryValueCallback
& callback
) {
171 base::ThreadTaskRunnerHandle::Get()->PostTask(
172 FROM_HERE
, base::Bind(&FakeShillManagerClient::PassStubGeoNetworks
,
173 weak_ptr_factory_
.GetWeakPtr(), callback
));
176 void FakeShillManagerClient::SetProperty(const std::string
& name
,
177 const base::Value
& value
,
178 const base::Closure
& callback
,
179 const ErrorCallback
& error_callback
) {
180 VLOG(2) << "SetProperty: " << name
;
181 stub_properties_
.SetWithoutPathExpansion(name
, value
.DeepCopy());
182 CallNotifyObserversPropertyChanged(name
);
183 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, callback
);
186 void FakeShillManagerClient::RequestScan(const std::string
& type
,
187 const base::Closure
& callback
,
188 const ErrorCallback
& error_callback
) {
189 VLOG(1) << "RequestScan: " << type
;
190 // For Stub purposes, default to a Wifi scan.
191 std::string device_type
= shill::kTypeWifi
;
194 ShillDeviceClient::TestInterface
* device_client
=
195 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
196 std::string device_path
= device_client
->GetDevicePathForType(device_type
);
197 if (!device_path
.empty()) {
198 device_client
->SetDeviceProperty(
199 device_path
, shill::kScanningProperty
, base::FundamentalValue(true));
201 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
203 base::Bind(&FakeShillManagerClient::ScanCompleted
,
204 weak_ptr_factory_
.GetWeakPtr(), device_path
, callback
),
205 base::TimeDelta::FromSeconds(interactive_delay_
));
208 void FakeShillManagerClient::EnableTechnology(
209 const std::string
& type
,
210 const base::Closure
& callback
,
211 const ErrorCallback
& error_callback
) {
212 base::ListValue
* enabled_list
= NULL
;
213 if (!stub_properties_
.GetListWithoutPathExpansion(
214 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
215 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, callback
);
216 base::ThreadTaskRunnerHandle::Get()->PostTask(
218 base::Bind(error_callback
, "StubError", "Property not found"));
221 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
223 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
224 weak_ptr_factory_
.GetWeakPtr(), type
, callback
, true),
225 base::TimeDelta::FromSeconds(interactive_delay_
));
228 void FakeShillManagerClient::DisableTechnology(
229 const std::string
& type
,
230 const base::Closure
& callback
,
231 const ErrorCallback
& error_callback
) {
232 base::ListValue
* enabled_list
= NULL
;
233 if (!stub_properties_
.GetListWithoutPathExpansion(
234 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
235 base::ThreadTaskRunnerHandle::Get()->PostTask(
237 base::Bind(error_callback
, "StubError", "Property not found"));
240 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
242 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
243 weak_ptr_factory_
.GetWeakPtr(), type
, callback
, false),
244 base::TimeDelta::FromSeconds(interactive_delay_
));
247 void FakeShillManagerClient::ConfigureService(
248 const base::DictionaryValue
& properties
,
249 const ObjectPathCallback
& callback
,
250 const ErrorCallback
& error_callback
) {
251 ShillServiceClient::TestInterface
* service_client
=
252 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
256 if (!properties
.GetString(shill::kGuidProperty
, &guid
) ||
257 !properties
.GetString(shill::kTypeProperty
, &type
)) {
258 LOG(ERROR
) << "ConfigureService requires GUID and Type to be defined";
259 // If the properties aren't filled out completely, then just return an empty
261 base::ThreadTaskRunnerHandle::Get()->PostTask(
262 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
266 // For the purposes of this stub, we're going to assume that the GUID property
267 // is set to the service path because we don't want to re-implement Shill's
268 // property matching magic here.
269 std::string service_path
= guid
;
271 std::string ipconfig_path
;
272 properties
.GetString(shill::kIPConfigProperty
, &ipconfig_path
);
274 // Merge the new properties with existing properties, if any.
275 const base::DictionaryValue
* existing_properties
=
276 service_client
->GetServiceProperties(service_path
);
277 if (!existing_properties
) {
278 // Add a new service to the service client stub because none exists, yet.
279 // This calls AddManagerService.
280 service_client
->AddServiceWithIPConfig(service_path
,
287 existing_properties
= service_client
->GetServiceProperties(service_path
);
290 scoped_ptr
<base::DictionaryValue
> merged_properties(
291 existing_properties
->DeepCopy());
292 merged_properties
->MergeDictionary(&properties
);
294 // Now set all the properties.
295 for (base::DictionaryValue::Iterator
iter(*merged_properties
);
296 !iter
.IsAtEnd(); iter
.Advance()) {
297 service_client
->SetServiceProperty(service_path
, iter
.key(), iter
.value());
300 // If the Profile property is set, add it to ProfileClient.
301 std::string profile_path
;
302 merged_properties
->GetStringWithoutPathExpansion(shill::kProfileProperty
,
304 if (!profile_path
.empty()) {
305 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface()->
306 AddService(profile_path
, service_path
);
309 base::ThreadTaskRunnerHandle::Get()->PostTask(
310 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath(service_path
)));
313 void FakeShillManagerClient::ConfigureServiceForProfile(
314 const dbus::ObjectPath
& profile_path
,
315 const base::DictionaryValue
& properties
,
316 const ObjectPathCallback
& callback
,
317 const ErrorCallback
& error_callback
) {
318 std::string profile_property
;
319 properties
.GetStringWithoutPathExpansion(shill::kProfileProperty
,
321 CHECK(profile_property
== profile_path
.value());
322 ConfigureService(properties
, callback
, error_callback
);
326 void FakeShillManagerClient::GetService(
327 const base::DictionaryValue
& properties
,
328 const ObjectPathCallback
& callback
,
329 const ErrorCallback
& error_callback
) {
330 base::ThreadTaskRunnerHandle::Get()->PostTask(
331 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
334 void FakeShillManagerClient::VerifyDestination(
335 const VerificationProperties
& properties
,
336 const BooleanCallback
& callback
,
337 const ErrorCallback
& error_callback
) {
338 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
339 base::Bind(callback
, true));
342 void FakeShillManagerClient::VerifyAndEncryptCredentials(
343 const VerificationProperties
& properties
,
344 const std::string
& service_path
,
345 const StringCallback
& callback
,
346 const ErrorCallback
& error_callback
) {
347 base::ThreadTaskRunnerHandle::Get()->PostTask(
348 FROM_HERE
, base::Bind(callback
, "encrypted_credentials"));
351 void FakeShillManagerClient::VerifyAndEncryptData(
352 const VerificationProperties
& properties
,
353 const std::string
& data
,
354 const StringCallback
& callback
,
355 const ErrorCallback
& error_callback
) {
356 base::ThreadTaskRunnerHandle::Get()->PostTask(
357 FROM_HERE
, base::Bind(callback
, "encrypted_data"));
360 void FakeShillManagerClient::ConnectToBestServices(
361 const base::Closure
& callback
,
362 const ErrorCallback
& error_callback
) {
363 if (best_service_
.empty()) {
364 VLOG(1) << "No 'best' service set.";
368 DBusThreadManager::Get()->GetShillServiceClient()->Connect(
369 dbus::ObjectPath(best_service_
), callback
, error_callback
);
372 ShillManagerClient::TestInterface
* FakeShillManagerClient::GetTestInterface() {
376 // ShillManagerClient::TestInterface overrides.
378 void FakeShillManagerClient::AddDevice(const std::string
& device_path
) {
379 if (GetListProperty(shill::kDevicesProperty
)
380 ->AppendIfNotPresent(new base::StringValue(device_path
))) {
381 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
385 void FakeShillManagerClient::RemoveDevice(const std::string
& device_path
) {
386 base::StringValue
device_path_value(device_path
);
387 if (GetListProperty(shill::kDevicesProperty
)->Remove(
388 device_path_value
, NULL
)) {
389 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
393 void FakeShillManagerClient::ClearDevices() {
394 GetListProperty(shill::kDevicesProperty
)->Clear();
395 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
398 void FakeShillManagerClient::AddTechnology(const std::string
& type
,
400 if (GetListProperty(shill::kAvailableTechnologiesProperty
)
401 ->AppendIfNotPresent(new base::StringValue(type
))) {
402 CallNotifyObserversPropertyChanged(
403 shill::kAvailableTechnologiesProperty
);
406 GetListProperty(shill::kEnabledTechnologiesProperty
)
407 ->AppendIfNotPresent(new base::StringValue(type
))) {
408 CallNotifyObserversPropertyChanged(
409 shill::kEnabledTechnologiesProperty
);
413 void FakeShillManagerClient::RemoveTechnology(const std::string
& type
) {
414 base::StringValue
type_value(type
);
415 if (GetListProperty(shill::kAvailableTechnologiesProperty
)->Remove(
417 CallNotifyObserversPropertyChanged(
418 shill::kAvailableTechnologiesProperty
);
420 if (GetListProperty(shill::kEnabledTechnologiesProperty
)->Remove(
422 CallNotifyObserversPropertyChanged(
423 shill::kEnabledTechnologiesProperty
);
427 void FakeShillManagerClient::SetTechnologyInitializing(const std::string
& type
,
430 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)
431 ->AppendIfNotPresent(new base::StringValue(type
))) {
432 CallNotifyObserversPropertyChanged(
433 shill::kUninitializedTechnologiesProperty
);
436 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)->Remove(
437 base::StringValue(type
), NULL
)) {
438 CallNotifyObserversPropertyChanged(
439 shill::kUninitializedTechnologiesProperty
);
444 void FakeShillManagerClient::AddGeoNetwork(
445 const std::string
& technology
,
446 const base::DictionaryValue
& network
) {
447 base::ListValue
* list_value
= NULL
;
448 if (!stub_geo_networks_
.GetListWithoutPathExpansion(technology
,
450 list_value
= new base::ListValue
;
451 stub_geo_networks_
.SetWithoutPathExpansion(technology
, list_value
);
453 list_value
->Append(network
.DeepCopy());
456 void FakeShillManagerClient::AddProfile(const std::string
& profile_path
) {
457 const char* key
= shill::kProfilesProperty
;
458 if (GetListProperty(key
)
459 ->AppendIfNotPresent(new base::StringValue(profile_path
))) {
460 CallNotifyObserversPropertyChanged(key
);
464 void FakeShillManagerClient::ClearProperties() {
465 stub_properties_
.Clear();
468 void FakeShillManagerClient::SetManagerProperty(const std::string
& key
,
469 const base::Value
& value
) {
470 SetProperty(key
, value
,
471 base::Bind(&base::DoNothing
), base::Bind(&LogErrorCallback
));
474 void FakeShillManagerClient::AddManagerService(
475 const std::string
& service_path
,
476 bool notify_observers
) {
477 VLOG(2) << "AddManagerService: " << service_path
;
478 GetListProperty(shill::kServiceCompleteListProperty
)
479 ->AppendIfNotPresent(new base::StringValue(service_path
));
480 SortManagerServices(false);
481 if (notify_observers
)
482 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
485 void FakeShillManagerClient::RemoveManagerService(
486 const std::string
& service_path
) {
487 VLOG(2) << "RemoveManagerService: " << service_path
;
488 base::StringValue
service_path_value(service_path
);
489 GetListProperty(shill::kServiceCompleteListProperty
)->Remove(
490 service_path_value
, NULL
);
491 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
494 void FakeShillManagerClient::ClearManagerServices() {
495 VLOG(1) << "ClearManagerServices";
496 GetListProperty(shill::kServiceCompleteListProperty
)->Clear();
497 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
500 void FakeShillManagerClient::ServiceStateChanged(
501 const std::string
& service_path
,
502 const std::string
& state
) {
503 if (service_path
== default_service_
&& !IsConnectedState(state
)) {
504 // Default service is no longer connected; clear.
505 default_service_
.clear();
506 base::StringValue
default_service_value(default_service_
);
507 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
511 void FakeShillManagerClient::SortManagerServices(bool notify
) {
512 VLOG(1) << "SortManagerServices";
513 static const char* ordered_types
[] = {shill::kTypeEthernet
,
514 shill::kTypeEthernetEap
,
516 shill::kTypeCellular
,
520 base::ListValue
* complete_list
=
521 GetListProperty(shill::kServiceCompleteListProperty
);
522 if (complete_list
->empty())
524 scoped_ptr
<base::ListValue
> prev_complete_list(complete_list
->DeepCopy());
526 std::vector
<std::string
> active_services
;
527 std::vector
<std::string
> inactive_services
;
528 std::vector
<std::string
> disabled_services
;
529 for (size_t i
= 0; i
< arraysize(ordered_types
); ++i
) {
530 AppendServicesForType(complete_list
,
532 TechnologyEnabled(ordered_types
[i
]),
537 complete_list
->Clear();
538 for (size_t i
= 0; i
< active_services
.size(); ++i
)
539 complete_list
->AppendString(active_services
[i
]);
540 for (size_t i
= 0; i
< inactive_services
.size(); ++i
)
541 complete_list
->AppendString(inactive_services
[i
]);
542 for (size_t i
= 0; i
< disabled_services
.size(); ++i
)
543 complete_list
->AppendString(disabled_services
[i
]);
545 if (notify
&& !complete_list
->Equals(prev_complete_list
.get()))
546 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
548 // Set the first active service as the Default service.
549 std::string new_default_service
;
550 if (!active_services
.empty()) {
551 ShillServiceClient::TestInterface
* service_client
=
552 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
553 std::string service_path
= active_services
[0];
554 const base::DictionaryValue
* properties
=
555 service_client
->GetServiceProperties(service_path
);
557 LOG(ERROR
) << "Properties not found for service: " << service_path
;
560 properties
->GetString(shill::kStateProperty
, &state
);
561 if (IsConnectedState(state
))
562 new_default_service
= service_path
;
565 if (default_service_
!= new_default_service
) {
566 default_service_
= new_default_service
;
567 base::StringValue
default_service_value(default_service_
);
568 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
572 int FakeShillManagerClient::GetInteractiveDelay() const {
573 return interactive_delay_
;
576 void FakeShillManagerClient::SetBestServiceToConnect(
577 const std::string
& service_path
) {
578 best_service_
= service_path
;
581 void FakeShillManagerClient::SetupDefaultEnvironment() {
582 // Bail out from setup if there is no message loop. This will be the common
583 // case for tests that are not testing Shill.
584 if (!base::ThreadTaskRunnerHandle::IsSet())
587 DBusThreadManager
* dbus_manager
= DBusThreadManager::Get();
588 ShillServiceClient::TestInterface
* services
=
589 dbus_manager
->GetShillServiceClient()->GetTestInterface();
591 ShillProfileClient::TestInterface
* profiles
=
592 dbus_manager
->GetShillProfileClient()->GetTestInterface();
594 ShillDeviceClient::TestInterface
* devices
=
595 dbus_manager
->GetShillDeviceClient()->GetTestInterface();
597 ShillIPConfigClient::TestInterface
* ip_configs
=
598 dbus_manager
->GetShillIPConfigClient()->GetTestInterface();
601 const std::string shared_profile
= ShillProfileClient::GetSharedProfilePath();
602 profiles
->AddProfile(shared_profile
, std::string());
604 const bool add_to_visible
= true;
607 base::DictionaryValue ipconfig_v4_dictionary
;
608 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
609 shill::kAddressProperty
, "100.0.0.1");
610 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
611 shill::kGatewayProperty
, "100.0.0.2");
612 ipconfig_v4_dictionary
.SetIntegerWithoutPathExpansion(
613 shill::kPrefixlenProperty
, 1);
614 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
615 shill::kMethodProperty
, shill::kTypeIPv4
);
616 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
617 shill::kWebProxyAutoDiscoveryUrlProperty
, "http://wpad.com/wpad.dat");
618 ip_configs
->AddIPConfig("ipconfig_v4_path", ipconfig_v4_dictionary
);
619 base::DictionaryValue ipconfig_v6_dictionary
;
620 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
621 shill::kAddressProperty
, "0:0:0:0:100:0:0:1");
622 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
623 shill::kMethodProperty
, shill::kTypeIPv6
);
624 ip_configs
->AddIPConfig("ipconfig_v6_path", ipconfig_v6_dictionary
);
630 state
= GetInitialStateForType(shill::kTypeEthernet
, &enabled
);
631 if (state
== shill::kStateOnline
|| state
== shill::kStateIdle
) {
632 AddTechnology(shill::kTypeEthernet
, enabled
);
634 "/device/eth1", shill::kTypeEthernet
, "stub_eth_device1");
635 devices
->SetDeviceProperty("/device/eth1",
636 shill::kAddressProperty
,
637 base::StringValue("0123456789ab"));
638 base::ListValue eth_ip_configs
;
639 eth_ip_configs
.AppendString("ipconfig_v4_path");
640 eth_ip_configs
.AppendString("ipconfig_v6_path");
641 devices
->SetDeviceProperty("/device/eth1",
642 shill::kIPConfigsProperty
,
644 const std::string kFakeEthernetNetworkPath
= "/service/eth1";
645 services
->AddService(kFakeEthernetNetworkPath
,
646 kFakeEthernetNetworkGuid
,
648 shill::kTypeEthernet
,
651 profiles
->AddService(shared_profile
, kFakeEthernetNetworkPath
);
655 if (s_tdls_busy_count
!= 0) {
656 DBusThreadManager::Get()
657 ->GetShillDeviceClient()
659 ->SetTDLSBusyCount(s_tdls_busy_count
);
662 state
= GetInitialStateForType(shill::kTypeWifi
, &enabled
);
663 if (state
!= kTechnologyUnavailable
) {
664 bool portaled
= false;
665 if (state
== shill::kStatePortal
) {
667 state
= shill::kStateIdle
;
669 AddTechnology(shill::kTypeWifi
, enabled
);
670 devices
->AddDevice("/device/wifi1", shill::kTypeWifi
, "stub_wifi_device1");
671 devices
->SetDeviceProperty("/device/wifi1",
672 shill::kAddressProperty
,
673 base::StringValue("23456789abcd"));
674 base::ListValue wifi_ip_configs
;
675 wifi_ip_configs
.AppendString("ipconfig_v4_path");
676 wifi_ip_configs
.AppendString("ipconfig_v6_path");
677 devices
->SetDeviceProperty("/device/wifi1",
678 shill::kIPConfigsProperty
,
681 const std::string kWifi1Path
= "/service/wifi1";
682 services
->AddService(kWifi1Path
,
688 services
->SetServiceProperty(kWifi1Path
,
689 shill::kSecurityClassProperty
,
690 base::StringValue(shill::kSecurityWep
));
691 services
->SetServiceProperty(kWifi1Path
,
692 shill::kConnectableProperty
,
693 base::FundamentalValue(true));
694 profiles
->AddService(shared_profile
, kWifi1Path
);
696 const std::string kWifi2Path
= "/service/wifi2";
697 services
->AddService(kWifi2Path
,
699 "wifi2_PSK" /* name */,
703 services
->SetServiceProperty(kWifi2Path
,
704 shill::kSecurityClassProperty
,
705 base::StringValue(shill::kSecurityPsk
));
706 services
->SetServiceProperty(
707 kWifi2Path
, shill::kSignalStrengthProperty
, base::FundamentalValue(80));
708 profiles
->AddService(shared_profile
, kWifi2Path
);
710 const std::string kWifi3Path
= "/service/wifi3";
711 services
->AddService(kWifi3Path
,
717 services
->SetServiceProperty(
718 kWifi3Path
, shill::kSignalStrengthProperty
, base::FundamentalValue(40));
721 const std::string kPortaledWifiPath
= "/service/portaled_wifi";
722 services
->AddService(kPortaledWifiPath
, "portaled_wifi_guid",
723 "Portaled Wifi" /* name */, shill::kTypeWifi
,
724 shill::kStateIdle
, add_to_visible
);
725 services
->SetServiceProperty(kPortaledWifiPath
,
726 shill::kSecurityClassProperty
,
727 base::StringValue(shill::kSecurityNone
));
728 services
->SetConnectBehavior(
730 base::Bind(&UpdatePortaledWifiState
, kPortaledWifiPath
));
731 services
->SetServiceProperty(kPortaledWifiPath
,
732 shill::kConnectableProperty
,
733 base::FundamentalValue(true));
734 profiles
->AddService(shared_profile
, kPortaledWifiPath
);
737 for (int i
= 0; i
< s_extra_wifi_networks
; ++i
) {
739 std::string path
= base::StringPrintf("/service/wifi%d", id
);
740 std::string guid
= base::StringPrintf("wifi%d_guid", id
);
741 std::string name
= base::StringPrintf("wifi%d", id
);
742 services
->AddService(path
, guid
, name
, shill::kTypeWifi
,
743 shill::kStateIdle
, add_to_visible
);
748 const std::string kWimaxPath
= "/service/wimax1";
749 state
= GetInitialStateForType(shill::kTypeWimax
, &enabled
);
750 if (state
!= kTechnologyUnavailable
) {
751 AddTechnology(shill::kTypeWimax
, enabled
);
753 "/device/wimax1", shill::kTypeWimax
, "stub_wimax_device1");
755 services
->AddService(kWimaxPath
, "wimax1_guid", "wimax1" /* name */,
756 shill::kTypeWimax
, state
, add_to_visible
);
757 services
->SetServiceProperty(kWimaxPath
, shill::kConnectableProperty
,
758 base::FundamentalValue(true));
759 base::FundamentalValue
strength_value(80);
760 services
->SetServiceProperty(kWimaxPath
, shill::kSignalStrengthProperty
,
762 profiles
->AddService(shared_profile
, kWimaxPath
);
766 state
= GetInitialStateForType(shill::kTypeCellular
, &enabled
);
767 if (state
!= kTechnologyUnavailable
) {
768 bool activated
= false;
769 if (state
== kNetworkActivated
) {
771 state
= shill::kStateOnline
;
773 AddTechnology(shill::kTypeCellular
, enabled
);
775 "/device/cellular1", shill::kTypeCellular
, "stub_cellular_device1");
776 devices
->SetDeviceProperty("/device/cellular1",
777 shill::kCarrierProperty
,
778 base::StringValue(shill::kCarrierSprint
));
779 base::ListValue carrier_list
;
780 carrier_list
.AppendString(shill::kCarrierSprint
);
781 carrier_list
.AppendString(shill::kCarrierGenericUMTS
);
782 devices
->SetDeviceProperty("/device/cellular1",
783 shill::kSupportedCarriersProperty
,
785 devices
->SetDeviceProperty("/device/cellular1",
786 shill::kSupportNetworkScanProperty
,
787 base::FundamentalValue(true));
788 if (roaming_state_
== kRoamingRequired
) {
789 devices
->SetDeviceProperty("/device/cellular1",
790 shill::kProviderRequiresRoamingProperty
,
791 base::FundamentalValue(true));
793 if (cellular_technology_
== shill::kNetworkTechnologyGsm
) {
794 devices
->SetDeviceProperty("/device/cellular1",
795 shill::kSIMPresentProperty
,
796 base::FundamentalValue(true));
797 devices
->SetSimLocked("/device/cellular1", false);
800 services
->AddService(kCellularServicePath
,
802 "cellular1" /* name */,
803 shill::kTypeCellular
,
806 base::StringValue
technology_value(cellular_technology_
);
807 devices
->SetDeviceProperty("/device/cellular1",
808 shill::kTechnologyFamilyProperty
,
810 services
->SetServiceProperty(kCellularServicePath
,
811 shill::kNetworkTechnologyProperty
,
815 services
->SetServiceProperty(
816 kCellularServicePath
,
817 shill::kActivationStateProperty
,
818 base::StringValue(shill::kActivationStateActivated
));
819 services
->SetServiceProperty(kCellularServicePath
,
820 shill::kConnectableProperty
,
821 base::FundamentalValue(true));
823 services
->SetServiceProperty(
824 kCellularServicePath
,
825 shill::kActivationStateProperty
,
826 base::StringValue(shill::kActivationStateNotActivated
));
829 std::string shill_roaming_state
;
830 if (roaming_state_
== kRoamingRequired
)
831 shill_roaming_state
= shill::kRoamingStateRoaming
;
832 else if (roaming_state_
.empty())
833 shill_roaming_state
= shill::kRoamingStateHome
;
834 else // |roaming_state_| is expected to be a valid Shill state.
835 shill_roaming_state
= roaming_state_
;
836 services
->SetServiceProperty(kCellularServicePath
,
837 shill::kRoamingStateProperty
,
838 base::StringValue(shill_roaming_state
));
840 base::DictionaryValue apn
;
841 apn
.SetStringWithoutPathExpansion(shill::kApnProperty
, "testapn");
842 apn
.SetStringWithoutPathExpansion(shill::kApnNameProperty
, "Test APN");
843 apn
.SetStringWithoutPathExpansion(shill::kApnLocalizedNameProperty
,
844 "Localized Test APN");
845 apn
.SetStringWithoutPathExpansion(shill::kApnUsernameProperty
, "User1");
846 apn
.SetStringWithoutPathExpansion(shill::kApnPasswordProperty
, "password");
847 base::DictionaryValue apn2
;
848 apn2
.SetStringWithoutPathExpansion(shill::kApnProperty
, "testapn2");
849 services
->SetServiceProperty(kCellularServicePath
,
850 shill::kCellularApnProperty
, apn
);
851 services
->SetServiceProperty(kCellularServicePath
,
852 shill::kCellularLastGoodApnProperty
, apn
);
853 base::ListValue apn_list
;
854 apn_list
.Append(apn
.DeepCopy());
855 apn_list
.Append(apn2
.DeepCopy());
856 devices
->SetDeviceProperty("/device/cellular1",
857 shill::kCellularApnListProperty
, apn_list
);
859 profiles
->AddService(shared_profile
, kCellularServicePath
);
863 state
= GetInitialStateForType(shill::kTypeVPN
, &enabled
);
864 if (state
!= kTechnologyUnavailable
) {
865 // Set the "Provider" dictionary properties. Note: when setting these in
866 // Shill, "Provider.Type", etc keys are used, but when reading the values
867 // "Provider" . "Type", etc keys are used. Here we are setting the values
868 // that will be read (by the UI, tests, etc).
869 base::DictionaryValue provider_properties_openvpn
;
870 provider_properties_openvpn
.SetString(shill::kTypeProperty
,
871 shill::kProviderOpenVpn
);
872 provider_properties_openvpn
.SetString(shill::kHostProperty
, "vpn_host");
874 services
->AddService("/service/vpn1",
880 services
->SetServiceProperty(
881 "/service/vpn1", shill::kProviderProperty
, provider_properties_openvpn
);
882 profiles
->AddService(shared_profile
, "/service/vpn1");
884 base::DictionaryValue provider_properties_l2tp
;
885 provider_properties_l2tp
.SetString(shill::kTypeProperty
,
886 shill::kProviderL2tpIpsec
);
887 provider_properties_l2tp
.SetString(shill::kHostProperty
, "vpn_host2");
889 services
->AddService("/service/vpn2",
895 services
->SetServiceProperty(
896 "/service/vpn2", shill::kProviderProperty
, provider_properties_l2tp
);
899 // Additional device states
900 for (DevicePropertyMap::iterator iter1
= shill_device_property_map_
.begin();
901 iter1
!= shill_device_property_map_
.end(); ++iter1
) {
902 std::string device_type
= iter1
->first
;
903 std::string device_path
= devices
->GetDevicePathForType(device_type
);
904 for (ShillPropertyMap::iterator iter2
= iter1
->second
.begin();
905 iter2
!= iter1
->second
.end(); ++iter2
) {
906 devices
->SetDeviceProperty(device_path
, iter2
->first
, *(iter2
->second
));
907 delete iter2
->second
;
911 SortManagerServices(true);
916 void FakeShillManagerClient::PassStubProperties(
917 const DictionaryValueCallback
& callback
) const {
918 scoped_ptr
<base::DictionaryValue
> stub_properties(
919 stub_properties_
.DeepCopy());
920 stub_properties
->SetWithoutPathExpansion(
921 shill::kServiceCompleteListProperty
,
922 GetEnabledServiceList(shill::kServiceCompleteListProperty
));
923 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, *stub_properties
);
926 void FakeShillManagerClient::PassStubGeoNetworks(
927 const DictionaryValueCallback
& callback
) const {
928 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, stub_geo_networks_
);
931 void FakeShillManagerClient::CallNotifyObserversPropertyChanged(
932 const std::string
& property
) {
933 // Avoid unnecessary delayed task if we have no observers (e.g. during
935 if (!observer_list_
.might_have_observers())
937 base::ThreadTaskRunnerHandle::Get()->PostTask(
939 base::Bind(&FakeShillManagerClient::NotifyObserversPropertyChanged
,
940 weak_ptr_factory_
.GetWeakPtr(), property
));
943 void FakeShillManagerClient::NotifyObserversPropertyChanged(
944 const std::string
& property
) {
945 VLOG(1) << "NotifyObserversPropertyChanged: " << property
;
946 base::Value
* value
= NULL
;
947 if (!stub_properties_
.GetWithoutPathExpansion(property
, &value
)) {
948 LOG(ERROR
) << "Notify for unknown property: " << property
;
951 if (property
== shill::kServiceCompleteListProperty
) {
952 scoped_ptr
<base::ListValue
> services(GetEnabledServiceList(property
));
953 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
955 OnPropertyChanged(property
, *(services
.get())));
958 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
960 OnPropertyChanged(property
, *value
));
963 base::ListValue
* FakeShillManagerClient::GetListProperty(
964 const std::string
& property
) {
965 base::ListValue
* list_property
= NULL
;
966 if (!stub_properties_
.GetListWithoutPathExpansion(
967 property
, &list_property
)) {
968 list_property
= new base::ListValue
;
969 stub_properties_
.SetWithoutPathExpansion(property
, list_property
);
971 return list_property
;
974 bool FakeShillManagerClient::TechnologyEnabled(const std::string
& type
) const {
975 if (type
== shill::kTypeVPN
)
976 return true; // VPN is always "enabled" since there is no associated device
977 if (type
== shill::kTypeEthernetEap
)
979 bool enabled
= false;
980 const base::ListValue
* technologies
;
981 if (stub_properties_
.GetListWithoutPathExpansion(
982 shill::kEnabledTechnologiesProperty
, &technologies
)) {
983 base::StringValue
type_value(type
);
984 if (technologies
->Find(type_value
) != technologies
->end())
990 void FakeShillManagerClient::SetTechnologyEnabled(
991 const std::string
& type
,
992 const base::Closure
& callback
,
994 base::ListValue
* enabled_list
=
995 GetListProperty(shill::kEnabledTechnologiesProperty
);
997 enabled_list
->AppendIfNotPresent(new base::StringValue(type
));
999 enabled_list
->Remove(base::StringValue(type
), NULL
);
1000 CallNotifyObserversPropertyChanged(
1001 shill::kEnabledTechnologiesProperty
);
1002 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, callback
);
1003 // May affect available services.
1004 SortManagerServices(true);
1007 base::ListValue
* FakeShillManagerClient::GetEnabledServiceList(
1008 const std::string
& property
) const {
1009 base::ListValue
* new_service_list
= new base::ListValue
;
1010 const base::ListValue
* service_list
;
1011 if (stub_properties_
.GetListWithoutPathExpansion(property
, &service_list
)) {
1012 ShillServiceClient::TestInterface
* service_client
=
1013 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
1014 for (base::ListValue::const_iterator iter
= service_list
->begin();
1015 iter
!= service_list
->end(); ++iter
) {
1016 std::string service_path
;
1017 if (!(*iter
)->GetAsString(&service_path
))
1019 const base::DictionaryValue
* properties
=
1020 service_client
->GetServiceProperties(service_path
);
1022 LOG(ERROR
) << "Properties not found for service: " << service_path
;
1026 properties
->GetString(shill::kTypeProperty
, &type
);
1027 if (TechnologyEnabled(type
))
1028 new_service_list
->Append((*iter
)->DeepCopy());
1031 return new_service_list
;
1034 void FakeShillManagerClient::ScanCompleted(const std::string
& device_path
,
1035 const base::Closure
& callback
) {
1036 if (!device_path
.empty()) {
1037 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
1038 SetDeviceProperty(device_path
,
1039 shill::kScanningProperty
,
1040 base::FundamentalValue(false));
1042 VLOG(1) << "ScanCompleted";
1043 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
1044 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, callback
);
1047 void FakeShillManagerClient::ParseCommandLineSwitch() {
1049 SetInitialNetworkState(shill::kTypeEthernet
, shill::kStateOnline
);
1050 SetInitialNetworkState(shill::kTypeWifi
, shill::kStateOnline
);
1051 SetInitialNetworkState(shill::kTypeCellular
, shill::kStateIdle
);
1052 SetInitialNetworkState(shill::kTypeVPN
, shill::kStateIdle
);
1054 // Parse additional options
1055 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
1056 if (!command_line
->HasSwitch(switches::kShillStub
))
1059 std::string option_str
=
1060 command_line
->GetSwitchValueASCII(switches::kShillStub
);
1061 VLOG(1) << "Parsing command line:" << option_str
;
1062 base::StringPairs string_pairs
;
1063 base::SplitStringIntoKeyValuePairs(option_str
, '=', ',', &string_pairs
);
1064 for (base::StringPairs::iterator iter
= string_pairs
.begin();
1065 iter
!= string_pairs
.end(); ++iter
) {
1066 ParseOption((*iter
).first
, (*iter
).second
);
1070 bool FakeShillManagerClient::ParseOption(const std::string
& arg0
,
1071 const std::string
& arg1
) {
1072 VLOG(1) << "Parsing command line option: '" << arg0
<< "=" << arg1
<< "'";
1073 if ((arg0
== "clear" || arg0
== "reset") && arg1
== "1") {
1074 shill_initial_state_map_
.clear();
1076 } else if (arg0
== "interactive") {
1079 base::StringToInt(arg1
, &seconds
);
1080 interactive_delay_
= seconds
;
1082 } else if (arg0
== "sim_lock") {
1083 bool locked
= (arg1
== "1");
1084 base::DictionaryValue
* simlock_dict
= new base::DictionaryValue
;
1085 simlock_dict
->SetBoolean(shill::kSIMLockEnabledProperty
, true);
1086 std::string lock_type
= locked
? shill::kSIMLockPin
: "";
1087 simlock_dict
->SetString(shill::kSIMLockTypeProperty
, lock_type
);
1089 simlock_dict
->SetInteger(shill::kSIMLockRetriesLeftProperty
,
1090 FakeShillDeviceClient::kSimPinRetryCount
);
1092 shill_device_property_map_
[shill::kTypeCellular
]
1093 [shill::kSIMLockStatusProperty
] = simlock_dict
;
1094 shill_device_property_map_
1095 [shill::kTypeCellular
][shill::kTechnologyFamilyProperty
] =
1096 new base::StringValue(shill::kNetworkTechnologyGsm
);
1098 } else if (arg0
== "sim_present") {
1099 bool present
= (arg1
== "1");
1100 base::FundamentalValue
* sim_present
= new base::FundamentalValue(present
);
1101 shill_device_property_map_
[shill::kTypeCellular
]
1102 [shill::kSIMPresentProperty
] = sim_present
;
1104 } else if (arg0
== "tdls_busy") {
1106 base::StringToInt(arg1
, &s_tdls_busy_count
);
1108 s_tdls_busy_count
= 1;
1110 } else if (arg0
== "roaming") {
1111 // "home", "roaming", or "required"
1112 roaming_state_
= arg1
;
1115 return SetInitialNetworkState(arg0
, arg1
);
1118 bool FakeShillManagerClient::SetInitialNetworkState(
1119 std::string type_arg
,
1120 const std::string
& state_arg
) {
1121 int state_arg_as_int
= -1;
1122 base::StringToInt(state_arg
, &state_arg_as_int
);
1125 if (state_arg
.empty() || state_arg
== "1" || state_arg
== "on" ||
1126 state_arg
== "enabled" || state_arg
== "connected" ||
1127 state_arg
== "online") {
1128 // Enabled and connected (default value)
1129 state
= shill::kStateOnline
;
1130 } else if (state_arg
== "0" || state_arg
== "off" ||
1131 state_arg
== "inactive" || state_arg
== shill::kStateIdle
) {
1132 // Technology enabled, services are created but are not connected.
1133 state
= shill::kStateIdle
;
1134 } else if (type_arg
== shill::kTypeWifi
&& state_arg_as_int
> 1) {
1135 // Enabled and connected, add extra wifi networks.
1136 state
= shill::kStateOnline
;
1137 s_extra_wifi_networks
= state_arg_as_int
- 1;
1138 } else if (state_arg
== "disabled" || state_arg
== "disconnect") {
1139 // Technology disabled but available, services created but not connected.
1140 state
= kNetworkDisabled
;
1141 } else if (state_arg
== "none" || state_arg
== "offline") {
1142 // Technology not available, do not create services.
1143 state
= kTechnologyUnavailable
;
1144 } else if (state_arg
== "portal") {
1145 // Technology is enabled, a service is connected and in Portal state.
1146 state
= shill::kStatePortal
;
1147 } else if (state_arg
== "active" || state_arg
== "activated") {
1148 // Technology is enabled, a service is connected and Activated.
1149 state
= kNetworkActivated
;
1150 } else if (type_arg
== shill::kTypeCellular
&&
1151 IsCellularTechnology(state_arg
)) {
1152 state
= shill::kStateOnline
;
1153 cellular_technology_
= state_arg
;
1154 } else if (type_arg
== shill::kTypeCellular
&& state_arg
== "LTEAdvanced") {
1155 // Special case, Shill name contains a ' '.
1156 state
= shill::kStateOnline
;
1157 cellular_technology_
= shill::kNetworkTechnologyLteAdvanced
;
1159 LOG(ERROR
) << "Unrecognized initial state: " << type_arg
<< "="
1165 if (type_arg
== "wireless") {
1166 shill_initial_state_map_
[shill::kTypeWifi
] = state
;
1167 shill_initial_state_map_
[shill::kTypeCellular
] = state
;
1170 // Convenience synonyms.
1171 if (type_arg
== "eth")
1172 type_arg
= shill::kTypeEthernet
;
1174 if (type_arg
!= shill::kTypeEthernet
&&
1175 type_arg
!= shill::kTypeWifi
&&
1176 type_arg
!= shill::kTypeCellular
&&
1177 type_arg
!= shill::kTypeWimax
&&
1178 type_arg
!= shill::kTypeVPN
) {
1179 LOG(WARNING
) << "Unrecognized Shill network type: " << type_arg
;
1183 // Disabled ethernet is the same as unavailable.
1184 if (type_arg
== shill::kTypeEthernet
&& state
== kNetworkDisabled
)
1185 state
= kTechnologyUnavailable
;
1187 shill_initial_state_map_
[type_arg
] = state
;
1191 std::string
FakeShillManagerClient::GetInitialStateForType(
1192 const std::string
& type
,
1195 std::map
<std::string
, std::string
>::const_iterator iter
=
1196 shill_initial_state_map_
.find(type
);
1197 if (iter
== shill_initial_state_map_
.end()) {
1199 result
= kTechnologyUnavailable
;
1201 std::string state
= iter
->second
;
1202 if (state
== kNetworkDisabled
) {
1204 result
= shill::kStateIdle
;
1209 if ((state
== shill::kStatePortal
&& type
!= shill::kTypeWifi
) ||
1210 (state
== kNetworkActivated
&& type
!= shill::kTypeCellular
)) {
1211 LOG(WARNING
) << "Invalid state: " << state
<< " for " << type
;
1212 result
= shill::kStateIdle
;
1215 VLOG(1) << "Initial state for: " << type
<< " = " << result
1216 << " Enabled: " << *enabled
;
1220 } // namespace chromeos