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 const char* kTechnologyUnavailable
= "unavailable";
109 const char* kNetworkActivated
= "activated";
110 const char* kNetworkDisabled
= "disabled";
111 const char* kCellularServicePath
= "/service/cellular1";
112 const char* kRoamingRequired
= "required";
117 const char FakeShillManagerClient::kFakeEthernetNetworkGuid
[] = "eth1_guid";
119 FakeShillManagerClient::FakeShillManagerClient()
120 : interactive_delay_(0),
121 weak_ptr_factory_(this) {
122 ParseCommandLineSwitch();
125 FakeShillManagerClient::~FakeShillManagerClient() {}
127 // ShillManagerClient overrides.
129 void FakeShillManagerClient::Init(dbus::Bus
* bus
) {}
131 void FakeShillManagerClient::AddPropertyChangedObserver(
132 ShillPropertyChangedObserver
* observer
) {
133 observer_list_
.AddObserver(observer
);
136 void FakeShillManagerClient::RemovePropertyChangedObserver(
137 ShillPropertyChangedObserver
* observer
) {
138 observer_list_
.RemoveObserver(observer
);
141 void FakeShillManagerClient::GetProperties(
142 const DictionaryValueCallback
& callback
) {
143 VLOG(1) << "Manager.GetProperties";
144 base::MessageLoop::current()->PostTask(
145 FROM_HERE
, base::Bind(
146 &FakeShillManagerClient::PassStubProperties
,
147 weak_ptr_factory_
.GetWeakPtr(),
151 void FakeShillManagerClient::GetNetworksForGeolocation(
152 const DictionaryValueCallback
& callback
) {
153 base::MessageLoop::current()->PostTask(
154 FROM_HERE
, base::Bind(
155 &FakeShillManagerClient::PassStubGeoNetworks
,
156 weak_ptr_factory_
.GetWeakPtr(),
160 void FakeShillManagerClient::SetProperty(const std::string
& name
,
161 const base::Value
& value
,
162 const base::Closure
& callback
,
163 const ErrorCallback
& error_callback
) {
164 VLOG(2) << "SetProperty: " << name
;
165 stub_properties_
.SetWithoutPathExpansion(name
, value
.DeepCopy());
166 CallNotifyObserversPropertyChanged(name
);
167 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
170 void FakeShillManagerClient::RequestScan(const std::string
& type
,
171 const base::Closure
& callback
,
172 const ErrorCallback
& error_callback
) {
173 // For Stub purposes, default to a Wifi scan.
174 std::string device_type
= shill::kTypeWifi
;
177 ShillDeviceClient::TestInterface
* device_client
=
178 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
179 std::string device_path
= device_client
->GetDevicePathForType(device_type
);
180 if (!device_path
.empty()) {
181 device_client
->SetDeviceProperty(
182 device_path
, shill::kScanningProperty
, base::FundamentalValue(true));
184 base::MessageLoop::current()->PostDelayedTask(
186 base::Bind(&FakeShillManagerClient::ScanCompleted
,
187 weak_ptr_factory_
.GetWeakPtr(),
190 base::TimeDelta::FromSeconds(interactive_delay_
));
193 void FakeShillManagerClient::EnableTechnology(
194 const std::string
& type
,
195 const base::Closure
& callback
,
196 const ErrorCallback
& error_callback
) {
197 base::ListValue
* enabled_list
= NULL
;
198 if (!stub_properties_
.GetListWithoutPathExpansion(
199 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
200 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
201 base::MessageLoop::current()->PostTask(
203 base::Bind(error_callback
, "StubError", "Property not found"));
206 base::MessageLoop::current()->PostDelayedTask(
208 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
209 weak_ptr_factory_
.GetWeakPtr(),
213 base::TimeDelta::FromSeconds(interactive_delay_
));
216 void FakeShillManagerClient::DisableTechnology(
217 const std::string
& type
,
218 const base::Closure
& callback
,
219 const ErrorCallback
& error_callback
) {
220 base::ListValue
* enabled_list
= NULL
;
221 if (!stub_properties_
.GetListWithoutPathExpansion(
222 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
223 base::MessageLoop::current()->PostTask(
225 base::Bind(error_callback
, "StubError", "Property not found"));
228 base::MessageLoop::current()->PostDelayedTask(
230 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
231 weak_ptr_factory_
.GetWeakPtr(),
235 base::TimeDelta::FromSeconds(interactive_delay_
));
238 void FakeShillManagerClient::ConfigureService(
239 const base::DictionaryValue
& properties
,
240 const ObjectPathCallback
& callback
,
241 const ErrorCallback
& error_callback
) {
242 ShillServiceClient::TestInterface
* service_client
=
243 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
247 if (!properties
.GetString(shill::kGuidProperty
, &guid
) ||
248 !properties
.GetString(shill::kTypeProperty
, &type
)) {
249 LOG(ERROR
) << "ConfigureService requires GUID and Type to be defined";
250 // If the properties aren't filled out completely, then just return an empty
252 base::MessageLoop::current()->PostTask(
253 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
257 // For the purposes of this stub, we're going to assume that the GUID property
258 // is set to the service path because we don't want to re-implement Shill's
259 // property matching magic here.
260 std::string service_path
= guid
;
262 std::string ipconfig_path
;
263 properties
.GetString(shill::kIPConfigProperty
, &ipconfig_path
);
265 // Merge the new properties with existing properties, if any.
266 const base::DictionaryValue
* existing_properties
=
267 service_client
->GetServiceProperties(service_path
);
268 if (!existing_properties
) {
269 // Add a new service to the service client stub because none exists, yet.
270 // This calls AddManagerService.
271 service_client
->AddServiceWithIPConfig(service_path
,
278 existing_properties
= service_client
->GetServiceProperties(service_path
);
281 scoped_ptr
<base::DictionaryValue
> merged_properties(
282 existing_properties
->DeepCopy());
283 merged_properties
->MergeDictionary(&properties
);
285 // Now set all the properties.
286 for (base::DictionaryValue::Iterator
iter(*merged_properties
);
287 !iter
.IsAtEnd(); iter
.Advance()) {
288 service_client
->SetServiceProperty(service_path
, iter
.key(), iter
.value());
291 // If the Profile property is set, add it to ProfileClient.
292 std::string profile_path
;
293 merged_properties
->GetStringWithoutPathExpansion(shill::kProfileProperty
,
295 if (!profile_path
.empty()) {
296 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface()->
297 AddService(profile_path
, service_path
);
300 base::MessageLoop::current()->PostTask(
301 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath(service_path
)));
304 void FakeShillManagerClient::ConfigureServiceForProfile(
305 const dbus::ObjectPath
& profile_path
,
306 const base::DictionaryValue
& properties
,
307 const ObjectPathCallback
& callback
,
308 const ErrorCallback
& error_callback
) {
309 std::string profile_property
;
310 properties
.GetStringWithoutPathExpansion(shill::kProfileProperty
,
312 CHECK(profile_property
== profile_path
.value());
313 ConfigureService(properties
, callback
, error_callback
);
317 void FakeShillManagerClient::GetService(
318 const base::DictionaryValue
& properties
,
319 const ObjectPathCallback
& callback
,
320 const ErrorCallback
& error_callback
) {
321 base::MessageLoop::current()->PostTask(
322 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
325 void FakeShillManagerClient::VerifyDestination(
326 const VerificationProperties
& properties
,
327 const BooleanCallback
& callback
,
328 const ErrorCallback
& error_callback
) {
329 base::MessageLoop::current()->PostTask(FROM_HERE
, base::Bind(callback
, true));
332 void FakeShillManagerClient::VerifyAndEncryptCredentials(
333 const VerificationProperties
& properties
,
334 const std::string
& service_path
,
335 const StringCallback
& callback
,
336 const ErrorCallback
& error_callback
) {
337 base::MessageLoop::current()->PostTask(
338 FROM_HERE
, base::Bind(callback
, "encrypted_credentials"));
341 void FakeShillManagerClient::VerifyAndEncryptData(
342 const VerificationProperties
& properties
,
343 const std::string
& data
,
344 const StringCallback
& callback
,
345 const ErrorCallback
& error_callback
) {
346 base::MessageLoop::current()->PostTask(
347 FROM_HERE
, base::Bind(callback
, "encrypted_data"));
350 void FakeShillManagerClient::ConnectToBestServices(
351 const base::Closure
& callback
,
352 const ErrorCallback
& error_callback
) {
353 if (best_service_
.empty()) {
354 VLOG(1) << "No 'best' service set.";
358 DBusThreadManager::Get()->GetShillServiceClient()->Connect(
359 dbus::ObjectPath(best_service_
), callback
, error_callback
);
362 ShillManagerClient::TestInterface
* FakeShillManagerClient::GetTestInterface() {
366 // ShillManagerClient::TestInterface overrides.
368 void FakeShillManagerClient::AddDevice(const std::string
& device_path
) {
369 if (GetListProperty(shill::kDevicesProperty
)
370 ->AppendIfNotPresent(new base::StringValue(device_path
))) {
371 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
375 void FakeShillManagerClient::RemoveDevice(const std::string
& device_path
) {
376 base::StringValue
device_path_value(device_path
);
377 if (GetListProperty(shill::kDevicesProperty
)->Remove(
378 device_path_value
, NULL
)) {
379 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
383 void FakeShillManagerClient::ClearDevices() {
384 GetListProperty(shill::kDevicesProperty
)->Clear();
385 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
388 void FakeShillManagerClient::AddTechnology(const std::string
& type
,
390 if (GetListProperty(shill::kAvailableTechnologiesProperty
)
391 ->AppendIfNotPresent(new base::StringValue(type
))) {
392 CallNotifyObserversPropertyChanged(
393 shill::kAvailableTechnologiesProperty
);
396 GetListProperty(shill::kEnabledTechnologiesProperty
)
397 ->AppendIfNotPresent(new base::StringValue(type
))) {
398 CallNotifyObserversPropertyChanged(
399 shill::kEnabledTechnologiesProperty
);
403 void FakeShillManagerClient::RemoveTechnology(const std::string
& type
) {
404 base::StringValue
type_value(type
);
405 if (GetListProperty(shill::kAvailableTechnologiesProperty
)->Remove(
407 CallNotifyObserversPropertyChanged(
408 shill::kAvailableTechnologiesProperty
);
410 if (GetListProperty(shill::kEnabledTechnologiesProperty
)->Remove(
412 CallNotifyObserversPropertyChanged(
413 shill::kEnabledTechnologiesProperty
);
417 void FakeShillManagerClient::SetTechnologyInitializing(const std::string
& type
,
420 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)
421 ->AppendIfNotPresent(new base::StringValue(type
))) {
422 CallNotifyObserversPropertyChanged(
423 shill::kUninitializedTechnologiesProperty
);
426 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)->Remove(
427 base::StringValue(type
), NULL
)) {
428 CallNotifyObserversPropertyChanged(
429 shill::kUninitializedTechnologiesProperty
);
434 void FakeShillManagerClient::AddGeoNetwork(
435 const std::string
& technology
,
436 const base::DictionaryValue
& network
) {
437 base::ListValue
* list_value
= NULL
;
438 if (!stub_geo_networks_
.GetListWithoutPathExpansion(technology
,
440 list_value
= new base::ListValue
;
441 stub_geo_networks_
.SetWithoutPathExpansion(technology
, list_value
);
443 list_value
->Append(network
.DeepCopy());
446 void FakeShillManagerClient::AddProfile(const std::string
& profile_path
) {
447 const char* key
= shill::kProfilesProperty
;
448 if (GetListProperty(key
)
449 ->AppendIfNotPresent(new base::StringValue(profile_path
))) {
450 CallNotifyObserversPropertyChanged(key
);
454 void FakeShillManagerClient::ClearProperties() {
455 stub_properties_
.Clear();
458 void FakeShillManagerClient::SetManagerProperty(const std::string
& key
,
459 const base::Value
& value
) {
460 SetProperty(key
, value
,
461 base::Bind(&base::DoNothing
), base::Bind(&LogErrorCallback
));
464 void FakeShillManagerClient::AddManagerService(
465 const std::string
& service_path
,
466 bool notify_observers
) {
467 VLOG(2) << "AddManagerService: " << service_path
;
468 GetListProperty(shill::kServiceCompleteListProperty
)
469 ->AppendIfNotPresent(new base::StringValue(service_path
));
470 SortManagerServices(false);
471 if (notify_observers
)
472 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
475 void FakeShillManagerClient::RemoveManagerService(
476 const std::string
& service_path
) {
477 VLOG(2) << "RemoveManagerService: " << service_path
;
478 base::StringValue
service_path_value(service_path
);
479 GetListProperty(shill::kServiceCompleteListProperty
)->Remove(
480 service_path_value
, NULL
);
481 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
484 void FakeShillManagerClient::ClearManagerServices() {
485 VLOG(1) << "ClearManagerServices";
486 GetListProperty(shill::kServiceCompleteListProperty
)->Clear();
487 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
490 void FakeShillManagerClient::ServiceStateChanged(
491 const std::string
& service_path
,
492 const std::string
& state
) {
493 if (service_path
== default_service_
&& !IsConnectedState(state
)) {
494 // Default service is no longer connected; clear.
495 default_service_
.clear();
496 base::StringValue
default_service_value(default_service_
);
497 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
501 void FakeShillManagerClient::SortManagerServices(bool notify
) {
502 VLOG(1) << "SortManagerServices";
503 static const char* ordered_types
[] = {shill::kTypeEthernet
,
504 shill::kTypeEthernetEap
,
506 shill::kTypeCellular
,
510 base::ListValue
* complete_list
=
511 GetListProperty(shill::kServiceCompleteListProperty
);
512 if (complete_list
->empty())
514 scoped_ptr
<base::ListValue
> prev_complete_list(complete_list
->DeepCopy());
516 std::vector
<std::string
> active_services
;
517 std::vector
<std::string
> inactive_services
;
518 std::vector
<std::string
> disabled_services
;
519 for (size_t i
= 0; i
< arraysize(ordered_types
); ++i
) {
520 AppendServicesForType(complete_list
,
522 TechnologyEnabled(ordered_types
[i
]),
527 complete_list
->Clear();
528 for (size_t i
= 0; i
< active_services
.size(); ++i
)
529 complete_list
->AppendString(active_services
[i
]);
530 for (size_t i
= 0; i
< inactive_services
.size(); ++i
)
531 complete_list
->AppendString(inactive_services
[i
]);
532 for (size_t i
= 0; i
< disabled_services
.size(); ++i
)
533 complete_list
->AppendString(disabled_services
[i
]);
535 if (notify
&& !complete_list
->Equals(prev_complete_list
.get()))
536 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
538 // Set the first active service as the Default service.
539 std::string new_default_service
;
540 if (!active_services
.empty()) {
541 ShillServiceClient::TestInterface
* service_client
=
542 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
543 std::string service_path
= active_services
[0];
544 const base::DictionaryValue
* properties
=
545 service_client
->GetServiceProperties(service_path
);
547 LOG(ERROR
) << "Properties not found for service: " << service_path
;
550 properties
->GetString(shill::kStateProperty
, &state
);
551 if (IsConnectedState(state
))
552 new_default_service
= service_path
;
555 if (default_service_
!= new_default_service
) {
556 default_service_
= new_default_service
;
557 base::StringValue
default_service_value(default_service_
);
558 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
562 int FakeShillManagerClient::GetInteractiveDelay() const {
563 return interactive_delay_
;
566 void FakeShillManagerClient::SetBestServiceToConnect(
567 const std::string
& service_path
) {
568 best_service_
= service_path
;
571 void FakeShillManagerClient::SetupDefaultEnvironment() {
572 // Bail out from setup if there is no message loop. This will be the common
573 // case for tests that are not testing Shill.
574 if (!base::MessageLoop::current())
577 DBusThreadManager
* dbus_manager
= DBusThreadManager::Get();
578 ShillServiceClient::TestInterface
* services
=
579 dbus_manager
->GetShillServiceClient()->GetTestInterface();
581 ShillProfileClient::TestInterface
* profiles
=
582 dbus_manager
->GetShillProfileClient()->GetTestInterface();
584 ShillDeviceClient::TestInterface
* devices
=
585 dbus_manager
->GetShillDeviceClient()->GetTestInterface();
587 ShillIPConfigClient::TestInterface
* ip_configs
=
588 dbus_manager
->GetShillIPConfigClient()->GetTestInterface();
591 const std::string shared_profile
= ShillProfileClient::GetSharedProfilePath();
592 profiles
->AddProfile(shared_profile
, std::string());
594 const bool add_to_visible
= true;
597 base::DictionaryValue ipconfig_v4_dictionary
;
598 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
599 shill::kAddressProperty
, "100.0.0.1");
600 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
601 shill::kGatewayProperty
, "100.0.0.2");
602 ipconfig_v4_dictionary
.SetIntegerWithoutPathExpansion(
603 shill::kPrefixlenProperty
, 1);
604 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
605 shill::kMethodProperty
, shill::kTypeIPv4
);
606 ip_configs
->AddIPConfig("ipconfig_v4_path", ipconfig_v4_dictionary
);
607 base::DictionaryValue ipconfig_v6_dictionary
;
608 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
609 shill::kAddressProperty
, "0:0:0:0:100:0:0:1");
610 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
611 shill::kMethodProperty
, shill::kTypeIPv6
);
612 ip_configs
->AddIPConfig("ipconfig_v6_path", ipconfig_v6_dictionary
);
618 state
= GetInitialStateForType(shill::kTypeEthernet
, &enabled
);
619 if (state
== shill::kStateOnline
) {
620 AddTechnology(shill::kTypeEthernet
, enabled
);
622 "/device/eth1", shill::kTypeEthernet
, "stub_eth_device1");
623 devices
->SetDeviceProperty("/device/eth1",
624 shill::kAddressProperty
,
625 base::StringValue("0123456789ab"));
626 base::ListValue eth_ip_configs
;
627 eth_ip_configs
.AppendString("ipconfig_v4_path");
628 eth_ip_configs
.AppendString("ipconfig_v6_path");
629 devices
->SetDeviceProperty("/device/eth1",
630 shill::kIPConfigsProperty
,
632 const std::string kFakeEthernetNetworkPath
= "/service/eth1";
633 services
->AddService(kFakeEthernetNetworkPath
,
634 kFakeEthernetNetworkGuid
,
636 shill::kTypeEthernet
,
639 profiles
->AddService(shared_profile
, kFakeEthernetNetworkPath
);
643 if (s_tdls_busy_count
!= 0) {
644 DBusThreadManager::Get()
645 ->GetShillDeviceClient()
647 ->SetTDLSBusyCount(s_tdls_busy_count
);
650 state
= GetInitialStateForType(shill::kTypeWifi
, &enabled
);
651 if (state
!= kTechnologyUnavailable
) {
652 bool portaled
= false;
653 if (state
== shill::kStatePortal
) {
655 state
= shill::kStateIdle
;
657 AddTechnology(shill::kTypeWifi
, enabled
);
658 devices
->AddDevice("/device/wifi1", shill::kTypeWifi
, "stub_wifi_device1");
659 devices
->SetDeviceProperty("/device/wifi1",
660 shill::kAddressProperty
,
661 base::StringValue("23456789abcd"));
662 base::ListValue wifi_ip_configs
;
663 wifi_ip_configs
.AppendString("ipconfig_v4_path");
664 wifi_ip_configs
.AppendString("ipconfig_v6_path");
665 devices
->SetDeviceProperty("/device/wifi1",
666 shill::kIPConfigsProperty
,
669 const std::string kWifi1Path
= "/service/wifi1";
670 services
->AddService(kWifi1Path
,
676 services
->SetServiceProperty(kWifi1Path
,
677 shill::kSecurityClassProperty
,
678 base::StringValue(shill::kSecurityWep
));
679 services
->SetServiceProperty(kWifi1Path
,
680 shill::kConnectableProperty
,
681 base::FundamentalValue(true));
682 profiles
->AddService(shared_profile
, kWifi1Path
);
684 const std::string kWifi2Path
= "/service/wifi2";
685 services
->AddService(kWifi2Path
,
687 "wifi2_PSK" /* name */,
691 services
->SetServiceProperty(kWifi2Path
,
692 shill::kSecurityClassProperty
,
693 base::StringValue(shill::kSecurityPsk
));
694 services
->SetServiceProperty(
695 kWifi2Path
, shill::kSignalStrengthProperty
, base::FundamentalValue(80));
696 profiles
->AddService(shared_profile
, kWifi2Path
);
698 const std::string kWifi3Path
= "/service/wifi3";
699 services
->AddService(kWifi3Path
,
705 services
->SetServiceProperty(
706 kWifi3Path
, shill::kSignalStrengthProperty
, base::FundamentalValue(40));
709 const std::string kPortaledWifiPath
= "/service/portaled_wifi";
710 services
->AddService(kPortaledWifiPath
,
711 "portaled_wifi_guid",
712 "Portaled Wifi" /* name */,
716 services
->SetServiceProperty(kPortaledWifiPath
,
717 shill::kSecurityClassProperty
,
718 base::StringValue(shill::kSecurityNone
));
719 services
->SetConnectBehavior(kPortaledWifiPath
,
720 base::Bind(&UpdatePortaledWifiState
,
722 services
->SetServiceProperty(kPortaledWifiPath
,
723 shill::kConnectableProperty
,
724 base::FundamentalValue(true));
725 profiles
->AddService(shared_profile
, kPortaledWifiPath
);
730 const std::string kWimaxPath
= "/service/wimax1";
731 state
= GetInitialStateForType(shill::kTypeWimax
, &enabled
);
732 if (state
!= kTechnologyUnavailable
) {
733 AddTechnology(shill::kTypeWimax
, enabled
);
735 "/device/wimax1", shill::kTypeWimax
, "stub_wimax_device1");
737 services
->AddService(kWimaxPath
, "wimax1_guid", "wimax1" /* name */,
738 shill::kTypeWimax
, state
, add_to_visible
);
739 services
->SetServiceProperty(kWimaxPath
, shill::kConnectableProperty
,
740 base::FundamentalValue(true));
741 base::FundamentalValue
strength_value(80);
742 services
->SetServiceProperty(kWimaxPath
, shill::kSignalStrengthProperty
,
744 profiles
->AddService(shared_profile
, kWimaxPath
);
748 state
= GetInitialStateForType(shill::kTypeCellular
, &enabled
);
749 if (state
!= kTechnologyUnavailable
) {
750 bool activated
= false;
751 if (state
== kNetworkActivated
) {
753 state
= shill::kStateIdle
;
755 AddTechnology(shill::kTypeCellular
, enabled
);
757 "/device/cellular1", shill::kTypeCellular
, "stub_cellular_device1");
758 devices
->SetDeviceProperty("/device/cellular1",
759 shill::kCarrierProperty
,
760 base::StringValue(shill::kCarrierSprint
));
761 base::ListValue carrier_list
;
762 carrier_list
.AppendString(shill::kCarrierSprint
);
763 carrier_list
.AppendString(shill::kCarrierGenericUMTS
);
764 devices
->SetDeviceProperty("/device/cellular1",
765 shill::kSupportedCarriersProperty
,
767 if (roaming_state_
== kRoamingRequired
) {
768 devices
->SetDeviceProperty("/device/cellular1",
769 shill::kProviderRequiresRoamingProperty
,
770 base::FundamentalValue(true));
773 services
->AddService(kCellularServicePath
,
775 "cellular1" /* name */,
776 shill::kTypeCellular
,
779 base::StringValue
technology_value(shill::kNetworkTechnologyGsm
);
780 devices
->SetDeviceProperty("/device/cellular1",
781 shill::kTechnologyFamilyProperty
,
783 services
->SetServiceProperty(kCellularServicePath
,
784 shill::kNetworkTechnologyProperty
,
788 services
->SetServiceProperty(
789 kCellularServicePath
,
790 shill::kActivationStateProperty
,
791 base::StringValue(shill::kActivationStateActivated
));
792 services
->SetServiceProperty(kCellularServicePath
,
793 shill::kConnectableProperty
,
794 base::FundamentalValue(true));
796 services
->SetServiceProperty(
797 kCellularServicePath
,
798 shill::kActivationStateProperty
,
799 base::StringValue(shill::kActivationStateNotActivated
));
802 std::string shill_roaming_state
;
803 if (roaming_state_
== kRoamingRequired
)
804 shill_roaming_state
= shill::kRoamingStateRoaming
;
805 else if (roaming_state_
.empty())
806 shill_roaming_state
= shill::kRoamingStateHome
;
807 else // |roaming_state_| is expected to be a valid Shill state.
808 shill_roaming_state
= roaming_state_
;
809 services
->SetServiceProperty(kCellularServicePath
,
810 shill::kRoamingStateProperty
,
811 base::StringValue(shill_roaming_state
));
812 profiles
->AddService(shared_profile
, kCellularServicePath
);
816 state
= GetInitialStateForType(shill::kTypeVPN
, &enabled
);
817 if (state
!= kTechnologyUnavailable
) {
818 // Set the "Provider" dictionary properties. Note: when setting these in
819 // Shill, "Provider.Type", etc keys are used, but when reading the values
820 // "Provider" . "Type", etc keys are used. Here we are setting the values
821 // that will be read (by the UI, tests, etc).
822 base::DictionaryValue provider_properties_openvpn
;
823 provider_properties_openvpn
.SetString(shill::kTypeProperty
,
824 shill::kProviderOpenVpn
);
825 provider_properties_openvpn
.SetString(shill::kHostProperty
, "vpn_host");
827 services
->AddService("/service/vpn1",
833 services
->SetServiceProperty(
834 "/service/vpn1", shill::kProviderProperty
, provider_properties_openvpn
);
835 profiles
->AddService(shared_profile
, "/service/vpn1");
837 base::DictionaryValue provider_properties_l2tp
;
838 provider_properties_l2tp
.SetString(shill::kTypeProperty
,
839 shill::kProviderL2tpIpsec
);
840 provider_properties_l2tp
.SetString(shill::kHostProperty
, "vpn_host2");
842 services
->AddService("/service/vpn2",
848 services
->SetServiceProperty(
849 "/service/vpn2", shill::kProviderProperty
, provider_properties_l2tp
);
852 // Additional device states
853 for (DevicePropertyMap::iterator iter1
= shill_device_property_map_
.begin();
854 iter1
!= shill_device_property_map_
.end(); ++iter1
) {
855 std::string device_type
= iter1
->first
;
856 std::string device_path
= devices
->GetDevicePathForType(device_type
);
857 for (ShillPropertyMap::iterator iter2
= iter1
->second
.begin();
858 iter2
!= iter1
->second
.end(); ++iter2
) {
859 devices
->SetDeviceProperty(device_path
, iter2
->first
, *(iter2
->second
));
860 delete iter2
->second
;
864 SortManagerServices(true);
869 void FakeShillManagerClient::PassStubProperties(
870 const DictionaryValueCallback
& callback
) const {
871 scoped_ptr
<base::DictionaryValue
> stub_properties(
872 stub_properties_
.DeepCopy());
873 stub_properties
->SetWithoutPathExpansion(
874 shill::kServiceCompleteListProperty
,
875 GetEnabledServiceList(shill::kServiceCompleteListProperty
));
876 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, *stub_properties
);
879 void FakeShillManagerClient::PassStubGeoNetworks(
880 const DictionaryValueCallback
& callback
) const {
881 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, stub_geo_networks_
);
884 void FakeShillManagerClient::CallNotifyObserversPropertyChanged(
885 const std::string
& property
) {
886 // Avoid unnecessary delayed task if we have no observers (e.g. during
888 if (!observer_list_
.might_have_observers())
890 base::MessageLoop::current()->PostTask(
892 base::Bind(&FakeShillManagerClient::NotifyObserversPropertyChanged
,
893 weak_ptr_factory_
.GetWeakPtr(),
897 void FakeShillManagerClient::NotifyObserversPropertyChanged(
898 const std::string
& property
) {
899 VLOG(1) << "NotifyObserversPropertyChanged: " << property
;
900 base::Value
* value
= NULL
;
901 if (!stub_properties_
.GetWithoutPathExpansion(property
, &value
)) {
902 LOG(ERROR
) << "Notify for unknown property: " << property
;
905 if (property
== shill::kServiceCompleteListProperty
) {
906 scoped_ptr
<base::ListValue
> services(GetEnabledServiceList(property
));
907 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
909 OnPropertyChanged(property
, *(services
.get())));
912 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
914 OnPropertyChanged(property
, *value
));
917 base::ListValue
* FakeShillManagerClient::GetListProperty(
918 const std::string
& property
) {
919 base::ListValue
* list_property
= NULL
;
920 if (!stub_properties_
.GetListWithoutPathExpansion(
921 property
, &list_property
)) {
922 list_property
= new base::ListValue
;
923 stub_properties_
.SetWithoutPathExpansion(property
, list_property
);
925 return list_property
;
928 bool FakeShillManagerClient::TechnologyEnabled(const std::string
& type
) const {
929 if (type
== shill::kTypeVPN
)
930 return true; // VPN is always "enabled" since there is no associated device
931 if (type
== shill::kTypeEthernetEap
)
933 bool enabled
= false;
934 const base::ListValue
* technologies
;
935 if (stub_properties_
.GetListWithoutPathExpansion(
936 shill::kEnabledTechnologiesProperty
, &technologies
)) {
937 base::StringValue
type_value(type
);
938 if (technologies
->Find(type_value
) != technologies
->end())
944 void FakeShillManagerClient::SetTechnologyEnabled(
945 const std::string
& type
,
946 const base::Closure
& callback
,
948 base::ListValue
* enabled_list
=
949 GetListProperty(shill::kEnabledTechnologiesProperty
);
951 enabled_list
->AppendIfNotPresent(new base::StringValue(type
));
953 enabled_list
->Remove(base::StringValue(type
), NULL
);
954 CallNotifyObserversPropertyChanged(
955 shill::kEnabledTechnologiesProperty
);
956 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
957 // May affect available services.
958 SortManagerServices(true);
961 base::ListValue
* FakeShillManagerClient::GetEnabledServiceList(
962 const std::string
& property
) const {
963 base::ListValue
* new_service_list
= new base::ListValue
;
964 const base::ListValue
* service_list
;
965 if (stub_properties_
.GetListWithoutPathExpansion(property
, &service_list
)) {
966 ShillServiceClient::TestInterface
* service_client
=
967 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
968 for (base::ListValue::const_iterator iter
= service_list
->begin();
969 iter
!= service_list
->end(); ++iter
) {
970 std::string service_path
;
971 if (!(*iter
)->GetAsString(&service_path
))
973 const base::DictionaryValue
* properties
=
974 service_client
->GetServiceProperties(service_path
);
976 LOG(ERROR
) << "Properties not found for service: " << service_path
;
980 properties
->GetString(shill::kTypeProperty
, &type
);
981 if (TechnologyEnabled(type
))
982 new_service_list
->Append((*iter
)->DeepCopy());
985 return new_service_list
;
988 void FakeShillManagerClient::ScanCompleted(const std::string
& device_path
,
989 const base::Closure
& callback
) {
990 if (!device_path
.empty()) {
991 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
992 SetDeviceProperty(device_path
,
993 shill::kScanningProperty
,
994 base::FundamentalValue(false));
996 VLOG(2) << "ScanCompleted";
997 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
998 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
1001 void FakeShillManagerClient::ParseCommandLineSwitch() {
1003 SetInitialNetworkState(shill::kTypeEthernet
, shill::kStateOnline
);
1004 SetInitialNetworkState(shill::kTypeWifi
, shill::kStateOnline
);
1005 SetInitialNetworkState(shill::kTypeCellular
, shill::kStateIdle
);
1006 SetInitialNetworkState(shill::kTypeVPN
, shill::kStateIdle
);
1008 // Parse additional options
1009 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
1010 if (!command_line
->HasSwitch(switches::kShillStub
))
1013 std::string option_str
=
1014 command_line
->GetSwitchValueASCII(switches::kShillStub
);
1015 VLOG(1) << "Parsing command line:" << option_str
;
1016 base::StringPairs string_pairs
;
1017 base::SplitStringIntoKeyValuePairs(option_str
, '=', ',', &string_pairs
);
1018 for (base::StringPairs::iterator iter
= string_pairs
.begin();
1019 iter
!= string_pairs
.end(); ++iter
) {
1020 ParseOption((*iter
).first
, (*iter
).second
);
1024 bool FakeShillManagerClient::ParseOption(const std::string
& arg0
,
1025 const std::string
& arg1
) {
1026 VLOG(1) << "Parsing command line option: '" << arg0
<< "=" << arg1
<< "'";
1027 if ((arg0
== "clear" || arg0
== "reset") && arg1
== "1") {
1028 shill_initial_state_map_
.clear();
1030 } else if (arg0
== "interactive") {
1033 base::StringToInt(arg1
, &seconds
);
1034 interactive_delay_
= seconds
;
1036 } else if (arg0
== "sim_lock") {
1037 bool locked
= (arg1
== "1") ? true : false;
1038 base::DictionaryValue
* simlock_dict
= new base::DictionaryValue
;
1039 simlock_dict
->Set(shill::kSIMLockEnabledProperty
,
1040 new base::FundamentalValue(locked
));
1041 // TODO(stevenjb): Investigate why non-empty value breaks UI.
1042 std::string lock_type
= ""; // shill::kSIMLockPin
1043 simlock_dict
->SetString(shill::kSIMLockTypeProperty
, lock_type
);
1044 simlock_dict
->SetInteger(shill::kSIMLockRetriesLeftProperty
, 5);
1046 shill_device_property_map_
[shill::kTypeCellular
]
1047 [shill::kSIMLockStatusProperty
] = simlock_dict
;
1048 shill_device_property_map_
1049 [shill::kTypeCellular
][shill::kTechnologyFamilyProperty
] =
1050 new base::StringValue(shill::kNetworkTechnologyGsm
);
1052 } else if (arg0
== "tdls_busy") {
1054 base::StringToInt(arg1
, &s_tdls_busy_count
);
1056 s_tdls_busy_count
= 1;
1058 } else if (arg0
== "roaming") {
1059 // "home", "roaming", or "required"
1060 roaming_state_
= arg1
;
1063 return SetInitialNetworkState(arg0
, arg1
);
1066 bool FakeShillManagerClient::SetInitialNetworkState(std::string type_arg
,
1067 std::string state_arg
) {
1069 state_arg
= base::StringToLowerASCII(state_arg
);
1070 if (state_arg
.empty() || state_arg
== "1" || state_arg
== "on" ||
1071 state_arg
== "enabled" || state_arg
== "connected" ||
1072 state_arg
== "online") {
1073 // Enabled and connected (default value)
1074 state
= shill::kStateOnline
;
1075 } else if (state_arg
== "0" || state_arg
== "off" ||
1076 state_arg
== "inactive" || state_arg
== shill::kStateIdle
) {
1077 // Technology enabled, services are created but are not connected.
1078 state
= shill::kStateIdle
;
1079 } else if (state_arg
== "disabled" || state_arg
== "disconnect") {
1080 // Technology disabled but available, services created but not connected.
1081 state
= kNetworkDisabled
;
1082 } else if (state_arg
== "none" || state_arg
== "offline") {
1083 // Technology not available, do not create services.
1084 state
= kTechnologyUnavailable
;
1085 } else if (state_arg
== "portal") {
1086 // Technology is enabled, a service is connected and in Portal state.
1087 state
= shill::kStatePortal
;
1088 } else if (state_arg
== "active" || state_arg
== "activated") {
1089 // Technology is enabled, a service is connected and Activated.
1090 state
= kNetworkActivated
;
1092 LOG(ERROR
) << "Unrecognized initial state: " << state_arg
;
1096 type_arg
= base::StringToLowerASCII(type_arg
);
1098 if (type_arg
== "wireless") {
1099 shill_initial_state_map_
[shill::kTypeWifi
] = state
;
1100 shill_initial_state_map_
[shill::kTypeCellular
] = state
;
1103 // Convenience synonyms.
1104 if (type_arg
== "eth")
1105 type_arg
= shill::kTypeEthernet
;
1107 if (type_arg
!= shill::kTypeEthernet
&&
1108 type_arg
!= shill::kTypeWifi
&&
1109 type_arg
!= shill::kTypeCellular
&&
1110 type_arg
!= shill::kTypeWimax
&&
1111 type_arg
!= shill::kTypeVPN
) {
1112 LOG(WARNING
) << "Unrecognized Shill network type: " << type_arg
;
1116 // Unconnected or disabled ethernet is the same as unavailable.
1117 if (type_arg
== shill::kTypeEthernet
&&
1118 (state
== shill::kStateIdle
|| state
== kNetworkDisabled
)) {
1119 state
= kTechnologyUnavailable
;
1122 shill_initial_state_map_
[type_arg
] = state
;
1126 std::string
FakeShillManagerClient::GetInitialStateForType(
1127 const std::string
& type
,
1129 std::map
<std::string
, std::string
>::const_iterator iter
=
1130 shill_initial_state_map_
.find(type
);
1131 if (iter
== shill_initial_state_map_
.end()) {
1133 return kTechnologyUnavailable
;
1135 std::string state
= iter
->second
;
1136 if (state
== kNetworkDisabled
) {
1138 return shill::kStateIdle
;
1141 if ((state
== shill::kStatePortal
&& type
!= shill::kTypeWifi
) ||
1142 (state
== kNetworkActivated
&& type
!= shill::kTypeCellular
)) {
1143 LOG(WARNING
) << "Invalid state: " << state
<< " for " << type
;
1144 return shill::kStateIdle
;
1149 } // namespace chromeos