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 // Used to compare values for finding entries to erase in a ListValue.
32 // (ListValue only implements a const_iterator version of Find).
34 explicit ValueEquals(const base::Value
* first
) : first_(first
) {}
35 bool operator()(const base::Value
* second
) const {
36 return first_
->Equals(second
);
38 const base::Value
* first_
;
41 // Appends string entries from |service_list_in| whose entries in ServiceClient
42 // have Type |match_type| to one of the output lists based on the entry's State.
43 void AppendServicesForType(
44 const base::ListValue
* service_list_in
,
45 const char* match_type
,
46 bool technology_enabled
,
47 std::vector
<std::string
>* active_service_list_out
,
48 std::vector
<std::string
>* inactive_service_list_out
,
49 std::vector
<std::string
>* disabled_service_list_out
) {
50 ShillServiceClient::TestInterface
* service_client
=
51 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
52 for (base::ListValue::const_iterator iter
= service_list_in
->begin();
53 iter
!= service_list_in
->end(); ++iter
) {
54 std::string service_path
;
55 if (!(*iter
)->GetAsString(&service_path
))
57 const base::DictionaryValue
* properties
=
58 service_client
->GetServiceProperties(service_path
);
60 LOG(ERROR
) << "Properties not found for service: " << service_path
;
64 properties
->GetString(shill::kTypeProperty
, &type
);
65 if (type
!= match_type
)
67 if (!technology_enabled
) {
69 properties
->GetString(shill::kProfileProperty
, &profile
);
74 if (technology_enabled
)
75 properties
->GetBoolean(shill::kVisibleProperty
, &visible
);
77 disabled_service_list_out
->push_back(service_path
);
81 properties
->GetString(shill::kStateProperty
, &state
);
82 if (state
== shill::kStateOnline
||
83 state
== shill::kStateAssociation
||
84 state
== shill::kStateConfiguration
||
85 state
== shill::kStatePortal
||
86 state
== shill::kStateReady
) {
87 active_service_list_out
->push_back(service_path
);
89 inactive_service_list_out
->push_back(service_path
);
94 void LogErrorCallback(const std::string
& error_name
,
95 const std::string
& error_message
) {
96 LOG(ERROR
) << error_name
<< ": " << error_message
;
99 bool IsConnectedState(const std::string
& state
) {
100 return state
== shill::kStateOnline
|| state
== shill::kStatePortal
||
101 state
== shill::kStateReady
;
104 void UpdatePortaledWifiState(const std::string
& service_path
) {
105 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
106 ->SetServiceProperty(service_path
,
107 shill::kStateProperty
,
108 base::StringValue(shill::kStatePortal
));
111 const char* kTechnologyUnavailable
= "unavailable";
112 const char* kNetworkActivated
= "activated";
113 const char* kNetworkDisabled
= "disabled";
118 const char FakeShillManagerClient::kFakeEthernetNetworkPath
[] = "/service/eth1";
120 FakeShillManagerClient::FakeShillManagerClient()
121 : interactive_delay_(0),
122 weak_ptr_factory_(this) {
123 ParseCommandLineSwitch();
126 FakeShillManagerClient::~FakeShillManagerClient() {}
128 // ShillManagerClient overrides.
130 void FakeShillManagerClient::Init(dbus::Bus
* bus
) {}
132 void FakeShillManagerClient::AddPropertyChangedObserver(
133 ShillPropertyChangedObserver
* observer
) {
134 observer_list_
.AddObserver(observer
);
137 void FakeShillManagerClient::RemovePropertyChangedObserver(
138 ShillPropertyChangedObserver
* observer
) {
139 observer_list_
.RemoveObserver(observer
);
142 void FakeShillManagerClient::GetProperties(
143 const DictionaryValueCallback
& callback
) {
144 DVLOG(1) << "Manager.GetProperties";
145 base::MessageLoop::current()->PostTask(
146 FROM_HERE
, base::Bind(
147 &FakeShillManagerClient::PassStubProperties
,
148 weak_ptr_factory_
.GetWeakPtr(),
152 void FakeShillManagerClient::GetNetworksForGeolocation(
153 const DictionaryValueCallback
& callback
) {
154 base::MessageLoop::current()->PostTask(
155 FROM_HERE
, base::Bind(
156 &FakeShillManagerClient::PassStubGeoNetworks
,
157 weak_ptr_factory_
.GetWeakPtr(),
161 void FakeShillManagerClient::SetProperty(const std::string
& name
,
162 const base::Value
& value
,
163 const base::Closure
& callback
,
164 const ErrorCallback
& error_callback
) {
165 DVLOG(2) << "SetProperty: " << name
;
166 stub_properties_
.SetWithoutPathExpansion(name
, value
.DeepCopy());
167 CallNotifyObserversPropertyChanged(name
);
168 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
171 void FakeShillManagerClient::RequestScan(const std::string
& type
,
172 const base::Closure
& callback
,
173 const ErrorCallback
& error_callback
) {
174 // For Stub purposes, default to a Wifi scan.
175 std::string device_type
= shill::kTypeWifi
;
178 ShillDeviceClient::TestInterface
* device_client
=
179 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
180 std::string device_path
= device_client
->GetDevicePathForType(device_type
);
181 if (!device_path
.empty()) {
182 device_client
->SetDeviceProperty(
183 device_path
, shill::kScanningProperty
, base::FundamentalValue(true));
185 base::MessageLoop::current()->PostDelayedTask(
187 base::Bind(&FakeShillManagerClient::ScanCompleted
,
188 weak_ptr_factory_
.GetWeakPtr(),
191 base::TimeDelta::FromSeconds(interactive_delay_
));
194 void FakeShillManagerClient::EnableTechnology(
195 const std::string
& type
,
196 const base::Closure
& callback
,
197 const ErrorCallback
& error_callback
) {
198 base::ListValue
* enabled_list
= NULL
;
199 if (!stub_properties_
.GetListWithoutPathExpansion(
200 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
201 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
202 base::MessageLoop::current()->PostTask(
204 base::Bind(error_callback
, "StubError", "Property not found"));
207 base::MessageLoop::current()->PostDelayedTask(
209 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
210 weak_ptr_factory_
.GetWeakPtr(),
214 base::TimeDelta::FromSeconds(interactive_delay_
));
217 void FakeShillManagerClient::DisableTechnology(
218 const std::string
& type
,
219 const base::Closure
& callback
,
220 const ErrorCallback
& error_callback
) {
221 base::ListValue
* enabled_list
= NULL
;
222 if (!stub_properties_
.GetListWithoutPathExpansion(
223 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
224 base::MessageLoop::current()->PostTask(
226 base::Bind(error_callback
, "StubError", "Property not found"));
229 base::MessageLoop::current()->PostDelayedTask(
231 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
232 weak_ptr_factory_
.GetWeakPtr(),
236 base::TimeDelta::FromSeconds(interactive_delay_
));
239 void FakeShillManagerClient::ConfigureService(
240 const base::DictionaryValue
& properties
,
241 const ObjectPathCallback
& callback
,
242 const ErrorCallback
& error_callback
) {
243 ShillServiceClient::TestInterface
* service_client
=
244 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
248 if (!properties
.GetString(shill::kGuidProperty
, &guid
) ||
249 !properties
.GetString(shill::kTypeProperty
, &type
)) {
250 LOG(ERROR
) << "ConfigureService requires GUID and Type to be defined";
251 // If the properties aren't filled out completely, then just return an empty
253 base::MessageLoop::current()->PostTask(
254 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
258 // For the purposes of this stub, we're going to assume that the GUID property
259 // is set to the service path because we don't want to re-implement Shill's
260 // property matching magic here.
261 std::string service_path
= guid
;
263 std::string ipconfig_path
;
264 properties
.GetString(shill::kIPConfigProperty
, &ipconfig_path
);
266 // Merge the new properties with existing properties, if any.
267 const base::DictionaryValue
* existing_properties
=
268 service_client
->GetServiceProperties(service_path
);
269 if (!existing_properties
) {
270 // Add a new service to the service client stub because none exists, yet.
271 // This calls AddManagerService.
272 service_client
->AddServiceWithIPConfig(service_path
,
276 shill::kStateIdle
, ipconfig_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
)->AppendIfNotPresent(
370 base::Value::CreateStringValue(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(base::Value::CreateStringValue(type
))) {
392 CallNotifyObserversPropertyChanged(
393 shill::kAvailableTechnologiesProperty
);
396 GetListProperty(shill::kEnabledTechnologiesProperty
)->
397 AppendIfNotPresent(base::Value::CreateStringValue(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(base::Value::CreateStringValue(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 DVLOG(2) << "AddManagerService: " << service_path
;
467 GetListProperty(shill::kServiceCompleteListProperty
)->AppendIfNotPresent(
468 base::Value::CreateStringValue(service_path
));
469 SortManagerServices(false);
470 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
471 // SortManagerServices will add the service to Services if it is visible.
472 const base::ListValue
* services
= GetListProperty(shill::kServicesProperty
);
473 if (services
->Find(base::StringValue(service_path
)) != services
->end())
474 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
477 void FakeShillManagerClient::RemoveManagerService(
478 const std::string
& service_path
) {
479 DVLOG(2) << "RemoveManagerService: " << service_path
;
480 base::StringValue
service_path_value(service_path
);
481 GetListProperty(shill::kServiceCompleteListProperty
)->Remove(
482 service_path_value
, NULL
);
483 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
484 if (GetListProperty(shill::kServicesProperty
)->Remove(
485 service_path_value
, NULL
)) {
486 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
490 void FakeShillManagerClient::ClearManagerServices() {
491 DVLOG(1) << "ClearManagerServices";
492 GetListProperty(shill::kServiceCompleteListProperty
)->Clear();
493 GetListProperty(shill::kServicesProperty
)->Clear();
494 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
495 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
498 void FakeShillManagerClient::ServiceStateChanged(
499 const std::string
& service_path
,
500 const std::string
& state
) {
501 if (service_path
== default_service_
&& !IsConnectedState(state
)) {
502 // Default service is no longer connected; clear.
503 default_service_
.clear();
504 base::StringValue
default_service_value(default_service_
);
505 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
509 void FakeShillManagerClient::SortManagerServices(bool notify
) {
510 DVLOG(1) << "SortManagerServices";
511 static const char* ordered_types
[] = {shill::kTypeEthernet
,
513 shill::kTypeCellular
,
517 base::ListValue
* service_list
= GetListProperty(shill::kServicesProperty
);
518 scoped_ptr
<base::ListValue
> prev_service_list(service_list
->DeepCopy());
519 base::ListValue
* complete_list
=
520 GetListProperty(shill::kServiceCompleteListProperty
);
521 if (complete_list
->empty())
523 scoped_ptr
<base::ListValue
> prev_complete_list(complete_list
->DeepCopy());
525 std::vector
<std::string
> active_services
;
526 std::vector
<std::string
> inactive_services
;
527 std::vector
<std::string
> disabled_services
;
528 for (size_t i
= 0; i
< arraysize(ordered_types
); ++i
) {
529 AppendServicesForType(complete_list
,
531 TechnologyEnabled(ordered_types
[i
]),
536 service_list
->Clear();
537 complete_list
->Clear();
538 for (size_t i
= 0; i
< active_services
.size(); ++i
) {
539 complete_list
->AppendString(active_services
[i
]);
540 service_list
->AppendString(active_services
[i
]);
542 for (size_t i
= 0; i
< inactive_services
.size(); ++i
) {
543 complete_list
->AppendString(inactive_services
[i
]);
544 service_list
->AppendString(inactive_services
[i
]);
546 for (size_t i
= 0; i
< disabled_services
.size(); ++i
) {
547 complete_list
->AppendString(disabled_services
[i
]);
551 if (!service_list
->Equals(prev_service_list
.get()))
552 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
553 if (!complete_list
->Equals(prev_complete_list
.get()))
554 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
557 // Set the first active service as the Default service.
558 std::string new_default_service
;
559 if (!active_services
.empty()) {
560 ShillServiceClient::TestInterface
* service_client
=
561 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
562 std::string service_path
= active_services
[0];
563 const base::DictionaryValue
* properties
=
564 service_client
->GetServiceProperties(service_path
);
566 LOG(ERROR
) << "Properties not found for service: " << service_path
;
569 properties
->GetString(shill::kStateProperty
, &state
);
570 if (IsConnectedState(state
))
571 new_default_service
= service_path
;
574 if (default_service_
!= new_default_service
) {
575 default_service_
= new_default_service
;
576 base::StringValue
default_service_value(default_service_
);
577 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
581 int FakeShillManagerClient::GetInteractiveDelay() const {
582 return interactive_delay_
;
585 void FakeShillManagerClient::SetBestServiceToConnect(
586 const std::string
& service_path
) {
587 best_service_
= service_path
;
590 void FakeShillManagerClient::SetupDefaultEnvironment() {
591 DBusThreadManager
* dbus_manager
= DBusThreadManager::Get();
592 ShillServiceClient::TestInterface
* services
=
593 dbus_manager
->GetShillServiceClient()->GetTestInterface();
595 ShillProfileClient::TestInterface
* profiles
=
596 dbus_manager
->GetShillProfileClient()->GetTestInterface();
598 ShillDeviceClient::TestInterface
* devices
=
599 dbus_manager
->GetShillDeviceClient()->GetTestInterface();
601 ShillIPConfigClient::TestInterface
* ip_configs
=
602 dbus_manager
->GetShillIPConfigClient()->GetTestInterface();
605 const std::string shared_profile
= ShillProfileClient::GetSharedProfilePath();
606 profiles
->AddProfile(shared_profile
, std::string());
608 const bool add_to_visible
= true;
614 base::DictionaryValue ipconfig_v4_dictionary
;
615 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
616 shill::kAddressProperty
, "0.0.0.0");
617 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
618 shill::kGatewayProperty
, "0.0.0.1");
619 ipconfig_v4_dictionary
.SetIntegerWithoutPathExpansion(
620 shill::kPrefixlenProperty
, 0);
621 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
622 shill::kMethodProperty
, shill::kTypeIPv4
);
623 ip_configs
->AddIPConfig("ipconfig_v4_path", ipconfig_v4_dictionary
);
624 base::DictionaryValue ipconfig_v6_dictionary
;
625 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
626 shill::kAddressProperty
, "0:0:0:0:0:0:0:0");
627 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
628 shill::kMethodProperty
, shill::kTypeIPv6
);
629 ip_configs
->AddIPConfig("ipconfig_v6_path", ipconfig_v6_dictionary
);
632 state
= GetInitialStateForType(shill::kTypeEthernet
, &enabled
);
633 if (state
== shill::kStateOnline
) {
634 AddTechnology(shill::kTypeEthernet
, enabled
);
636 "/device/eth1", shill::kTypeEthernet
, "stub_eth_device1");
637 devices
->SetDeviceProperty("/device/eth1",
638 shill::kAddressProperty
,
639 base::StringValue("0123456789ab"));
640 base::ListValue eth_ip_configs
;
641 eth_ip_configs
.AppendString("ipconfig_v4_path");
642 eth_ip_configs
.AppendString("ipconfig_v6_path");
643 devices
->SetDeviceProperty("/device/eth1",
644 shill::kIPConfigsProperty
,
646 services
->AddService(kFakeEthernetNetworkPath
, "eth1",
647 shill::kTypeEthernet
,
650 profiles
->AddService(shared_profile
, kFakeEthernetNetworkPath
);
654 state
= GetInitialStateForType(shill::kTypeWifi
, &enabled
);
655 if (state
!= kTechnologyUnavailable
) {
656 bool portaled
= false;
657 if (state
== shill::kStatePortal
) {
659 state
= shill::kStateIdle
;
661 AddTechnology(shill::kTypeWifi
, enabled
);
662 devices
->AddDevice("/device/wifi1", shill::kTypeWifi
, "stub_wifi_device1");
663 devices
->SetDeviceProperty("/device/wifi1",
664 shill::kAddressProperty
,
665 base::StringValue("23456789abc"));
666 base::ListValue wifi_ip_configs
;
667 wifi_ip_configs
.AppendString("ipconfig_v4_path");
668 wifi_ip_configs
.AppendString("ipconfig_v6_path");
669 devices
->SetDeviceProperty("/device/wifi1",
670 shill::kIPConfigsProperty
,
673 services
->AddService("/service/wifi1",
678 services
->SetServiceProperty("/service/wifi1",
679 shill::kSecurityProperty
,
680 base::StringValue(shill::kSecurityWep
));
681 profiles
->AddService(shared_profile
, "/service/wifi1");
683 services
->AddService("/service/wifi2",
688 services
->SetServiceProperty("/service/wifi2",
689 shill::kSecurityProperty
,
690 base::StringValue(shill::kSecurityPsk
));
692 base::FundamentalValue
strength_value(80);
693 services
->SetServiceProperty(
694 "/service/wifi2", shill::kSignalStrengthProperty
, strength_value
);
695 profiles
->AddService(shared_profile
, "/service/wifi2");
698 const std::string kPortaledWifiPath
= "/service/portaled_wifi";
699 services
->AddService(kPortaledWifiPath
,
704 services
->SetServiceProperty(kPortaledWifiPath
,
705 shill::kSecurityProperty
,
706 base::StringValue(shill::kSecurityNone
));
707 services
->SetConnectBehavior(kPortaledWifiPath
,
708 base::Bind(&UpdatePortaledWifiState
,
710 services
->SetServiceProperty(kPortaledWifiPath
,
711 shill::kConnectableProperty
,
712 base::FundamentalValue(true));
713 profiles
->AddService(shared_profile
, kPortaledWifiPath
);
718 state
= GetInitialStateForType(shill::kTypeWimax
, &enabled
);
719 if (state
!= kTechnologyUnavailable
) {
720 AddTechnology(shill::kTypeWimax
, enabled
);
722 "/device/wimax1", shill::kTypeWimax
, "stub_wimax_device1");
724 services
->AddService("/service/wimax1",
729 services
->SetServiceProperty("/service/wimax1",
730 shill::kConnectableProperty
,
731 base::FundamentalValue(true));
735 state
= GetInitialStateForType(shill::kTypeCellular
, &enabled
);
736 if (state
!= kTechnologyUnavailable
) {
737 bool activated
= false;
738 if (state
== kNetworkActivated
) {
740 state
= shill::kStateIdle
;
742 AddTechnology(shill::kTypeCellular
, enabled
);
744 "/device/cellular1", shill::kTypeCellular
, "stub_cellular_device1");
745 devices
->SetDeviceProperty("/device/cellular1",
746 shill::kCarrierProperty
,
747 base::StringValue(shill::kCarrierSprint
));
749 services
->AddService("/service/cellular1",
751 shill::kTypeCellular
,
754 base::StringValue
technology_value(shill::kNetworkTechnologyGsm
);
755 services
->SetServiceProperty("/service/cellular1",
756 shill::kNetworkTechnologyProperty
,
760 services
->SetServiceProperty(
761 "/service/cellular1",
762 shill::kActivationStateProperty
,
763 base::StringValue(shill::kActivationStateActivated
));
764 services
->SetServiceProperty("/service/cellular1",
765 shill::kConnectableProperty
,
766 base::FundamentalValue(true));
768 services
->SetServiceProperty(
769 "/service/cellular1",
770 shill::kActivationStateProperty
,
771 base::StringValue(shill::kActivationStateNotActivated
));
774 services
->SetServiceProperty("/service/cellular1",
775 shill::kRoamingStateProperty
,
776 base::StringValue(shill::kRoamingStateHome
));
780 state
= GetInitialStateForType(shill::kTypeVPN
, &enabled
);
781 if (state
!= kTechnologyUnavailable
) {
782 // Set the "Provider" dictionary properties. Note: when setting these in
783 // Shill, "Provider.Type", etc keys are used, but when reading the values
784 // "Provider" . "Type", etc keys are used. Here we are setting the values
785 // that will be read (by the UI, tests, etc).
786 base::DictionaryValue provider_properties
;
787 provider_properties
.SetString(shill::kTypeProperty
,
788 shill::kProviderOpenVpn
);
789 provider_properties
.SetString(shill::kHostProperty
, "vpn_host");
791 services
->AddService("/service/vpn1",
796 services
->SetServiceProperty(
797 "/service/vpn1", shill::kProviderProperty
, provider_properties
);
798 profiles
->AddService(shared_profile
, "/service/vpn1");
800 services
->AddService("/service/vpn2",
805 services
->SetServiceProperty(
806 "/service/vpn2", shill::kProviderProperty
, provider_properties
);
809 SortManagerServices(true);
814 void FakeShillManagerClient::PassStubProperties(
815 const DictionaryValueCallback
& callback
) const {
816 scoped_ptr
<base::DictionaryValue
> stub_properties(
817 stub_properties_
.DeepCopy());
818 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, *stub_properties
);
821 void FakeShillManagerClient::PassStubGeoNetworks(
822 const DictionaryValueCallback
& callback
) const {
823 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, stub_geo_networks_
);
826 void FakeShillManagerClient::CallNotifyObserversPropertyChanged(
827 const std::string
& property
) {
828 // Avoid unnecessary delayed task if we have no observers (e.g. during
830 if (!observer_list_
.might_have_observers())
832 base::MessageLoop::current()->PostTask(
834 base::Bind(&FakeShillManagerClient::NotifyObserversPropertyChanged
,
835 weak_ptr_factory_
.GetWeakPtr(),
839 void FakeShillManagerClient::NotifyObserversPropertyChanged(
840 const std::string
& property
) {
841 DVLOG(1) << "NotifyObserversPropertyChanged: " << property
;
842 base::Value
* value
= NULL
;
843 if (!stub_properties_
.GetWithoutPathExpansion(property
, &value
)) {
844 LOG(ERROR
) << "Notify for unknown property: " << property
;
847 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
849 OnPropertyChanged(property
, *value
));
852 base::ListValue
* FakeShillManagerClient::GetListProperty(
853 const std::string
& property
) {
854 base::ListValue
* list_property
= NULL
;
855 if (!stub_properties_
.GetListWithoutPathExpansion(
856 property
, &list_property
)) {
857 list_property
= new base::ListValue
;
858 stub_properties_
.SetWithoutPathExpansion(property
, list_property
);
860 return list_property
;
863 bool FakeShillManagerClient::TechnologyEnabled(const std::string
& type
) const {
864 if (type
== shill::kTypeVPN
)
865 return true; // VPN is always "enabled" since there is no associated device
866 bool enabled
= false;
867 const base::ListValue
* technologies
;
868 if (stub_properties_
.GetListWithoutPathExpansion(
869 shill::kEnabledTechnologiesProperty
, &technologies
)) {
870 base::StringValue
type_value(type
);
871 if (technologies
->Find(type_value
) != technologies
->end())
877 void FakeShillManagerClient::SetTechnologyEnabled(
878 const std::string
& type
,
879 const base::Closure
& callback
,
881 base::ListValue
* enabled_list
=
882 GetListProperty(shill::kEnabledTechnologiesProperty
);
884 enabled_list
->AppendIfNotPresent(new base::StringValue(type
));
886 enabled_list
->Remove(base::StringValue(type
), NULL
);
887 CallNotifyObserversPropertyChanged(
888 shill::kEnabledTechnologiesProperty
);
889 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
890 // May affect available services.
891 SortManagerServices(true);
894 void FakeShillManagerClient::ScanCompleted(const std::string
& device_path
,
895 const base::Closure
& callback
) {
896 if (!device_path
.empty()) {
897 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
898 SetDeviceProperty(device_path
,
899 shill::kScanningProperty
,
900 base::FundamentalValue(false));
902 DVLOG(2) << "ScanCompleted";
903 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty
);
904 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
905 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
908 void FakeShillManagerClient::ParseCommandLineSwitch() {
909 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
910 if (command_line
->HasSwitch(switches::kShillStub
)) {
911 std::string option_str
=
912 command_line
->GetSwitchValueASCII(switches::kShillStub
);
913 base::StringPairs string_pairs
;
914 base::SplitStringIntoKeyValuePairs(option_str
, '=', ',', &string_pairs
);
915 for (base::StringPairs::iterator iter
= string_pairs
.begin();
916 iter
!= string_pairs
.end(); ++iter
) {
917 ParseOption((*iter
).first
, (*iter
).second
);
922 SetInitialNetworkState(shill::kTypeEthernet
, shill::kStateOnline
);
923 SetInitialNetworkState(shill::kTypeWifi
, shill::kStateOnline
);
924 SetInitialNetworkState(shill::kTypeCellular
, shill::kStateIdle
);
925 SetInitialNetworkState(shill::kTypeVPN
, shill::kStateIdle
);
928 bool FakeShillManagerClient::ParseOption(const std::string
& arg0
,
929 const std::string
& arg1
) {
930 if (arg0
== "interactive") {
933 base::StringToInt(arg1
, &seconds
);
934 interactive_delay_
= seconds
;
937 return SetInitialNetworkState(arg0
, arg1
);
940 bool FakeShillManagerClient::SetInitialNetworkState(std::string type_arg
,
941 std::string state_arg
) {
943 state_arg
= StringToLowerASCII(state_arg
);
944 if (state_arg
.empty() || state_arg
== "1" || state_arg
== "on" ||
945 state_arg
== "enabled" || state_arg
== "connected" ||
946 state_arg
== "online") {
947 // Enabled and connected (default value)
948 state
= shill::kStateOnline
;
949 } else if (state_arg
== "0" || state_arg
== "off" ||
950 state_arg
== "inactive" || state_arg
== shill::kStateIdle
) {
951 // Technology enabled, services are created but are not connected.
952 state
= shill::kStateIdle
;
953 } else if (state_arg
== "disabled" || state_arg
== "disconnect") {
954 // Technology disabled but available, services created but not connected.
955 state
= kNetworkDisabled
;
956 } else if (state_arg
== "none" || state_arg
== "offline") {
957 // Technology not available, do not create services.
958 state
= kTechnologyUnavailable
;
959 } else if (state_arg
== "portal") {
960 // Technology is enabled, a service is connected and in Portal state.
961 state
= shill::kStatePortal
;
962 } else if (state_arg
== "active" || state_arg
== "activated") {
963 // Technology is enabled, a service is connected and Activated.
964 state
= kNetworkActivated
;
966 LOG(ERROR
) << "Unrecognized initial state: " << state_arg
;
970 type_arg
= StringToLowerASCII(type_arg
);
972 if (type_arg
== "wireless") {
973 shill_initial_state_map_
[shill::kTypeWifi
] = state
;
974 shill_initial_state_map_
[shill::kTypeCellular
] = state
;
977 // Convenience synonyms.
978 if (type_arg
== "eth")
979 type_arg
= shill::kTypeEthernet
;
981 if (type_arg
!= shill::kTypeEthernet
&&
982 type_arg
!= shill::kTypeWifi
&&
983 type_arg
!= shill::kTypeCellular
&&
984 type_arg
!= shill::kTypeWimax
&&
985 type_arg
!= shill::kTypeVPN
) {
986 LOG(WARNING
) << "Unrecognized Shill network type: " << type_arg
;
990 // Unconnected or disabled ethernet is the same as unavailable.
991 if (type_arg
== shill::kTypeEthernet
&&
992 (state
== shill::kStateIdle
|| state
== kNetworkDisabled
)) {
993 state
= kTechnologyUnavailable
;
996 shill_initial_state_map_
[type_arg
] = state
;
1000 std::string
FakeShillManagerClient::GetInitialStateForType(
1001 const std::string
& type
,
1003 std::map
<std::string
, std::string
>::const_iterator iter
=
1004 shill_initial_state_map_
.find(type
);
1005 if (iter
== shill_initial_state_map_
.end()) {
1007 return kTechnologyUnavailable
;
1009 std::string state
= iter
->second
;
1010 if (state
== kNetworkDisabled
) {
1012 return shill::kStateIdle
;
1015 if ((state
== shill::kStatePortal
&& type
!= shill::kTypeWifi
) ||
1016 (state
== kNetworkActivated
&& type
!= shill::kTypeCellular
)) {
1017 LOG(WARNING
) << "Invalid state: " << state
<< " for " << type
;
1018 return shill::kStateIdle
;
1023 } // namespace chromeos