Don't preload rarely seen large images
[chromium-blink-merge.git] / chromeos / dbus / fake_shill_device_client.cc
blobdec971142169ed06b2b6f3e267c2d6c941ec00de
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"
7 #include <algorithm>
9 #include "base/bind.h"
10 #include "base/location.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/stl_util.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "base/values.h"
15 #include "chromeos/dbus/dbus_thread_manager.h"
16 #include "chromeos/dbus/shill_manager_client.h"
17 #include "chromeos/dbus/shill_property_changed_observer.h"
18 #include "dbus/bus.h"
19 #include "dbus/message.h"
20 #include "dbus/object_path.h"
21 #include "dbus/object_proxy.h"
22 #include "dbus/values_util.h"
23 #include "net/base/ip_endpoint.h"
24 #include "third_party/cros_system_api/dbus/service_constants.h"
26 namespace chromeos {
28 namespace {
30 std::string kSimPin = "1111";
31 std::string kFailedMessage = "Failed";
33 void ErrorFunction(const std::string& device_path,
34 const std::string& error_name,
35 const std::string& error_message) {
36 LOG(ERROR) << "Shill Error for: " << device_path
37 << ": " << error_name << " : " << error_message;
40 void PostError(const std::string& error,
41 const ShillDeviceClient::ErrorCallback& error_callback) {
42 base::ThreadTaskRunnerHandle::Get()->PostTask(
43 FROM_HERE, base::Bind(error_callback, error, kFailedMessage));
46 void PostNotFoundError(const ShillDeviceClient::ErrorCallback& error_callback) {
47 PostError(shill::kErrorResultNotFound, error_callback);
50 bool IsReadOnlyProperty(const std::string& name) {
51 if (name == shill::kCarrierProperty)
52 return true;
53 return false;
56 } // namespace
58 FakeShillDeviceClient::FakeShillDeviceClient()
59 : initial_tdls_busy_count_(0),
60 tdls_busy_count_(0),
61 weak_ptr_factory_(this) {
64 FakeShillDeviceClient::~FakeShillDeviceClient() {
65 STLDeleteContainerPairSecondPointers(
66 observer_list_.begin(), observer_list_.end());
69 // ShillDeviceClient overrides.
71 void FakeShillDeviceClient::Init(dbus::Bus* bus) {}
73 void FakeShillDeviceClient::AddPropertyChangedObserver(
74 const dbus::ObjectPath& device_path,
75 ShillPropertyChangedObserver* observer) {
76 GetObserverList(device_path).AddObserver(observer);
79 void FakeShillDeviceClient::RemovePropertyChangedObserver(
80 const dbus::ObjectPath& device_path,
81 ShillPropertyChangedObserver* observer) {
82 GetObserverList(device_path).RemoveObserver(observer);
85 void FakeShillDeviceClient::GetProperties(
86 const dbus::ObjectPath& device_path,
87 const DictionaryValueCallback& callback) {
88 base::ThreadTaskRunnerHandle::Get()->PostTask(
89 FROM_HERE,
90 base::Bind(&FakeShillDeviceClient::PassStubDeviceProperties,
91 weak_ptr_factory_.GetWeakPtr(), device_path, callback));
94 void FakeShillDeviceClient::ProposeScan(
95 const dbus::ObjectPath& device_path,
96 const VoidDBusMethodCallback& callback) {
97 PostVoidCallback(callback, DBUS_METHOD_CALL_SUCCESS);
100 void FakeShillDeviceClient::SetProperty(const dbus::ObjectPath& device_path,
101 const std::string& name,
102 const base::Value& value,
103 const base::Closure& callback,
104 const ErrorCallback& error_callback) {
105 if (IsReadOnlyProperty(name))
106 PostError(shill::kErrorResultInvalidArguments, error_callback);
107 SetPropertyInternal(device_path, name, value, callback, error_callback);
110 void FakeShillDeviceClient::SetPropertyInternal(
111 const dbus::ObjectPath& device_path,
112 const std::string& name,
113 const base::Value& value,
114 const base::Closure& callback,
115 const ErrorCallback& error_callback) {
116 base::DictionaryValue* device_properties = NULL;
117 if (!stub_devices_.GetDictionaryWithoutPathExpansion(device_path.value(),
118 &device_properties)) {
119 PostNotFoundError(error_callback);
120 return;
122 device_properties->SetWithoutPathExpansion(name, value.DeepCopy());
123 base::ThreadTaskRunnerHandle::Get()->PostTask(
124 FROM_HERE,
125 base::Bind(&FakeShillDeviceClient::NotifyObserversPropertyChanged,
126 weak_ptr_factory_.GetWeakPtr(), device_path, name));
127 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
130 void FakeShillDeviceClient::ClearProperty(
131 const dbus::ObjectPath& device_path,
132 const std::string& name,
133 const VoidDBusMethodCallback& callback) {
134 base::DictionaryValue* device_properties = NULL;
135 if (!stub_devices_.GetDictionaryWithoutPathExpansion(device_path.value(),
136 &device_properties)) {
137 PostVoidCallback(callback, DBUS_METHOD_CALL_FAILURE);
138 return;
140 device_properties->RemoveWithoutPathExpansion(name, NULL);
141 PostVoidCallback(callback, DBUS_METHOD_CALL_SUCCESS);
144 void FakeShillDeviceClient::AddIPConfig(
145 const dbus::ObjectPath& device_path,
146 const std::string& method,
147 const ObjectPathDBusMethodCallback& callback) {
148 base::ThreadTaskRunnerHandle::Get()->PostTask(
149 FROM_HERE,
150 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, dbus::ObjectPath()));
153 void FakeShillDeviceClient::RequirePin(const dbus::ObjectPath& device_path,
154 const std::string& pin,
155 bool require,
156 const base::Closure& callback,
157 const ErrorCallback& error_callback) {
158 VLOG(1) << "RequirePin: " << device_path.value();
159 if (pin != kSimPin) {
160 base::ThreadTaskRunnerHandle::Get()->PostTask(
161 FROM_HERE,
162 base::Bind(error_callback, shill::kErrorResultIncorrectPin, ""));
163 return;
165 base::DictionaryValue* device_properties = NULL;
166 if (!stub_devices_.GetDictionaryWithoutPathExpansion(device_path.value(),
167 &device_properties)) {
168 PostNotFoundError(error_callback);
169 return;
171 base::DictionaryValue* simlock_dict = NULL;
172 if (!device_properties->GetDictionaryWithoutPathExpansion(
173 shill::kSIMLockStatusProperty, &simlock_dict)) {
174 simlock_dict = new base::DictionaryValue;
175 device_properties->SetWithoutPathExpansion(
176 shill::kSIMLockStatusProperty, simlock_dict);
178 simlock_dict->Clear();
179 simlock_dict->SetBoolean(shill::kSIMLockEnabledProperty, require);
180 // TODO(stevenjb): Investigate why non-empty value breaks UI.
181 std::string lock_type = ""; // shill::kSIMLockPin
182 simlock_dict->SetString(shill::kSIMLockTypeProperty, lock_type);
183 simlock_dict->SetInteger(shill::kSIMLockRetriesLeftProperty, 5);
185 NotifyObserversPropertyChanged(device_path, shill::kSIMLockStatusProperty);
186 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
189 void FakeShillDeviceClient::EnterPin(const dbus::ObjectPath& device_path,
190 const std::string& pin,
191 const base::Closure& callback,
192 const ErrorCallback& error_callback) {
193 VLOG(1) << "EnterPin: " << device_path.value();
194 if (pin != kSimPin) {
195 base::ThreadTaskRunnerHandle::Get()->PostTask(
196 FROM_HERE,
197 base::Bind(error_callback, shill::kErrorResultIncorrectPin, ""));
198 return;
200 if (!stub_devices_.HasKey(device_path.value())) {
201 PostNotFoundError(error_callback);
202 return;
204 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
207 void FakeShillDeviceClient::UnblockPin(const dbus::ObjectPath& device_path,
208 const std::string& puk,
209 const std::string& pin,
210 const base::Closure& callback,
211 const ErrorCallback& error_callback) {
212 VLOG(1) << "UnblockPin: " << device_path.value();
213 if (!stub_devices_.HasKey(device_path.value())) {
214 PostNotFoundError(error_callback);
215 return;
217 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
220 void FakeShillDeviceClient::ChangePin(const dbus::ObjectPath& device_path,
221 const std::string& old_pin,
222 const std::string& new_pin,
223 const base::Closure& callback,
224 const ErrorCallback& error_callback) {
225 VLOG(1) << "ChangePin: " << device_path.value();
226 if (!stub_devices_.HasKey(device_path.value())) {
227 PostNotFoundError(error_callback);
228 return;
230 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
233 void FakeShillDeviceClient::Register(const dbus::ObjectPath& device_path,
234 const std::string& network_id,
235 const base::Closure& callback,
236 const ErrorCallback& error_callback) {
237 if (!stub_devices_.HasKey(device_path.value())) {
238 PostNotFoundError(error_callback);
239 return;
241 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
244 void FakeShillDeviceClient::SetCarrier(const dbus::ObjectPath& device_path,
245 const std::string& carrier,
246 const base::Closure& callback,
247 const ErrorCallback& error_callback) {
248 SetPropertyInternal(device_path, shill::kCarrierProperty,
249 base::StringValue(carrier), callback, error_callback);
252 void FakeShillDeviceClient::Reset(const dbus::ObjectPath& device_path,
253 const base::Closure& callback,
254 const ErrorCallback& error_callback) {
255 if (!stub_devices_.HasKey(device_path.value())) {
256 PostNotFoundError(error_callback);
257 return;
259 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
262 void FakeShillDeviceClient::PerformTDLSOperation(
263 const dbus::ObjectPath& device_path,
264 const std::string& operation,
265 const std::string& peer,
266 const StringCallback& callback,
267 const ErrorCallback& error_callback) {
268 if (!stub_devices_.HasKey(device_path.value())) {
269 PostNotFoundError(error_callback);
270 return;
272 // Use -1 to emulate a TDLS failure.
273 if (tdls_busy_count_ == -1) {
274 base::ThreadTaskRunnerHandle::Get()->PostTask(
275 FROM_HERE,
276 base::Bind(error_callback, shill::kErrorDhcpFailed, "Failed"));
277 return;
279 if (operation != shill::kTDLSStatusOperation && tdls_busy_count_ > 0) {
280 --tdls_busy_count_;
281 base::ThreadTaskRunnerHandle::Get()->PostTask(
282 FROM_HERE, base::Bind(error_callback, shill::kErrorResultInProgress,
283 "In-Progress"));
284 return;
287 tdls_busy_count_ = initial_tdls_busy_count_;
289 std::string result;
290 if (operation == shill::kTDLSDiscoverOperation) {
291 if (tdls_state_.empty())
292 tdls_state_ = shill::kTDLSDisconnectedState;
293 } else if (operation == shill::kTDLSSetupOperation) {
294 if (tdls_state_.empty())
295 tdls_state_ = shill::kTDLSConnectedState;
296 } else if (operation == shill::kTDLSTeardownOperation) {
297 if (tdls_state_.empty())
298 tdls_state_ = shill::kTDLSDisconnectedState;
299 } else if (operation == shill::kTDLSStatusOperation) {
300 result = tdls_state_;
303 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
304 base::Bind(callback, result));
307 void FakeShillDeviceClient::AddWakeOnPacketConnection(
308 const dbus::ObjectPath& device_path,
309 const net::IPEndPoint& ip_endpoint,
310 const base::Closure& callback,
311 const ErrorCallback& error_callback) {
312 if (!stub_devices_.HasKey(device_path.value())) {
313 PostNotFoundError(error_callback);
314 return;
317 wake_on_packet_connections_[device_path].insert(ip_endpoint);
319 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
322 void FakeShillDeviceClient::RemoveWakeOnPacketConnection(
323 const dbus::ObjectPath& device_path,
324 const net::IPEndPoint& ip_endpoint,
325 const base::Closure& callback,
326 const ErrorCallback& error_callback) {
327 const auto device_iter = wake_on_packet_connections_.find(device_path);
328 if (!stub_devices_.HasKey(device_path.value()) ||
329 device_iter == wake_on_packet_connections_.end()) {
330 PostNotFoundError(error_callback);
331 return;
334 const auto endpoint_iter = device_iter->second.find(ip_endpoint);
335 if (endpoint_iter == device_iter->second.end()) {
336 PostNotFoundError(error_callback);
337 return;
340 device_iter->second.erase(endpoint_iter);
342 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
345 void FakeShillDeviceClient::RemoveAllWakeOnPacketConnections(
346 const dbus::ObjectPath& device_path,
347 const base::Closure& callback,
348 const ErrorCallback& error_callback) {
349 const auto iter = wake_on_packet_connections_.find(device_path);
350 if (!stub_devices_.HasKey(device_path.value()) ||
351 iter == wake_on_packet_connections_.end()) {
352 PostNotFoundError(error_callback);
353 return;
356 wake_on_packet_connections_.erase(iter);
358 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
361 ShillDeviceClient::TestInterface* FakeShillDeviceClient::GetTestInterface() {
362 return this;
365 // ShillDeviceClient::TestInterface overrides.
367 void FakeShillDeviceClient::AddDevice(const std::string& device_path,
368 const std::string& type,
369 const std::string& name) {
370 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
371 AddDevice(device_path);
373 base::DictionaryValue* properties = GetDeviceProperties(device_path);
374 properties->SetStringWithoutPathExpansion(shill::kTypeProperty, type);
375 properties->SetStringWithoutPathExpansion(shill::kNameProperty, name);
376 properties->SetStringWithoutPathExpansion(shill::kDBusObjectProperty,
377 device_path);
378 properties->SetStringWithoutPathExpansion(
379 shill::kDBusServiceProperty, modemmanager::kModemManager1ServiceName);
380 if (type == shill::kTypeCellular) {
381 properties->SetBooleanWithoutPathExpansion(
382 shill::kCellularAllowRoamingProperty, false);
386 void FakeShillDeviceClient::RemoveDevice(const std::string& device_path) {
387 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
388 RemoveDevice(device_path);
390 stub_devices_.RemoveWithoutPathExpansion(device_path, NULL);
393 void FakeShillDeviceClient::ClearDevices() {
394 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
395 ClearDevices();
397 stub_devices_.Clear();
400 void FakeShillDeviceClient::SetDeviceProperty(const std::string& device_path,
401 const std::string& name,
402 const base::Value& value) {
403 VLOG(1) << "SetDeviceProperty: " << device_path
404 << ": " << name << " = " << value;
405 SetPropertyInternal(dbus::ObjectPath(device_path), name, value,
406 base::Bind(&base::DoNothing),
407 base::Bind(&ErrorFunction, device_path));
410 std::string FakeShillDeviceClient::GetDevicePathForType(
411 const std::string& type) {
412 for (base::DictionaryValue::Iterator iter(stub_devices_);
413 !iter.IsAtEnd(); iter.Advance()) {
414 const base::DictionaryValue* properties = NULL;
415 if (!iter.value().GetAsDictionary(&properties))
416 continue;
417 std::string prop_type;
418 if (!properties->GetStringWithoutPathExpansion(
419 shill::kTypeProperty, &prop_type) ||
420 prop_type != type)
421 continue;
422 return iter.key();
424 return std::string();
427 void FakeShillDeviceClient::SetTDLSBusyCount(int count) {
428 tdls_busy_count_ = std::max(count, -1);
431 void FakeShillDeviceClient::SetTDLSState(const std::string& state) {
432 tdls_state_ = state;
435 void FakeShillDeviceClient::PassStubDeviceProperties(
436 const dbus::ObjectPath& device_path,
437 const DictionaryValueCallback& callback) const {
438 const base::DictionaryValue* device_properties = NULL;
439 if (!stub_devices_.GetDictionaryWithoutPathExpansion(
440 device_path.value(), &device_properties)) {
441 base::DictionaryValue empty_dictionary;
442 callback.Run(DBUS_METHOD_CALL_FAILURE, empty_dictionary);
443 return;
445 callback.Run(DBUS_METHOD_CALL_SUCCESS, *device_properties);
448 // Posts a task to run a void callback with status code |status|.
449 void FakeShillDeviceClient::PostVoidCallback(
450 const VoidDBusMethodCallback& callback,
451 DBusMethodCallStatus status) {
452 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
453 base::Bind(callback, status));
456 void FakeShillDeviceClient::NotifyObserversPropertyChanged(
457 const dbus::ObjectPath& device_path,
458 const std::string& property) {
459 base::DictionaryValue* dict = NULL;
460 std::string path = device_path.value();
461 if (!stub_devices_.GetDictionaryWithoutPathExpansion(path, &dict)) {
462 LOG(ERROR) << "Notify for unknown service: " << path;
463 return;
465 base::Value* value = NULL;
466 if (!dict->GetWithoutPathExpansion(property, &value)) {
467 LOG(ERROR) << "Notify for unknown property: "
468 << path << " : " << property;
469 return;
471 FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
472 GetObserverList(device_path),
473 OnPropertyChanged(property, *value));
476 base::DictionaryValue* FakeShillDeviceClient::GetDeviceProperties(
477 const std::string& device_path) {
478 base::DictionaryValue* properties = NULL;
479 if (!stub_devices_.GetDictionaryWithoutPathExpansion(
480 device_path, &properties)) {
481 properties = new base::DictionaryValue;
482 stub_devices_.SetWithoutPathExpansion(device_path, properties);
484 return properties;
487 FakeShillDeviceClient::PropertyObserverList&
488 FakeShillDeviceClient::GetObserverList(const dbus::ObjectPath& device_path) {
489 std::map<dbus::ObjectPath, PropertyObserverList*>::iterator iter =
490 observer_list_.find(device_path);
491 if (iter != observer_list_.end())
492 return *(iter->second);
493 PropertyObserverList* observer_list = new PropertyObserverList();
494 observer_list_[device_path] = observer_list;
495 return *observer_list;
498 } // namespace chromeos