Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chromeos / dbus / fake_shill_manager_client.cc
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.
4
5 #include "chromeos/dbus/fake_shill_manager_client.h"
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/values.h"
11 #include "chromeos/chromeos_switches.h"
12 #include "chromeos/dbus/dbus_thread_manager.h"
13 #include "chromeos/dbus/shill_device_client.h"
14 #include "chromeos/dbus/shill_profile_client.h"
15 #include "chromeos/dbus/shill_property_changed_observer.h"
16 #include "chromeos/dbus/shill_service_client.h"
17 #include "dbus/bus.h"
18 #include "dbus/message.h"
19 #include "dbus/object_path.h"
20 #include "dbus/values_util.h"
21 #include "third_party/cros_system_api/dbus/service_constants.h"
22
23 namespace chromeos {
24
25 namespace {
26
27 // Used to compare values for finding entries to erase in a ListValue.
28 // (ListValue only implements a const_iterator version of Find).
29 struct ValueEquals {
30   explicit ValueEquals(const base::Value* first) : first_(first) {}
31   bool operator()(const base::Value* second) const {
32     return first_->Equals(second);
33   }
34   const base::Value* first_;
35 };
36
37 // Appends string entries from |service_list_in| whose entries in ServiceClient
38 // have Type |match_type| to either an active list or an inactive list
39 // based on the entry's State.
40 void AppendServicesForType(
41     const base::ListValue* service_list_in,
42     const char* match_type,
43     std::vector<std::string>* active_service_list_out,
44     std::vector<std::string>* inactive_service_list_out) {
45   ShillServiceClient::TestInterface* service_client =
46       DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
47   for (base::ListValue::const_iterator iter = service_list_in->begin();
48        iter != service_list_in->end(); ++iter) {
49     std::string service_path;
50     if (!(*iter)->GetAsString(&service_path))
51       continue;
52     const base::DictionaryValue* properties =
53         service_client->GetServiceProperties(service_path);
54     if (!properties) {
55       LOG(ERROR) << "Properties not found for service: " << service_path;
56       continue;
57     }
58     std::string type;
59     properties->GetString(shill::kTypeProperty, &type);
60     if (type != match_type)
61       continue;
62     std::string state;
63     properties->GetString(shill::kStateProperty, &state);
64     if (state == shill::kStateOnline ||
65         state == shill::kStateAssociation ||
66         state == shill::kStateConfiguration ||
67         state == shill::kStatePortal ||
68         state == shill::kStateReady) {
69       active_service_list_out->push_back(service_path);
70     } else {
71       inactive_service_list_out->push_back(service_path);
72     }
73   }
74 }
75
76 }  // namespace
77
78 FakeShillManagerClient::FakeShillManagerClient()
79     : weak_ptr_factory_(this) {
80 }
81
82 FakeShillManagerClient::~FakeShillManagerClient() {}
83
84 // ShillManagerClient overrides.
85
86 void FakeShillManagerClient::Init(dbus::Bus* bus) {}
87
88 void FakeShillManagerClient::AddPropertyChangedObserver(
89     ShillPropertyChangedObserver* observer) {
90   observer_list_.AddObserver(observer);
91 }
92
93 void FakeShillManagerClient::RemovePropertyChangedObserver(
94     ShillPropertyChangedObserver* observer) {
95   observer_list_.RemoveObserver(observer);
96 }
97
98 void FakeShillManagerClient::GetProperties(
99     const DictionaryValueCallback& callback) {
100   base::MessageLoop::current()->PostTask(
101       FROM_HERE, base::Bind(
102           &FakeShillManagerClient::PassStubProperties,
103           weak_ptr_factory_.GetWeakPtr(),
104           callback));
105 }
106
107 void FakeShillManagerClient::GetNetworksForGeolocation(
108     const DictionaryValueCallback& callback) {
109   base::MessageLoop::current()->PostTask(
110       FROM_HERE, base::Bind(
111           &FakeShillManagerClient::PassStubGeoNetworks,
112           weak_ptr_factory_.GetWeakPtr(),
113           callback));
114 }
115
116 void FakeShillManagerClient::SetProperty(const std::string& name,
117                                          const base::Value& value,
118                                          const base::Closure& callback,
119                                          const ErrorCallback& error_callback) {
120   stub_properties_.SetWithoutPathExpansion(name, value.DeepCopy());
121   CallNotifyObserversPropertyChanged(name, 0);
122   base::MessageLoop::current()->PostTask(FROM_HERE, callback);
123 }
124
125 void FakeShillManagerClient::RequestScan(const std::string& type,
126                                          const base::Closure& callback,
127                                          const ErrorCallback& error_callback) {
128   // For Stub purposes, default to a Wifi scan.
129   std::string device_type = shill::kTypeWifi;
130   if (!type.empty())
131     device_type = type;
132   ShillDeviceClient::TestInterface* device_client =
133       DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
134   std::string device_path = device_client->GetDevicePathForType(device_type);
135   if (!device_path.empty()) {
136     device_client->SetDeviceProperty(device_path,
137                                      shill::kScanningProperty,
138                                      base::FundamentalValue(true));
139   }
140   const int kScanDurationSeconds = 3;
141   int scan_duration_seconds = kScanDurationSeconds;
142   if (!CommandLine::ForCurrentProcess()->HasSwitch(
143       chromeos::switches::kEnableStubInteractive)) {
144     scan_duration_seconds = 0;
145   }
146   base::MessageLoop::current()->PostDelayedTask(
147       FROM_HERE,
148       base::Bind(&FakeShillManagerClient::ScanCompleted,
149                  weak_ptr_factory_.GetWeakPtr(), device_path, callback),
150       base::TimeDelta::FromSeconds(scan_duration_seconds));
151 }
152
153 void FakeShillManagerClient::EnableTechnology(
154     const std::string& type,
155     const base::Closure& callback,
156     const ErrorCallback& error_callback) {
157   base::ListValue* enabled_list = NULL;
158   if (!stub_properties_.GetListWithoutPathExpansion(
159       shill::kEnabledTechnologiesProperty, &enabled_list)) {
160     base::MessageLoop::current()->PostTask(FROM_HERE, callback);
161     base::MessageLoop::current()->PostTask(
162         FROM_HERE,
163         base::Bind(error_callback, "StubError", "Property not found"));
164     return;
165   }
166   if (CommandLine::ForCurrentProcess()->HasSwitch(
167           chromeos::switches::kEnableStubInteractive)) {
168     const int kEnableTechnologyDelaySeconds = 3;
169     base::MessageLoop::current()->PostDelayedTask(
170         FROM_HERE,
171         base::Bind(&FakeShillManagerClient::SetTechnologyEnabled,
172                    weak_ptr_factory_.GetWeakPtr(), type, callback, true),
173         base::TimeDelta::FromSeconds(kEnableTechnologyDelaySeconds));
174   } else {
175     SetTechnologyEnabled(type, callback, true);
176   }
177 }
178
179 void FakeShillManagerClient::DisableTechnology(
180     const std::string& type,
181     const base::Closure& callback,
182     const ErrorCallback& error_callback) {
183   base::ListValue* enabled_list = NULL;
184   if (!stub_properties_.GetListWithoutPathExpansion(
185       shill::kEnabledTechnologiesProperty, &enabled_list)) {
186     base::MessageLoop::current()->PostTask(
187         FROM_HERE,
188         base::Bind(error_callback, "StubError", "Property not found"));
189     return;
190   }
191   if (CommandLine::ForCurrentProcess()->HasSwitch(
192           chromeos::switches::kEnableStubInteractive)) {
193     const int kDisableTechnologyDelaySeconds = 3;
194     base::MessageLoop::current()->PostDelayedTask(
195         FROM_HERE,
196         base::Bind(&FakeShillManagerClient::SetTechnologyEnabled,
197                    weak_ptr_factory_.GetWeakPtr(), type, callback, false),
198         base::TimeDelta::FromSeconds(kDisableTechnologyDelaySeconds));
199   } else {
200     SetTechnologyEnabled(type, callback, false);
201   }
202 }
203
204 void FakeShillManagerClient::ConfigureService(
205     const base::DictionaryValue& properties,
206     const ObjectPathCallback& callback,
207     const ErrorCallback& error_callback) {
208   ShillServiceClient::TestInterface* service_client =
209       DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
210
211   std::string guid;
212   std::string type;
213   if (!properties.GetString(shill::kGuidProperty, &guid) ||
214       !properties.GetString(shill::kTypeProperty, &type)) {
215     LOG(ERROR) << "ConfigureService requies GUID and Type to be defined";
216     // If the properties aren't filled out completely, then just return an empty
217     // object path.
218     base::MessageLoop::current()->PostTask(
219         FROM_HERE, base::Bind(callback, dbus::ObjectPath()));
220     return;
221   }
222
223   // For the purposes of this stub, we're going to assume that the GUID property
224   // is set to the service path because we don't want to re-implement Shill's
225   // property matching magic here.
226   std::string service_path = guid;
227
228   std::string ipconfig_path;
229   properties.GetString(shill::kIPConfigProperty, &ipconfig_path);
230
231   // Merge the new properties with existing properties, if any.
232   const base::DictionaryValue* existing_properties =
233       service_client->GetServiceProperties(service_path);
234   if (!existing_properties) {
235     // Add a new service to the service client stub because none exists, yet.
236     // This calls AddManagerService.
237     service_client->AddServiceWithIPConfig(service_path, guid, type,
238                                            shill::kStateIdle, ipconfig_path,
239                                            true /* visible */,
240                                            true /* watch */);
241     existing_properties = service_client->GetServiceProperties(service_path);
242   }
243
244   scoped_ptr<base::DictionaryValue> merged_properties(
245       existing_properties->DeepCopy());
246   merged_properties->MergeDictionary(&properties);
247
248   // Now set all the properties.
249   for (base::DictionaryValue::Iterator iter(*merged_properties);
250        !iter.IsAtEnd(); iter.Advance()) {
251     service_client->SetServiceProperty(service_path, iter.key(), iter.value());
252   }
253
254   // If the Profile property is set, add it to ProfileClient.
255   std::string profile_path;
256   merged_properties->GetStringWithoutPathExpansion(shill::kProfileProperty,
257                                                    &profile_path);
258   if (!profile_path.empty()) {
259     DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface()->
260         AddService(profile_path, service_path);
261   }
262
263   base::MessageLoop::current()->PostTask(
264       FROM_HERE, base::Bind(callback, dbus::ObjectPath(service_path)));
265 }
266
267 void FakeShillManagerClient::ConfigureServiceForProfile(
268     const dbus::ObjectPath& profile_path,
269     const base::DictionaryValue& properties,
270     const ObjectPathCallback& callback,
271     const ErrorCallback& error_callback) {
272   std::string profile_property;
273   properties.GetStringWithoutPathExpansion(shill::kProfileProperty,
274                                            &profile_property);
275   CHECK(profile_property == profile_path.value());
276   ConfigureService(properties, callback, error_callback);
277 }
278
279
280 void FakeShillManagerClient::GetService(
281     const base::DictionaryValue& properties,
282     const ObjectPathCallback& callback,
283     const ErrorCallback& error_callback) {
284   base::MessageLoop::current()->PostTask(
285       FROM_HERE, base::Bind(callback, dbus::ObjectPath()));
286 }
287
288 void FakeShillManagerClient::VerifyDestination(
289     const VerificationProperties& properties,
290     const BooleanCallback& callback,
291     const ErrorCallback& error_callback) {
292   base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true));
293 }
294
295 void FakeShillManagerClient::VerifyAndEncryptCredentials(
296     const VerificationProperties& properties,
297     const std::string& service_path,
298     const StringCallback& callback,
299     const ErrorCallback& error_callback) {
300   base::MessageLoop::current()->PostTask(
301       FROM_HERE, base::Bind(callback, "encrypted_credentials"));
302 }
303
304 void FakeShillManagerClient::VerifyAndEncryptData(
305     const VerificationProperties& properties,
306     const std::string& data,
307     const StringCallback& callback,
308     const ErrorCallback& error_callback) {
309   base::MessageLoop::current()->PostTask(FROM_HERE,
310                                    base::Bind(callback, "encrypted_data"));
311 }
312
313 void FakeShillManagerClient::ConnectToBestServices(
314     const base::Closure& callback,
315     const ErrorCallback& error_callback) {
316 }
317
318 ShillManagerClient::TestInterface* FakeShillManagerClient::GetTestInterface() {
319   return this;
320 }
321
322 // ShillManagerClient::TestInterface overrides.
323
324 void FakeShillManagerClient::AddDevice(const std::string& device_path) {
325   if (GetListProperty(shill::kDevicesProperty)->AppendIfNotPresent(
326       base::Value::CreateStringValue(device_path))) {
327     CallNotifyObserversPropertyChanged(shill::kDevicesProperty, 0);
328   }
329 }
330
331 void FakeShillManagerClient::RemoveDevice(const std::string& device_path) {
332   base::StringValue device_path_value(device_path);
333   if (GetListProperty(shill::kDevicesProperty)->Remove(
334       device_path_value, NULL)) {
335     CallNotifyObserversPropertyChanged(shill::kDevicesProperty, 0);
336   }
337 }
338
339 void FakeShillManagerClient::ClearDevices() {
340   GetListProperty(shill::kDevicesProperty)->Clear();
341   CallNotifyObserversPropertyChanged(shill::kDevicesProperty, 0);
342 }
343
344 void FakeShillManagerClient::AddTechnology(const std::string& type,
345                                            bool enabled) {
346   if (GetListProperty(shill::kAvailableTechnologiesProperty)->
347       AppendIfNotPresent(base::Value::CreateStringValue(type))) {
348     CallNotifyObserversPropertyChanged(
349         shill::kAvailableTechnologiesProperty, 0);
350   }
351   if (enabled &&
352       GetListProperty(shill::kEnabledTechnologiesProperty)->
353       AppendIfNotPresent(base::Value::CreateStringValue(type))) {
354     CallNotifyObserversPropertyChanged(
355         shill::kEnabledTechnologiesProperty, 0);
356   }
357 }
358
359 void FakeShillManagerClient::RemoveTechnology(const std::string& type) {
360   base::StringValue type_value(type);
361   if (GetListProperty(shill::kAvailableTechnologiesProperty)->Remove(
362       type_value, NULL)) {
363     CallNotifyObserversPropertyChanged(
364         shill::kAvailableTechnologiesProperty, 0);
365   }
366   if (GetListProperty(shill::kEnabledTechnologiesProperty)->Remove(
367       type_value, NULL)) {
368     CallNotifyObserversPropertyChanged(
369         shill::kEnabledTechnologiesProperty, 0);
370   }
371 }
372
373 void FakeShillManagerClient::SetTechnologyInitializing(const std::string& type,
374                                                        bool initializing) {
375   if (initializing) {
376     if (GetListProperty(shill::kUninitializedTechnologiesProperty)->
377         AppendIfNotPresent(base::Value::CreateStringValue(type))) {
378       CallNotifyObserversPropertyChanged(
379           shill::kUninitializedTechnologiesProperty, 0);
380     }
381   } else {
382     if (GetListProperty(shill::kUninitializedTechnologiesProperty)->Remove(
383             base::StringValue(type), NULL)) {
384       CallNotifyObserversPropertyChanged(
385           shill::kUninitializedTechnologiesProperty, 0);
386     }
387   }
388 }
389
390 void FakeShillManagerClient::ClearProperties() {
391   stub_properties_.Clear();
392 }
393
394 void FakeShillManagerClient::AddManagerService(const std::string& service_path,
395                                                bool add_to_visible_list,
396                                                bool add_to_watch_list) {
397   // Always add to ServiceCompleteListProperty.
398   GetListProperty(shill::kServiceCompleteListProperty)->AppendIfNotPresent(
399       base::Value::CreateStringValue(service_path));
400   // If visible, add to Services and notify if new.
401   if (add_to_visible_list &&
402       GetListProperty(shill::kServicesProperty)->AppendIfNotPresent(
403       base::Value::CreateStringValue(service_path))) {
404     CallNotifyObserversPropertyChanged(shill::kServicesProperty, 0);
405   }
406   if (add_to_watch_list)
407     AddServiceToWatchList(service_path);
408 }
409
410 void FakeShillManagerClient::RemoveManagerService(
411     const std::string& service_path) {
412   base::StringValue service_path_value(service_path);
413   if (GetListProperty(shill::kServicesProperty)->Remove(
414       service_path_value, NULL)) {
415     CallNotifyObserversPropertyChanged(shill::kServicesProperty, 0);
416   }
417   GetListProperty(shill::kServiceCompleteListProperty)->Remove(
418       service_path_value, NULL);
419   if (GetListProperty(shill::kServiceWatchListProperty)->Remove(
420       service_path_value, NULL)) {
421     CallNotifyObserversPropertyChanged(
422         shill::kServiceWatchListProperty, 0);
423   }
424 }
425
426 void FakeShillManagerClient::ClearManagerServices() {
427   GetListProperty(shill::kServicesProperty)->Clear();
428   GetListProperty(shill::kServiceCompleteListProperty)->Clear();
429   GetListProperty(shill::kServiceWatchListProperty)->Clear();
430   CallNotifyObserversPropertyChanged(shill::kServicesProperty, 0);
431   CallNotifyObserversPropertyChanged(shill::kServiceWatchListProperty, 0);
432 }
433
434 void FakeShillManagerClient::SortManagerServices() {
435   static const char* ordered_types[] = {
436     shill::kTypeEthernet,
437     shill::kTypeWifi,
438     shill::kTypeCellular,
439     shill::kTypeWimax,
440     shill::kTypeVPN
441   };
442   base::ListValue* service_list = GetListProperty(shill::kServicesProperty);
443   if (!service_list || service_list->empty())
444     return;
445   std::vector<std::string> active_services;
446   std::vector<std::string> inactive_services;
447   for (size_t i = 0; i < arraysize(ordered_types); ++i) {
448     AppendServicesForType(service_list, ordered_types[i],
449                           &active_services, &inactive_services);
450   }
451   service_list->Clear();
452   for (size_t i = 0; i < active_services.size(); ++i)
453     service_list->AppendString(active_services[i]);
454   for (size_t i = 0; i < inactive_services.size(); ++i)
455     service_list->AppendString(inactive_services[i]);
456
457   CallNotifyObserversPropertyChanged(shill::kServicesProperty, 0);
458 }
459
460 void FakeShillManagerClient::AddGeoNetwork(
461     const std::string& technology,
462     const base::DictionaryValue& network) {
463   base::ListValue* list_value = NULL;
464   if (!stub_geo_networks_.GetListWithoutPathExpansion(
465       technology, &list_value)) {
466     list_value = new base::ListValue;
467     stub_geo_networks_.SetWithoutPathExpansion(technology, list_value);
468   }
469   list_value->Append(network.DeepCopy());
470 }
471
472 void FakeShillManagerClient::AddProfile(const std::string& profile_path) {
473   const char* key = shill::kProfilesProperty;
474   if (GetListProperty(key)->AppendIfNotPresent(
475           new base::StringValue(profile_path))) {
476     CallNotifyObserversPropertyChanged(key, 0);
477   }
478 }
479
480 void FakeShillManagerClient::AddServiceToWatchList(
481     const std::string& service_path) {
482   // Remove and insert the service, moving it to the front of the watch list.
483   GetListProperty(shill::kServiceWatchListProperty)->Remove(
484       base::StringValue(service_path), NULL);
485   GetListProperty(shill::kServiceWatchListProperty)->Insert(
486       0, base::Value::CreateStringValue(service_path));
487   CallNotifyObserversPropertyChanged(
488       shill::kServiceWatchListProperty, 0);
489 }
490
491 void FakeShillManagerClient::PassStubProperties(
492     const DictionaryValueCallback& callback) const {
493   scoped_ptr<base::DictionaryValue> stub_properties(
494       stub_properties_.DeepCopy());
495   // Remove disabled services from the list.
496   stub_properties->SetWithoutPathExpansion(
497       shill::kServicesProperty,
498       GetEnabledServiceList(shill::kServicesProperty));
499   stub_properties->SetWithoutPathExpansion(
500       shill::kServiceWatchListProperty,
501       GetEnabledServiceList(shill::kServiceWatchListProperty));
502   callback.Run(DBUS_METHOD_CALL_SUCCESS, *stub_properties);
503 }
504
505 void FakeShillManagerClient::PassStubGeoNetworks(
506     const DictionaryValueCallback& callback) const {
507   callback.Run(DBUS_METHOD_CALL_SUCCESS, stub_geo_networks_);
508 }
509
510 void FakeShillManagerClient::CallNotifyObserversPropertyChanged(
511     const std::string& property,
512     int delay_ms) {
513   // Avoid unnecessary delayed task if we have no observers (e.g. during
514   // initial setup).
515   if (!observer_list_.might_have_observers())
516     return;
517   if (!CommandLine::ForCurrentProcess()->HasSwitch(
518           chromeos::switches::kEnableStubInteractive)) {
519     delay_ms = 0;
520   }
521   base::MessageLoop::current()->PostDelayedTask(
522       FROM_HERE,
523       base::Bind(&FakeShillManagerClient::NotifyObserversPropertyChanged,
524                  weak_ptr_factory_.GetWeakPtr(),
525                  property),
526                  base::TimeDelta::FromMilliseconds(delay_ms));
527 }
528
529 void FakeShillManagerClient::NotifyObserversPropertyChanged(
530     const std::string& property) {
531   if (property == shill::kServicesProperty ||
532       property == shill::kServiceWatchListProperty) {
533     scoped_ptr<base::ListValue> services(GetEnabledServiceList(property));
534     FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
535                       observer_list_,
536                       OnPropertyChanged(property, *(services.get())));
537     return;
538   }
539   if (property == shill::kDevicesProperty) {
540     base::ListValue* devices = NULL;
541     if (stub_properties_.GetListWithoutPathExpansion(
542             shill::kDevicesProperty, &devices)) {
543       FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
544                         observer_list_,
545                         OnPropertyChanged(property, *devices));
546     }
547     return;
548   }
549   base::Value* value = NULL;
550   if (!stub_properties_.GetWithoutPathExpansion(property, &value)) {
551     LOG(ERROR) << "Notify for unknown property: " << property;
552     return;
553   }
554   FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
555                     observer_list_,
556                     OnPropertyChanged(property, *value));
557 }
558
559 base::ListValue* FakeShillManagerClient::GetListProperty(
560     const std::string& property) {
561   base::ListValue* list_property = NULL;
562   if (!stub_properties_.GetListWithoutPathExpansion(
563       property, &list_property)) {
564     list_property = new base::ListValue;
565     stub_properties_.SetWithoutPathExpansion(property, list_property);
566   }
567   return list_property;
568 }
569
570 bool FakeShillManagerClient::TechnologyEnabled(const std::string& type) const {
571   if (type == shill::kTypeVPN)
572     return true;  // VPN is always "enabled" since there is no associated device
573   bool enabled = false;
574   const base::ListValue* technologies;
575   if (stub_properties_.GetListWithoutPathExpansion(
576           shill::kEnabledTechnologiesProperty, &technologies)) {
577     base::StringValue type_value(type);
578     if (technologies->Find(type_value) != technologies->end())
579       enabled = true;
580   }
581   return enabled;
582 }
583
584 void FakeShillManagerClient::SetTechnologyEnabled(
585     const std::string& type,
586     const base::Closure& callback,
587     bool enabled) {
588   base::ListValue* enabled_list = NULL;
589   stub_properties_.GetListWithoutPathExpansion(
590       shill::kEnabledTechnologiesProperty, &enabled_list);
591   DCHECK(enabled_list);
592   if (enabled)
593     enabled_list->AppendIfNotPresent(new base::StringValue(type));
594   else
595     enabled_list->Remove(base::StringValue(type), NULL);
596   CallNotifyObserversPropertyChanged(
597       shill::kEnabledTechnologiesProperty, 0 /* already delayed */);
598   base::MessageLoop::current()->PostTask(FROM_HERE, callback);
599   // May affect available services
600   CallNotifyObserversPropertyChanged(shill::kServicesProperty, 0);
601   CallNotifyObserversPropertyChanged(shill::kServiceWatchListProperty, 0);
602 }
603
604 base::ListValue* FakeShillManagerClient::GetEnabledServiceList(
605     const std::string& property) const {
606   base::ListValue* new_service_list = new base::ListValue;
607   const base::ListValue* service_list;
608   if (stub_properties_.GetListWithoutPathExpansion(property, &service_list)) {
609     ShillServiceClient::TestInterface* service_client =
610         DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
611     for (base::ListValue::const_iterator iter = service_list->begin();
612          iter != service_list->end(); ++iter) {
613       std::string service_path;
614       if (!(*iter)->GetAsString(&service_path))
615         continue;
616       const base::DictionaryValue* properties =
617           service_client->GetServiceProperties(service_path);
618       if (!properties) {
619         LOG(ERROR) << "Properties not found for service: " << service_path;
620         continue;
621       }
622       std::string name;
623       properties->GetString(shill::kNameProperty, &name);
624       std::string type;
625       properties->GetString(shill::kTypeProperty, &type);
626       if (TechnologyEnabled(type))
627         new_service_list->Append((*iter)->DeepCopy());
628     }
629   }
630   return new_service_list;
631 }
632
633 void FakeShillManagerClient::ScanCompleted(const std::string& device_path,
634                                            const base::Closure& callback) {
635   if (!device_path.empty()) {
636     DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface()->
637         SetDeviceProperty(device_path,
638                           shill::kScanningProperty,
639                           base::FundamentalValue(false));
640   }
641   CallNotifyObserversPropertyChanged(shill::kServicesProperty, 0);
642   CallNotifyObserversPropertyChanged(shill::kServiceWatchListProperty, 0);
643   base::MessageLoop::current()->PostTask(FROM_HERE, callback);
644 }
645
646 }  // namespace chromeos