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/strings/stringprintf.h"
14 #include "base/values.h"
15 #include "chromeos/chromeos_switches.h"
16 #include "chromeos/dbus/dbus_thread_manager.h"
17 #include "chromeos/dbus/shill_device_client.h"
18 #include "chromeos/dbus/shill_ipconfig_client.h"
19 #include "chromeos/dbus/shill_profile_client.h"
20 #include "chromeos/dbus/shill_property_changed_observer.h"
21 #include "chromeos/dbus/shill_service_client.h"
23 #include "dbus/message.h"
24 #include "dbus/object_path.h"
25 #include "dbus/values_util.h"
26 #include "third_party/cros_system_api/dbus/service_constants.h"
32 // Allow parsed command line option 'tdls_busy' to set the fake busy count.
33 int s_tdls_busy_count
= 0;
34 int s_extra_wifi_networks
= 0;
36 // Used to compare values for finding entries to erase in a ListValue.
37 // (ListValue only implements a const_iterator version of Find).
39 explicit ValueEquals(const base::Value
* first
) : first_(first
) {}
40 bool operator()(const base::Value
* second
) const {
41 return first_
->Equals(second
);
43 const base::Value
* first_
;
46 // Appends string entries from |service_list_in| whose entries in ServiceClient
47 // have Type |match_type| to one of the output lists based on the entry's State.
48 void AppendServicesForType(
49 const base::ListValue
* service_list_in
,
50 const char* match_type
,
51 bool technology_enabled
,
52 std::vector
<std::string
>* active_service_list_out
,
53 std::vector
<std::string
>* inactive_service_list_out
,
54 std::vector
<std::string
>* disabled_service_list_out
) {
55 ShillServiceClient::TestInterface
* service_client
=
56 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
57 for (base::ListValue::const_iterator iter
= service_list_in
->begin();
58 iter
!= service_list_in
->end(); ++iter
) {
59 std::string service_path
;
60 if (!(*iter
)->GetAsString(&service_path
))
62 const base::DictionaryValue
* properties
=
63 service_client
->GetServiceProperties(service_path
);
65 LOG(ERROR
) << "Properties not found for service: " << service_path
;
69 properties
->GetString(shill::kTypeProperty
, &type
);
70 if (type
!= match_type
)
73 if (technology_enabled
)
74 properties
->GetBoolean(shill::kVisibleProperty
, &visible
);
76 disabled_service_list_out
->push_back(service_path
);
80 properties
->GetString(shill::kStateProperty
, &state
);
81 if (state
== shill::kStateOnline
||
82 state
== shill::kStateAssociation
||
83 state
== shill::kStateConfiguration
||
84 state
== shill::kStatePortal
||
85 state
== shill::kStateReady
) {
86 active_service_list_out
->push_back(service_path
);
88 inactive_service_list_out
->push_back(service_path
);
93 void LogErrorCallback(const std::string
& error_name
,
94 const std::string
& error_message
) {
95 LOG(ERROR
) << error_name
<< ": " << error_message
;
98 bool IsConnectedState(const std::string
& state
) {
99 return state
== shill::kStateOnline
|| state
== shill::kStatePortal
||
100 state
== shill::kStateReady
;
103 void UpdatePortaledWifiState(const std::string
& service_path
) {
104 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
105 ->SetServiceProperty(service_path
,
106 shill::kStateProperty
,
107 base::StringValue(shill::kStatePortal
));
110 bool IsCellularTechnology(const std::string
& type
) {
111 return (type
== shill::kNetworkTechnology1Xrtt
||
112 type
== shill::kNetworkTechnologyEvdo
||
113 type
== shill::kNetworkTechnologyGsm
||
114 type
== shill::kNetworkTechnologyGprs
||
115 type
== shill::kNetworkTechnologyEdge
||
116 type
== shill::kNetworkTechnologyUmts
||
117 type
== shill::kNetworkTechnologyHspa
||
118 type
== shill::kNetworkTechnologyHspaPlus
||
119 type
== shill::kNetworkTechnologyLte
||
120 type
== shill::kNetworkTechnologyLteAdvanced
);
123 const char* kTechnologyUnavailable
= "unavailable";
124 const char* kNetworkActivated
= "activated";
125 const char* kNetworkDisabled
= "disabled";
126 const char* kCellularServicePath
= "/service/cellular1";
127 const char* kRoamingRequired
= "required";
132 const char FakeShillManagerClient::kFakeEthernetNetworkGuid
[] = "eth1_guid";
134 FakeShillManagerClient::FakeShillManagerClient()
135 : interactive_delay_(0),
136 cellular_technology_(shill::kNetworkTechnologyGsm
),
137 weak_ptr_factory_(this) {
138 ParseCommandLineSwitch();
141 FakeShillManagerClient::~FakeShillManagerClient() {}
143 // ShillManagerClient overrides.
145 void FakeShillManagerClient::Init(dbus::Bus
* bus
) {}
147 void FakeShillManagerClient::AddPropertyChangedObserver(
148 ShillPropertyChangedObserver
* observer
) {
149 observer_list_
.AddObserver(observer
);
152 void FakeShillManagerClient::RemovePropertyChangedObserver(
153 ShillPropertyChangedObserver
* observer
) {
154 observer_list_
.RemoveObserver(observer
);
157 void FakeShillManagerClient::GetProperties(
158 const DictionaryValueCallback
& callback
) {
159 VLOG(1) << "Manager.GetProperties";
160 base::MessageLoop::current()->PostTask(
161 FROM_HERE
, base::Bind(
162 &FakeShillManagerClient::PassStubProperties
,
163 weak_ptr_factory_
.GetWeakPtr(),
167 void FakeShillManagerClient::GetNetworksForGeolocation(
168 const DictionaryValueCallback
& callback
) {
169 base::MessageLoop::current()->PostTask(
170 FROM_HERE
, base::Bind(
171 &FakeShillManagerClient::PassStubGeoNetworks
,
172 weak_ptr_factory_
.GetWeakPtr(),
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::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
186 void FakeShillManagerClient::RequestScan(const std::string
& type
,
187 const base::Closure
& callback
,
188 const ErrorCallback
& error_callback
) {
189 // For Stub purposes, default to a Wifi scan.
190 std::string device_type
= shill::kTypeWifi
;
193 ShillDeviceClient::TestInterface
* device_client
=
194 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
195 std::string device_path
= device_client
->GetDevicePathForType(device_type
);
196 if (!device_path
.empty()) {
197 device_client
->SetDeviceProperty(
198 device_path
, shill::kScanningProperty
, base::FundamentalValue(true));
200 base::MessageLoop::current()->PostDelayedTask(
202 base::Bind(&FakeShillManagerClient::ScanCompleted
,
203 weak_ptr_factory_
.GetWeakPtr(),
206 base::TimeDelta::FromSeconds(interactive_delay_
));
209 void FakeShillManagerClient::EnableTechnology(
210 const std::string
& type
,
211 const base::Closure
& callback
,
212 const ErrorCallback
& error_callback
) {
213 base::ListValue
* enabled_list
= NULL
;
214 if (!stub_properties_
.GetListWithoutPathExpansion(
215 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
216 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
217 base::MessageLoop::current()->PostTask(
219 base::Bind(error_callback
, "StubError", "Property not found"));
222 base::MessageLoop::current()->PostDelayedTask(
224 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
225 weak_ptr_factory_
.GetWeakPtr(),
229 base::TimeDelta::FromSeconds(interactive_delay_
));
232 void FakeShillManagerClient::DisableTechnology(
233 const std::string
& type
,
234 const base::Closure
& callback
,
235 const ErrorCallback
& error_callback
) {
236 base::ListValue
* enabled_list
= NULL
;
237 if (!stub_properties_
.GetListWithoutPathExpansion(
238 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
239 base::MessageLoop::current()->PostTask(
241 base::Bind(error_callback
, "StubError", "Property not found"));
244 base::MessageLoop::current()->PostDelayedTask(
246 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
247 weak_ptr_factory_
.GetWeakPtr(),
251 base::TimeDelta::FromSeconds(interactive_delay_
));
254 void FakeShillManagerClient::ConfigureService(
255 const base::DictionaryValue
& properties
,
256 const ObjectPathCallback
& callback
,
257 const ErrorCallback
& error_callback
) {
258 ShillServiceClient::TestInterface
* service_client
=
259 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
263 if (!properties
.GetString(shill::kGuidProperty
, &guid
) ||
264 !properties
.GetString(shill::kTypeProperty
, &type
)) {
265 LOG(ERROR
) << "ConfigureService requires GUID and Type to be defined";
266 // If the properties aren't filled out completely, then just return an empty
268 base::MessageLoop::current()->PostTask(
269 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
273 // For the purposes of this stub, we're going to assume that the GUID property
274 // is set to the service path because we don't want to re-implement Shill's
275 // property matching magic here.
276 std::string service_path
= guid
;
278 std::string ipconfig_path
;
279 properties
.GetString(shill::kIPConfigProperty
, &ipconfig_path
);
281 // Merge the new properties with existing properties, if any.
282 const base::DictionaryValue
* existing_properties
=
283 service_client
->GetServiceProperties(service_path
);
284 if (!existing_properties
) {
285 // Add a new service to the service client stub because none exists, yet.
286 // This calls AddManagerService.
287 service_client
->AddServiceWithIPConfig(service_path
,
294 existing_properties
= service_client
->GetServiceProperties(service_path
);
297 scoped_ptr
<base::DictionaryValue
> merged_properties(
298 existing_properties
->DeepCopy());
299 merged_properties
->MergeDictionary(&properties
);
301 // Now set all the properties.
302 for (base::DictionaryValue::Iterator
iter(*merged_properties
);
303 !iter
.IsAtEnd(); iter
.Advance()) {
304 service_client
->SetServiceProperty(service_path
, iter
.key(), iter
.value());
307 // If the Profile property is set, add it to ProfileClient.
308 std::string profile_path
;
309 merged_properties
->GetStringWithoutPathExpansion(shill::kProfileProperty
,
311 if (!profile_path
.empty()) {
312 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface()->
313 AddService(profile_path
, service_path
);
316 base::MessageLoop::current()->PostTask(
317 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath(service_path
)));
320 void FakeShillManagerClient::ConfigureServiceForProfile(
321 const dbus::ObjectPath
& profile_path
,
322 const base::DictionaryValue
& properties
,
323 const ObjectPathCallback
& callback
,
324 const ErrorCallback
& error_callback
) {
325 std::string profile_property
;
326 properties
.GetStringWithoutPathExpansion(shill::kProfileProperty
,
328 CHECK(profile_property
== profile_path
.value());
329 ConfigureService(properties
, callback
, error_callback
);
333 void FakeShillManagerClient::GetService(
334 const base::DictionaryValue
& properties
,
335 const ObjectPathCallback
& callback
,
336 const ErrorCallback
& error_callback
) {
337 base::MessageLoop::current()->PostTask(
338 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
341 void FakeShillManagerClient::VerifyDestination(
342 const VerificationProperties
& properties
,
343 const BooleanCallback
& callback
,
344 const ErrorCallback
& error_callback
) {
345 base::MessageLoop::current()->PostTask(FROM_HERE
, base::Bind(callback
, true));
348 void FakeShillManagerClient::VerifyAndEncryptCredentials(
349 const VerificationProperties
& properties
,
350 const std::string
& service_path
,
351 const StringCallback
& callback
,
352 const ErrorCallback
& error_callback
) {
353 base::MessageLoop::current()->PostTask(
354 FROM_HERE
, base::Bind(callback
, "encrypted_credentials"));
357 void FakeShillManagerClient::VerifyAndEncryptData(
358 const VerificationProperties
& properties
,
359 const std::string
& data
,
360 const StringCallback
& callback
,
361 const ErrorCallback
& error_callback
) {
362 base::MessageLoop::current()->PostTask(
363 FROM_HERE
, base::Bind(callback
, "encrypted_data"));
366 void FakeShillManagerClient::ConnectToBestServices(
367 const base::Closure
& callback
,
368 const ErrorCallback
& error_callback
) {
369 if (best_service_
.empty()) {
370 VLOG(1) << "No 'best' service set.";
374 DBusThreadManager::Get()->GetShillServiceClient()->Connect(
375 dbus::ObjectPath(best_service_
), callback
, error_callback
);
378 ShillManagerClient::TestInterface
* FakeShillManagerClient::GetTestInterface() {
382 // ShillManagerClient::TestInterface overrides.
384 void FakeShillManagerClient::AddDevice(const std::string
& device_path
) {
385 if (GetListProperty(shill::kDevicesProperty
)
386 ->AppendIfNotPresent(new base::StringValue(device_path
))) {
387 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
391 void FakeShillManagerClient::RemoveDevice(const std::string
& device_path
) {
392 base::StringValue
device_path_value(device_path
);
393 if (GetListProperty(shill::kDevicesProperty
)->Remove(
394 device_path_value
, NULL
)) {
395 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
399 void FakeShillManagerClient::ClearDevices() {
400 GetListProperty(shill::kDevicesProperty
)->Clear();
401 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
404 void FakeShillManagerClient::AddTechnology(const std::string
& type
,
406 if (GetListProperty(shill::kAvailableTechnologiesProperty
)
407 ->AppendIfNotPresent(new base::StringValue(type
))) {
408 CallNotifyObserversPropertyChanged(
409 shill::kAvailableTechnologiesProperty
);
412 GetListProperty(shill::kEnabledTechnologiesProperty
)
413 ->AppendIfNotPresent(new base::StringValue(type
))) {
414 CallNotifyObserversPropertyChanged(
415 shill::kEnabledTechnologiesProperty
);
419 void FakeShillManagerClient::RemoveTechnology(const std::string
& type
) {
420 base::StringValue
type_value(type
);
421 if (GetListProperty(shill::kAvailableTechnologiesProperty
)->Remove(
423 CallNotifyObserversPropertyChanged(
424 shill::kAvailableTechnologiesProperty
);
426 if (GetListProperty(shill::kEnabledTechnologiesProperty
)->Remove(
428 CallNotifyObserversPropertyChanged(
429 shill::kEnabledTechnologiesProperty
);
433 void FakeShillManagerClient::SetTechnologyInitializing(const std::string
& type
,
436 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)
437 ->AppendIfNotPresent(new base::StringValue(type
))) {
438 CallNotifyObserversPropertyChanged(
439 shill::kUninitializedTechnologiesProperty
);
442 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)->Remove(
443 base::StringValue(type
), NULL
)) {
444 CallNotifyObserversPropertyChanged(
445 shill::kUninitializedTechnologiesProperty
);
450 void FakeShillManagerClient::AddGeoNetwork(
451 const std::string
& technology
,
452 const base::DictionaryValue
& network
) {
453 base::ListValue
* list_value
= NULL
;
454 if (!stub_geo_networks_
.GetListWithoutPathExpansion(technology
,
456 list_value
= new base::ListValue
;
457 stub_geo_networks_
.SetWithoutPathExpansion(technology
, list_value
);
459 list_value
->Append(network
.DeepCopy());
462 void FakeShillManagerClient::AddProfile(const std::string
& profile_path
) {
463 const char* key
= shill::kProfilesProperty
;
464 if (GetListProperty(key
)
465 ->AppendIfNotPresent(new base::StringValue(profile_path
))) {
466 CallNotifyObserversPropertyChanged(key
);
470 void FakeShillManagerClient::ClearProperties() {
471 stub_properties_
.Clear();
474 void FakeShillManagerClient::SetManagerProperty(const std::string
& key
,
475 const base::Value
& value
) {
476 SetProperty(key
, value
,
477 base::Bind(&base::DoNothing
), base::Bind(&LogErrorCallback
));
480 void FakeShillManagerClient::AddManagerService(
481 const std::string
& service_path
,
482 bool notify_observers
) {
483 VLOG(2) << "AddManagerService: " << service_path
;
484 GetListProperty(shill::kServiceCompleteListProperty
)
485 ->AppendIfNotPresent(new base::StringValue(service_path
));
486 SortManagerServices(false);
487 if (notify_observers
)
488 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
491 void FakeShillManagerClient::RemoveManagerService(
492 const std::string
& service_path
) {
493 VLOG(2) << "RemoveManagerService: " << service_path
;
494 base::StringValue
service_path_value(service_path
);
495 GetListProperty(shill::kServiceCompleteListProperty
)->Remove(
496 service_path_value
, NULL
);
497 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
500 void FakeShillManagerClient::ClearManagerServices() {
501 VLOG(1) << "ClearManagerServices";
502 GetListProperty(shill::kServiceCompleteListProperty
)->Clear();
503 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
506 void FakeShillManagerClient::ServiceStateChanged(
507 const std::string
& service_path
,
508 const std::string
& state
) {
509 if (service_path
== default_service_
&& !IsConnectedState(state
)) {
510 // Default service is no longer connected; clear.
511 default_service_
.clear();
512 base::StringValue
default_service_value(default_service_
);
513 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
517 void FakeShillManagerClient::SortManagerServices(bool notify
) {
518 VLOG(1) << "SortManagerServices";
519 static const char* ordered_types
[] = {shill::kTypeEthernet
,
520 shill::kTypeEthernetEap
,
522 shill::kTypeCellular
,
526 base::ListValue
* complete_list
=
527 GetListProperty(shill::kServiceCompleteListProperty
);
528 if (complete_list
->empty())
530 scoped_ptr
<base::ListValue
> prev_complete_list(complete_list
->DeepCopy());
532 std::vector
<std::string
> active_services
;
533 std::vector
<std::string
> inactive_services
;
534 std::vector
<std::string
> disabled_services
;
535 for (size_t i
= 0; i
< arraysize(ordered_types
); ++i
) {
536 AppendServicesForType(complete_list
,
538 TechnologyEnabled(ordered_types
[i
]),
543 complete_list
->Clear();
544 for (size_t i
= 0; i
< active_services
.size(); ++i
)
545 complete_list
->AppendString(active_services
[i
]);
546 for (size_t i
= 0; i
< inactive_services
.size(); ++i
)
547 complete_list
->AppendString(inactive_services
[i
]);
548 for (size_t i
= 0; i
< disabled_services
.size(); ++i
)
549 complete_list
->AppendString(disabled_services
[i
]);
551 if (notify
&& !complete_list
->Equals(prev_complete_list
.get()))
552 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
554 // Set the first active service as the Default service.
555 std::string new_default_service
;
556 if (!active_services
.empty()) {
557 ShillServiceClient::TestInterface
* service_client
=
558 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
559 std::string service_path
= active_services
[0];
560 const base::DictionaryValue
* properties
=
561 service_client
->GetServiceProperties(service_path
);
563 LOG(ERROR
) << "Properties not found for service: " << service_path
;
566 properties
->GetString(shill::kStateProperty
, &state
);
567 if (IsConnectedState(state
))
568 new_default_service
= service_path
;
571 if (default_service_
!= new_default_service
) {
572 default_service_
= new_default_service
;
573 base::StringValue
default_service_value(default_service_
);
574 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
578 int FakeShillManagerClient::GetInteractiveDelay() const {
579 return interactive_delay_
;
582 void FakeShillManagerClient::SetBestServiceToConnect(
583 const std::string
& service_path
) {
584 best_service_
= service_path
;
587 void FakeShillManagerClient::SetupDefaultEnvironment() {
588 // Bail out from setup if there is no message loop. This will be the common
589 // case for tests that are not testing Shill.
590 if (!base::MessageLoop::current())
593 DBusThreadManager
* dbus_manager
= DBusThreadManager::Get();
594 ShillServiceClient::TestInterface
* services
=
595 dbus_manager
->GetShillServiceClient()->GetTestInterface();
597 ShillProfileClient::TestInterface
* profiles
=
598 dbus_manager
->GetShillProfileClient()->GetTestInterface();
600 ShillDeviceClient::TestInterface
* devices
=
601 dbus_manager
->GetShillDeviceClient()->GetTestInterface();
603 ShillIPConfigClient::TestInterface
* ip_configs
=
604 dbus_manager
->GetShillIPConfigClient()->GetTestInterface();
607 const std::string shared_profile
= ShillProfileClient::GetSharedProfilePath();
608 profiles
->AddProfile(shared_profile
, std::string());
610 const bool add_to_visible
= true;
613 base::DictionaryValue ipconfig_v4_dictionary
;
614 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
615 shill::kAddressProperty
, "100.0.0.1");
616 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
617 shill::kGatewayProperty
, "100.0.0.2");
618 ipconfig_v4_dictionary
.SetIntegerWithoutPathExpansion(
619 shill::kPrefixlenProperty
, 1);
620 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
621 shill::kMethodProperty
, shill::kTypeIPv4
);
622 ip_configs
->AddIPConfig("ipconfig_v4_path", ipconfig_v4_dictionary
);
623 base::DictionaryValue ipconfig_v6_dictionary
;
624 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
625 shill::kAddressProperty
, "0:0:0:0:100:0:0:1");
626 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
627 shill::kMethodProperty
, shill::kTypeIPv6
);
628 ip_configs
->AddIPConfig("ipconfig_v6_path", ipconfig_v6_dictionary
);
634 state
= GetInitialStateForType(shill::kTypeEthernet
, &enabled
);
635 if (state
== shill::kStateOnline
) {
636 AddTechnology(shill::kTypeEthernet
, enabled
);
638 "/device/eth1", shill::kTypeEthernet
, "stub_eth_device1");
639 devices
->SetDeviceProperty("/device/eth1",
640 shill::kAddressProperty
,
641 base::StringValue("0123456789ab"));
642 base::ListValue eth_ip_configs
;
643 eth_ip_configs
.AppendString("ipconfig_v4_path");
644 eth_ip_configs
.AppendString("ipconfig_v6_path");
645 devices
->SetDeviceProperty("/device/eth1",
646 shill::kIPConfigsProperty
,
648 const std::string kFakeEthernetNetworkPath
= "/service/eth1";
649 services
->AddService(kFakeEthernetNetworkPath
,
650 kFakeEthernetNetworkGuid
,
652 shill::kTypeEthernet
,
655 profiles
->AddService(shared_profile
, kFakeEthernetNetworkPath
);
659 if (s_tdls_busy_count
!= 0) {
660 DBusThreadManager::Get()
661 ->GetShillDeviceClient()
663 ->SetTDLSBusyCount(s_tdls_busy_count
);
666 state
= GetInitialStateForType(shill::kTypeWifi
, &enabled
);
667 if (state
!= kTechnologyUnavailable
) {
668 bool portaled
= false;
669 if (state
== shill::kStatePortal
) {
671 state
= shill::kStateIdle
;
673 AddTechnology(shill::kTypeWifi
, enabled
);
674 devices
->AddDevice("/device/wifi1", shill::kTypeWifi
, "stub_wifi_device1");
675 devices
->SetDeviceProperty("/device/wifi1",
676 shill::kAddressProperty
,
677 base::StringValue("23456789abcd"));
678 base::ListValue wifi_ip_configs
;
679 wifi_ip_configs
.AppendString("ipconfig_v4_path");
680 wifi_ip_configs
.AppendString("ipconfig_v6_path");
681 devices
->SetDeviceProperty("/device/wifi1",
682 shill::kIPConfigsProperty
,
685 const std::string kWifi1Path
= "/service/wifi1";
686 services
->AddService(kWifi1Path
,
692 services
->SetServiceProperty(kWifi1Path
,
693 shill::kSecurityClassProperty
,
694 base::StringValue(shill::kSecurityWep
));
695 services
->SetServiceProperty(kWifi1Path
,
696 shill::kConnectableProperty
,
697 base::FundamentalValue(true));
698 profiles
->AddService(shared_profile
, kWifi1Path
);
700 const std::string kWifi2Path
= "/service/wifi2";
701 services
->AddService(kWifi2Path
,
703 "wifi2_PSK" /* name */,
707 services
->SetServiceProperty(kWifi2Path
,
708 shill::kSecurityClassProperty
,
709 base::StringValue(shill::kSecurityPsk
));
710 services
->SetServiceProperty(
711 kWifi2Path
, shill::kSignalStrengthProperty
, base::FundamentalValue(80));
712 profiles
->AddService(shared_profile
, kWifi2Path
);
714 const std::string kWifi3Path
= "/service/wifi3";
715 services
->AddService(kWifi3Path
,
721 services
->SetServiceProperty(
722 kWifi3Path
, shill::kSignalStrengthProperty
, base::FundamentalValue(40));
725 const std::string kPortaledWifiPath
= "/service/portaled_wifi";
726 services
->AddService(kPortaledWifiPath
, "portaled_wifi_guid",
727 "Portaled Wifi" /* name */, shill::kTypeWifi
,
728 shill::kStateIdle
, add_to_visible
);
729 services
->SetServiceProperty(kPortaledWifiPath
,
730 shill::kSecurityClassProperty
,
731 base::StringValue(shill::kSecurityNone
));
732 services
->SetConnectBehavior(
734 base::Bind(&UpdatePortaledWifiState
, kPortaledWifiPath
));
735 services
->SetServiceProperty(kPortaledWifiPath
,
736 shill::kConnectableProperty
,
737 base::FundamentalValue(true));
738 profiles
->AddService(shared_profile
, kPortaledWifiPath
);
741 for (int i
= 0; i
< s_extra_wifi_networks
; ++i
) {
743 std::string path
= base::StringPrintf("/service/wifi%d", id
);
744 std::string guid
= base::StringPrintf("wifi%d_guid", id
);
745 std::string name
= base::StringPrintf("wifi%d", id
);
746 services
->AddService(path
, guid
, name
, shill::kTypeWifi
,
747 shill::kStateIdle
, add_to_visible
);
752 const std::string kWimaxPath
= "/service/wimax1";
753 state
= GetInitialStateForType(shill::kTypeWimax
, &enabled
);
754 if (state
!= kTechnologyUnavailable
) {
755 AddTechnology(shill::kTypeWimax
, enabled
);
757 "/device/wimax1", shill::kTypeWimax
, "stub_wimax_device1");
759 services
->AddService(kWimaxPath
, "wimax1_guid", "wimax1" /* name */,
760 shill::kTypeWimax
, state
, add_to_visible
);
761 services
->SetServiceProperty(kWimaxPath
, shill::kConnectableProperty
,
762 base::FundamentalValue(true));
763 base::FundamentalValue
strength_value(80);
764 services
->SetServiceProperty(kWimaxPath
, shill::kSignalStrengthProperty
,
766 profiles
->AddService(shared_profile
, kWimaxPath
);
770 state
= GetInitialStateForType(shill::kTypeCellular
, &enabled
);
771 if (state
!= kTechnologyUnavailable
) {
772 bool activated
= false;
773 if (state
== kNetworkActivated
) {
775 state
= shill::kStateIdle
;
777 AddTechnology(shill::kTypeCellular
, enabled
);
779 "/device/cellular1", shill::kTypeCellular
, "stub_cellular_device1");
780 devices
->SetDeviceProperty("/device/cellular1",
781 shill::kCarrierProperty
,
782 base::StringValue(shill::kCarrierSprint
));
783 base::ListValue carrier_list
;
784 carrier_list
.AppendString(shill::kCarrierSprint
);
785 carrier_list
.AppendString(shill::kCarrierGenericUMTS
);
786 devices
->SetDeviceProperty("/device/cellular1",
787 shill::kSupportedCarriersProperty
,
789 devices
->SetDeviceProperty("/device/cellular1",
790 shill::kSupportNetworkScanProperty
,
791 base::FundamentalValue(true));
792 if (roaming_state_
== kRoamingRequired
) {
793 devices
->SetDeviceProperty("/device/cellular1",
794 shill::kProviderRequiresRoamingProperty
,
795 base::FundamentalValue(true));
798 services
->AddService(kCellularServicePath
,
800 "cellular1" /* name */,
801 shill::kTypeCellular
,
804 base::StringValue
technology_value(cellular_technology_
);
805 devices
->SetDeviceProperty("/device/cellular1",
806 shill::kTechnologyFamilyProperty
,
808 services
->SetServiceProperty(kCellularServicePath
,
809 shill::kNetworkTechnologyProperty
,
813 services
->SetServiceProperty(
814 kCellularServicePath
,
815 shill::kActivationStateProperty
,
816 base::StringValue(shill::kActivationStateActivated
));
817 services
->SetServiceProperty(kCellularServicePath
,
818 shill::kConnectableProperty
,
819 base::FundamentalValue(true));
821 services
->SetServiceProperty(
822 kCellularServicePath
,
823 shill::kActivationStateProperty
,
824 base::StringValue(shill::kActivationStateNotActivated
));
827 std::string shill_roaming_state
;
828 if (roaming_state_
== kRoamingRequired
)
829 shill_roaming_state
= shill::kRoamingStateRoaming
;
830 else if (roaming_state_
.empty())
831 shill_roaming_state
= shill::kRoamingStateHome
;
832 else // |roaming_state_| is expected to be a valid Shill state.
833 shill_roaming_state
= roaming_state_
;
834 services
->SetServiceProperty(kCellularServicePath
,
835 shill::kRoamingStateProperty
,
836 base::StringValue(shill_roaming_state
));
837 profiles
->AddService(shared_profile
, kCellularServicePath
);
841 state
= GetInitialStateForType(shill::kTypeVPN
, &enabled
);
842 if (state
!= kTechnologyUnavailable
) {
843 // Set the "Provider" dictionary properties. Note: when setting these in
844 // Shill, "Provider.Type", etc keys are used, but when reading the values
845 // "Provider" . "Type", etc keys are used. Here we are setting the values
846 // that will be read (by the UI, tests, etc).
847 base::DictionaryValue provider_properties_openvpn
;
848 provider_properties_openvpn
.SetString(shill::kTypeProperty
,
849 shill::kProviderOpenVpn
);
850 provider_properties_openvpn
.SetString(shill::kHostProperty
, "vpn_host");
852 services
->AddService("/service/vpn1",
858 services
->SetServiceProperty(
859 "/service/vpn1", shill::kProviderProperty
, provider_properties_openvpn
);
860 profiles
->AddService(shared_profile
, "/service/vpn1");
862 base::DictionaryValue provider_properties_l2tp
;
863 provider_properties_l2tp
.SetString(shill::kTypeProperty
,
864 shill::kProviderL2tpIpsec
);
865 provider_properties_l2tp
.SetString(shill::kHostProperty
, "vpn_host2");
867 services
->AddService("/service/vpn2",
873 services
->SetServiceProperty(
874 "/service/vpn2", shill::kProviderProperty
, provider_properties_l2tp
);
877 // Additional device states
878 for (DevicePropertyMap::iterator iter1
= shill_device_property_map_
.begin();
879 iter1
!= shill_device_property_map_
.end(); ++iter1
) {
880 std::string device_type
= iter1
->first
;
881 std::string device_path
= devices
->GetDevicePathForType(device_type
);
882 for (ShillPropertyMap::iterator iter2
= iter1
->second
.begin();
883 iter2
!= iter1
->second
.end(); ++iter2
) {
884 devices
->SetDeviceProperty(device_path
, iter2
->first
, *(iter2
->second
));
885 delete iter2
->second
;
889 SortManagerServices(true);
894 void FakeShillManagerClient::PassStubProperties(
895 const DictionaryValueCallback
& callback
) const {
896 scoped_ptr
<base::DictionaryValue
> stub_properties(
897 stub_properties_
.DeepCopy());
898 stub_properties
->SetWithoutPathExpansion(
899 shill::kServiceCompleteListProperty
,
900 GetEnabledServiceList(shill::kServiceCompleteListProperty
));
901 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, *stub_properties
);
904 void FakeShillManagerClient::PassStubGeoNetworks(
905 const DictionaryValueCallback
& callback
) const {
906 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, stub_geo_networks_
);
909 void FakeShillManagerClient::CallNotifyObserversPropertyChanged(
910 const std::string
& property
) {
911 // Avoid unnecessary delayed task if we have no observers (e.g. during
913 if (!observer_list_
.might_have_observers())
915 base::MessageLoop::current()->PostTask(
917 base::Bind(&FakeShillManagerClient::NotifyObserversPropertyChanged
,
918 weak_ptr_factory_
.GetWeakPtr(),
922 void FakeShillManagerClient::NotifyObserversPropertyChanged(
923 const std::string
& property
) {
924 VLOG(1) << "NotifyObserversPropertyChanged: " << property
;
925 base::Value
* value
= NULL
;
926 if (!stub_properties_
.GetWithoutPathExpansion(property
, &value
)) {
927 LOG(ERROR
) << "Notify for unknown property: " << property
;
930 if (property
== shill::kServiceCompleteListProperty
) {
931 scoped_ptr
<base::ListValue
> services(GetEnabledServiceList(property
));
932 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
934 OnPropertyChanged(property
, *(services
.get())));
937 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
939 OnPropertyChanged(property
, *value
));
942 base::ListValue
* FakeShillManagerClient::GetListProperty(
943 const std::string
& property
) {
944 base::ListValue
* list_property
= NULL
;
945 if (!stub_properties_
.GetListWithoutPathExpansion(
946 property
, &list_property
)) {
947 list_property
= new base::ListValue
;
948 stub_properties_
.SetWithoutPathExpansion(property
, list_property
);
950 return list_property
;
953 bool FakeShillManagerClient::TechnologyEnabled(const std::string
& type
) const {
954 if (type
== shill::kTypeVPN
)
955 return true; // VPN is always "enabled" since there is no associated device
956 if (type
== shill::kTypeEthernetEap
)
958 bool enabled
= false;
959 const base::ListValue
* technologies
;
960 if (stub_properties_
.GetListWithoutPathExpansion(
961 shill::kEnabledTechnologiesProperty
, &technologies
)) {
962 base::StringValue
type_value(type
);
963 if (technologies
->Find(type_value
) != technologies
->end())
969 void FakeShillManagerClient::SetTechnologyEnabled(
970 const std::string
& type
,
971 const base::Closure
& callback
,
973 base::ListValue
* enabled_list
=
974 GetListProperty(shill::kEnabledTechnologiesProperty
);
976 enabled_list
->AppendIfNotPresent(new base::StringValue(type
));
978 enabled_list
->Remove(base::StringValue(type
), NULL
);
979 CallNotifyObserversPropertyChanged(
980 shill::kEnabledTechnologiesProperty
);
981 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
982 // May affect available services.
983 SortManagerServices(true);
986 base::ListValue
* FakeShillManagerClient::GetEnabledServiceList(
987 const std::string
& property
) const {
988 base::ListValue
* new_service_list
= new base::ListValue
;
989 const base::ListValue
* service_list
;
990 if (stub_properties_
.GetListWithoutPathExpansion(property
, &service_list
)) {
991 ShillServiceClient::TestInterface
* service_client
=
992 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
993 for (base::ListValue::const_iterator iter
= service_list
->begin();
994 iter
!= service_list
->end(); ++iter
) {
995 std::string service_path
;
996 if (!(*iter
)->GetAsString(&service_path
))
998 const base::DictionaryValue
* properties
=
999 service_client
->GetServiceProperties(service_path
);
1001 LOG(ERROR
) << "Properties not found for service: " << service_path
;
1005 properties
->GetString(shill::kTypeProperty
, &type
);
1006 if (TechnologyEnabled(type
))
1007 new_service_list
->Append((*iter
)->DeepCopy());
1010 return new_service_list
;
1013 void FakeShillManagerClient::ScanCompleted(const std::string
& device_path
,
1014 const base::Closure
& callback
) {
1015 if (!device_path
.empty()) {
1016 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
1017 SetDeviceProperty(device_path
,
1018 shill::kScanningProperty
,
1019 base::FundamentalValue(false));
1021 VLOG(2) << "ScanCompleted";
1022 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
1023 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
1026 void FakeShillManagerClient::ParseCommandLineSwitch() {
1028 SetInitialNetworkState(shill::kTypeEthernet
, shill::kStateOnline
);
1029 SetInitialNetworkState(shill::kTypeWifi
, shill::kStateOnline
);
1030 SetInitialNetworkState(shill::kTypeCellular
, shill::kStateIdle
);
1031 SetInitialNetworkState(shill::kTypeVPN
, shill::kStateIdle
);
1033 // Parse additional options
1034 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
1035 if (!command_line
->HasSwitch(switches::kShillStub
))
1038 std::string option_str
=
1039 command_line
->GetSwitchValueASCII(switches::kShillStub
);
1040 VLOG(1) << "Parsing command line:" << option_str
;
1041 base::StringPairs string_pairs
;
1042 base::SplitStringIntoKeyValuePairs(option_str
, '=', ',', &string_pairs
);
1043 for (base::StringPairs::iterator iter
= string_pairs
.begin();
1044 iter
!= string_pairs
.end(); ++iter
) {
1045 ParseOption((*iter
).first
, (*iter
).second
);
1049 bool FakeShillManagerClient::ParseOption(const std::string
& arg0
,
1050 const std::string
& arg1
) {
1051 VLOG(1) << "Parsing command line option: '" << arg0
<< "=" << arg1
<< "'";
1052 if ((arg0
== "clear" || arg0
== "reset") && arg1
== "1") {
1053 shill_initial_state_map_
.clear();
1055 } else if (arg0
== "interactive") {
1058 base::StringToInt(arg1
, &seconds
);
1059 interactive_delay_
= seconds
;
1061 } else if (arg0
== "sim_lock") {
1062 bool locked
= (arg1
== "1") ? true : false;
1063 base::DictionaryValue
* simlock_dict
= new base::DictionaryValue
;
1064 simlock_dict
->Set(shill::kSIMLockEnabledProperty
,
1065 new base::FundamentalValue(locked
));
1066 std::string lock_type
= shill::kSIMLockPin
;
1067 simlock_dict
->SetString(shill::kSIMLockTypeProperty
, lock_type
);
1068 simlock_dict
->SetInteger(shill::kSIMLockRetriesLeftProperty
, 5);
1070 shill_device_property_map_
[shill::kTypeCellular
]
1071 [shill::kSIMLockStatusProperty
] = simlock_dict
;
1072 shill_device_property_map_
1073 [shill::kTypeCellular
][shill::kTechnologyFamilyProperty
] =
1074 new base::StringValue(shill::kNetworkTechnologyGsm
);
1076 } else if (arg0
== "tdls_busy") {
1078 base::StringToInt(arg1
, &s_tdls_busy_count
);
1080 s_tdls_busy_count
= 1;
1082 } else if (arg0
== "roaming") {
1083 // "home", "roaming", or "required"
1084 roaming_state_
= arg1
;
1087 return SetInitialNetworkState(arg0
, arg1
);
1090 bool FakeShillManagerClient::SetInitialNetworkState(std::string type_arg
,
1091 std::string state_arg
) {
1092 int state_arg_as_int
= -1;
1093 base::StringToInt(state_arg
, &state_arg_as_int
);
1096 if (state_arg
.empty() || state_arg
== "1" || state_arg
== "on" ||
1097 state_arg
== "enabled" || state_arg
== "connected" ||
1098 state_arg
== "online") {
1099 // Enabled and connected (default value)
1100 state
= shill::kStateOnline
;
1101 } else if (state_arg
== "0" || state_arg
== "off" ||
1102 state_arg
== "inactive" || state_arg
== shill::kStateIdle
) {
1103 // Technology enabled, services are created but are not connected.
1104 state
= shill::kStateIdle
;
1105 } else if (type_arg
== shill::kTypeWifi
&& state_arg_as_int
> 1) {
1106 // Enabled and connected, add extra wifi networks.
1107 state
= shill::kStateOnline
;
1108 s_extra_wifi_networks
= state_arg_as_int
- 1;
1109 } else if (state_arg
== "disabled" || state_arg
== "disconnect") {
1110 // Technology disabled but available, services created but not connected.
1111 state
= kNetworkDisabled
;
1112 } else if (state_arg
== "none" || state_arg
== "offline") {
1113 // Technology not available, do not create services.
1114 state
= kTechnologyUnavailable
;
1115 } else if (state_arg
== "portal") {
1116 // Technology is enabled, a service is connected and in Portal state.
1117 state
= shill::kStatePortal
;
1118 } else if (state_arg
== "active" || state_arg
== "activated") {
1119 // Technology is enabled, a service is connected and Activated.
1120 state
= kNetworkActivated
;
1121 } else if (type_arg
== shill::kTypeCellular
&&
1122 IsCellularTechnology(state_arg
)) {
1123 state
= shill::kStateOnline
;
1124 cellular_technology_
= state_arg
;
1125 } else if (type_arg
== shill::kTypeCellular
&& state_arg
== "LTEAdvanced") {
1126 // Special case, Shill name contains a ' '.
1127 state
= shill::kStateOnline
;
1128 cellular_technology_
= shill::kNetworkTechnologyLteAdvanced
;
1130 LOG(ERROR
) << "Unrecognized initial state: " << type_arg
<< "="
1136 if (type_arg
== "wireless") {
1137 shill_initial_state_map_
[shill::kTypeWifi
] = state
;
1138 shill_initial_state_map_
[shill::kTypeCellular
] = state
;
1141 // Convenience synonyms.
1142 if (type_arg
== "eth")
1143 type_arg
= shill::kTypeEthernet
;
1145 if (type_arg
!= shill::kTypeEthernet
&&
1146 type_arg
!= shill::kTypeWifi
&&
1147 type_arg
!= shill::kTypeCellular
&&
1148 type_arg
!= shill::kTypeWimax
&&
1149 type_arg
!= shill::kTypeVPN
) {
1150 LOG(WARNING
) << "Unrecognized Shill network type: " << type_arg
;
1154 // Unconnected or disabled ethernet is the same as unavailable.
1155 if (type_arg
== shill::kTypeEthernet
&&
1156 (state
== shill::kStateIdle
|| state
== kNetworkDisabled
)) {
1157 state
= kTechnologyUnavailable
;
1160 shill_initial_state_map_
[type_arg
] = state
;
1164 std::string
FakeShillManagerClient::GetInitialStateForType(
1165 const std::string
& type
,
1167 std::map
<std::string
, std::string
>::const_iterator iter
=
1168 shill_initial_state_map_
.find(type
);
1169 if (iter
== shill_initial_state_map_
.end()) {
1171 return kTechnologyUnavailable
;
1173 std::string state
= iter
->second
;
1174 if (state
== kNetworkDisabled
) {
1176 return shill::kStateIdle
;
1179 if ((state
== shill::kStatePortal
&& type
!= shill::kTypeWifi
) ||
1180 (state
== kNetworkActivated
&& type
!= shill::kTypeCellular
)) {
1181 LOG(WARNING
) << "Invalid state: " << state
<< " for " << type
;
1182 return shill::kStateIdle
;
1187 } // namespace chromeos