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_profile_client.h"
18 #include "chromeos/dbus/shill_property_changed_observer.h"
19 #include "chromeos/dbus/shill_service_client.h"
21 #include "dbus/message.h"
22 #include "dbus/object_path.h"
23 #include "dbus/values_util.h"
24 #include "third_party/cros_system_api/dbus/service_constants.h"
30 // Used to compare values for finding entries to erase in a ListValue.
31 // (ListValue only implements a const_iterator version of Find).
33 explicit ValueEquals(const base::Value
* first
) : first_(first
) {}
34 bool operator()(const base::Value
* second
) const {
35 return first_
->Equals(second
);
37 const base::Value
* first_
;
40 // Appends string entries from |service_list_in| whose entries in ServiceClient
41 // have Type |match_type| to either an active list or an inactive list
42 // based on the entry's State.
43 void AppendServicesForType(
44 const base::ListValue
* service_list_in
,
45 const char* match_type
,
46 std::vector
<std::string
>* active_service_list_out
,
47 std::vector
<std::string
>* inactive_service_list_out
) {
48 ShillServiceClient::TestInterface
* service_client
=
49 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
50 for (base::ListValue::const_iterator iter
= service_list_in
->begin();
51 iter
!= service_list_in
->end(); ++iter
) {
52 std::string service_path
;
53 if (!(*iter
)->GetAsString(&service_path
))
55 const base::DictionaryValue
* properties
=
56 service_client
->GetServiceProperties(service_path
);
58 LOG(ERROR
) << "Properties not found for service: " << service_path
;
62 properties
->GetString(shill::kTypeProperty
, &type
);
63 if (type
!= match_type
)
66 properties
->GetString(shill::kStateProperty
, &state
);
67 if (state
== shill::kStateOnline
||
68 state
== shill::kStateAssociation
||
69 state
== shill::kStateConfiguration
||
70 state
== shill::kStatePortal
||
71 state
== shill::kStateReady
) {
72 active_service_list_out
->push_back(service_path
);
74 inactive_service_list_out
->push_back(service_path
);
79 void LogErrorCallback(const std::string
& error_name
,
80 const std::string
& error_message
) {
81 LOG(ERROR
) << error_name
<< ": " << error_message
;
84 bool IsConnectedState(const std::string
& state
) {
85 return state
== shill::kStateOnline
|| state
== shill::kStatePortal
||
86 state
== shill::kStateReady
;
89 void UpdatePortaledWifiState(const std::string
& service_path
) {
90 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
91 ->SetServiceProperty(service_path
,
92 shill::kStateProperty
,
93 base::StringValue(shill::kStatePortal
));
96 const char* kTechnologyUnavailable
= "unavailable";
97 const char* kNetworkActivated
= "activated";
98 const char* kNetworkDisabled
= "disabled";
102 FakeShillManagerClient::FakeShillManagerClient()
103 : interactive_delay_(0),
104 weak_ptr_factory_(this) {
105 ParseCommandLineSwitch();
108 FakeShillManagerClient::~FakeShillManagerClient() {}
110 // ShillManagerClient overrides.
112 void FakeShillManagerClient::Init(dbus::Bus
* bus
) {}
114 void FakeShillManagerClient::AddPropertyChangedObserver(
115 ShillPropertyChangedObserver
* observer
) {
116 observer_list_
.AddObserver(observer
);
119 void FakeShillManagerClient::RemovePropertyChangedObserver(
120 ShillPropertyChangedObserver
* observer
) {
121 observer_list_
.RemoveObserver(observer
);
124 void FakeShillManagerClient::GetProperties(
125 const DictionaryValueCallback
& callback
) {
126 base::MessageLoop::current()->PostTask(
127 FROM_HERE
, base::Bind(
128 &FakeShillManagerClient::PassStubProperties
,
129 weak_ptr_factory_
.GetWeakPtr(),
133 void FakeShillManagerClient::GetNetworksForGeolocation(
134 const DictionaryValueCallback
& callback
) {
135 base::MessageLoop::current()->PostTask(
136 FROM_HERE
, base::Bind(
137 &FakeShillManagerClient::PassStubGeoNetworks
,
138 weak_ptr_factory_
.GetWeakPtr(),
142 void FakeShillManagerClient::SetProperty(const std::string
& name
,
143 const base::Value
& value
,
144 const base::Closure
& callback
,
145 const ErrorCallback
& error_callback
) {
146 stub_properties_
.SetWithoutPathExpansion(name
, value
.DeepCopy());
147 CallNotifyObserversPropertyChanged(name
);
148 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
151 void FakeShillManagerClient::RequestScan(const std::string
& type
,
152 const base::Closure
& callback
,
153 const ErrorCallback
& error_callback
) {
154 // For Stub purposes, default to a Wifi scan.
155 std::string device_type
= shill::kTypeWifi
;
158 ShillDeviceClient::TestInterface
* device_client
=
159 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
160 std::string device_path
= device_client
->GetDevicePathForType(device_type
);
161 if (!device_path
.empty()) {
162 device_client
->SetDeviceProperty(
163 device_path
, shill::kScanningProperty
, base::FundamentalValue(true));
165 base::MessageLoop::current()->PostDelayedTask(
167 base::Bind(&FakeShillManagerClient::ScanCompleted
,
168 weak_ptr_factory_
.GetWeakPtr(),
171 base::TimeDelta::FromSeconds(interactive_delay_
));
174 void FakeShillManagerClient::EnableTechnology(
175 const std::string
& type
,
176 const base::Closure
& callback
,
177 const ErrorCallback
& error_callback
) {
178 base::ListValue
* enabled_list
= NULL
;
179 if (!stub_properties_
.GetListWithoutPathExpansion(
180 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
181 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
182 base::MessageLoop::current()->PostTask(
184 base::Bind(error_callback
, "StubError", "Property not found"));
187 base::MessageLoop::current()->PostDelayedTask(
189 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
190 weak_ptr_factory_
.GetWeakPtr(),
194 base::TimeDelta::FromSeconds(interactive_delay_
));
197 void FakeShillManagerClient::DisableTechnology(
198 const std::string
& type
,
199 const base::Closure
& callback
,
200 const ErrorCallback
& error_callback
) {
201 base::ListValue
* enabled_list
= NULL
;
202 if (!stub_properties_
.GetListWithoutPathExpansion(
203 shill::kAvailableTechnologiesProperty
, &enabled_list
)) {
204 base::MessageLoop::current()->PostTask(
206 base::Bind(error_callback
, "StubError", "Property not found"));
209 base::MessageLoop::current()->PostDelayedTask(
211 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled
,
212 weak_ptr_factory_
.GetWeakPtr(),
216 base::TimeDelta::FromSeconds(interactive_delay_
));
219 void FakeShillManagerClient::ConfigureService(
220 const base::DictionaryValue
& properties
,
221 const ObjectPathCallback
& callback
,
222 const ErrorCallback
& error_callback
) {
223 ShillServiceClient::TestInterface
* service_client
=
224 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
228 if (!properties
.GetString(shill::kGuidProperty
, &guid
) ||
229 !properties
.GetString(shill::kTypeProperty
, &type
)) {
230 LOG(ERROR
) << "ConfigureService requires GUID and Type to be defined";
231 // If the properties aren't filled out completely, then just return an empty
233 base::MessageLoop::current()->PostTask(
234 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
238 // For the purposes of this stub, we're going to assume that the GUID property
239 // is set to the service path because we don't want to re-implement Shill's
240 // property matching magic here.
241 std::string service_path
= guid
;
243 std::string ipconfig_path
;
244 properties
.GetString(shill::kIPConfigProperty
, &ipconfig_path
);
246 // Merge the new properties with existing properties, if any.
247 const base::DictionaryValue
* existing_properties
=
248 service_client
->GetServiceProperties(service_path
);
249 if (!existing_properties
) {
250 // Add a new service to the service client stub because none exists, yet.
251 // This calls AddManagerService.
252 service_client
->AddServiceWithIPConfig(service_path
, guid
, type
,
253 shill::kStateIdle
, ipconfig_path
,
256 existing_properties
= service_client
->GetServiceProperties(service_path
);
259 scoped_ptr
<base::DictionaryValue
> merged_properties(
260 existing_properties
->DeepCopy());
261 merged_properties
->MergeDictionary(&properties
);
263 // Now set all the properties.
264 for (base::DictionaryValue::Iterator
iter(*merged_properties
);
265 !iter
.IsAtEnd(); iter
.Advance()) {
266 service_client
->SetServiceProperty(service_path
, iter
.key(), iter
.value());
269 // If the Profile property is set, add it to ProfileClient.
270 std::string profile_path
;
271 merged_properties
->GetStringWithoutPathExpansion(shill::kProfileProperty
,
273 if (!profile_path
.empty()) {
274 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface()->
275 AddService(profile_path
, service_path
);
278 base::MessageLoop::current()->PostTask(
279 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath(service_path
)));
282 void FakeShillManagerClient::ConfigureServiceForProfile(
283 const dbus::ObjectPath
& profile_path
,
284 const base::DictionaryValue
& properties
,
285 const ObjectPathCallback
& callback
,
286 const ErrorCallback
& error_callback
) {
287 std::string profile_property
;
288 properties
.GetStringWithoutPathExpansion(shill::kProfileProperty
,
290 CHECK(profile_property
== profile_path
.value());
291 ConfigureService(properties
, callback
, error_callback
);
295 void FakeShillManagerClient::GetService(
296 const base::DictionaryValue
& properties
,
297 const ObjectPathCallback
& callback
,
298 const ErrorCallback
& error_callback
) {
299 base::MessageLoop::current()->PostTask(
300 FROM_HERE
, base::Bind(callback
, dbus::ObjectPath()));
303 void FakeShillManagerClient::VerifyDestination(
304 const VerificationProperties
& properties
,
305 const BooleanCallback
& callback
,
306 const ErrorCallback
& error_callback
) {
307 base::MessageLoop::current()->PostTask(FROM_HERE
, base::Bind(callback
, true));
310 void FakeShillManagerClient::VerifyAndEncryptCredentials(
311 const VerificationProperties
& properties
,
312 const std::string
& service_path
,
313 const StringCallback
& callback
,
314 const ErrorCallback
& error_callback
) {
315 base::MessageLoop::current()->PostTask(
316 FROM_HERE
, base::Bind(callback
, "encrypted_credentials"));
319 void FakeShillManagerClient::VerifyAndEncryptData(
320 const VerificationProperties
& properties
,
321 const std::string
& data
,
322 const StringCallback
& callback
,
323 const ErrorCallback
& error_callback
) {
324 base::MessageLoop::current()->PostTask(
325 FROM_HERE
, base::Bind(callback
, "encrypted_data"));
328 void FakeShillManagerClient::ConnectToBestServices(
329 const base::Closure
& callback
,
330 const ErrorCallback
& error_callback
) {
333 ShillManagerClient::TestInterface
* FakeShillManagerClient::GetTestInterface() {
337 // ShillManagerClient::TestInterface overrides.
339 void FakeShillManagerClient::AddDevice(const std::string
& device_path
) {
340 if (GetListProperty(shill::kDevicesProperty
)->AppendIfNotPresent(
341 base::Value::CreateStringValue(device_path
))) {
342 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
346 void FakeShillManagerClient::RemoveDevice(const std::string
& device_path
) {
347 base::StringValue
device_path_value(device_path
);
348 if (GetListProperty(shill::kDevicesProperty
)->Remove(
349 device_path_value
, NULL
)) {
350 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
354 void FakeShillManagerClient::ClearDevices() {
355 GetListProperty(shill::kDevicesProperty
)->Clear();
356 CallNotifyObserversPropertyChanged(shill::kDevicesProperty
);
359 void FakeShillManagerClient::AddTechnology(const std::string
& type
,
361 if (GetListProperty(shill::kAvailableTechnologiesProperty
)->
362 AppendIfNotPresent(base::Value::CreateStringValue(type
))) {
363 CallNotifyObserversPropertyChanged(
364 shill::kAvailableTechnologiesProperty
);
367 GetListProperty(shill::kEnabledTechnologiesProperty
)->
368 AppendIfNotPresent(base::Value::CreateStringValue(type
))) {
369 CallNotifyObserversPropertyChanged(
370 shill::kEnabledTechnologiesProperty
);
374 void FakeShillManagerClient::RemoveTechnology(const std::string
& type
) {
375 base::StringValue
type_value(type
);
376 if (GetListProperty(shill::kAvailableTechnologiesProperty
)->Remove(
378 CallNotifyObserversPropertyChanged(
379 shill::kAvailableTechnologiesProperty
);
381 if (GetListProperty(shill::kEnabledTechnologiesProperty
)->Remove(
383 CallNotifyObserversPropertyChanged(
384 shill::kEnabledTechnologiesProperty
);
388 void FakeShillManagerClient::SetTechnologyInitializing(const std::string
& type
,
391 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)->
392 AppendIfNotPresent(base::Value::CreateStringValue(type
))) {
393 CallNotifyObserversPropertyChanged(
394 shill::kUninitializedTechnologiesProperty
);
397 if (GetListProperty(shill::kUninitializedTechnologiesProperty
)->Remove(
398 base::StringValue(type
), NULL
)) {
399 CallNotifyObserversPropertyChanged(
400 shill::kUninitializedTechnologiesProperty
);
405 void FakeShillManagerClient::AddGeoNetwork(
406 const std::string
& technology
,
407 const base::DictionaryValue
& network
) {
408 base::ListValue
* list_value
= NULL
;
409 if (!stub_geo_networks_
.GetListWithoutPathExpansion(technology
,
411 list_value
= new base::ListValue
;
412 stub_geo_networks_
.SetWithoutPathExpansion(technology
, list_value
);
414 list_value
->Append(network
.DeepCopy());
417 void FakeShillManagerClient::AddProfile(const std::string
& profile_path
) {
418 const char* key
= shill::kProfilesProperty
;
419 if (GetListProperty(key
)
420 ->AppendIfNotPresent(new base::StringValue(profile_path
))) {
421 CallNotifyObserversPropertyChanged(key
);
425 void FakeShillManagerClient::ClearProperties() {
426 stub_properties_
.Clear();
429 void FakeShillManagerClient::SetManagerProperty(const std::string
& key
,
430 const base::Value
& value
) {
431 SetProperty(key
, value
,
432 base::Bind(&base::DoNothing
), base::Bind(&LogErrorCallback
));
435 void FakeShillManagerClient::AddManagerService(const std::string
& service_path
,
436 bool add_to_visible_list
,
437 bool add_to_watch_list
) {
438 // Always add to ServiceCompleteListProperty.
439 GetListProperty(shill::kServiceCompleteListProperty
)->AppendIfNotPresent(
440 base::Value::CreateStringValue(service_path
));
441 // If visible, add to Services and notify if new.
442 if (add_to_visible_list
&&
443 GetListProperty(shill::kServicesProperty
)->AppendIfNotPresent(
444 base::Value::CreateStringValue(service_path
))) {
445 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
447 if (add_to_watch_list
)
448 AddServiceToWatchList(service_path
);
451 void FakeShillManagerClient::RemoveManagerService(
452 const std::string
& service_path
) {
453 base::StringValue
service_path_value(service_path
);
454 if (GetListProperty(shill::kServicesProperty
)->Remove(
455 service_path_value
, NULL
)) {
456 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
458 GetListProperty(shill::kServiceCompleteListProperty
)->Remove(
459 service_path_value
, NULL
);
460 if (GetListProperty(shill::kServiceWatchListProperty
)->Remove(
461 service_path_value
, NULL
)) {
462 CallNotifyObserversPropertyChanged(
463 shill::kServiceWatchListProperty
);
467 void FakeShillManagerClient::ClearManagerServices() {
468 GetListProperty(shill::kServicesProperty
)->Clear();
469 GetListProperty(shill::kServiceCompleteListProperty
)->Clear();
470 GetListProperty(shill::kServiceWatchListProperty
)->Clear();
471 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
472 CallNotifyObserversPropertyChanged(shill::kServiceWatchListProperty
);
475 void FakeShillManagerClient::ServiceStateChanged(
476 const std::string
& service_path
,
477 const std::string
& state
) {
478 if (service_path
== default_service_
&& !IsConnectedState(state
)) {
479 // Default service is no longer connected; clear.
480 default_service_
.clear();
481 base::StringValue
default_service_value(default_service_
);
482 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
486 void FakeShillManagerClient::SortManagerServices() {
487 static const char* ordered_types
[] = {
488 shill::kTypeEthernet
,
490 shill::kTypeCellular
,
494 base::ListValue
* service_list
= GetListProperty(shill::kServicesProperty
);
495 if (!service_list
|| service_list
->empty()) {
496 if (!default_service_
.empty()) {
497 default_service_
.clear();
498 base::StringValue
empty_value("");
499 SetManagerProperty(shill::kDefaultServiceProperty
, empty_value
);
503 std::vector
<std::string
> active_services
;
504 std::vector
<std::string
> inactive_services
;
505 for (size_t i
= 0; i
< arraysize(ordered_types
); ++i
) {
506 AppendServicesForType(service_list
, ordered_types
[i
],
507 &active_services
, &inactive_services
);
509 service_list
->Clear();
510 for (size_t i
= 0; i
< active_services
.size(); ++i
)
511 service_list
->AppendString(active_services
[i
]);
512 for (size_t i
= 0; i
< inactive_services
.size(); ++i
)
513 service_list
->AppendString(inactive_services
[i
]);
515 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
517 // Set the first active service as the Default service.
518 std::string new_default_service
;
519 if (!active_services
.empty()) {
520 ShillServiceClient::TestInterface
* service_client
=
521 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
522 std::string service_path
= active_services
[0];
523 const base::DictionaryValue
* properties
=
524 service_client
->GetServiceProperties(service_path
);
526 LOG(ERROR
) << "Properties not found for service: " << service_path
;
529 properties
->GetString(shill::kStateProperty
, &state
);
530 if (IsConnectedState(state
))
531 new_default_service
= service_path
;
534 if (default_service_
!= new_default_service
) {
535 default_service_
= new_default_service
;
536 base::StringValue
default_service_value(default_service_
);
537 SetManagerProperty(shill::kDefaultServiceProperty
, default_service_value
);
542 int FakeShillManagerClient::GetInteractiveDelay() const {
543 return interactive_delay_
;
546 void FakeShillManagerClient::SetupDefaultEnvironment() {
547 DBusThreadManager
* dbus_manager
= DBusThreadManager::Get();
548 ShillServiceClient::TestInterface
* services
=
549 dbus_manager
->GetShillServiceClient()->GetTestInterface();
550 ShillProfileClient::TestInterface
* profiles
=
551 dbus_manager
->GetShillProfileClient()->GetTestInterface();
552 ShillDeviceClient::TestInterface
* devices
=
553 dbus_manager
->GetShillDeviceClient()->GetTestInterface();
554 if (!services
|| !profiles
|| !devices
)
557 const std::string shared_profile
= ShillProfileClient::GetSharedProfilePath();
558 profiles
->AddProfile(shared_profile
, std::string());
560 const bool add_to_visible
= true;
561 const bool add_to_watchlist
= true;
567 state
= GetInitialStateForType(shill::kTypeEthernet
, &enabled
);
568 if (state
== shill::kStateOnline
) {
569 AddTechnology(shill::kTypeEthernet
, enabled
);
571 "/device/eth1", shill::kTypeEthernet
, "stub_eth_device1");
572 services
->AddService("eth1", "eth1",
573 shill::kTypeEthernet
,
575 add_to_visible
, add_to_watchlist
);
576 profiles
->AddService(shared_profile
, "eth1");
580 state
= GetInitialStateForType(shill::kTypeWifi
, &enabled
);
581 if (state
!= kTechnologyUnavailable
) {
582 bool portaled
= false;
583 if (state
== shill::kStatePortal
) {
585 state
= shill::kStateIdle
;
587 AddTechnology(shill::kTypeWifi
, enabled
);
588 devices
->AddDevice("/device/wifi1", shill::kTypeWifi
, "stub_wifi_device1");
590 services
->AddService("wifi1",
594 add_to_visible
, add_to_watchlist
);
595 services
->SetServiceProperty("wifi1",
596 shill::kSecurityProperty
,
597 base::StringValue(shill::kSecurityWep
));
598 profiles
->AddService(shared_profile
, "wifi1");
600 services
->AddService("wifi2",
604 add_to_visible
, add_to_watchlist
);
605 services
->SetServiceProperty("wifi2",
606 shill::kSecurityProperty
,
607 base::StringValue(shill::kSecurityPsk
));
609 base::FundamentalValue
strength_value(80);
610 services
->SetServiceProperty(
611 "wifi2", shill::kSignalStrengthProperty
, strength_value
);
612 profiles
->AddService(shared_profile
, "wifi2");
615 const std::string kPortaledWifiPath
= "portaled_wifi";
616 services
->AddService(kPortaledWifiPath
,
620 add_to_visible
, add_to_watchlist
);
621 services
->SetServiceProperty(kPortaledWifiPath
,
622 shill::kSecurityProperty
,
623 base::StringValue(shill::kSecurityNone
));
624 services
->SetConnectBehavior(kPortaledWifiPath
,
625 base::Bind(&UpdatePortaledWifiState
,
627 services
->SetServiceProperty(kPortaledWifiPath
,
628 shill::kConnectableProperty
,
629 base::FundamentalValue(true));
630 profiles
->AddService(shared_profile
, kPortaledWifiPath
);
635 state
= GetInitialStateForType(shill::kTypeWimax
, &enabled
);
636 if (state
!= kTechnologyUnavailable
) {
637 AddTechnology(shill::kTypeWimax
, enabled
);
639 "/device/wimax1", shill::kTypeWimax
, "stub_wimax_device1");
641 services
->AddService("wimax1",
645 add_to_visible
, add_to_watchlist
);
646 services
->SetServiceProperty(
647 "wimax1", shill::kConnectableProperty
, base::FundamentalValue(true));
651 state
= GetInitialStateForType(shill::kTypeCellular
, &enabled
);
652 if (state
!= kTechnologyUnavailable
) {
653 bool activated
= false;
654 if (state
== kNetworkActivated
) {
656 state
= shill::kStateIdle
;
658 AddTechnology(shill::kTypeCellular
, enabled
);
660 "/device/cellular1", shill::kTypeCellular
, "stub_cellular_device1");
661 devices
->SetDeviceProperty("/device/cellular1",
662 shill::kCarrierProperty
,
663 base::StringValue(shill::kCarrierSprint
));
665 services
->AddService("cellular1",
667 shill::kTypeCellular
,
669 add_to_visible
, add_to_watchlist
);
670 base::StringValue
technology_value(shill::kNetworkTechnologyGsm
);
671 services
->SetServiceProperty(
672 "cellular1", shill::kNetworkTechnologyProperty
, technology_value
);
675 services
->SetServiceProperty(
677 shill::kActivationStateProperty
,
678 base::StringValue(shill::kActivationStateActivated
));
679 services
->SetServiceProperty("cellular1",
680 shill::kConnectableProperty
,
681 base::FundamentalValue(true));
683 services
->SetServiceProperty(
685 shill::kActivationStateProperty
,
686 base::StringValue(shill::kActivationStateNotActivated
));
689 services
->SetServiceProperty("cellular1",
690 shill::kRoamingStateProperty
,
691 base::StringValue(shill::kRoamingStateHome
));
695 state
= GetInitialStateForType(shill::kTypeVPN
, &enabled
);
696 if (state
!= kTechnologyUnavailable
) {
697 // Set the "Provider" dictionary properties. Note: when setting these in
698 // Shill, "Provider.Type", etc keys are used, but when reading the values
699 // "Provider" . "Type", etc keys are used. Here we are setting the values
700 // that will be read (by the UI, tests, etc).
701 base::DictionaryValue provider_properties
;
702 provider_properties
.SetString(shill::kTypeProperty
,
703 shill::kProviderOpenVpn
);
704 provider_properties
.SetString(shill::kHostProperty
, "vpn_host");
706 services
->AddService("vpn1",
710 add_to_visible
, add_to_watchlist
);
711 services
->SetServiceProperty(
712 "vpn1", shill::kProviderProperty
, provider_properties
);
713 profiles
->AddService(shared_profile
, "vpn1");
715 services
->AddService("vpn2",
719 add_to_visible
, add_to_watchlist
);
720 services
->SetServiceProperty(
721 "vpn2", shill::kProviderProperty
, provider_properties
);
724 SortManagerServices();
729 void FakeShillManagerClient::AddServiceToWatchList(
730 const std::string
& service_path
) {
731 // Remove and insert the service, moving it to the front of the watch list.
732 GetListProperty(shill::kServiceWatchListProperty
)->Remove(
733 base::StringValue(service_path
), NULL
);
734 GetListProperty(shill::kServiceWatchListProperty
)->Insert(
735 0, base::Value::CreateStringValue(service_path
));
736 CallNotifyObserversPropertyChanged(
737 shill::kServiceWatchListProperty
);
740 void FakeShillManagerClient::PassStubProperties(
741 const DictionaryValueCallback
& callback
) const {
742 scoped_ptr
<base::DictionaryValue
> stub_properties(
743 stub_properties_
.DeepCopy());
744 // Remove disabled services from the list.
745 stub_properties
->SetWithoutPathExpansion(
746 shill::kServicesProperty
,
747 GetEnabledServiceList(shill::kServicesProperty
));
748 stub_properties
->SetWithoutPathExpansion(
749 shill::kServiceWatchListProperty
,
750 GetEnabledServiceList(shill::kServiceWatchListProperty
));
751 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, *stub_properties
);
754 void FakeShillManagerClient::PassStubGeoNetworks(
755 const DictionaryValueCallback
& callback
) const {
756 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, stub_geo_networks_
);
759 void FakeShillManagerClient::CallNotifyObserversPropertyChanged(
760 const std::string
& property
) {
761 // Avoid unnecessary delayed task if we have no observers (e.g. during
763 if (!observer_list_
.might_have_observers())
765 base::MessageLoop::current()->PostTask(
767 base::Bind(&FakeShillManagerClient::NotifyObserversPropertyChanged
,
768 weak_ptr_factory_
.GetWeakPtr(),
772 void FakeShillManagerClient::NotifyObserversPropertyChanged(
773 const std::string
& property
) {
774 if (property
== shill::kServicesProperty
||
775 property
== shill::kServiceWatchListProperty
) {
776 scoped_ptr
<base::ListValue
> services(GetEnabledServiceList(property
));
777 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
779 OnPropertyChanged(property
, *(services
.get())));
782 if (property
== shill::kDevicesProperty
) {
783 base::ListValue
* devices
= NULL
;
784 if (stub_properties_
.GetListWithoutPathExpansion(
785 shill::kDevicesProperty
, &devices
)) {
786 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
788 OnPropertyChanged(property
, *devices
));
792 base::Value
* value
= NULL
;
793 if (!stub_properties_
.GetWithoutPathExpansion(property
, &value
)) {
794 LOG(ERROR
) << "Notify for unknown property: " << property
;
797 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
799 OnPropertyChanged(property
, *value
));
802 base::ListValue
* FakeShillManagerClient::GetListProperty(
803 const std::string
& property
) {
804 base::ListValue
* list_property
= NULL
;
805 if (!stub_properties_
.GetListWithoutPathExpansion(
806 property
, &list_property
)) {
807 list_property
= new base::ListValue
;
808 stub_properties_
.SetWithoutPathExpansion(property
, list_property
);
810 return list_property
;
813 bool FakeShillManagerClient::TechnologyEnabled(const std::string
& type
) const {
814 if (type
== shill::kTypeVPN
)
815 return true; // VPN is always "enabled" since there is no associated device
816 bool enabled
= false;
817 const base::ListValue
* technologies
;
818 if (stub_properties_
.GetListWithoutPathExpansion(
819 shill::kEnabledTechnologiesProperty
, &technologies
)) {
820 base::StringValue
type_value(type
);
821 if (technologies
->Find(type_value
) != technologies
->end())
827 void FakeShillManagerClient::SetTechnologyEnabled(
828 const std::string
& type
,
829 const base::Closure
& callback
,
831 base::ListValue
* enabled_list
=
832 GetListProperty(shill::kEnabledTechnologiesProperty
);
834 enabled_list
->AppendIfNotPresent(new base::StringValue(type
));
836 enabled_list
->Remove(base::StringValue(type
), NULL
);
837 CallNotifyObserversPropertyChanged(
838 shill::kEnabledTechnologiesProperty
);
839 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
840 // May affect available services
841 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
842 CallNotifyObserversPropertyChanged(shill::kServiceWatchListProperty
);
845 base::ListValue
* FakeShillManagerClient::GetEnabledServiceList(
846 const std::string
& property
) const {
847 base::ListValue
* new_service_list
= new base::ListValue
;
848 const base::ListValue
* service_list
;
849 if (stub_properties_
.GetListWithoutPathExpansion(property
, &service_list
)) {
850 ShillServiceClient::TestInterface
* service_client
=
851 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
852 for (base::ListValue::const_iterator iter
= service_list
->begin();
853 iter
!= service_list
->end(); ++iter
) {
854 std::string service_path
;
855 if (!(*iter
)->GetAsString(&service_path
))
857 const base::DictionaryValue
* properties
=
858 service_client
->GetServiceProperties(service_path
);
860 LOG(ERROR
) << "Properties not found for service: " << service_path
;
864 properties
->GetString(shill::kNameProperty
, &name
);
866 properties
->GetString(shill::kTypeProperty
, &type
);
867 if (TechnologyEnabled(type
))
868 new_service_list
->Append((*iter
)->DeepCopy());
871 return new_service_list
;
874 void FakeShillManagerClient::ScanCompleted(const std::string
& device_path
,
875 const base::Closure
& callback
) {
876 if (!device_path
.empty()) {
877 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
878 SetDeviceProperty(device_path
,
879 shill::kScanningProperty
,
880 base::FundamentalValue(false));
882 CallNotifyObserversPropertyChanged(shill::kServicesProperty
);
883 CallNotifyObserversPropertyChanged(shill::kServiceWatchListProperty
);
884 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
887 void FakeShillManagerClient::ParseCommandLineSwitch() {
888 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
889 if (command_line
->HasSwitch(switches::kShillStub
)) {
890 std::string option_str
=
891 command_line
->GetSwitchValueASCII(switches::kShillStub
);
892 base::StringPairs string_pairs
;
893 base::SplitStringIntoKeyValuePairs(option_str
, '=', ',', &string_pairs
);
894 for (base::StringPairs::iterator iter
= string_pairs
.begin();
895 iter
!= string_pairs
.end(); ++iter
) {
896 ParseOption((*iter
).first
, (*iter
).second
);
901 SetInitialNetworkState(shill::kTypeEthernet
, shill::kStateOnline
);
902 SetInitialNetworkState(shill::kTypeWifi
, shill::kStateOnline
);
903 SetInitialNetworkState(shill::kTypeCellular
, shill::kStateIdle
);
904 SetInitialNetworkState(shill::kTypeVPN
, shill::kStateIdle
);
907 bool FakeShillManagerClient::ParseOption(const std::string
& arg0
,
908 const std::string
& arg1
) {
909 if (arg0
== "interactive") {
912 base::StringToInt(arg1
, &seconds
);
913 interactive_delay_
= seconds
;
916 return SetInitialNetworkState(arg0
, arg1
);
919 bool FakeShillManagerClient::SetInitialNetworkState(std::string type_arg
,
920 std::string state_arg
) {
922 state_arg
= StringToLowerASCII(state_arg
);
923 if (state_arg
.empty() || state_arg
== "1" || state_arg
== "on" ||
924 state_arg
== "enabled" || state_arg
== "connected" ||
925 state_arg
== "online") {
926 // Enabled and connected (default value)
927 state
= shill::kStateOnline
;
928 } else if (state_arg
== "0" || state_arg
== "off" ||
929 state_arg
== "inactive" || state_arg
== shill::kStateIdle
) {
930 // Technology enabled, services are created but are not connected.
931 state
= shill::kStateIdle
;
932 } else if (state_arg
== "disabled" || state_arg
== "disconnect") {
933 // Technology disabled but available, services created but not connected.
934 state
= kNetworkDisabled
;
935 } else if (state_arg
== "none" || state_arg
== "offline") {
936 // Technology not available, do not create services.
937 state
= kTechnologyUnavailable
;
938 } else if (state_arg
== "portal") {
939 // Technology is enabled, a service is connected and in Portal state.
940 state
= shill::kStatePortal
;
941 } else if (state_arg
== "active" || state_arg
== "activated") {
942 // Technology is enabled, a service is connected and Activated.
943 state
= kNetworkActivated
;
945 LOG(ERROR
) << "Unrecognized initial state: " << state_arg
;
949 type_arg
= StringToLowerASCII(type_arg
);
951 if (type_arg
== "wireless") {
952 shill_initial_state_map_
[shill::kTypeWifi
] = state
;
953 shill_initial_state_map_
[shill::kTypeCellular
] = state
;
956 // Convenience synonyms.
957 if (type_arg
== "eth")
958 type_arg
= shill::kTypeEthernet
;
960 if (type_arg
!= shill::kTypeEthernet
&&
961 type_arg
!= shill::kTypeWifi
&&
962 type_arg
!= shill::kTypeCellular
&&
963 type_arg
!= shill::kTypeWimax
&&
964 type_arg
!= shill::kTypeVPN
) {
965 LOG(WARNING
) << "Unrecognized Shill network type: " << type_arg
;
969 // Unconnected or disabled ethernet is the same as unavailable.
970 if (type_arg
== shill::kTypeEthernet
&&
971 (state
== shill::kStateIdle
|| state
== kNetworkDisabled
)) {
972 state
= kTechnologyUnavailable
;
975 shill_initial_state_map_
[type_arg
] = state
;
979 std::string
FakeShillManagerClient::GetInitialStateForType(
980 const std::string
& type
,
982 std::map
<std::string
, std::string
>::const_iterator iter
=
983 shill_initial_state_map_
.find(type
);
984 if (iter
== shill_initial_state_map_
.end()) {
986 return kTechnologyUnavailable
;
988 std::string state
= iter
->second
;
989 if (state
== kNetworkDisabled
) {
991 return shill::kStateIdle
;
994 if ((state
== shill::kStatePortal
&& type
!= shill::kTypeWifi
) ||
995 (state
== kNetworkActivated
&& type
!= shill::kTypeCellular
)) {
996 LOG(WARNING
) << "Invalid state: " << state
<< " for " << type
;
997 return shill::kStateIdle
;
1002 } // namespace chromeos