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 either an active list or an inactive list
43 // based on the entry's State.
44 void AppendServicesForType(
45 const base::ListValue
* service_list_in
,
46 const char* match_type
,
47 std::vector
<std::string
>* active_service_list_out
,
48 std::vector
<std::string
>* inactive_service_list_out
) {
49 ShillServiceClient::TestInterface
* service_client
=
50 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
51 for (base::ListValue::const_iterator iter
= service_list_in
->begin();
52 iter
!= service_list_in
->end(); ++iter
) {
53 std::string service_path
;
54 if (!(*iter
)->GetAsString(&service_path
))
56 const base::DictionaryValue
* properties
=
57 service_client
->GetServiceProperties(service_path
);
59 LOG(ERROR
) << "Properties not found for service: " << service_path
;
63 properties
->GetString(shill::kTypeProperty
, &type
);
64 if (type
!= match_type
)
67 properties
->GetString(shill::kStateProperty
, &state
);
68 if (state
== shill::kStateOnline
||
69 state
== shill::kStateAssociation
||
70 state
== shill::kStateConfiguration
||
71 state
== shill::kStatePortal
||
72 state
== shill::kStateReady
) {
73 active_service_list_out
->push_back(service_path
);
75 inactive_service_list_out
->push_back(service_path
);
80 void LogErrorCallback(const std::string
& error_name
,
81 const std::string
& error_message
) {
82 LOG(ERROR
) << error_name
<< ": " << error_message
;
85 bool IsConnectedState(const std::string
& state
) {
86 return state
== shill::kStateOnline
|| state
== shill::kStatePortal
||
87 state
== shill::kStateReady
;
90 void UpdatePortaledWifiState(const std::string
& service_path
) {
91 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
92 ->SetServiceProperty(service_path
,
93 shill::kStateProperty
,
94 base::StringValue(shill::kStatePortal
));
97 const char* kTechnologyUnavailable
= "unavailable";
98 const char* kNetworkActivated
= "activated";
99 const char* kNetworkDisabled
= "disabled";
103 FakeShillManagerClient::FakeShillManagerClient()
104 : interactive_delay_(0),
105 weak_ptr_factory_(this) {
106 ParseCommandLineSwitch();
109 FakeShillManagerClient::~FakeShillManagerClient() {}
111 // ShillManagerClient overrides.
113 void FakeShillManagerClient::Init(dbus::Bus
* bus
) {}
115 void FakeShillManagerClient::AddPropertyChangedObserver(
116 ShillPropertyChangedObserver
* observer
) {
117 observer_list_
.AddObserver(observer
);
120 void FakeShillManagerClient::RemovePropertyChangedObserver(
121 ShillPropertyChangedObserver
* observer
) {
122 observer_list_
.RemoveObserver(observer
);
125 void FakeShillManagerClient::GetProperties(
126 const DictionaryValueCallback
& callback
) {
127 base::MessageLoop::current()->PostTask(
128 FROM_HERE
, base::Bind(
129 &FakeShillManagerClient::PassStubProperties
,
130 weak_ptr_factory_
.GetWeakPtr(),
134 void FakeShillManagerClient::GetNetworksForGeolocation(
135 const DictionaryValueCallback
& callback
) {
136 base::MessageLoop::current()->PostTask(
137 FROM_HERE
, base::Bind(
138 &FakeShillManagerClient::PassStubGeoNetworks
,
139 weak_ptr_factory_
.GetWeakPtr(),
143 void FakeShillManagerClient::SetProperty(const std::string
& name
,
144 const base::Value
& value
,
145 const base::Closure
& callback
,
146 const ErrorCallback
& error_callback
) {
147 stub_properties_
.SetWithoutPathExpansion(name
, value
.DeepCopy());
148 CallNotifyObserversPropertyChanged(name
);
149 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
152 void FakeShillManagerClient::RequestScan(const std::string
& type
,
153 const base::Closure
& callback
,
154 const ErrorCallback
& error_callback
) {
155 // For Stub purposes, default to a Wifi scan.
156 std::string device_type
= shill::kTypeWifi
;
159 ShillDeviceClient::TestInterface
* device_client
=
160 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
161 std::string device_path
= device_client
->GetDevicePathForType(device_type
);
162 if (!device_path
.empty()) {
163 device_client
->SetDeviceProperty(
164 device_path
, shill::kScanningProperty
, base::FundamentalValue(true));
166 base::MessageLoop::current()->PostDelayedTask(
168 base::Bind(&FakeShillManagerClient::ScanCompleted
,
169 weak_ptr_factory_
.GetWeakPtr(),
172 base::TimeDelta::FromSeconds(interactive_delay_
));
175 void FakeShillManagerClient::EnableTechnology(
176 const std::string
& type
,
177 const base::Closure
& callback
,
178 const ErrorCallback
& error_callback
) {
179 base::ListValue
* enabled_list
= NULL
;
180 if (!stub_properties_
.GetListWithoutPathExpansion(
181 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
182 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
183 base::MessageLoop::current()->PostTask(
185 base::Bind(error_callback
, "StubError", "Property not found"));
188 base::MessageLoop::current()->PostDelayedTask(
190 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
191 weak_ptr_factory_
.GetWeakPtr(),
195 base::TimeDelta::FromSeconds(interactive_delay_
));
198 void FakeShillManagerClient::DisableTechnology(
199 const std::string
& type
,
200 const base::Closure
& callback
,
201 const ErrorCallback
& error_callback
) {
202 base::ListValue
* enabled_list
= NULL
;
203 if (!stub_properties_
.GetListWithoutPathExpansion(
204 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
205 base::MessageLoop::current()->PostTask(
207 base::Bind(error_callback
, "StubError", "Property not found"));
210 base::MessageLoop::current()->PostDelayedTask(
212 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
213 weak_ptr_factory_
.GetWeakPtr(),
217 base::TimeDelta::FromSeconds(interactive_delay_
));
220 void FakeShillManagerClient::ConfigureService(
221 const base::DictionaryValue
& properties
,
222 const ObjectPathCallback
& callback
,
223 const ErrorCallback
& error_callback
) {
224 ShillServiceClient::TestInterface
* service_client
=
225 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
229 if (!properties
.GetString(shill::kGuidProperty
, &guid
) ||
230 !properties
.GetString(shill::kTypeProperty
, &type
)) {
231 LOG(ERROR
) << "ConfigureService requires GUID and Type to be defined";
232 // If the properties aren't filled out completely, then just return an empty
234 base::MessageLoop::current()->PostTask(
235 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
239 // For the purposes of this stub, we're going to assume that the GUID property
240 // is set to the service path because we don't want to re-implement Shill's
241 // property matching magic here.
242 std::string service_path
= guid
;
244 std::string ipconfig_path
;
245 properties
.GetString(shill::kIPConfigProperty
, &ipconfig_path
);
247 // Merge the new properties with existing properties, if any.
248 const base::DictionaryValue
* existing_properties
=
249 service_client
->GetServiceProperties(service_path
);
250 if (!existing_properties
) {
251 // Add a new service to the service client stub because none exists, yet.
252 // This calls AddManagerService.
253 service_client
->AddServiceWithIPConfig(service_path
,
257 shill::kStateIdle
, ipconfig_path
,
260 existing_properties
= service_client
->GetServiceProperties(service_path
);
263 scoped_ptr
<base::DictionaryValue
> merged_properties(
264 existing_properties
->DeepCopy());
265 merged_properties
->MergeDictionary(&properties
);
267 // Now set all the properties.
268 for (base::DictionaryValue::Iterator
iter(*merged_properties
);
269 !iter
.IsAtEnd(); iter
.Advance()) {
270 service_client
->SetServiceProperty(service_path
, iter
.key(), iter
.value());
273 // If the Profile property is set, add it to ProfileClient.
274 std::string profile_path
;
275 merged_properties
->GetStringWithoutPathExpansion(shill::kProfileProperty
,
277 if (!profile_path
.empty()) {
278 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface()->
279 AddService(profile_path
, service_path
);
282 base::MessageLoop::current()->PostTask(
283 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath(service_path
)));
286 void FakeShillManagerClient::ConfigureServiceForProfile(
287 const dbus::ObjectPath
& profile_path
,
288 const base::DictionaryValue
& properties
,
289 const ObjectPathCallback
& callback
,
290 const ErrorCallback
& error_callback
) {
291 std::string profile_property
;
292 properties
.GetStringWithoutPathExpansion(shill::kProfileProperty
,
294 CHECK(profile_property
== profile_path
.value());
295 ConfigureService(properties
, callback
, error_callback
);
299 void FakeShillManagerClient::GetService(
300 const base::DictionaryValue
& properties
,
301 const ObjectPathCallback
& callback
,
302 const ErrorCallback
& error_callback
) {
303 base::MessageLoop::current()->PostTask(
304 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
307 void FakeShillManagerClient::VerifyDestination(
308 const VerificationProperties
& properties
,
309 const BooleanCallback
& callback
,
310 const ErrorCallback
& error_callback
) {
311 base::MessageLoop::current()->PostTask(FROM_HERE
, base::Bind(callback
, true));
314 void FakeShillManagerClient::VerifyAndEncryptCredentials(
315 const VerificationProperties
& properties
,
316 const std::string
& service_path
,
317 const StringCallback
& callback
,
318 const ErrorCallback
& error_callback
) {
319 base::MessageLoop::current()->PostTask(
320 FROM_HERE
, base::Bind(callback
, "encrypted_credentials"));
323 void FakeShillManagerClient::VerifyAndEncryptData(
324 const VerificationProperties
& properties
,
325 const std::string
& data
,
326 const StringCallback
& callback
,
327 const ErrorCallback
& error_callback
) {
328 base::MessageLoop::current()->PostTask(
329 FROM_HERE
, base::Bind(callback
, "encrypted_data"));
332 void FakeShillManagerClient::ConnectToBestServices(
333 const base::Closure
& callback
,
334 const ErrorCallback
& error_callback
) {
335 if (best_service_
.empty()) {
336 VLOG(1) << "No 'best' service set.";
340 DBusThreadManager::Get()->GetShillServiceClient()->Connect(
341 dbus::ObjectPath(best_service_
), callback
, error_callback
);
344 ShillManagerClient::TestInterface
* FakeShillManagerClient::GetTestInterface() {
348 // ShillManagerClient::TestInterface overrides.
350 void FakeShillManagerClient::AddDevice(const std::string
& device_path
) {
351 if (GetListProperty(shill::kDevicesProperty
)->AppendIfNotPresent(
352 base::Value::CreateStringValue(device_path
))) {
353 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
357 void FakeShillManagerClient::RemoveDevice(const std::string
& device_path
) {
358 base::StringValue
device_path_value(device_path
);
359 if (GetListProperty(shill::kDevicesProperty
)->Remove(
360 device_path_value
, NULL
)) {
361 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
365 void FakeShillManagerClient::ClearDevices() {
366 GetListProperty(shill::kDevicesProperty
)->Clear();
367 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
370 void FakeShillManagerClient::AddTechnology(const std::string
& type
,
372 if (GetListProperty(shill::kAvailableTechnologiesProperty
)->
373 AppendIfNotPresent(base::Value::CreateStringValue(type
))) {
374 CallNotifyObserversPropertyChanged(
375 shill::kAvailableTechnologiesProperty
);
378 GetListProperty(shill::kEnabledTechnologiesProperty
)->
379 AppendIfNotPresent(base::Value::CreateStringValue(type
))) {
380 CallNotifyObserversPropertyChanged(
381 shill::kEnabledTechnologiesProperty
);
385 void FakeShillManagerClient::RemoveTechnology(const std::string
& type
) {
386 base::StringValue
type_value(type
);
387 if (GetListProperty(shill::kAvailableTechnologiesProperty
)->Remove(
389 CallNotifyObserversPropertyChanged(
390 shill::kAvailableTechnologiesProperty
);
392 if (GetListProperty(shill::kEnabledTechnologiesProperty
)->Remove(
394 CallNotifyObserversPropertyChanged(
395 shill::kEnabledTechnologiesProperty
);
399 void FakeShillManagerClient::SetTechnologyInitializing(const std::string
& type
,
402 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)->
403 AppendIfNotPresent(base::Value::CreateStringValue(type
))) {
404 CallNotifyObserversPropertyChanged(
405 shill::kUninitializedTechnologiesProperty
);
408 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)->Remove(
409 base::StringValue(type
), NULL
)) {
410 CallNotifyObserversPropertyChanged(
411 shill::kUninitializedTechnologiesProperty
);
416 void FakeShillManagerClient::AddGeoNetwork(
417 const std::string
& technology
,
418 const base::DictionaryValue
& network
) {
419 base::ListValue
* list_value
= NULL
;
420 if (!stub_geo_networks_
.GetListWithoutPathExpansion(technology
,
422 list_value
= new base::ListValue
;
423 stub_geo_networks_
.SetWithoutPathExpansion(technology
, list_value
);
425 list_value
->Append(network
.DeepCopy());
428 void FakeShillManagerClient::AddProfile(const std::string
& profile_path
) {
429 const char* key
= shill::kProfilesProperty
;
430 if (GetListProperty(key
)
431 ->AppendIfNotPresent(new base::StringValue(profile_path
))) {
432 CallNotifyObserversPropertyChanged(key
);
436 void FakeShillManagerClient::ClearProperties() {
437 stub_properties_
.Clear();
440 void FakeShillManagerClient::SetManagerProperty(const std::string
& key
,
441 const base::Value
& value
) {
442 SetProperty(key
, value
,
443 base::Bind(&base::DoNothing
), base::Bind(&LogErrorCallback
));
446 void FakeShillManagerClient::AddManagerService(const std::string
& service_path
,
447 bool add_to_visible_list
,
448 bool add_to_watch_list
) {
449 // Always add to ServiceCompleteListProperty.
450 GetListProperty(shill::kServiceCompleteListProperty
)->AppendIfNotPresent(
451 base::Value::CreateStringValue(service_path
));
452 // If visible, add to Services and notify if new.
453 if (add_to_visible_list
&&
454 GetListProperty(shill::kServicesProperty
)->AppendIfNotPresent(
455 base::Value::CreateStringValue(service_path
))) {
456 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
458 if (add_to_watch_list
)
459 AddServiceToWatchList(service_path
);
462 void FakeShillManagerClient::RemoveManagerService(
463 const std::string
& service_path
,
464 bool remove_from_complete_list
) {
465 base::StringValue
service_path_value(service_path
);
466 if (remove_from_complete_list
) {
467 GetListProperty(shill::kServiceCompleteListProperty
)->Remove(
468 service_path_value
, NULL
);
470 if (GetListProperty(shill::kServicesProperty
)->Remove(
471 service_path_value
, NULL
)) {
472 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
474 if (GetListProperty(shill::kServiceWatchListProperty
)->Remove(
475 service_path_value
, NULL
)) {
476 CallNotifyObserversPropertyChanged(shill::kServiceWatchListProperty
);
480 void FakeShillManagerClient::ClearManagerServices() {
481 GetListProperty(shill::kServiceCompleteListProperty
)->Clear();
482 GetListProperty(shill::kServicesProperty
)->Clear();
483 GetListProperty(shill::kServiceWatchListProperty
)->Clear();
484 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
485 CallNotifyObserversPropertyChanged(shill::kServiceWatchListProperty
);
488 void FakeShillManagerClient::ServiceStateChanged(
489 const std::string
& service_path
,
490 const std::string
& state
) {
491 if (service_path
== default_service_
&& !IsConnectedState(state
)) {
492 // Default service is no longer connected; clear.
493 default_service_
.clear();
494 base::StringValue
default_service_value(default_service_
);
495 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
499 void FakeShillManagerClient::SortManagerServices() {
500 SortServiceList(shill::kServicesProperty
);
501 SortServiceList(shill::kServiceCompleteListProperty
);
504 void FakeShillManagerClient::SortServiceList(const std::string
& property
) {
505 static const char* ordered_types
[] = {
506 shill::kTypeEthernet
,
508 shill::kTypeCellular
,
513 base::ListValue
* service_list
= GetListProperty(property
);
514 std::vector
<std::string
> active_services
;
515 std::vector
<std::string
> inactive_services
;
516 if (service_list
&& !service_list
->empty()) {
517 for (size_t i
= 0; i
< arraysize(ordered_types
); ++i
) {
518 AppendServicesForType(service_list
, ordered_types
[i
],
519 &active_services
, &inactive_services
);
521 service_list
->Clear();
522 for (size_t i
= 0; i
< active_services
.size(); ++i
)
523 service_list
->AppendString(active_services
[i
]);
524 for (size_t i
= 0; i
< inactive_services
.size(); ++i
)
525 service_list
->AppendString(inactive_services
[i
]);
528 if (property
!= shill::kServicesProperty
)
531 CallNotifyObserversPropertyChanged(property
);
533 // Set the first active service as the Default service.
534 std::string new_default_service
;
535 if (!active_services
.empty()) {
536 ShillServiceClient::TestInterface
* service_client
=
537 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
538 std::string service_path
= active_services
[0];
539 const base::DictionaryValue
* properties
=
540 service_client
->GetServiceProperties(service_path
);
542 LOG(ERROR
) << "Properties not found for service: " << service_path
;
545 properties
->GetString(shill::kStateProperty
, &state
);
546 if (IsConnectedState(state
))
547 new_default_service
= service_path
;
550 if (default_service_
!= new_default_service
) {
551 default_service_
= new_default_service
;
552 base::StringValue
default_service_value(default_service_
);
553 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
557 int FakeShillManagerClient::GetInteractiveDelay() const {
558 return interactive_delay_
;
561 void FakeShillManagerClient::SetBestServiceToConnect(
562 const std::string
& service_path
) {
563 best_service_
= service_path
;
566 void FakeShillManagerClient::SetupDefaultEnvironment() {
567 DBusThreadManager
* dbus_manager
= DBusThreadManager::Get();
568 ShillServiceClient::TestInterface
* services
=
569 dbus_manager
->GetShillServiceClient()->GetTestInterface();
571 ShillProfileClient::TestInterface
* profiles
=
572 dbus_manager
->GetShillProfileClient()->GetTestInterface();
574 ShillDeviceClient::TestInterface
* devices
=
575 dbus_manager
->GetShillDeviceClient()->GetTestInterface();
577 ShillIPConfigClient::TestInterface
* ip_configs
=
578 dbus_manager
->GetShillIPConfigClient()->GetTestInterface();
581 const std::string shared_profile
= ShillProfileClient::GetSharedProfilePath();
582 profiles
->AddProfile(shared_profile
, std::string());
584 const bool add_to_visible
= true;
585 const bool add_to_watchlist
= true;
591 base::DictionaryValue ipconfig_v4_dictionary
;
592 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
593 shill::kAddressProperty
, "0.0.0.0");
594 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
595 shill::kGatewayProperty
, "0.0.0.1");
596 ipconfig_v4_dictionary
.SetIntegerWithoutPathExpansion(
597 shill::kPrefixlenProperty
, 0);
598 ipconfig_v4_dictionary
.SetStringWithoutPathExpansion(
599 shill::kMethodProperty
, shill::kTypeIPv4
);
600 ip_configs
->AddIPConfig("ipconfig_v4_path", ipconfig_v4_dictionary
);
601 base::DictionaryValue ipconfig_v6_dictionary
;
602 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
603 shill::kAddressProperty
, "0:0:0:0:0:0:0:0");
604 ipconfig_v6_dictionary
.SetStringWithoutPathExpansion(
605 shill::kMethodProperty
, shill::kTypeIPv6
);
606 ip_configs
->AddIPConfig("ipconfig_v6_path", ipconfig_v6_dictionary
);
609 state
= GetInitialStateForType(shill::kTypeEthernet
, &enabled
);
610 if (state
== shill::kStateOnline
) {
611 AddTechnology(shill::kTypeEthernet
, enabled
);
613 "/device/eth1", shill::kTypeEthernet
, "stub_eth_device1");
614 devices
->SetDeviceProperty("/device/eth1",
615 shill::kAddressProperty
,
616 base::StringValue("0123456789ab"));
617 base::ListValue eth_ip_configs
;
618 eth_ip_configs
.AppendString("ipconfig_v4_path");
619 eth_ip_configs
.AppendString("ipconfig_v6_path");
620 devices
->SetDeviceProperty("/device/eth1",
621 shill::kIPConfigsProperty
,
623 services
->AddService("eth1", "eth1",
624 shill::kTypeEthernet
,
626 add_to_visible
, add_to_watchlist
);
627 profiles
->AddService(shared_profile
, "eth1");
631 state
= GetInitialStateForType(shill::kTypeWifi
, &enabled
);
632 if (state
!= kTechnologyUnavailable
) {
633 bool portaled
= false;
634 if (state
== shill::kStatePortal
) {
636 state
= shill::kStateIdle
;
638 AddTechnology(shill::kTypeWifi
, enabled
);
639 devices
->AddDevice("/device/wifi1", shill::kTypeWifi
, "stub_wifi_device1");
640 devices
->SetDeviceProperty("/device/wifi1",
641 shill::kAddressProperty
,
642 base::StringValue("23456789abc"));
643 base::ListValue wifi_ip_configs
;
644 wifi_ip_configs
.AppendString("ipconfig_v4_path");
645 wifi_ip_configs
.AppendString("ipconfig_v6_path");
646 devices
->SetDeviceProperty("/device/wifi1",
647 shill::kIPConfigsProperty
,
650 services
->AddService("wifi1",
654 add_to_visible
, add_to_watchlist
);
655 services
->SetServiceProperty("wifi1",
656 shill::kSecurityProperty
,
657 base::StringValue(shill::kSecurityWep
));
658 profiles
->AddService(shared_profile
, "wifi1");
660 services
->AddService("wifi2",
664 add_to_visible
, add_to_watchlist
);
665 services
->SetServiceProperty("wifi2",
666 shill::kSecurityProperty
,
667 base::StringValue(shill::kSecurityPsk
));
669 base::FundamentalValue
strength_value(80);
670 services
->SetServiceProperty(
671 "wifi2", shill::kSignalStrengthProperty
, strength_value
);
672 profiles
->AddService(shared_profile
, "wifi2");
675 const std::string kPortaledWifiPath
= "portaled_wifi";
676 services
->AddService(kPortaledWifiPath
,
680 add_to_visible
, add_to_watchlist
);
681 services
->SetServiceProperty(kPortaledWifiPath
,
682 shill::kSecurityProperty
,
683 base::StringValue(shill::kSecurityNone
));
684 services
->SetConnectBehavior(kPortaledWifiPath
,
685 base::Bind(&UpdatePortaledWifiState
,
687 services
->SetServiceProperty(kPortaledWifiPath
,
688 shill::kConnectableProperty
,
689 base::FundamentalValue(true));
690 profiles
->AddService(shared_profile
, kPortaledWifiPath
);
695 state
= GetInitialStateForType(shill::kTypeWimax
, &enabled
);
696 if (state
!= kTechnologyUnavailable
) {
697 AddTechnology(shill::kTypeWimax
, enabled
);
699 "/device/wimax1", shill::kTypeWimax
, "stub_wimax_device1");
701 services
->AddService("wimax1",
705 add_to_visible
, add_to_watchlist
);
706 services
->SetServiceProperty(
707 "wimax1", shill::kConnectableProperty
, base::FundamentalValue(true));
711 state
= GetInitialStateForType(shill::kTypeCellular
, &enabled
);
712 if (state
!= kTechnologyUnavailable
) {
713 bool activated
= false;
714 if (state
== kNetworkActivated
) {
716 state
= shill::kStateIdle
;
718 AddTechnology(shill::kTypeCellular
, enabled
);
720 "/device/cellular1", shill::kTypeCellular
, "stub_cellular_device1");
721 devices
->SetDeviceProperty("/device/cellular1",
722 shill::kCarrierProperty
,
723 base::StringValue(shill::kCarrierSprint
));
725 services
->AddService("cellular1",
727 shill::kTypeCellular
,
729 add_to_visible
, add_to_watchlist
);
730 base::StringValue
technology_value(shill::kNetworkTechnologyGsm
);
731 services
->SetServiceProperty(
732 "cellular1", shill::kNetworkTechnologyProperty
, technology_value
);
735 services
->SetServiceProperty(
737 shill::kActivationStateProperty
,
738 base::StringValue(shill::kActivationStateActivated
));
739 services
->SetServiceProperty("cellular1",
740 shill::kConnectableProperty
,
741 base::FundamentalValue(true));
743 services
->SetServiceProperty(
745 shill::kActivationStateProperty
,
746 base::StringValue(shill::kActivationStateNotActivated
));
749 services
->SetServiceProperty("cellular1",
750 shill::kRoamingStateProperty
,
751 base::StringValue(shill::kRoamingStateHome
));
755 state
= GetInitialStateForType(shill::kTypeVPN
, &enabled
);
756 if (state
!= kTechnologyUnavailable
) {
757 // Set the "Provider" dictionary properties. Note: when setting these in
758 // Shill, "Provider.Type", etc keys are used, but when reading the values
759 // "Provider" . "Type", etc keys are used. Here we are setting the values
760 // that will be read (by the UI, tests, etc).
761 base::DictionaryValue provider_properties
;
762 provider_properties
.SetString(shill::kTypeProperty
,
763 shill::kProviderOpenVpn
);
764 provider_properties
.SetString(shill::kHostProperty
, "vpn_host");
766 services
->AddService("vpn1",
770 add_to_visible
, add_to_watchlist
);
771 services
->SetServiceProperty(
772 "vpn1", shill::kProviderProperty
, provider_properties
);
773 profiles
->AddService(shared_profile
, "vpn1");
775 services
->AddService("vpn2",
779 add_to_visible
, add_to_watchlist
);
780 services
->SetServiceProperty(
781 "vpn2", shill::kProviderProperty
, provider_properties
);
784 SortManagerServices();
789 void FakeShillManagerClient::AddServiceToWatchList(
790 const std::string
& service_path
) {
791 // Remove and insert the service, moving it to the front of the watch list.
792 GetListProperty(shill::kServiceWatchListProperty
)->Remove(
793 base::StringValue(service_path
), NULL
);
794 GetListProperty(shill::kServiceWatchListProperty
)->Insert(
795 0, base::Value::CreateStringValue(service_path
));
796 CallNotifyObserversPropertyChanged(
797 shill::kServiceWatchListProperty
);
800 void FakeShillManagerClient::PassStubProperties(
801 const DictionaryValueCallback
& callback
) const {
802 scoped_ptr
<base::DictionaryValue
> stub_properties(
803 stub_properties_
.DeepCopy());
804 // Remove disabled services from the list.
805 stub_properties
->SetWithoutPathExpansion(
806 shill::kServicesProperty
,
807 GetEnabledServiceList(shill::kServicesProperty
));
808 stub_properties
->SetWithoutPathExpansion(
809 shill::kServiceWatchListProperty
,
810 GetEnabledServiceList(shill::kServiceWatchListProperty
));
811 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, *stub_properties
);
814 void FakeShillManagerClient::PassStubGeoNetworks(
815 const DictionaryValueCallback
& callback
) const {
816 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, stub_geo_networks_
);
819 void FakeShillManagerClient::CallNotifyObserversPropertyChanged(
820 const std::string
& property
) {
821 // Avoid unnecessary delayed task if we have no observers (e.g. during
823 if (!observer_list_
.might_have_observers())
825 base::MessageLoop::current()->PostTask(
827 base::Bind(&FakeShillManagerClient::NotifyObserversPropertyChanged
,
828 weak_ptr_factory_
.GetWeakPtr(),
832 void FakeShillManagerClient::NotifyObserversPropertyChanged(
833 const std::string
& property
) {
834 if (property
== shill::kServicesProperty
||
835 property
== shill::kServiceWatchListProperty
) {
836 scoped_ptr
<base::ListValue
> services(GetEnabledServiceList(property
));
837 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
839 OnPropertyChanged(property
, *(services
.get())));
842 if (property
== shill::kDevicesProperty
) {
843 base::ListValue
* devices
= NULL
;
844 if (stub_properties_
.GetListWithoutPathExpansion(
845 shill::kDevicesProperty
, &devices
)) {
846 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
848 OnPropertyChanged(property
, *devices
));
852 base::Value
* value
= NULL
;
853 if (!stub_properties_
.GetWithoutPathExpansion(property
, &value
)) {
854 LOG(ERROR
) << "Notify for unknown property: " << property
;
857 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
859 OnPropertyChanged(property
, *value
));
862 base::ListValue
* FakeShillManagerClient::GetListProperty(
863 const std::string
& property
) {
864 base::ListValue
* list_property
= NULL
;
865 if (!stub_properties_
.GetListWithoutPathExpansion(
866 property
, &list_property
)) {
867 list_property
= new base::ListValue
;
868 stub_properties_
.SetWithoutPathExpansion(property
, list_property
);
870 return list_property
;
873 bool FakeShillManagerClient::TechnologyEnabled(const std::string
& type
) const {
874 if (type
== shill::kTypeVPN
)
875 return true; // VPN is always "enabled" since there is no associated device
876 bool enabled
= false;
877 const base::ListValue
* technologies
;
878 if (stub_properties_
.GetListWithoutPathExpansion(
879 shill::kEnabledTechnologiesProperty
, &technologies
)) {
880 base::StringValue
type_value(type
);
881 if (technologies
->Find(type_value
) != technologies
->end())
887 void FakeShillManagerClient::SetTechnologyEnabled(
888 const std::string
& type
,
889 const base::Closure
& callback
,
891 base::ListValue
* enabled_list
=
892 GetListProperty(shill::kEnabledTechnologiesProperty
);
894 enabled_list
->AppendIfNotPresent(new base::StringValue(type
));
896 enabled_list
->Remove(base::StringValue(type
), NULL
);
897 CallNotifyObserversPropertyChanged(
898 shill::kEnabledTechnologiesProperty
);
899 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
900 // May affect available services
901 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
902 CallNotifyObserversPropertyChanged(shill::kServiceWatchListProperty
);
905 base::ListValue
* FakeShillManagerClient::GetEnabledServiceList(
906 const std::string
& property
) const {
907 base::ListValue
* new_service_list
= new base::ListValue
;
908 const base::ListValue
* service_list
;
909 if (stub_properties_
.GetListWithoutPathExpansion(property
, &service_list
)) {
910 ShillServiceClient::TestInterface
* service_client
=
911 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
912 for (base::ListValue::const_iterator iter
= service_list
->begin();
913 iter
!= service_list
->end(); ++iter
) {
914 std::string service_path
;
915 if (!(*iter
)->GetAsString(&service_path
))
917 const base::DictionaryValue
* properties
=
918 service_client
->GetServiceProperties(service_path
);
920 LOG(ERROR
) << "Properties not found for service: " << service_path
;
924 properties
->GetString(shill::kTypeProperty
, &type
);
925 if (TechnologyEnabled(type
))
926 new_service_list
->Append((*iter
)->DeepCopy());
929 return new_service_list
;
932 void FakeShillManagerClient::ScanCompleted(const std::string
& device_path
,
933 const base::Closure
& callback
) {
934 if (!device_path
.empty()) {
935 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
936 SetDeviceProperty(device_path
,
937 shill::kScanningProperty
,
938 base::FundamentalValue(false));
940 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
941 CallNotifyObserversPropertyChanged(shill::kServiceWatchListProperty
);
942 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
945 void FakeShillManagerClient::ParseCommandLineSwitch() {
946 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
947 if (command_line
->HasSwitch(switches::kShillStub
)) {
948 std::string option_str
=
949 command_line
->GetSwitchValueASCII(switches::kShillStub
);
950 base::StringPairs string_pairs
;
951 base::SplitStringIntoKeyValuePairs(option_str
, '=', ',', &string_pairs
);
952 for (base::StringPairs::iterator iter
= string_pairs
.begin();
953 iter
!= string_pairs
.end(); ++iter
) {
954 ParseOption((*iter
).first
, (*iter
).second
);
959 SetInitialNetworkState(shill::kTypeEthernet
, shill::kStateOnline
);
960 SetInitialNetworkState(shill::kTypeWifi
, shill::kStateOnline
);
961 SetInitialNetworkState(shill::kTypeCellular
, shill::kStateIdle
);
962 SetInitialNetworkState(shill::kTypeVPN
, shill::kStateIdle
);
965 bool FakeShillManagerClient::ParseOption(const std::string
& arg0
,
966 const std::string
& arg1
) {
967 if (arg0
== "interactive") {
970 base::StringToInt(arg1
, &seconds
);
971 interactive_delay_
= seconds
;
974 return SetInitialNetworkState(arg0
, arg1
);
977 bool FakeShillManagerClient::SetInitialNetworkState(std::string type_arg
,
978 std::string state_arg
) {
980 state_arg
= StringToLowerASCII(state_arg
);
981 if (state_arg
.empty() || state_arg
== "1" || state_arg
== "on" ||
982 state_arg
== "enabled" || state_arg
== "connected" ||
983 state_arg
== "online") {
984 // Enabled and connected (default value)
985 state
= shill::kStateOnline
;
986 } else if (state_arg
== "0" || state_arg
== "off" ||
987 state_arg
== "inactive" || state_arg
== shill::kStateIdle
) {
988 // Technology enabled, services are created but are not connected.
989 state
= shill::kStateIdle
;
990 } else if (state_arg
== "disabled" || state_arg
== "disconnect") {
991 // Technology disabled but available, services created but not connected.
992 state
= kNetworkDisabled
;
993 } else if (state_arg
== "none" || state_arg
== "offline") {
994 // Technology not available, do not create services.
995 state
= kTechnologyUnavailable
;
996 } else if (state_arg
== "portal") {
997 // Technology is enabled, a service is connected and in Portal state.
998 state
= shill::kStatePortal
;
999 } else if (state_arg
== "active" || state_arg
== "activated") {
1000 // Technology is enabled, a service is connected and Activated.
1001 state
= kNetworkActivated
;
1003 LOG(ERROR
) << "Unrecognized initial state: " << state_arg
;
1007 type_arg
= StringToLowerASCII(type_arg
);
1009 if (type_arg
== "wireless") {
1010 shill_initial_state_map_
[shill::kTypeWifi
] = state
;
1011 shill_initial_state_map_
[shill::kTypeCellular
] = state
;
1014 // Convenience synonyms.
1015 if (type_arg
== "eth")
1016 type_arg
= shill::kTypeEthernet
;
1018 if (type_arg
!= shill::kTypeEthernet
&&
1019 type_arg
!= shill::kTypeWifi
&&
1020 type_arg
!= shill::kTypeCellular
&&
1021 type_arg
!= shill::kTypeWimax
&&
1022 type_arg
!= shill::kTypeVPN
) {
1023 LOG(WARNING
) << "Unrecognized Shill network type: " << type_arg
;
1027 // Unconnected or disabled ethernet is the same as unavailable.
1028 if (type_arg
== shill::kTypeEthernet
&&
1029 (state
== shill::kStateIdle
|| state
== kNetworkDisabled
)) {
1030 state
= kTechnologyUnavailable
;
1033 shill_initial_state_map_
[type_arg
] = state
;
1037 std::string
FakeShillManagerClient::GetInitialStateForType(
1038 const std::string
& type
,
1040 std::map
<std::string
, std::string
>::const_iterator iter
=
1041 shill_initial_state_map_
.find(type
);
1042 if (iter
== shill_initial_state_map_
.end()) {
1044 return kTechnologyUnavailable
;
1046 std::string state
= iter
->second
;
1047 if (state
== kNetworkDisabled
) {
1049 return shill::kStateIdle
;
1052 if ((state
== shill::kStatePortal
&& type
!= shill::kTypeWifi
) ||
1053 (state
== kNetworkActivated
&& type
!= shill::kTypeCellular
)) {
1054 LOG(WARNING
) << "Invalid state: " << state
<< " for " << type
;
1055 return shill::kStateIdle
;
1060 } // namespace chromeos