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)
68 if (technology_enabled)
69 properties->GetBoolean(shill::kVisibleProperty, &visible);
71 disabled_service_list_out->push_back(service_path);
75 properties->GetString(shill::kStateProperty, &state);
76 if (state == shill::kStateOnline ||
77 state == shill::kStateAssociation ||
78 state == shill::kStateConfiguration ||
79 state == shill::kStatePortal ||
80 state == shill::kStateReady) {
81 active_service_list_out->push_back(service_path);
83 inactive_service_list_out->push_back(service_path);
88 void LogErrorCallback(const std::string& error_name,
89 const std::string& error_message) {
90 LOG(ERROR) << error_name << ": " << error_message;
93 bool IsConnectedState(const std::string& state) {
94 return state == shill::kStateOnline || state == shill::kStatePortal ||
95 state == shill::kStateReady;
98 void UpdatePortaledWifiState(const std::string& service_path) {
99 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
100 ->SetServiceProperty(service_path,
101 shill::kStateProperty,
102 base::StringValue(shill::kStatePortal));
105 const char* kTechnologyUnavailable = "unavailable";
106 const char* kNetworkActivated = "activated";
107 const char* kNetworkDisabled = "disabled";
108 const char* kCellularServicePath = "/service/cellular1";
113 const char FakeShillManagerClient::kFakeEthernetNetworkGuid[] = "eth1_guid";
115 FakeShillManagerClient::FakeShillManagerClient()
116 : interactive_delay_(0),
117 weak_ptr_factory_(this) {
118 ParseCommandLineSwitch();
121 FakeShillManagerClient::~FakeShillManagerClient() {}
123 // ShillManagerClient overrides.
125 void FakeShillManagerClient::Init(dbus::Bus* bus) {}
127 void FakeShillManagerClient::AddPropertyChangedObserver(
128 ShillPropertyChangedObserver* observer) {
129 observer_list_.AddObserver(observer);
132 void FakeShillManagerClient::RemovePropertyChangedObserver(
133 ShillPropertyChangedObserver* observer) {
134 observer_list_.RemoveObserver(observer);
137 void FakeShillManagerClient::GetProperties(
138 const DictionaryValueCallback& callback) {
139 DVLOG(1) << "Manager.GetProperties";
140 base::MessageLoop::current()->PostTask(
141 FROM_HERE, base::Bind(
142 &FakeShillManagerClient::PassStubProperties,
143 weak_ptr_factory_.GetWeakPtr(),
147 void FakeShillManagerClient::GetNetworksForGeolocation(
148 const DictionaryValueCallback& callback) {
149 base::MessageLoop::current()->PostTask(
150 FROM_HERE, base::Bind(
151 &FakeShillManagerClient::PassStubGeoNetworks,
152 weak_ptr_factory_.GetWeakPtr(),
156 void FakeShillManagerClient::SetProperty(const std::string& name,
157 const base::Value& value,
158 const base::Closure& callback,
159 const ErrorCallback& error_callback) {
160 DVLOG(2) << "SetProperty: " << name;
161 stub_properties_.SetWithoutPathExpansion(name, value.DeepCopy());
162 CallNotifyObserversPropertyChanged(name);
163 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
166 void FakeShillManagerClient::RequestScan(const std::string& type,
167 const base::Closure& callback,
168 const ErrorCallback& error_callback) {
169 // For Stub purposes, default to a Wifi scan.
170 std::string device_type = shill::kTypeWifi;
173 ShillDeviceClient::TestInterface* device_client =
174 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
175 std::string device_path = device_client->GetDevicePathForType(device_type);
176 if (!device_path.empty()) {
177 device_client->SetDeviceProperty(
178 device_path, shill::kScanningProperty, base::FundamentalValue(true));
180 base::MessageLoop::current()->PostDelayedTask(
182 base::Bind(&FakeShillManagerClient::ScanCompleted,
183 weak_ptr_factory_.GetWeakPtr(),
186 base::TimeDelta::FromSeconds(interactive_delay_));
189 void FakeShillManagerClient::EnableTechnology(
190 const std::string& type,
191 const base::Closure& callback,
192 const ErrorCallback& error_callback) {
193 base::ListValue* enabled_list = NULL;
194 if (!stub_properties_.GetListWithoutPathExpansion(
195 shill::kAvailableTechnologiesProperty, &enabled_list)) {
196 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
197 base::MessageLoop::current()->PostTask(
199 base::Bind(error_callback, "StubError", "Property not found"));
202 base::MessageLoop::current()->PostDelayedTask(
204 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled,
205 weak_ptr_factory_.GetWeakPtr(),
209 base::TimeDelta::FromSeconds(interactive_delay_));
212 void FakeShillManagerClient::DisableTechnology(
213 const std::string& type,
214 const base::Closure& callback,
215 const ErrorCallback& error_callback) {
216 base::ListValue* enabled_list = NULL;
217 if (!stub_properties_.GetListWithoutPathExpansion(
218 shill::kAvailableTechnologiesProperty, &enabled_list)) {
219 base::MessageLoop::current()->PostTask(
221 base::Bind(error_callback, "StubError", "Property not found"));
224 base::MessageLoop::current()->PostDelayedTask(
226 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled,
227 weak_ptr_factory_.GetWeakPtr(),
231 base::TimeDelta::FromSeconds(interactive_delay_));
234 void FakeShillManagerClient::ConfigureService(
235 const base::DictionaryValue& properties,
236 const ObjectPathCallback& callback,
237 const ErrorCallback& error_callback) {
238 ShillServiceClient::TestInterface* service_client =
239 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
243 if (!properties.GetString(shill::kGuidProperty, &guid) ||
244 !properties.GetString(shill::kTypeProperty, &type)) {
245 LOG(ERROR) << "ConfigureService requires GUID and Type to be defined";
246 // If the properties aren't filled out completely, then just return an empty
248 base::MessageLoop::current()->PostTask(
249 FROM_HERE, base::Bind(callback, dbus::ObjectPath()));
253 // For the purposes of this stub, we're going to assume that the GUID property
254 // is set to the service path because we don't want to re-implement Shill's
255 // property matching magic here.
256 std::string service_path = guid;
258 std::string ipconfig_path;
259 properties.GetString(shill::kIPConfigProperty, &ipconfig_path);
261 // Merge the new properties with existing properties, if any.
262 const base::DictionaryValue* existing_properties =
263 service_client->GetServiceProperties(service_path);
264 if (!existing_properties) {
265 // Add a new service to the service client stub because none exists, yet.
266 // This calls AddManagerService.
267 service_client->AddServiceWithIPConfig(service_path,
274 existing_properties = service_client->GetServiceProperties(service_path);
277 scoped_ptr<base::DictionaryValue> merged_properties(
278 existing_properties->DeepCopy());
279 merged_properties->MergeDictionary(&properties);
281 // Now set all the properties.
282 for (base::DictionaryValue::Iterator iter(*merged_properties);
283 !iter.IsAtEnd(); iter.Advance()) {
284 service_client->SetServiceProperty(service_path, iter.key(), iter.value());
287 // If the Profile property is set, add it to ProfileClient.
288 std::string profile_path;
289 merged_properties->GetStringWithoutPathExpansion(shill::kProfileProperty,
291 if (!profile_path.empty()) {
292 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface()->
293 AddService(profile_path, service_path);
296 base::MessageLoop::current()->PostTask(
297 FROM_HERE, base::Bind(callback, dbus::ObjectPath(service_path)));
300 void FakeShillManagerClient::ConfigureServiceForProfile(
301 const dbus::ObjectPath& profile_path,
302 const base::DictionaryValue& properties,
303 const ObjectPathCallback& callback,
304 const ErrorCallback& error_callback) {
305 std::string profile_property;
306 properties.GetStringWithoutPathExpansion(shill::kProfileProperty,
308 CHECK(profile_property == profile_path.value());
309 ConfigureService(properties, callback, error_callback);
313 void FakeShillManagerClient::GetService(
314 const base::DictionaryValue& properties,
315 const ObjectPathCallback& callback,
316 const ErrorCallback& error_callback) {
317 base::MessageLoop::current()->PostTask(
318 FROM_HERE, base::Bind(callback, dbus::ObjectPath()));
321 void FakeShillManagerClient::VerifyDestination(
322 const VerificationProperties& properties,
323 const BooleanCallback& callback,
324 const ErrorCallback& error_callback) {
325 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true));
328 void FakeShillManagerClient::VerifyAndEncryptCredentials(
329 const VerificationProperties& properties,
330 const std::string& service_path,
331 const StringCallback& callback,
332 const ErrorCallback& error_callback) {
333 base::MessageLoop::current()->PostTask(
334 FROM_HERE, base::Bind(callback, "encrypted_credentials"));
337 void FakeShillManagerClient::VerifyAndEncryptData(
338 const VerificationProperties& properties,
339 const std::string& data,
340 const StringCallback& callback,
341 const ErrorCallback& error_callback) {
342 base::MessageLoop::current()->PostTask(
343 FROM_HERE, base::Bind(callback, "encrypted_data"));
346 void FakeShillManagerClient::ConnectToBestServices(
347 const base::Closure& callback,
348 const ErrorCallback& error_callback) {
349 if (best_service_.empty()) {
350 VLOG(1) << "No 'best' service set.";
354 DBusThreadManager::Get()->GetShillServiceClient()->Connect(
355 dbus::ObjectPath(best_service_), callback, error_callback);
358 ShillManagerClient::TestInterface* FakeShillManagerClient::GetTestInterface() {
362 // ShillManagerClient::TestInterface overrides.
364 void FakeShillManagerClient::AddDevice(const std::string& device_path) {
365 if (GetListProperty(shill::kDevicesProperty)
366 ->AppendIfNotPresent(new base::StringValue(device_path))) {
367 CallNotifyObserversPropertyChanged(shill::kDevicesProperty);
371 void FakeShillManagerClient::RemoveDevice(const std::string& device_path) {
372 base::StringValue device_path_value(device_path);
373 if (GetListProperty(shill::kDevicesProperty)->Remove(
374 device_path_value, NULL)) {
375 CallNotifyObserversPropertyChanged(shill::kDevicesProperty);
379 void FakeShillManagerClient::ClearDevices() {
380 GetListProperty(shill::kDevicesProperty)->Clear();
381 CallNotifyObserversPropertyChanged(shill::kDevicesProperty);
384 void FakeShillManagerClient::AddTechnology(const std::string& type,
386 if (GetListProperty(shill::kAvailableTechnologiesProperty)
387 ->AppendIfNotPresent(new base::StringValue(type))) {
388 CallNotifyObserversPropertyChanged(
389 shill::kAvailableTechnologiesProperty);
392 GetListProperty(shill::kEnabledTechnologiesProperty)
393 ->AppendIfNotPresent(new base::StringValue(type))) {
394 CallNotifyObserversPropertyChanged(
395 shill::kEnabledTechnologiesProperty);
399 void FakeShillManagerClient::RemoveTechnology(const std::string& type) {
400 base::StringValue type_value(type);
401 if (GetListProperty(shill::kAvailableTechnologiesProperty)->Remove(
403 CallNotifyObserversPropertyChanged(
404 shill::kAvailableTechnologiesProperty);
406 if (GetListProperty(shill::kEnabledTechnologiesProperty)->Remove(
408 CallNotifyObserversPropertyChanged(
409 shill::kEnabledTechnologiesProperty);
413 void FakeShillManagerClient::SetTechnologyInitializing(const std::string& type,
416 if (GetListProperty(shill::kUninitializedTechnologiesProperty)
417 ->AppendIfNotPresent(new base::StringValue(type))) {
418 CallNotifyObserversPropertyChanged(
419 shill::kUninitializedTechnologiesProperty);
422 if (GetListProperty(shill::kUninitializedTechnologiesProperty)->Remove(
423 base::StringValue(type), NULL)) {
424 CallNotifyObserversPropertyChanged(
425 shill::kUninitializedTechnologiesProperty);
430 void FakeShillManagerClient::AddGeoNetwork(
431 const std::string& technology,
432 const base::DictionaryValue& network) {
433 base::ListValue* list_value = NULL;
434 if (!stub_geo_networks_.GetListWithoutPathExpansion(technology,
436 list_value = new base::ListValue;
437 stub_geo_networks_.SetWithoutPathExpansion(technology, list_value);
439 list_value->Append(network.DeepCopy());
442 void FakeShillManagerClient::AddProfile(const std::string& profile_path) {
443 const char* key = shill::kProfilesProperty;
444 if (GetListProperty(key)
445 ->AppendIfNotPresent(new base::StringValue(profile_path))) {
446 CallNotifyObserversPropertyChanged(key);
450 void FakeShillManagerClient::ClearProperties() {
451 stub_properties_.Clear();
454 void FakeShillManagerClient::SetManagerProperty(const std::string& key,
455 const base::Value& value) {
456 SetProperty(key, value,
457 base::Bind(&base::DoNothing), base::Bind(&LogErrorCallback));
460 void FakeShillManagerClient::AddManagerService(
461 const std::string& service_path,
462 bool notify_observers) {
463 DVLOG(2) << "AddManagerService: " << service_path;
464 GetListProperty(shill::kServiceCompleteListProperty)
465 ->AppendIfNotPresent(new base::StringValue(service_path));
466 SortManagerServices(false);
467 if (notify_observers)
468 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty);
471 void FakeShillManagerClient::RemoveManagerService(
472 const std::string& service_path) {
473 DVLOG(2) << "RemoveManagerService: " << service_path;
474 base::StringValue service_path_value(service_path);
475 GetListProperty(shill::kServiceCompleteListProperty)->Remove(
476 service_path_value, NULL);
477 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty);
480 void FakeShillManagerClient::ClearManagerServices() {
481 DVLOG(1) << "ClearManagerServices";
482 GetListProperty(shill::kServiceCompleteListProperty)->Clear();
483 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty);
486 void FakeShillManagerClient::ServiceStateChanged(
487 const std::string& service_path,
488 const std::string& state) {
489 if (service_path == default_service_ && !IsConnectedState(state)) {
490 // Default service is no longer connected; clear.
491 default_service_.clear();
492 base::StringValue default_service_value(default_service_);
493 SetManagerProperty(shill::kDefaultServiceProperty, default_service_value);
497 void FakeShillManagerClient::SortManagerServices(bool notify) {
498 DVLOG(1) << "SortManagerServices";
499 static const char* ordered_types[] = {shill::kTypeEthernet,
500 shill::kTypeEthernetEap,
502 shill::kTypeCellular,
506 base::ListValue* complete_list =
507 GetListProperty(shill::kServiceCompleteListProperty);
508 if (complete_list->empty())
510 scoped_ptr<base::ListValue> prev_complete_list(complete_list->DeepCopy());
512 std::vector<std::string> active_services;
513 std::vector<std::string> inactive_services;
514 std::vector<std::string> disabled_services;
515 for (size_t i = 0; i < arraysize(ordered_types); ++i) {
516 AppendServicesForType(complete_list,
518 TechnologyEnabled(ordered_types[i]),
523 complete_list->Clear();
524 for (size_t i = 0; i < active_services.size(); ++i)
525 complete_list->AppendString(active_services[i]);
526 for (size_t i = 0; i < inactive_services.size(); ++i)
527 complete_list->AppendString(inactive_services[i]);
528 for (size_t i = 0; i < disabled_services.size(); ++i)
529 complete_list->AppendString(disabled_services[i]);
531 if (notify && !complete_list->Equals(prev_complete_list.get()))
532 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty);
534 // Set the first active service as the Default service.
535 std::string new_default_service;
536 if (!active_services.empty()) {
537 ShillServiceClient::TestInterface* service_client =
538 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
539 std::string service_path = active_services[0];
540 const base::DictionaryValue* properties =
541 service_client->GetServiceProperties(service_path);
543 LOG(ERROR) << "Properties not found for service: " << service_path;
546 properties->GetString(shill::kStateProperty, &state);
547 if (IsConnectedState(state))
548 new_default_service = service_path;
551 if (default_service_ != new_default_service) {
552 default_service_ = new_default_service;
553 base::StringValue default_service_value(default_service_);
554 SetManagerProperty(shill::kDefaultServiceProperty, default_service_value);
558 int FakeShillManagerClient::GetInteractiveDelay() const {
559 return interactive_delay_;
562 void FakeShillManagerClient::SetBestServiceToConnect(
563 const std::string& service_path) {
564 best_service_ = service_path;
567 void FakeShillManagerClient::SetupDefaultEnvironment() {
568 DBusThreadManager* dbus_manager = DBusThreadManager::Get();
569 ShillServiceClient::TestInterface* services =
570 dbus_manager->GetShillServiceClient()->GetTestInterface();
572 ShillProfileClient::TestInterface* profiles =
573 dbus_manager->GetShillProfileClient()->GetTestInterface();
575 ShillDeviceClient::TestInterface* devices =
576 dbus_manager->GetShillDeviceClient()->GetTestInterface();
578 ShillIPConfigClient::TestInterface* ip_configs =
579 dbus_manager->GetShillIPConfigClient()->GetTestInterface();
582 const std::string shared_profile = ShillProfileClient::GetSharedProfilePath();
583 profiles->AddProfile(shared_profile, std::string());
585 const bool add_to_visible = true;
588 base::DictionaryValue ipconfig_v4_dictionary;
589 ipconfig_v4_dictionary.SetStringWithoutPathExpansion(
590 shill::kAddressProperty, "0.0.0.0");
591 ipconfig_v4_dictionary.SetStringWithoutPathExpansion(
592 shill::kGatewayProperty, "0.0.0.1");
593 ipconfig_v4_dictionary.SetIntegerWithoutPathExpansion(
594 shill::kPrefixlenProperty, 0);
595 ipconfig_v4_dictionary.SetStringWithoutPathExpansion(
596 shill::kMethodProperty, shill::kTypeIPv4);
597 ip_configs->AddIPConfig("ipconfig_v4_path", ipconfig_v4_dictionary);
598 base::DictionaryValue ipconfig_v6_dictionary;
599 ipconfig_v6_dictionary.SetStringWithoutPathExpansion(
600 shill::kAddressProperty, "0:0:0:0:0:0:0:0");
601 ipconfig_v6_dictionary.SetStringWithoutPathExpansion(
602 shill::kMethodProperty, shill::kTypeIPv6);
603 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 const std::string kFakeEthernetNetworkPath = "/service/eth1";
624 services->AddService(kFakeEthernetNetworkPath,
625 kFakeEthernetNetworkGuid,
627 shill::kTypeEthernet,
630 profiles->AddService(shared_profile, kFakeEthernetNetworkPath);
634 state = GetInitialStateForType(shill::kTypeWifi, &enabled);
635 if (state != kTechnologyUnavailable) {
636 bool portaled = false;
637 if (state == shill::kStatePortal) {
639 state = shill::kStateIdle;
641 AddTechnology(shill::kTypeWifi, enabled);
642 devices->AddDevice("/device/wifi1", shill::kTypeWifi, "stub_wifi_device1");
643 devices->SetDeviceProperty("/device/wifi1",
644 shill::kAddressProperty,
645 base::StringValue("23456789abc"));
646 base::ListValue wifi_ip_configs;
647 wifi_ip_configs.AppendString("ipconfig_v4_path");
648 wifi_ip_configs.AppendString("ipconfig_v6_path");
649 devices->SetDeviceProperty("/device/wifi1",
650 shill::kIPConfigsProperty,
653 const std::string kWifi1Path = "/service/wifi1";
654 services->AddService(kWifi1Path,
660 services->SetServiceProperty(kWifi1Path,
661 shill::kSecurityProperty,
662 base::StringValue(shill::kSecurityWep));
663 services->SetServiceProperty(kWifi1Path,
664 shill::kConnectableProperty,
665 base::FundamentalValue(true));
666 profiles->AddService(shared_profile, kWifi1Path);
668 const std::string kWifi2Path = "/service/wifi2";
669 services->AddService(kWifi2Path,
671 "wifi2_PSK" /* name */,
675 services->SetServiceProperty(kWifi2Path,
676 shill::kSecurityProperty,
677 base::StringValue(shill::kSecurityPsk));
679 base::FundamentalValue strength_value(80);
680 services->SetServiceProperty(
681 kWifi2Path, shill::kSignalStrengthProperty, strength_value);
682 profiles->AddService(shared_profile, kWifi2Path);
685 const std::string kPortaledWifiPath = "/service/portaled_wifi";
686 services->AddService(kPortaledWifiPath,
687 "portaled_wifi_guid",
688 "Portaled Wifi" /* name */,
692 services->SetServiceProperty(kPortaledWifiPath,
693 shill::kSecurityProperty,
694 base::StringValue(shill::kSecurityNone));
695 services->SetConnectBehavior(kPortaledWifiPath,
696 base::Bind(&UpdatePortaledWifiState,
698 services->SetServiceProperty(kPortaledWifiPath,
699 shill::kConnectableProperty,
700 base::FundamentalValue(true));
701 profiles->AddService(shared_profile, kPortaledWifiPath);
706 state = GetInitialStateForType(shill::kTypeWimax, &enabled);
707 if (state != kTechnologyUnavailable) {
708 AddTechnology(shill::kTypeWimax, enabled);
710 "/device/wimax1", shill::kTypeWimax, "stub_wimax_device1");
712 services->AddService("/service/wimax1",
718 services->SetServiceProperty("/service/wimax1",
719 shill::kConnectableProperty,
720 base::FundamentalValue(true));
721 base::FundamentalValue strength_value(80);
722 services->SetServiceProperty(
723 "/service/wimax1", shill::kSignalStrengthProperty, strength_value);
724 base::StringValue identity_value("test.identity");
725 services->SetServiceProperty(
726 "/service/wimax1", shill::kEapIdentityProperty, identity_value);
730 state = GetInitialStateForType(shill::kTypeCellular, &enabled);
731 if (state != kTechnologyUnavailable) {
732 bool activated = false;
733 if (state == kNetworkActivated) {
735 state = shill::kStateIdle;
737 AddTechnology(shill::kTypeCellular, enabled);
739 "/device/cellular1", shill::kTypeCellular, "stub_cellular_device1");
740 devices->SetDeviceProperty("/device/cellular1",
741 shill::kCarrierProperty,
742 base::StringValue(shill::kCarrierSprint));
744 services->AddService(kCellularServicePath,
746 "cellular1" /* name */,
747 shill::kTypeCellular,
750 base::StringValue technology_value(shill::kNetworkTechnologyGsm);
751 services->SetServiceProperty(kCellularServicePath,
752 shill::kNetworkTechnologyProperty,
756 services->SetServiceProperty(
757 kCellularServicePath,
758 shill::kActivationStateProperty,
759 base::StringValue(shill::kActivationStateActivated));
760 services->SetServiceProperty(kCellularServicePath,
761 shill::kConnectableProperty,
762 base::FundamentalValue(true));
764 services->SetServiceProperty(
765 kCellularServicePath,
766 shill::kActivationStateProperty,
767 base::StringValue(shill::kActivationStateNotActivated));
770 services->SetServiceProperty(kCellularServicePath,
771 shill::kRoamingStateProperty,
772 base::StringValue(shill::kRoamingStateHome));
776 state = GetInitialStateForType(shill::kTypeVPN, &enabled);
777 if (state != kTechnologyUnavailable) {
778 // Set the "Provider" dictionary properties. Note: when setting these in
779 // Shill, "Provider.Type", etc keys are used, but when reading the values
780 // "Provider" . "Type", etc keys are used. Here we are setting the values
781 // that will be read (by the UI, tests, etc).
782 base::DictionaryValue provider_properties;
783 provider_properties.SetString(shill::kTypeProperty,
784 shill::kProviderOpenVpn);
785 provider_properties.SetString(shill::kHostProperty, "vpn_host");
787 services->AddService("/service/vpn1",
793 services->SetServiceProperty(
794 "/service/vpn1", shill::kProviderProperty, provider_properties);
795 profiles->AddService(shared_profile, "/service/vpn1");
797 services->AddService("/service/vpn2",
803 services->SetServiceProperty(
804 "/service/vpn2", shill::kProviderProperty, provider_properties);
807 // Additional device states
808 for (DevicePropertyMap::iterator iter1 = shill_device_property_map_.begin();
809 iter1 != shill_device_property_map_.end(); ++iter1) {
810 std::string device_type = iter1->first;
811 std::string device_path = devices->GetDevicePathForType(device_type);
812 for (ShillPropertyMap::iterator iter2 = iter1->second.begin();
813 iter2 != iter1->second.end(); ++iter2) {
814 devices->SetDeviceProperty(device_path, iter2->first, *(iter2->second));
815 delete iter2->second;
819 SortManagerServices(true);
824 void FakeShillManagerClient::PassStubProperties(
825 const DictionaryValueCallback& callback) const {
826 scoped_ptr<base::DictionaryValue> stub_properties(
827 stub_properties_.DeepCopy());
828 stub_properties->SetWithoutPathExpansion(
829 shill::kServiceCompleteListProperty,
830 GetEnabledServiceList(shill::kServiceCompleteListProperty));
831 callback.Run(DBUS_METHOD_CALL_SUCCESS, *stub_properties);
834 void FakeShillManagerClient::PassStubGeoNetworks(
835 const DictionaryValueCallback& callback) const {
836 callback.Run(DBUS_METHOD_CALL_SUCCESS, stub_geo_networks_);
839 void FakeShillManagerClient::CallNotifyObserversPropertyChanged(
840 const std::string& property) {
841 // Avoid unnecessary delayed task if we have no observers (e.g. during
843 if (!observer_list_.might_have_observers())
845 base::MessageLoop::current()->PostTask(
847 base::Bind(&FakeShillManagerClient::NotifyObserversPropertyChanged,
848 weak_ptr_factory_.GetWeakPtr(),
852 void FakeShillManagerClient::NotifyObserversPropertyChanged(
853 const std::string& property) {
854 DVLOG(1) << "NotifyObserversPropertyChanged: " << property;
855 base::Value* value = NULL;
856 if (!stub_properties_.GetWithoutPathExpansion(property, &value)) {
857 LOG(ERROR) << "Notify for unknown property: " << property;
860 if (property == shill::kServiceCompleteListProperty) {
861 scoped_ptr<base::ListValue> services(GetEnabledServiceList(property));
862 FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
864 OnPropertyChanged(property, *(services.get())));
867 FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
869 OnPropertyChanged(property, *value));
872 base::ListValue* FakeShillManagerClient::GetListProperty(
873 const std::string& property) {
874 base::ListValue* list_property = NULL;
875 if (!stub_properties_.GetListWithoutPathExpansion(
876 property, &list_property)) {
877 list_property = new base::ListValue;
878 stub_properties_.SetWithoutPathExpansion(property, list_property);
880 return list_property;
883 bool FakeShillManagerClient::TechnologyEnabled(const std::string& type) const {
884 if (type == shill::kTypeVPN)
885 return true; // VPN is always "enabled" since there is no associated device
886 if (type == shill::kTypeEthernetEap)
888 bool enabled = false;
889 const base::ListValue* technologies;
890 if (stub_properties_.GetListWithoutPathExpansion(
891 shill::kEnabledTechnologiesProperty, &technologies)) {
892 base::StringValue type_value(type);
893 if (technologies->Find(type_value) != technologies->end())
899 void FakeShillManagerClient::SetTechnologyEnabled(
900 const std::string& type,
901 const base::Closure& callback,
903 base::ListValue* enabled_list =
904 GetListProperty(shill::kEnabledTechnologiesProperty);
906 enabled_list->AppendIfNotPresent(new base::StringValue(type));
908 enabled_list->Remove(base::StringValue(type), NULL);
909 CallNotifyObserversPropertyChanged(
910 shill::kEnabledTechnologiesProperty);
911 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
912 // May affect available services.
913 SortManagerServices(true);
916 base::ListValue* FakeShillManagerClient::GetEnabledServiceList(
917 const std::string& property) const {
918 base::ListValue* new_service_list = new base::ListValue;
919 const base::ListValue* service_list;
920 if (stub_properties_.GetListWithoutPathExpansion(property, &service_list)) {
921 ShillServiceClient::TestInterface* service_client =
922 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
923 for (base::ListValue::const_iterator iter = service_list->begin();
924 iter != service_list->end(); ++iter) {
925 std::string service_path;
926 if (!(*iter)->GetAsString(&service_path))
928 const base::DictionaryValue* properties =
929 service_client->GetServiceProperties(service_path);
931 LOG(ERROR) << "Properties not found for service: " << service_path;
935 properties->GetString(shill::kTypeProperty, &type);
936 if (TechnologyEnabled(type))
937 new_service_list->Append((*iter)->DeepCopy());
940 return new_service_list;
943 void FakeShillManagerClient::ScanCompleted(const std::string& device_path,
944 const base::Closure& callback) {
945 if (!device_path.empty()) {
946 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
947 SetDeviceProperty(device_path,
948 shill::kScanningProperty,
949 base::FundamentalValue(false));
951 DVLOG(2) << "ScanCompleted";
952 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty);
953 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
956 void FakeShillManagerClient::ParseCommandLineSwitch() {
958 SetInitialNetworkState(shill::kTypeEthernet, shill::kStateOnline);
959 SetInitialNetworkState(shill::kTypeWifi, shill::kStateOnline);
960 SetInitialNetworkState(shill::kTypeCellular, shill::kStateIdle);
961 SetInitialNetworkState(shill::kTypeVPN, shill::kStateIdle);
963 // Parse additional options
964 CommandLine* command_line = CommandLine::ForCurrentProcess();
965 if (!command_line->HasSwitch(switches::kShillStub))
968 std::string option_str =
969 command_line->GetSwitchValueASCII(switches::kShillStub);
970 VLOG(1) << "Parsing command line:" << option_str;
971 base::StringPairs string_pairs;
972 base::SplitStringIntoKeyValuePairs(option_str, '=', ',', &string_pairs);
973 for (base::StringPairs::iterator iter = string_pairs.begin();
974 iter != string_pairs.end(); ++iter) {
975 ParseOption((*iter).first, (*iter).second);
979 bool FakeShillManagerClient::ParseOption(const std::string& arg0,
980 const std::string& arg1) {
981 VLOG(1) << "Parsing command line option: '" << arg0 << "=" << arg1 << "'";
982 if ((arg0 == "clear" || arg0 == "reset") && arg1 == "1") {
983 shill_initial_state_map_.clear();
985 } else if (arg0 == "interactive") {
988 base::StringToInt(arg1, &seconds);
989 interactive_delay_ = seconds;
991 } else if (arg0 == "sim_lock") {
992 bool locked = (arg1 == "1") ? true : false;
993 base::DictionaryValue* simlock_dict = new base::DictionaryValue;
994 simlock_dict->Set(shill::kSIMLockEnabledProperty,
995 new base::FundamentalValue(locked));
996 // TODO(stevenjb): Investigate why non-empty value breaks UI.
997 std::string lock_type = ""; // shill::kSIMLockPin
998 simlock_dict->SetString(shill::kSIMLockTypeProperty, lock_type);
999 simlock_dict->SetInteger(shill::kSIMLockRetriesLeftProperty, 5);
1001 shill_device_property_map_
1002 [shill::kTypeCellular][shill::kSIMLockStatusProperty] = simlock_dict;
1003 shill_device_property_map_
1004 [shill::kTypeCellular][shill::kTechnologyFamilyProperty] =
1005 new base::StringValue(shill::kNetworkTechnologyGsm);
1008 return SetInitialNetworkState(arg0, arg1);
1011 bool FakeShillManagerClient::SetInitialNetworkState(std::string type_arg,
1012 std::string state_arg) {
1014 state_arg = base::StringToLowerASCII(state_arg);
1015 if (state_arg.empty() || state_arg == "1" || state_arg == "on" ||
1016 state_arg == "enabled" || state_arg == "connected" ||
1017 state_arg == "online") {
1018 // Enabled and connected (default value)
1019 state = shill::kStateOnline;
1020 } else if (state_arg == "0" || state_arg == "off" ||
1021 state_arg == "inactive" || state_arg == shill::kStateIdle) {
1022 // Technology enabled, services are created but are not connected.
1023 state = shill::kStateIdle;
1024 } else if (state_arg == "disabled" || state_arg == "disconnect") {
1025 // Technology disabled but available, services created but not connected.
1026 state = kNetworkDisabled;
1027 } else if (state_arg == "none" || state_arg == "offline") {
1028 // Technology not available, do not create services.
1029 state = kTechnologyUnavailable;
1030 } else if (state_arg == "portal") {
1031 // Technology is enabled, a service is connected and in Portal state.
1032 state = shill::kStatePortal;
1033 } else if (state_arg == "active" || state_arg == "activated") {
1034 // Technology is enabled, a service is connected and Activated.
1035 state = kNetworkActivated;
1037 LOG(ERROR) << "Unrecognized initial state: " << state_arg;
1041 type_arg = base::StringToLowerASCII(type_arg);
1043 if (type_arg == "wireless") {
1044 shill_initial_state_map_[shill::kTypeWifi] = state;
1045 shill_initial_state_map_[shill::kTypeCellular] = state;
1048 // Convenience synonyms.
1049 if (type_arg == "eth")
1050 type_arg = shill::kTypeEthernet;
1052 if (type_arg != shill::kTypeEthernet &&
1053 type_arg != shill::kTypeWifi &&
1054 type_arg != shill::kTypeCellular &&
1055 type_arg != shill::kTypeWimax &&
1056 type_arg != shill::kTypeVPN) {
1057 LOG(WARNING) << "Unrecognized Shill network type: " << type_arg;
1061 // Unconnected or disabled ethernet is the same as unavailable.
1062 if (type_arg == shill::kTypeEthernet &&
1063 (state == shill::kStateIdle || state == kNetworkDisabled)) {
1064 state = kTechnologyUnavailable;
1067 shill_initial_state_map_[type_arg] = state;
1071 std::string FakeShillManagerClient::GetInitialStateForType(
1072 const std::string& type,
1074 std::map<std::string, std::string>::const_iterator iter =
1075 shill_initial_state_map_.find(type);
1076 if (iter == shill_initial_state_map_.end()) {
1078 return kTechnologyUnavailable;
1080 std::string state = iter->second;
1081 if (state == kNetworkDisabled) {
1083 return shill::kStateIdle;
1086 if ((state == shill::kStatePortal && type != shill::kTypeWifi) ||
1087 (state == kNetworkActivated && type != shill::kTypeCellular)) {
1088 LOG(WARNING) << "Invalid state: " << state << " for " << type;
1089 return shill::kStateIdle;
1094 } // namespace chromeos