1 // Copyright (c) 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/shill_device_client_stub.h"
8 #include "base/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
& error_name
,
26 const std::string
& error_message
) {
27 LOG(ERROR
) << "Shill Error: " << error_name
<< " : " << error_message
;
32 ShillDeviceClientStub::ShillDeviceClientStub() : weak_ptr_factory_(this) {
33 SetDefaultProperties();
36 ShillDeviceClientStub::~ShillDeviceClientStub() {
37 STLDeleteContainerPairSecondPointers(
38 observer_list_
.begin(), observer_list_
.end());
41 // ShillDeviceClient overrides.
43 void ShillDeviceClientStub::AddPropertyChangedObserver(
44 const dbus::ObjectPath
& device_path
,
45 ShillPropertyChangedObserver
* observer
){
46 GetObserverList(device_path
).AddObserver(observer
);
49 void ShillDeviceClientStub::RemovePropertyChangedObserver(
50 const dbus::ObjectPath
& device_path
,
51 ShillPropertyChangedObserver
* observer
){
52 GetObserverList(device_path
).RemoveObserver(observer
);
55 void ShillDeviceClientStub::GetProperties(
56 const dbus::ObjectPath
& device_path
,
57 const DictionaryValueCallback
& callback
){
58 if (callback
.is_null())
60 MessageLoop::current()->PostTask(
62 base::Bind(&ShillDeviceClientStub::PassStubDeviceProperties
,
63 weak_ptr_factory_
.GetWeakPtr(),
64 device_path
, callback
));
67 base::DictionaryValue
* ShillDeviceClientStub::CallGetPropertiesAndBlock(
68 const dbus::ObjectPath
& device_path
){
69 base::DictionaryValue
* device_properties
= NULL
;
70 stub_devices_
.GetDictionaryWithoutPathExpansion(
71 device_path
.value(), &device_properties
);
72 return device_properties
;
75 void ShillDeviceClientStub::ProposeScan(const dbus::ObjectPath
& device_path
,
76 const VoidDBusMethodCallback
& callback
){
77 PostVoidCallback(callback
, DBUS_METHOD_CALL_SUCCESS
);
80 void ShillDeviceClientStub::SetProperty(const dbus::ObjectPath
& device_path
,
81 const std::string
& name
,
82 const base::Value
& value
,
83 const base::Closure
& callback
,
84 const ErrorCallback
& error_callback
){
85 base::DictionaryValue
* device_properties
= NULL
;
86 if (!stub_devices_
.GetDictionary(device_path
.value(), &device_properties
)) {
87 std::string
error_name("org.chromium.flimflam.Error.Failure");
88 std::string
error_message("Failed");
89 if (!error_callback
.is_null()) {
90 MessageLoop::current()->PostTask(FROM_HERE
,
91 base::Bind(error_callback
,
97 device_properties
->Set(name
, value
.DeepCopy());
98 MessageLoop::current()->PostTask(
100 base::Bind(&ShillDeviceClientStub::NotifyObserversPropertyChanged
,
101 weak_ptr_factory_
.GetWeakPtr(), device_path
, name
));
102 if (callback
.is_null())
104 MessageLoop::current()->PostTask(FROM_HERE
, callback
);
107 void ShillDeviceClientStub::ClearProperty(
108 const dbus::ObjectPath
& device_path
,
109 const std::string
& name
,
110 const VoidDBusMethodCallback
& callback
){
111 base::DictionaryValue
* device_properties
= NULL
;
112 if (!stub_devices_
.GetDictionary(device_path
.value(), &device_properties
)) {
113 PostVoidCallback(callback
, DBUS_METHOD_CALL_FAILURE
);
116 device_properties
->Remove(name
, NULL
);
117 PostVoidCallback(callback
, DBUS_METHOD_CALL_SUCCESS
);
120 void ShillDeviceClientStub::AddIPConfig(
121 const dbus::ObjectPath
& device_path
,
122 const std::string
& method
,
123 const ObjectPathDBusMethodCallback
& callback
){
124 if (callback
.is_null())
126 MessageLoop::current()->PostTask(FROM_HERE
,
128 DBUS_METHOD_CALL_SUCCESS
,
129 dbus::ObjectPath()));
132 void ShillDeviceClientStub::RequirePin(const dbus::ObjectPath
& device_path
,
133 const std::string
& pin
,
135 const base::Closure
& callback
,
136 const ErrorCallback
& error_callback
){
137 if (callback
.is_null())
139 MessageLoop::current()->PostTask(FROM_HERE
, callback
);
142 void ShillDeviceClientStub::EnterPin(const dbus::ObjectPath
& device_path
,
143 const std::string
& pin
,
144 const base::Closure
& callback
,
145 const ErrorCallback
& error_callback
){
146 if (callback
.is_null())
148 MessageLoop::current()->PostTask(FROM_HERE
, callback
);
151 void ShillDeviceClientStub::UnblockPin(const dbus::ObjectPath
& device_path
,
152 const std::string
& puk
,
153 const std::string
& pin
,
154 const base::Closure
& callback
,
155 const ErrorCallback
& error_callback
){
156 if (callback
.is_null())
158 MessageLoop::current()->PostTask(FROM_HERE
, callback
);
161 void ShillDeviceClientStub::ChangePin(const dbus::ObjectPath
& device_path
,
162 const std::string
& old_pin
,
163 const std::string
& new_pin
,
164 const base::Closure
& callback
,
165 const ErrorCallback
& error_callback
){
166 if (callback
.is_null())
168 MessageLoop::current()->PostTask(FROM_HERE
, callback
);
171 void ShillDeviceClientStub::Register(const dbus::ObjectPath
& device_path
,
172 const std::string
& network_id
,
173 const base::Closure
& callback
,
174 const ErrorCallback
& error_callback
){
175 if (callback
.is_null())
177 MessageLoop::current()->PostTask(FROM_HERE
, callback
);
180 void ShillDeviceClientStub::SetCarrier(const dbus::ObjectPath
& device_path
,
181 const std::string
& carrier
,
182 const base::Closure
& callback
,
183 const ErrorCallback
& error_callback
){
184 if (callback
.is_null())
186 MessageLoop::current()->PostTask(FROM_HERE
, callback
);
189 void ShillDeviceClientStub::Reset(const dbus::ObjectPath
& device_path
,
190 const base::Closure
& callback
,
191 const ErrorCallback
& error_callback
){
192 if (callback
.is_null())
194 MessageLoop::current()->PostTask(FROM_HERE
, callback
);
197 ShillDeviceClient::TestInterface
* ShillDeviceClientStub::GetTestInterface(){
201 // ShillDeviceClient::TestInterface overrides.
203 void ShillDeviceClientStub::AddDevice(const std::string
& device_path
,
204 const std::string
& type
,
205 const std::string
& object_path
){
206 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
207 AddDevice(device_path
);
209 base::DictionaryValue
* properties
= GetDeviceProperties(device_path
);
210 properties
->SetWithoutPathExpansion(
211 flimflam::kTypeProperty
,
212 base::Value::CreateStringValue(type
));
213 properties
->SetWithoutPathExpansion(
214 flimflam::kDBusObjectProperty
,
215 base::Value::CreateStringValue(object_path
));
216 properties
->SetWithoutPathExpansion(
217 flimflam::kDBusConnectionProperty
,
218 base::Value::CreateStringValue("/stub"));
221 void ShillDeviceClientStub::RemoveDevice(const std::string
& device_path
){
222 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
223 RemoveDevice(device_path
);
225 stub_devices_
.RemoveWithoutPathExpansion(device_path
, NULL
);
228 void ShillDeviceClientStub::ClearDevices(){
229 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
232 stub_devices_
.Clear();
235 void ShillDeviceClientStub::SetDeviceProperty(const std::string
& device_path
,
236 const std::string
& name
,
237 const base::Value
& value
){
238 VLOG(1) << "SetDeviceProperty: " << device_path
239 << ": " << name
<< " = " << value
;
240 SetProperty(dbus::ObjectPath(device_path
), name
, value
,
241 base::Bind(&base::DoNothing
),
242 base::Bind(&ErrorFunction
));
245 std::string
ShillDeviceClientStub::GetDevicePathForType(
246 const std::string
& type
) {
247 for (base::DictionaryValue::Iterator
iter(stub_devices_
);
248 !iter
.IsAtEnd(); iter
.Advance()) {
249 const base::DictionaryValue
* properties
= NULL
;
250 if (!iter
.value().GetAsDictionary(&properties
))
252 std::string prop_type
;
253 if (!properties
->GetStringWithoutPathExpansion(
254 flimflam::kTypeProperty
, &prop_type
) ||
259 return std::string();
262 void ShillDeviceClientStub::SetDefaultProperties() {
263 // Add a wifi device. Note: path matches Manager entry.
264 AddDevice("stub_wifi_device1", flimflam::kTypeWifi
, "/device/wifi1");
266 // Add a cellular device. Used in SMS stub. Note: path matches
268 AddDevice("stub_cellular_device1", flimflam::kTypeCellular
,
269 "/device/cellular1");
272 void ShillDeviceClientStub::PassStubDeviceProperties(
273 const dbus::ObjectPath
& device_path
,
274 const DictionaryValueCallback
& callback
) const {
275 const base::DictionaryValue
* device_properties
= NULL
;
276 if (!stub_devices_
.GetDictionaryWithoutPathExpansion(
277 device_path
.value(), &device_properties
)) {
278 base::DictionaryValue empty_dictionary
;
279 callback
.Run(DBUS_METHOD_CALL_FAILURE
, empty_dictionary
);
282 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, *device_properties
);
285 // Posts a task to run a void callback with status code |status|.
286 void ShillDeviceClientStub::PostVoidCallback(
287 const VoidDBusMethodCallback
& callback
,
288 DBusMethodCallStatus status
) {
289 if (callback
.is_null())
291 MessageLoop::current()->PostTask(FROM_HERE
,
292 base::Bind(callback
, status
));
295 void ShillDeviceClientStub::NotifyObserversPropertyChanged(
296 const dbus::ObjectPath
& device_path
,
297 const std::string
& property
) {
298 base::DictionaryValue
* dict
= NULL
;
299 std::string path
= device_path
.value();
300 if (!stub_devices_
.GetDictionaryWithoutPathExpansion(path
, &dict
)) {
301 LOG(ERROR
) << "Notify for unknown service: " << path
;
304 base::Value
* value
= NULL
;
305 if (!dict
->GetWithoutPathExpansion(property
, &value
)) {
306 LOG(ERROR
) << "Notify for unknown property: "
307 << path
<< " : " << property
;
310 FOR_EACH_OBSERVER(ShillPropertyChangedObserver
,
311 GetObserverList(device_path
),
312 OnPropertyChanged(property
, *value
));
315 base::DictionaryValue
* ShillDeviceClientStub::GetDeviceProperties(
316 const std::string
& device_path
) {
317 base::DictionaryValue
* properties
= NULL
;
318 if (!stub_devices_
.GetDictionaryWithoutPathExpansion(
319 device_path
, &properties
)) {
320 properties
= new base::DictionaryValue
;
321 stub_devices_
.Set(device_path
, properties
);
326 ShillDeviceClientStub::PropertyObserverList
&
327 ShillDeviceClientStub::GetObserverList(const dbus::ObjectPath
& device_path
) {
328 std::map
<dbus::ObjectPath
, PropertyObserverList
*>::iterator iter
=
329 observer_list_
.find(device_path
);
330 if (iter
!= observer_list_
.end())
331 return *(iter
->second
);
332 PropertyObserverList
* observer_list
= new PropertyObserverList();
333 observer_list_
[device_path
] = observer_list
;
334 return *observer_list
;
337 } // namespace chromeos