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_device_client.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/stl_util.h"
10 #include "base/values.h"
11 #include "chromeos/dbus/dbus_thread_manager.h"
12 #include "chromeos/dbus/shill_manager_client.h"
13 #include "chromeos/dbus/shill_property_changed_observer.h"
15 #include "dbus/message.h"
16 #include "dbus/object_path.h"
17 #include "dbus/object_proxy.h"
18 #include "dbus/values_util.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
25 void ErrorFunction(const std::string
& device_path
,
26 const std::string
& error_name
,
27 const std::string
& error_message
) {
28 LOG(ERROR
) << "Shill Error for: " << device_path
29 << ": " << error_name
<< " : " << error_message
;
32 void PostDeviceNotFoundError(
33 const ShillDeviceClient::ErrorCallback
& error_callback
) {
34 std::string
error_message("Failed");
35 base::MessageLoop::current()->PostTask(
37 base::Bind(error_callback
, shill::kErrorResultNotFound
, error_message
));
42 FakeShillDeviceClient::FakeShillDeviceClient()
43 : tdls_busy_count_(0),
44 weak_ptr_factory_(this) {
47 FakeShillDeviceClient::~FakeShillDeviceClient() {
48 STLDeleteContainerPairSecondPointers(
49 observer_list_
.begin(), observer_list_
.end());
52 // ShillDeviceClient overrides.
54 void FakeShillDeviceClient::Init(dbus::Bus
* bus
) {}
56 void FakeShillDeviceClient::AddPropertyChangedObserver(
57 const dbus::ObjectPath
& device_path
,
58 ShillPropertyChangedObserver
* observer
) {
59 GetObserverList(device_path
).AddObserver(observer
);
62 void FakeShillDeviceClient::RemovePropertyChangedObserver(
63 const dbus::ObjectPath
& device_path
,
64 ShillPropertyChangedObserver
* observer
) {
65 GetObserverList(device_path
).RemoveObserver(observer
);
68 void FakeShillDeviceClient::GetProperties(
69 const dbus::ObjectPath
& device_path
,
70 const DictionaryValueCallback
& callback
) {
71 base::MessageLoop::current()->PostTask(
73 base::Bind(&FakeShillDeviceClient::PassStubDeviceProperties
,
74 weak_ptr_factory_
.GetWeakPtr(),
75 device_path
, callback
));
78 void FakeShillDeviceClient::ProposeScan(
79 const dbus::ObjectPath
& device_path
,
80 const VoidDBusMethodCallback
& callback
) {
81 PostVoidCallback(callback
, DBUS_METHOD_CALL_SUCCESS
);
84 void FakeShillDeviceClient::SetProperty(const dbus::ObjectPath
& device_path
,
85 const std::string
& name
,
86 const base::Value
& value
,
87 const base::Closure
& callback
,
88 const ErrorCallback
& error_callback
) {
89 base::DictionaryValue
* device_properties
= NULL
;
90 if (!stub_devices_
.GetDictionaryWithoutPathExpansion(device_path
.value(),
91 &device_properties
)) {
92 PostDeviceNotFoundError(error_callback
);
95 device_properties
->SetWithoutPathExpansion(name
, value
.DeepCopy());
96 base::MessageLoop::current()->PostTask(
98 base::Bind(&FakeShillDeviceClient::NotifyObserversPropertyChanged
,
99 weak_ptr_factory_
.GetWeakPtr(), device_path
, name
));
100 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
103 void FakeShillDeviceClient::ClearProperty(
104 const dbus::ObjectPath
& device_path
,
105 const std::string
& name
,
106 const VoidDBusMethodCallback
& callback
) {
107 base::DictionaryValue
* device_properties
= NULL
;
108 if (!stub_devices_
.GetDictionaryWithoutPathExpansion(device_path
.value(),
109 &device_properties
)) {
110 PostVoidCallback(callback
, DBUS_METHOD_CALL_FAILURE
);
113 device_properties
->RemoveWithoutPathExpansion(name
, NULL
);
114 PostVoidCallback(callback
, DBUS_METHOD_CALL_SUCCESS
);
117 void FakeShillDeviceClient::AddIPConfig(
118 const dbus::ObjectPath
& device_path
,
119 const std::string
& method
,
120 const ObjectPathDBusMethodCallback
& callback
) {
121 base::MessageLoop::current()->PostTask(FROM_HERE
,
123 DBUS_METHOD_CALL_SUCCESS
,
124 dbus::ObjectPath()));
127 void FakeShillDeviceClient::RequirePin(const dbus::ObjectPath
& device_path
,
128 const std::string
& pin
,
130 const base::Closure
& callback
,
131 const ErrorCallback
& error_callback
) {
132 if (!stub_devices_
.HasKey(device_path
.value())) {
133 PostDeviceNotFoundError(error_callback
);
136 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
139 void FakeShillDeviceClient::EnterPin(const dbus::ObjectPath
& device_path
,
140 const std::string
& pin
,
141 const base::Closure
& callback
,
142 const ErrorCallback
& error_callback
) {
143 if (!stub_devices_
.HasKey(device_path
.value())) {
144 PostDeviceNotFoundError(error_callback
);
147 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
150 void FakeShillDeviceClient::UnblockPin(const dbus::ObjectPath
& device_path
,
151 const std::string
& puk
,
152 const std::string
& pin
,
153 const base::Closure
& callback
,
154 const ErrorCallback
& error_callback
) {
155 if (!stub_devices_
.HasKey(device_path
.value())) {
156 PostDeviceNotFoundError(error_callback
);
159 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
162 void FakeShillDeviceClient::ChangePin(const dbus::ObjectPath
& device_path
,
163 const std::string
& old_pin
,
164 const std::string
& new_pin
,
165 const base::Closure
& callback
,
166 const ErrorCallback
& error_callback
) {
167 if (!stub_devices_
.HasKey(device_path
.value())) {
168 PostDeviceNotFoundError(error_callback
);
171 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
174 void FakeShillDeviceClient::Register(const dbus::ObjectPath
& device_path
,
175 const std::string
& network_id
,
176 const base::Closure
& callback
,
177 const ErrorCallback
& error_callback
) {
178 if (!stub_devices_
.HasKey(device_path
.value())) {
179 PostDeviceNotFoundError(error_callback
);
182 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
185 void FakeShillDeviceClient::SetCarrier(const dbus::ObjectPath
& device_path
,
186 const std::string
& carrier
,
187 const base::Closure
& callback
,
188 const ErrorCallback
& error_callback
) {
189 if (!stub_devices_
.HasKey(device_path
.value())) {
190 PostDeviceNotFoundError(error_callback
);
193 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
196 void FakeShillDeviceClient::Reset(const dbus::ObjectPath
& device_path
,
197 const base::Closure
& callback
,
198 const ErrorCallback
& error_callback
) {
199 if (!stub_devices_
.HasKey(device_path
.value())) {
200 PostDeviceNotFoundError(error_callback
);
203 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
206 void FakeShillDeviceClient::PerformTDLSOperation(
207 const dbus::ObjectPath
& device_path
,
208 const std::string
& operation
,
209 const std::string
& peer
,
210 const StringCallback
& callback
,
211 const ErrorCallback
& error_callback
) {
212 if (!stub_devices_
.HasKey(device_path
.value())) {
213 PostDeviceNotFoundError(error_callback
);
216 if (tdls_busy_count_
) {
218 std::string
error_message("In-Progress");
219 base::MessageLoop::current()->PostTask(
221 base::Bind(error_callback
,
222 shill::kErrorResultInProgress
, error_message
));
226 if (operation
== shill::kTDLSStatusOperation
)
227 result
= shill::kTDLSConnectedState
;
228 base::MessageLoop::current()->PostTask(FROM_HERE
,
229 base::Bind(callback
, result
));
232 ShillDeviceClient::TestInterface
* FakeShillDeviceClient::GetTestInterface() {
236 // ShillDeviceClient::TestInterface overrides.
238 void FakeShillDeviceClient::AddDevice(const std::string
& device_path
,
239 const std::string
& type
,
240 const std::string
& object_path
) {
241 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
242 AddDevice(device_path
);
244 base::DictionaryValue
* properties
= GetDeviceProperties(device_path
);
245 properties
->SetWithoutPathExpansion(shill::kTypeProperty
,
246 base::Value::CreateStringValue(type
));
247 properties
->SetWithoutPathExpansion(
248 shill::kNameProperty
,
249 base::Value::CreateStringValue(object_path
));
250 properties
->SetWithoutPathExpansion(
251 shill::kDBusObjectProperty
, base::Value::CreateStringValue(object_path
));
252 properties
->SetWithoutPathExpansion(
253 shill::kDBusServiceProperty
,
254 base::Value::CreateStringValue(modemmanager::kModemManager1ServiceName
));
255 if (type
== shill::kTypeCellular
) {
256 properties
->SetWithoutPathExpansion(shill::kCellularAllowRoamingProperty
,
257 new base::FundamentalValue(false));
261 void FakeShillDeviceClient::RemoveDevice(const std::string
& device_path
) {
262 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
263 RemoveDevice(device_path
);
265 stub_devices_
.RemoveWithoutPathExpansion(device_path
, NULL
);
268 void FakeShillDeviceClient::ClearDevices() {
269 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
272 stub_devices_
.Clear();
275 void FakeShillDeviceClient::SetDeviceProperty(const std::string
& device_path
,
276 const std::string
& name
,
277 const base::Value
& value
) {
278 VLOG(1) << "SetDeviceProperty: " << device_path
279 << ": " << name
<< " = " << value
;
280 SetProperty(dbus::ObjectPath(device_path
), name
, value
,
281 base::Bind(&base::DoNothing
),
282 base::Bind(&ErrorFunction
, device_path
));
285 std::string
FakeShillDeviceClient::GetDevicePathForType(
286 const std::string
& type
) {
287 for (base::DictionaryValue::Iterator
iter(stub_devices_
);
288 !iter
.IsAtEnd(); iter
.Advance()) {
289 const base::DictionaryValue
* properties
= NULL
;
290 if (!iter
.value().GetAsDictionary(&properties
))
292 std::string prop_type
;
293 if (!properties
->GetStringWithoutPathExpansion(
294 shill::kTypeProperty
, &prop_type
) ||
299 return std::string();
302 void FakeShillDeviceClient::PassStubDeviceProperties(
303 const dbus::ObjectPath
& device_path
,
304 const DictionaryValueCallback
& callback
) const {
305 const base::DictionaryValue
* device_properties
= NULL
;
306 if (!stub_devices_
.GetDictionaryWithoutPathExpansion(
307 device_path
.value(), &device_properties
)) {
308 base::DictionaryValue empty_dictionary
;
309 callback
.Run(DBUS_METHOD_CALL_FAILURE
, empty_dictionary
);
312 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, *device_properties
);
315 // Posts a task to run a void callback with status code |status|.
316 void FakeShillDeviceClient::PostVoidCallback(
317 const VoidDBusMethodCallback
& callback
,
318 DBusMethodCallStatus status
) {
319 base::MessageLoop::current()->PostTask(FROM_HERE
,
320 base::Bind(callback
, status
));
323 void FakeShillDeviceClient::NotifyObserversPropertyChanged(
324 const dbus::ObjectPath
& device_path
,
325 const std::string
& property
) {
326 base::DictionaryValue
* dict
= NULL
;
327 std::string path
= device_path
.value();
328 if (!stub_devices_
.GetDictionaryWithoutPathExpansion(path
, &dict
)) {
329 LOG(ERROR
) << "Notify for unknown service: " << path
;
332 base::Value
* value
= NULL
;
333 if (!dict
->GetWithoutPathExpansion(property
, &value
)) {
334 LOG(ERROR
) << "Notify for unknown property: "
335 << path
<< " : " << property
;
338 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
339 GetObserverList(device_path
),
340 OnPropertyChanged(property
, *value
));
343 base::DictionaryValue
* FakeShillDeviceClient::GetDeviceProperties(
344 const std::string
& device_path
) {
345 base::DictionaryValue
* properties
= NULL
;
346 if (!stub_devices_
.GetDictionaryWithoutPathExpansion(
347 device_path
, &properties
)) {
348 properties
= new base::DictionaryValue
;
349 stub_devices_
.SetWithoutPathExpansion(device_path
, properties
);
354 FakeShillDeviceClient::PropertyObserverList
&
355 FakeShillDeviceClient::GetObserverList(const dbus::ObjectPath
& device_path
) {
356 std::map
<dbus::ObjectPath
, PropertyObserverList
*>::iterator iter
=
357 observer_list_
.find(device_path
);
358 if (iter
!= observer_list_
.end())
359 return *(iter
->second
);
360 PropertyObserverList
* observer_list
= new PropertyObserverList();
361 observer_list_
[device_path
] = observer_list
;
362 return *observer_list
;
365 } // namespace chromeos