Rewrite AndroidSyncSettings to be significantly simpler.
[chromium-blink-merge.git] / chromeos / dbus / fake_shill_manager_client.cc
blob72dedefa802d935d3be15c9e366fff3b72f70818
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"
7 #include "base/bind.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"
21 #include "dbus/bus.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"
27 namespace chromeos {
29 namespace {
31 // Allow parsed command line option 'tdls_busy' to set the fake busy count.
32 int s_tdls_busy_count = 0;
34 // Used to compare values for finding entries to erase in a ListValue.
35 // (ListValue only implements a const_iterator version of Find).
36 struct ValueEquals {
37 explicit ValueEquals(const base::Value* first) : first_(first) {}
38 bool operator()(const base::Value* second) const {
39 return first_->Equals(second);
41 const base::Value* first_;
44 // Appends string entries from |service_list_in| whose entries in ServiceClient
45 // have Type |match_type| to one of the output lists based on the entry's State.
46 void AppendServicesForType(
47 const base::ListValue* service_list_in,
48 const char* match_type,
49 bool technology_enabled,
50 std::vector<std::string>* active_service_list_out,
51 std::vector<std::string>* inactive_service_list_out,
52 std::vector<std::string>* disabled_service_list_out) {
53 ShillServiceClient::TestInterface* service_client =
54 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
55 for (base::ListValue::const_iterator iter = service_list_in->begin();
56 iter != service_list_in->end(); ++iter) {
57 std::string service_path;
58 if (!(*iter)->GetAsString(&service_path))
59 continue;
60 const base::DictionaryValue* properties =
61 service_client->GetServiceProperties(service_path);
62 if (!properties) {
63 LOG(ERROR) << "Properties not found for service: " << service_path;
64 continue;
66 std::string type;
67 properties->GetString(shill::kTypeProperty, &type);
68 if (type != match_type)
69 continue;
70 bool visible = false;
71 if (technology_enabled)
72 properties->GetBoolean(shill::kVisibleProperty, &visible);
73 if (!visible) {
74 disabled_service_list_out->push_back(service_path);
75 continue;
77 std::string state;
78 properties->GetString(shill::kStateProperty, &state);
79 if (state == shill::kStateOnline ||
80 state == shill::kStateAssociation ||
81 state == shill::kStateConfiguration ||
82 state == shill::kStatePortal ||
83 state == shill::kStateReady) {
84 active_service_list_out->push_back(service_path);
85 } else {
86 inactive_service_list_out->push_back(service_path);
91 void LogErrorCallback(const std::string& error_name,
92 const std::string& error_message) {
93 LOG(ERROR) << error_name << ": " << error_message;
96 bool IsConnectedState(const std::string& state) {
97 return state == shill::kStateOnline || state == shill::kStatePortal ||
98 state == shill::kStateReady;
101 void UpdatePortaledWifiState(const std::string& service_path) {
102 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
103 ->SetServiceProperty(service_path,
104 shill::kStateProperty,
105 base::StringValue(shill::kStatePortal));
108 const char* kTechnologyUnavailable = "unavailable";
109 const char* kNetworkActivated = "activated";
110 const char* kNetworkDisabled = "disabled";
111 const char* kCellularServicePath = "/service/cellular1";
112 const char* kRoamingRequired = "required";
114 } // namespace
116 // static
117 const char FakeShillManagerClient::kFakeEthernetNetworkGuid[] = "eth1_guid";
119 FakeShillManagerClient::FakeShillManagerClient()
120 : interactive_delay_(0),
121 weak_ptr_factory_(this) {
122 ParseCommandLineSwitch();
125 FakeShillManagerClient::~FakeShillManagerClient() {}
127 // ShillManagerClient overrides.
129 void FakeShillManagerClient::Init(dbus::Bus* bus) {}
131 void FakeShillManagerClient::AddPropertyChangedObserver(
132 ShillPropertyChangedObserver* observer) {
133 observer_list_.AddObserver(observer);
136 void FakeShillManagerClient::RemovePropertyChangedObserver(
137 ShillPropertyChangedObserver* observer) {
138 observer_list_.RemoveObserver(observer);
141 void FakeShillManagerClient::GetProperties(
142 const DictionaryValueCallback& callback) {
143 VLOG(1) << "Manager.GetProperties";
144 base::MessageLoop::current()->PostTask(
145 FROM_HERE, base::Bind(
146 &FakeShillManagerClient::PassStubProperties,
147 weak_ptr_factory_.GetWeakPtr(),
148 callback));
151 void FakeShillManagerClient::GetNetworksForGeolocation(
152 const DictionaryValueCallback& callback) {
153 base::MessageLoop::current()->PostTask(
154 FROM_HERE, base::Bind(
155 &FakeShillManagerClient::PassStubGeoNetworks,
156 weak_ptr_factory_.GetWeakPtr(),
157 callback));
160 void FakeShillManagerClient::SetProperty(const std::string& name,
161 const base::Value& value,
162 const base::Closure& callback,
163 const ErrorCallback& error_callback) {
164 VLOG(2) << "SetProperty: " << name;
165 stub_properties_.SetWithoutPathExpansion(name, value.DeepCopy());
166 CallNotifyObserversPropertyChanged(name);
167 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
170 void FakeShillManagerClient::RequestScan(const std::string& type,
171 const base::Closure& callback,
172 const ErrorCallback& error_callback) {
173 // For Stub purposes, default to a Wifi scan.
174 std::string device_type = shill::kTypeWifi;
175 if (!type.empty())
176 device_type = type;
177 ShillDeviceClient::TestInterface* device_client =
178 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
179 std::string device_path = device_client->GetDevicePathForType(device_type);
180 if (!device_path.empty()) {
181 device_client->SetDeviceProperty(
182 device_path, shill::kScanningProperty, base::FundamentalValue(true));
184 base::MessageLoop::current()->PostDelayedTask(
185 FROM_HERE,
186 base::Bind(&FakeShillManagerClient::ScanCompleted,
187 weak_ptr_factory_.GetWeakPtr(),
188 device_path,
189 callback),
190 base::TimeDelta::FromSeconds(interactive_delay_));
193 void FakeShillManagerClient::EnableTechnology(
194 const std::string& type,
195 const base::Closure& callback,
196 const ErrorCallback& error_callback) {
197 base::ListValue* enabled_list = NULL;
198 if (!stub_properties_.GetListWithoutPathExpansion(
199 shill::kAvailableTechnologiesProperty, &enabled_list)) {
200 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
201 base::MessageLoop::current()->PostTask(
202 FROM_HERE,
203 base::Bind(error_callback, "StubError", "Property not found"));
204 return;
206 base::MessageLoop::current()->PostDelayedTask(
207 FROM_HERE,
208 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled,
209 weak_ptr_factory_.GetWeakPtr(),
210 type,
211 callback,
212 true),
213 base::TimeDelta::FromSeconds(interactive_delay_));
216 void FakeShillManagerClient::DisableTechnology(
217 const std::string& type,
218 const base::Closure& callback,
219 const ErrorCallback& error_callback) {
220 base::ListValue* enabled_list = NULL;
221 if (!stub_properties_.GetListWithoutPathExpansion(
222 shill::kAvailableTechnologiesProperty, &enabled_list)) {
223 base::MessageLoop::current()->PostTask(
224 FROM_HERE,
225 base::Bind(error_callback, "StubError", "Property not found"));
226 return;
228 base::MessageLoop::current()->PostDelayedTask(
229 FROM_HERE,
230 base::Bind(&FakeShillManagerClient::SetTechnologyEnabled,
231 weak_ptr_factory_.GetWeakPtr(),
232 type,
233 callback,
234 false),
235 base::TimeDelta::FromSeconds(interactive_delay_));
238 void FakeShillManagerClient::ConfigureService(
239 const base::DictionaryValue& properties,
240 const ObjectPathCallback& callback,
241 const ErrorCallback& error_callback) {
242 ShillServiceClient::TestInterface* service_client =
243 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
245 std::string guid;
246 std::string type;
247 if (!properties.GetString(shill::kGuidProperty, &guid) ||
248 !properties.GetString(shill::kTypeProperty, &type)) {
249 LOG(ERROR) << "ConfigureService requires GUID and Type to be defined";
250 // If the properties aren't filled out completely, then just return an empty
251 // object path.
252 base::MessageLoop::current()->PostTask(
253 FROM_HERE, base::Bind(callback, dbus::ObjectPath()));
254 return;
257 // For the purposes of this stub, we're going to assume that the GUID property
258 // is set to the service path because we don't want to re-implement Shill's
259 // property matching magic here.
260 std::string service_path = guid;
262 std::string ipconfig_path;
263 properties.GetString(shill::kIPConfigProperty, &ipconfig_path);
265 // Merge the new properties with existing properties, if any.
266 const base::DictionaryValue* existing_properties =
267 service_client->GetServiceProperties(service_path);
268 if (!existing_properties) {
269 // Add a new service to the service client stub because none exists, yet.
270 // This calls AddManagerService.
271 service_client->AddServiceWithIPConfig(service_path,
272 guid /* guid */,
273 guid /* name */,
274 type,
275 shill::kStateIdle,
276 ipconfig_path,
277 true /* visible */);
278 existing_properties = service_client->GetServiceProperties(service_path);
281 scoped_ptr<base::DictionaryValue> merged_properties(
282 existing_properties->DeepCopy());
283 merged_properties->MergeDictionary(&properties);
285 // Now set all the properties.
286 for (base::DictionaryValue::Iterator iter(*merged_properties);
287 !iter.IsAtEnd(); iter.Advance()) {
288 service_client->SetServiceProperty(service_path, iter.key(), iter.value());
291 // If the Profile property is set, add it to ProfileClient.
292 std::string profile_path;
293 merged_properties->GetStringWithoutPathExpansion(shill::kProfileProperty,
294 &profile_path);
295 if (!profile_path.empty()) {
296 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface()->
297 AddService(profile_path, service_path);
300 base::MessageLoop::current()->PostTask(
301 FROM_HERE, base::Bind(callback, dbus::ObjectPath(service_path)));
304 void FakeShillManagerClient::ConfigureServiceForProfile(
305 const dbus::ObjectPath& profile_path,
306 const base::DictionaryValue& properties,
307 const ObjectPathCallback& callback,
308 const ErrorCallback& error_callback) {
309 std::string profile_property;
310 properties.GetStringWithoutPathExpansion(shill::kProfileProperty,
311 &profile_property);
312 CHECK(profile_property == profile_path.value());
313 ConfigureService(properties, callback, error_callback);
317 void FakeShillManagerClient::GetService(
318 const base::DictionaryValue& properties,
319 const ObjectPathCallback& callback,
320 const ErrorCallback& error_callback) {
321 base::MessageLoop::current()->PostTask(
322 FROM_HERE, base::Bind(callback, dbus::ObjectPath()));
325 void FakeShillManagerClient::VerifyDestination(
326 const VerificationProperties& properties,
327 const BooleanCallback& callback,
328 const ErrorCallback& error_callback) {
329 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true));
332 void FakeShillManagerClient::VerifyAndEncryptCredentials(
333 const VerificationProperties& properties,
334 const std::string& service_path,
335 const StringCallback& callback,
336 const ErrorCallback& error_callback) {
337 base::MessageLoop::current()->PostTask(
338 FROM_HERE, base::Bind(callback, "encrypted_credentials"));
341 void FakeShillManagerClient::VerifyAndEncryptData(
342 const VerificationProperties& properties,
343 const std::string& data,
344 const StringCallback& callback,
345 const ErrorCallback& error_callback) {
346 base::MessageLoop::current()->PostTask(
347 FROM_HERE, base::Bind(callback, "encrypted_data"));
350 void FakeShillManagerClient::ConnectToBestServices(
351 const base::Closure& callback,
352 const ErrorCallback& error_callback) {
353 if (best_service_.empty()) {
354 VLOG(1) << "No 'best' service set.";
355 return;
358 DBusThreadManager::Get()->GetShillServiceClient()->Connect(
359 dbus::ObjectPath(best_service_), callback, error_callback);
362 ShillManagerClient::TestInterface* FakeShillManagerClient::GetTestInterface() {
363 return this;
366 // ShillManagerClient::TestInterface overrides.
368 void FakeShillManagerClient::AddDevice(const std::string& device_path) {
369 if (GetListProperty(shill::kDevicesProperty)
370 ->AppendIfNotPresent(new base::StringValue(device_path))) {
371 CallNotifyObserversPropertyChanged(shill::kDevicesProperty);
375 void FakeShillManagerClient::RemoveDevice(const std::string& device_path) {
376 base::StringValue device_path_value(device_path);
377 if (GetListProperty(shill::kDevicesProperty)->Remove(
378 device_path_value, NULL)) {
379 CallNotifyObserversPropertyChanged(shill::kDevicesProperty);
383 void FakeShillManagerClient::ClearDevices() {
384 GetListProperty(shill::kDevicesProperty)->Clear();
385 CallNotifyObserversPropertyChanged(shill::kDevicesProperty);
388 void FakeShillManagerClient::AddTechnology(const std::string& type,
389 bool enabled) {
390 if (GetListProperty(shill::kAvailableTechnologiesProperty)
391 ->AppendIfNotPresent(new base::StringValue(type))) {
392 CallNotifyObserversPropertyChanged(
393 shill::kAvailableTechnologiesProperty);
395 if (enabled &&
396 GetListProperty(shill::kEnabledTechnologiesProperty)
397 ->AppendIfNotPresent(new base::StringValue(type))) {
398 CallNotifyObserversPropertyChanged(
399 shill::kEnabledTechnologiesProperty);
403 void FakeShillManagerClient::RemoveTechnology(const std::string& type) {
404 base::StringValue type_value(type);
405 if (GetListProperty(shill::kAvailableTechnologiesProperty)->Remove(
406 type_value, NULL)) {
407 CallNotifyObserversPropertyChanged(
408 shill::kAvailableTechnologiesProperty);
410 if (GetListProperty(shill::kEnabledTechnologiesProperty)->Remove(
411 type_value, NULL)) {
412 CallNotifyObserversPropertyChanged(
413 shill::kEnabledTechnologiesProperty);
417 void FakeShillManagerClient::SetTechnologyInitializing(const std::string& type,
418 bool initializing) {
419 if (initializing) {
420 if (GetListProperty(shill::kUninitializedTechnologiesProperty)
421 ->AppendIfNotPresent(new base::StringValue(type))) {
422 CallNotifyObserversPropertyChanged(
423 shill::kUninitializedTechnologiesProperty);
425 } else {
426 if (GetListProperty(shill::kUninitializedTechnologiesProperty)->Remove(
427 base::StringValue(type), NULL)) {
428 CallNotifyObserversPropertyChanged(
429 shill::kUninitializedTechnologiesProperty);
434 void FakeShillManagerClient::AddGeoNetwork(
435 const std::string& technology,
436 const base::DictionaryValue& network) {
437 base::ListValue* list_value = NULL;
438 if (!stub_geo_networks_.GetListWithoutPathExpansion(technology,
439 &list_value)) {
440 list_value = new base::ListValue;
441 stub_geo_networks_.SetWithoutPathExpansion(technology, list_value);
443 list_value->Append(network.DeepCopy());
446 void FakeShillManagerClient::AddProfile(const std::string& profile_path) {
447 const char* key = shill::kProfilesProperty;
448 if (GetListProperty(key)
449 ->AppendIfNotPresent(new base::StringValue(profile_path))) {
450 CallNotifyObserversPropertyChanged(key);
454 void FakeShillManagerClient::ClearProperties() {
455 stub_properties_.Clear();
458 void FakeShillManagerClient::SetManagerProperty(const std::string& key,
459 const base::Value& value) {
460 SetProperty(key, value,
461 base::Bind(&base::DoNothing), base::Bind(&LogErrorCallback));
464 void FakeShillManagerClient::AddManagerService(
465 const std::string& service_path,
466 bool notify_observers) {
467 VLOG(2) << "AddManagerService: " << service_path;
468 GetListProperty(shill::kServiceCompleteListProperty)
469 ->AppendIfNotPresent(new base::StringValue(service_path));
470 SortManagerServices(false);
471 if (notify_observers)
472 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty);
475 void FakeShillManagerClient::RemoveManagerService(
476 const std::string& service_path) {
477 VLOG(2) << "RemoveManagerService: " << service_path;
478 base::StringValue service_path_value(service_path);
479 GetListProperty(shill::kServiceCompleteListProperty)->Remove(
480 service_path_value, NULL);
481 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty);
484 void FakeShillManagerClient::ClearManagerServices() {
485 VLOG(1) << "ClearManagerServices";
486 GetListProperty(shill::kServiceCompleteListProperty)->Clear();
487 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty);
490 void FakeShillManagerClient::ServiceStateChanged(
491 const std::string& service_path,
492 const std::string& state) {
493 if (service_path == default_service_ && !IsConnectedState(state)) {
494 // Default service is no longer connected; clear.
495 default_service_.clear();
496 base::StringValue default_service_value(default_service_);
497 SetManagerProperty(shill::kDefaultServiceProperty, default_service_value);
501 void FakeShillManagerClient::SortManagerServices(bool notify) {
502 VLOG(1) << "SortManagerServices";
503 static const char* ordered_types[] = {shill::kTypeEthernet,
504 shill::kTypeEthernetEap,
505 shill::kTypeWifi,
506 shill::kTypeCellular,
507 shill::kTypeWimax,
508 shill::kTypeVPN};
510 base::ListValue* complete_list =
511 GetListProperty(shill::kServiceCompleteListProperty);
512 if (complete_list->empty())
513 return;
514 scoped_ptr<base::ListValue> prev_complete_list(complete_list->DeepCopy());
516 std::vector<std::string> active_services;
517 std::vector<std::string> inactive_services;
518 std::vector<std::string> disabled_services;
519 for (size_t i = 0; i < arraysize(ordered_types); ++i) {
520 AppendServicesForType(complete_list,
521 ordered_types[i],
522 TechnologyEnabled(ordered_types[i]),
523 &active_services,
524 &inactive_services,
525 &disabled_services);
527 complete_list->Clear();
528 for (size_t i = 0; i < active_services.size(); ++i)
529 complete_list->AppendString(active_services[i]);
530 for (size_t i = 0; i < inactive_services.size(); ++i)
531 complete_list->AppendString(inactive_services[i]);
532 for (size_t i = 0; i < disabled_services.size(); ++i)
533 complete_list->AppendString(disabled_services[i]);
535 if (notify && !complete_list->Equals(prev_complete_list.get()))
536 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty);
538 // Set the first active service as the Default service.
539 std::string new_default_service;
540 if (!active_services.empty()) {
541 ShillServiceClient::TestInterface* service_client =
542 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
543 std::string service_path = active_services[0];
544 const base::DictionaryValue* properties =
545 service_client->GetServiceProperties(service_path);
546 if (!properties) {
547 LOG(ERROR) << "Properties not found for service: " << service_path;
548 } else {
549 std::string state;
550 properties->GetString(shill::kStateProperty, &state);
551 if (IsConnectedState(state))
552 new_default_service = service_path;
555 if (default_service_ != new_default_service) {
556 default_service_ = new_default_service;
557 base::StringValue default_service_value(default_service_);
558 SetManagerProperty(shill::kDefaultServiceProperty, default_service_value);
562 int FakeShillManagerClient::GetInteractiveDelay() const {
563 return interactive_delay_;
566 void FakeShillManagerClient::SetBestServiceToConnect(
567 const std::string& service_path) {
568 best_service_ = service_path;
571 void FakeShillManagerClient::SetupDefaultEnvironment() {
572 // Bail out from setup if there is no message loop. This will be the common
573 // case for tests that are not testing Shill.
574 if (!base::MessageLoop::current())
575 return;
577 DBusThreadManager* dbus_manager = DBusThreadManager::Get();
578 ShillServiceClient::TestInterface* services =
579 dbus_manager->GetShillServiceClient()->GetTestInterface();
580 DCHECK(services);
581 ShillProfileClient::TestInterface* profiles =
582 dbus_manager->GetShillProfileClient()->GetTestInterface();
583 DCHECK(profiles);
584 ShillDeviceClient::TestInterface* devices =
585 dbus_manager->GetShillDeviceClient()->GetTestInterface();
586 DCHECK(devices);
587 ShillIPConfigClient::TestInterface* ip_configs =
588 dbus_manager->GetShillIPConfigClient()->GetTestInterface();
589 DCHECK(ip_configs);
591 const std::string shared_profile = ShillProfileClient::GetSharedProfilePath();
592 profiles->AddProfile(shared_profile, std::string());
594 const bool add_to_visible = true;
596 // IPConfigs
597 base::DictionaryValue ipconfig_v4_dictionary;
598 ipconfig_v4_dictionary.SetStringWithoutPathExpansion(
599 shill::kAddressProperty, "100.0.0.1");
600 ipconfig_v4_dictionary.SetStringWithoutPathExpansion(
601 shill::kGatewayProperty, "100.0.0.2");
602 ipconfig_v4_dictionary.SetIntegerWithoutPathExpansion(
603 shill::kPrefixlenProperty, 1);
604 ipconfig_v4_dictionary.SetStringWithoutPathExpansion(
605 shill::kMethodProperty, shill::kTypeIPv4);
606 ip_configs->AddIPConfig("ipconfig_v4_path", ipconfig_v4_dictionary);
607 base::DictionaryValue ipconfig_v6_dictionary;
608 ipconfig_v6_dictionary.SetStringWithoutPathExpansion(
609 shill::kAddressProperty, "0:0:0:0:100:0:0:1");
610 ipconfig_v6_dictionary.SetStringWithoutPathExpansion(
611 shill::kMethodProperty, shill::kTypeIPv6);
612 ip_configs->AddIPConfig("ipconfig_v6_path", ipconfig_v6_dictionary);
614 bool enabled;
615 std::string state;
617 // Ethernet
618 state = GetInitialStateForType(shill::kTypeEthernet, &enabled);
619 if (state == shill::kStateOnline) {
620 AddTechnology(shill::kTypeEthernet, enabled);
621 devices->AddDevice(
622 "/device/eth1", shill::kTypeEthernet, "stub_eth_device1");
623 devices->SetDeviceProperty("/device/eth1",
624 shill::kAddressProperty,
625 base::StringValue("0123456789ab"));
626 base::ListValue eth_ip_configs;
627 eth_ip_configs.AppendString("ipconfig_v4_path");
628 eth_ip_configs.AppendString("ipconfig_v6_path");
629 devices->SetDeviceProperty("/device/eth1",
630 shill::kIPConfigsProperty,
631 eth_ip_configs);
632 const std::string kFakeEthernetNetworkPath = "/service/eth1";
633 services->AddService(kFakeEthernetNetworkPath,
634 kFakeEthernetNetworkGuid,
635 "eth1" /* name */,
636 shill::kTypeEthernet,
637 state,
638 add_to_visible);
639 profiles->AddService(shared_profile, kFakeEthernetNetworkPath);
642 // Wifi
643 if (s_tdls_busy_count != 0) {
644 DBusThreadManager::Get()
645 ->GetShillDeviceClient()
646 ->GetTestInterface()
647 ->SetTDLSBusyCount(s_tdls_busy_count);
650 state = GetInitialStateForType(shill::kTypeWifi, &enabled);
651 if (state != kTechnologyUnavailable) {
652 bool portaled = false;
653 if (state == shill::kStatePortal) {
654 portaled = true;
655 state = shill::kStateIdle;
657 AddTechnology(shill::kTypeWifi, enabled);
658 devices->AddDevice("/device/wifi1", shill::kTypeWifi, "stub_wifi_device1");
659 devices->SetDeviceProperty("/device/wifi1",
660 shill::kAddressProperty,
661 base::StringValue("23456789abcd"));
662 base::ListValue wifi_ip_configs;
663 wifi_ip_configs.AppendString("ipconfig_v4_path");
664 wifi_ip_configs.AppendString("ipconfig_v6_path");
665 devices->SetDeviceProperty("/device/wifi1",
666 shill::kIPConfigsProperty,
667 wifi_ip_configs);
669 const std::string kWifi1Path = "/service/wifi1";
670 services->AddService(kWifi1Path,
671 "wifi1_guid",
672 "wifi1" /* name */,
673 shill::kTypeWifi,
674 state,
675 add_to_visible);
676 services->SetServiceProperty(kWifi1Path,
677 shill::kSecurityClassProperty,
678 base::StringValue(shill::kSecurityWep));
679 services->SetServiceProperty(kWifi1Path,
680 shill::kConnectableProperty,
681 base::FundamentalValue(true));
682 profiles->AddService(shared_profile, kWifi1Path);
684 const std::string kWifi2Path = "/service/wifi2";
685 services->AddService(kWifi2Path,
686 "wifi2_PSK_guid",
687 "wifi2_PSK" /* name */,
688 shill::kTypeWifi,
689 shill::kStateIdle,
690 add_to_visible);
691 services->SetServiceProperty(kWifi2Path,
692 shill::kSecurityClassProperty,
693 base::StringValue(shill::kSecurityPsk));
694 services->SetServiceProperty(
695 kWifi2Path, shill::kSignalStrengthProperty, base::FundamentalValue(80));
696 profiles->AddService(shared_profile, kWifi2Path);
698 const std::string kWifi3Path = "/service/wifi3";
699 services->AddService(kWifi3Path,
700 "", /* empty GUID */
701 "wifi3" /* name */,
702 shill::kTypeWifi,
703 shill::kStateIdle,
704 add_to_visible);
705 services->SetServiceProperty(
706 kWifi3Path, shill::kSignalStrengthProperty, base::FundamentalValue(40));
708 if (portaled) {
709 const std::string kPortaledWifiPath = "/service/portaled_wifi";
710 services->AddService(kPortaledWifiPath,
711 "portaled_wifi_guid",
712 "Portaled Wifi" /* name */,
713 shill::kTypeWifi,
714 shill::kStatePortal,
715 add_to_visible);
716 services->SetServiceProperty(kPortaledWifiPath,
717 shill::kSecurityClassProperty,
718 base::StringValue(shill::kSecurityNone));
719 services->SetConnectBehavior(kPortaledWifiPath,
720 base::Bind(&UpdatePortaledWifiState,
721 "portaled_wifi"));
722 services->SetServiceProperty(kPortaledWifiPath,
723 shill::kConnectableProperty,
724 base::FundamentalValue(true));
725 profiles->AddService(shared_profile, kPortaledWifiPath);
729 // Wimax
730 const std::string kWimaxPath = "/service/wimax1";
731 state = GetInitialStateForType(shill::kTypeWimax, &enabled);
732 if (state != kTechnologyUnavailable) {
733 AddTechnology(shill::kTypeWimax, enabled);
734 devices->AddDevice(
735 "/device/wimax1", shill::kTypeWimax, "stub_wimax_device1");
737 services->AddService(kWimaxPath, "wimax1_guid", "wimax1" /* name */,
738 shill::kTypeWimax, state, add_to_visible);
739 services->SetServiceProperty(kWimaxPath, shill::kConnectableProperty,
740 base::FundamentalValue(true));
741 base::FundamentalValue strength_value(80);
742 services->SetServiceProperty(kWimaxPath, shill::kSignalStrengthProperty,
743 strength_value);
744 profiles->AddService(shared_profile, kWimaxPath);
747 // Cellular
748 state = GetInitialStateForType(shill::kTypeCellular, &enabled);
749 if (state != kTechnologyUnavailable) {
750 bool activated = false;
751 if (state == kNetworkActivated) {
752 activated = true;
753 state = shill::kStateIdle;
755 AddTechnology(shill::kTypeCellular, enabled);
756 devices->AddDevice(
757 "/device/cellular1", shill::kTypeCellular, "stub_cellular_device1");
758 devices->SetDeviceProperty("/device/cellular1",
759 shill::kCarrierProperty,
760 base::StringValue(shill::kCarrierSprint));
761 base::ListValue carrier_list;
762 carrier_list.AppendString(shill::kCarrierSprint);
763 carrier_list.AppendString(shill::kCarrierGenericUMTS);
764 devices->SetDeviceProperty("/device/cellular1",
765 shill::kSupportedCarriersProperty,
766 carrier_list);
767 if (roaming_state_ == kRoamingRequired) {
768 devices->SetDeviceProperty("/device/cellular1",
769 shill::kProviderRequiresRoamingProperty,
770 base::FundamentalValue(true));
773 services->AddService(kCellularServicePath,
774 "cellular1_guid",
775 "cellular1" /* name */,
776 shill::kTypeCellular,
777 state,
778 add_to_visible);
779 base::StringValue technology_value(shill::kNetworkTechnologyGsm);
780 devices->SetDeviceProperty("/device/cellular1",
781 shill::kTechnologyFamilyProperty,
782 technology_value);
783 services->SetServiceProperty(kCellularServicePath,
784 shill::kNetworkTechnologyProperty,
785 technology_value);
787 if (activated) {
788 services->SetServiceProperty(
789 kCellularServicePath,
790 shill::kActivationStateProperty,
791 base::StringValue(shill::kActivationStateActivated));
792 services->SetServiceProperty(kCellularServicePath,
793 shill::kConnectableProperty,
794 base::FundamentalValue(true));
795 } else {
796 services->SetServiceProperty(
797 kCellularServicePath,
798 shill::kActivationStateProperty,
799 base::StringValue(shill::kActivationStateNotActivated));
802 std::string shill_roaming_state;
803 if (roaming_state_ == kRoamingRequired)
804 shill_roaming_state = shill::kRoamingStateRoaming;
805 else if (roaming_state_.empty())
806 shill_roaming_state = shill::kRoamingStateHome;
807 else // |roaming_state_| is expected to be a valid Shill state.
808 shill_roaming_state = roaming_state_;
809 services->SetServiceProperty(kCellularServicePath,
810 shill::kRoamingStateProperty,
811 base::StringValue(shill_roaming_state));
812 profiles->AddService(shared_profile, kCellularServicePath);
815 // VPN
816 state = GetInitialStateForType(shill::kTypeVPN, &enabled);
817 if (state != kTechnologyUnavailable) {
818 // Set the "Provider" dictionary properties. Note: when setting these in
819 // Shill, "Provider.Type", etc keys are used, but when reading the values
820 // "Provider" . "Type", etc keys are used. Here we are setting the values
821 // that will be read (by the UI, tests, etc).
822 base::DictionaryValue provider_properties_openvpn;
823 provider_properties_openvpn.SetString(shill::kTypeProperty,
824 shill::kProviderOpenVpn);
825 provider_properties_openvpn.SetString(shill::kHostProperty, "vpn_host");
827 services->AddService("/service/vpn1",
828 "vpn1_guid",
829 "vpn1" /* name */,
830 shill::kTypeVPN,
831 state,
832 add_to_visible);
833 services->SetServiceProperty(
834 "/service/vpn1", shill::kProviderProperty, provider_properties_openvpn);
835 profiles->AddService(shared_profile, "/service/vpn1");
837 base::DictionaryValue provider_properties_l2tp;
838 provider_properties_l2tp.SetString(shill::kTypeProperty,
839 shill::kProviderL2tpIpsec);
840 provider_properties_l2tp.SetString(shill::kHostProperty, "vpn_host2");
842 services->AddService("/service/vpn2",
843 "vpn2_guid",
844 "vpn2" /* name */,
845 shill::kTypeVPN,
846 shill::kStateIdle,
847 add_to_visible);
848 services->SetServiceProperty(
849 "/service/vpn2", shill::kProviderProperty, provider_properties_l2tp);
852 // Additional device states
853 for (DevicePropertyMap::iterator iter1 = shill_device_property_map_.begin();
854 iter1 != shill_device_property_map_.end(); ++iter1) {
855 std::string device_type = iter1->first;
856 std::string device_path = devices->GetDevicePathForType(device_type);
857 for (ShillPropertyMap::iterator iter2 = iter1->second.begin();
858 iter2 != iter1->second.end(); ++iter2) {
859 devices->SetDeviceProperty(device_path, iter2->first, *(iter2->second));
860 delete iter2->second;
864 SortManagerServices(true);
867 // Private methods
869 void FakeShillManagerClient::PassStubProperties(
870 const DictionaryValueCallback& callback) const {
871 scoped_ptr<base::DictionaryValue> stub_properties(
872 stub_properties_.DeepCopy());
873 stub_properties->SetWithoutPathExpansion(
874 shill::kServiceCompleteListProperty,
875 GetEnabledServiceList(shill::kServiceCompleteListProperty));
876 callback.Run(DBUS_METHOD_CALL_SUCCESS, *stub_properties);
879 void FakeShillManagerClient::PassStubGeoNetworks(
880 const DictionaryValueCallback& callback) const {
881 callback.Run(DBUS_METHOD_CALL_SUCCESS, stub_geo_networks_);
884 void FakeShillManagerClient::CallNotifyObserversPropertyChanged(
885 const std::string& property) {
886 // Avoid unnecessary delayed task if we have no observers (e.g. during
887 // initial setup).
888 if (!observer_list_.might_have_observers())
889 return;
890 base::MessageLoop::current()->PostTask(
891 FROM_HERE,
892 base::Bind(&FakeShillManagerClient::NotifyObserversPropertyChanged,
893 weak_ptr_factory_.GetWeakPtr(),
894 property));
897 void FakeShillManagerClient::NotifyObserversPropertyChanged(
898 const std::string& property) {
899 VLOG(1) << "NotifyObserversPropertyChanged: " << property;
900 base::Value* value = NULL;
901 if (!stub_properties_.GetWithoutPathExpansion(property, &value)) {
902 LOG(ERROR) << "Notify for unknown property: " << property;
903 return;
905 if (property == shill::kServiceCompleteListProperty) {
906 scoped_ptr<base::ListValue> services(GetEnabledServiceList(property));
907 FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
908 observer_list_,
909 OnPropertyChanged(property, *(services.get())));
910 return;
912 FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
913 observer_list_,
914 OnPropertyChanged(property, *value));
917 base::ListValue* FakeShillManagerClient::GetListProperty(
918 const std::string& property) {
919 base::ListValue* list_property = NULL;
920 if (!stub_properties_.GetListWithoutPathExpansion(
921 property, &list_property)) {
922 list_property = new base::ListValue;
923 stub_properties_.SetWithoutPathExpansion(property, list_property);
925 return list_property;
928 bool FakeShillManagerClient::TechnologyEnabled(const std::string& type) const {
929 if (type == shill::kTypeVPN)
930 return true; // VPN is always "enabled" since there is no associated device
931 if (type == shill::kTypeEthernetEap)
932 return true;
933 bool enabled = false;
934 const base::ListValue* technologies;
935 if (stub_properties_.GetListWithoutPathExpansion(
936 shill::kEnabledTechnologiesProperty, &technologies)) {
937 base::StringValue type_value(type);
938 if (technologies->Find(type_value) != technologies->end())
939 enabled = true;
941 return enabled;
944 void FakeShillManagerClient::SetTechnologyEnabled(
945 const std::string& type,
946 const base::Closure& callback,
947 bool enabled) {
948 base::ListValue* enabled_list =
949 GetListProperty(shill::kEnabledTechnologiesProperty);
950 if (enabled)
951 enabled_list->AppendIfNotPresent(new base::StringValue(type));
952 else
953 enabled_list->Remove(base::StringValue(type), NULL);
954 CallNotifyObserversPropertyChanged(
955 shill::kEnabledTechnologiesProperty);
956 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
957 // May affect available services.
958 SortManagerServices(true);
961 base::ListValue* FakeShillManagerClient::GetEnabledServiceList(
962 const std::string& property) const {
963 base::ListValue* new_service_list = new base::ListValue;
964 const base::ListValue* service_list;
965 if (stub_properties_.GetListWithoutPathExpansion(property, &service_list)) {
966 ShillServiceClient::TestInterface* service_client =
967 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
968 for (base::ListValue::const_iterator iter = service_list->begin();
969 iter != service_list->end(); ++iter) {
970 std::string service_path;
971 if (!(*iter)->GetAsString(&service_path))
972 continue;
973 const base::DictionaryValue* properties =
974 service_client->GetServiceProperties(service_path);
975 if (!properties) {
976 LOG(ERROR) << "Properties not found for service: " << service_path;
977 continue;
979 std::string type;
980 properties->GetString(shill::kTypeProperty, &type);
981 if (TechnologyEnabled(type))
982 new_service_list->Append((*iter)->DeepCopy());
985 return new_service_list;
988 void FakeShillManagerClient::ScanCompleted(const std::string& device_path,
989 const base::Closure& callback) {
990 if (!device_path.empty()) {
991 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
992 SetDeviceProperty(device_path,
993 shill::kScanningProperty,
994 base::FundamentalValue(false));
996 VLOG(2) << "ScanCompleted";
997 CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty);
998 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
1001 void FakeShillManagerClient::ParseCommandLineSwitch() {
1002 // Default setup
1003 SetInitialNetworkState(shill::kTypeEthernet, shill::kStateOnline);
1004 SetInitialNetworkState(shill::kTypeWifi, shill::kStateOnline);
1005 SetInitialNetworkState(shill::kTypeCellular, shill::kStateIdle);
1006 SetInitialNetworkState(shill::kTypeVPN, shill::kStateIdle);
1008 // Parse additional options
1009 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
1010 if (!command_line->HasSwitch(switches::kShillStub))
1011 return;
1013 std::string option_str =
1014 command_line->GetSwitchValueASCII(switches::kShillStub);
1015 VLOG(1) << "Parsing command line:" << option_str;
1016 base::StringPairs string_pairs;
1017 base::SplitStringIntoKeyValuePairs(option_str, '=', ',', &string_pairs);
1018 for (base::StringPairs::iterator iter = string_pairs.begin();
1019 iter != string_pairs.end(); ++iter) {
1020 ParseOption((*iter).first, (*iter).second);
1024 bool FakeShillManagerClient::ParseOption(const std::string& arg0,
1025 const std::string& arg1) {
1026 VLOG(1) << "Parsing command line option: '" << arg0 << "=" << arg1 << "'";
1027 if ((arg0 == "clear" || arg0 == "reset") && arg1 == "1") {
1028 shill_initial_state_map_.clear();
1029 return true;
1030 } else if (arg0 == "interactive") {
1031 int seconds = 3;
1032 if (!arg1.empty())
1033 base::StringToInt(arg1, &seconds);
1034 interactive_delay_ = seconds;
1035 return true;
1036 } else if (arg0 == "sim_lock") {
1037 bool locked = (arg1 == "1") ? true : false;
1038 base::DictionaryValue* simlock_dict = new base::DictionaryValue;
1039 simlock_dict->Set(shill::kSIMLockEnabledProperty,
1040 new base::FundamentalValue(locked));
1041 // TODO(stevenjb): Investigate why non-empty value breaks UI.
1042 std::string lock_type = ""; // shill::kSIMLockPin
1043 simlock_dict->SetString(shill::kSIMLockTypeProperty, lock_type);
1044 simlock_dict->SetInteger(shill::kSIMLockRetriesLeftProperty, 5);
1046 shill_device_property_map_[shill::kTypeCellular]
1047 [shill::kSIMLockStatusProperty] = simlock_dict;
1048 shill_device_property_map_
1049 [shill::kTypeCellular][shill::kTechnologyFamilyProperty] =
1050 new base::StringValue(shill::kNetworkTechnologyGsm);
1051 return true;
1052 } else if (arg0 == "tdls_busy") {
1053 if (!arg1.empty())
1054 base::StringToInt(arg1, &s_tdls_busy_count);
1055 else
1056 s_tdls_busy_count = 1;
1057 return true;
1058 } else if (arg0 == "roaming") {
1059 // "home", "roaming", or "required"
1060 roaming_state_ = arg1;
1061 return true;
1063 return SetInitialNetworkState(arg0, arg1);
1066 bool FakeShillManagerClient::SetInitialNetworkState(std::string type_arg,
1067 std::string state_arg) {
1068 std::string state;
1069 state_arg = base::StringToLowerASCII(state_arg);
1070 if (state_arg.empty() || state_arg == "1" || state_arg == "on" ||
1071 state_arg == "enabled" || state_arg == "connected" ||
1072 state_arg == "online") {
1073 // Enabled and connected (default value)
1074 state = shill::kStateOnline;
1075 } else if (state_arg == "0" || state_arg == "off" ||
1076 state_arg == "inactive" || state_arg == shill::kStateIdle) {
1077 // Technology enabled, services are created but are not connected.
1078 state = shill::kStateIdle;
1079 } else if (state_arg == "disabled" || state_arg == "disconnect") {
1080 // Technology disabled but available, services created but not connected.
1081 state = kNetworkDisabled;
1082 } else if (state_arg == "none" || state_arg == "offline") {
1083 // Technology not available, do not create services.
1084 state = kTechnologyUnavailable;
1085 } else if (state_arg == "portal") {
1086 // Technology is enabled, a service is connected and in Portal state.
1087 state = shill::kStatePortal;
1088 } else if (state_arg == "active" || state_arg == "activated") {
1089 // Technology is enabled, a service is connected and Activated.
1090 state = kNetworkActivated;
1091 } else {
1092 LOG(ERROR) << "Unrecognized initial state: " << state_arg;
1093 return false;
1096 type_arg = base::StringToLowerASCII(type_arg);
1097 // Special cases
1098 if (type_arg == "wireless") {
1099 shill_initial_state_map_[shill::kTypeWifi] = state;
1100 shill_initial_state_map_[shill::kTypeCellular] = state;
1101 return true;
1103 // Convenience synonyms.
1104 if (type_arg == "eth")
1105 type_arg = shill::kTypeEthernet;
1107 if (type_arg != shill::kTypeEthernet &&
1108 type_arg != shill::kTypeWifi &&
1109 type_arg != shill::kTypeCellular &&
1110 type_arg != shill::kTypeWimax &&
1111 type_arg != shill::kTypeVPN) {
1112 LOG(WARNING) << "Unrecognized Shill network type: " << type_arg;
1113 return false;
1116 // Unconnected or disabled ethernet is the same as unavailable.
1117 if (type_arg == shill::kTypeEthernet &&
1118 (state == shill::kStateIdle || state == kNetworkDisabled)) {
1119 state = kTechnologyUnavailable;
1122 shill_initial_state_map_[type_arg] = state;
1123 return true;
1126 std::string FakeShillManagerClient::GetInitialStateForType(
1127 const std::string& type,
1128 bool* enabled) {
1129 std::map<std::string, std::string>::const_iterator iter =
1130 shill_initial_state_map_.find(type);
1131 if (iter == shill_initial_state_map_.end()) {
1132 *enabled = false;
1133 return kTechnologyUnavailable;
1135 std::string state = iter->second;
1136 if (state == kNetworkDisabled) {
1137 *enabled = false;
1138 return shill::kStateIdle;
1140 *enabled = true;
1141 if ((state == shill::kStatePortal && type != shill::kTypeWifi) ||
1142 (state == kNetworkActivated && type != shill::kTypeCellular)) {
1143 LOG(WARNING) << "Invalid state: " << state << " for " << type;
1144 return shill::kStateIdle;
1146 return state;
1149 } // namespace chromeos