Only fsync leveldb's directory when the manifest is being updated.
[chromium-blink-merge.git] / chromeos / dbus / shill_service_client_stub.cc
blob17055c8936cb0226273d07ca689064a72f42675d
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_service_client_stub.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/message_loop.h"
10 #include "base/stl_util.h"
11 #include "base/values.h"
12 #include "chromeos/chromeos_switches.h"
13 #include "chromeos/dbus/dbus_thread_manager.h"
14 #include "chromeos/dbus/shill_manager_client.h"
15 #include "chromeos/dbus/shill_property_changed_observer.h"
16 #include "dbus/bus.h"
17 #include "dbus/message.h"
18 #include "dbus/object_proxy.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
21 namespace chromeos {
23 namespace {
25 void ErrorFunction(const std::string& error_name,
26 const std::string& error_message) {
27 LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message;
30 void PassStubListValue(const ShillServiceClient::ListValueCallback& callback,
31 base::ListValue* value) {
32 callback.Run(*value);
35 void PassStubServiceProperties(
36 const ShillServiceClient::DictionaryValueCallback& callback,
37 DBusMethodCallStatus call_status,
38 const base::DictionaryValue* properties) {
39 callback.Run(call_status, *properties);
42 } // namespace
44 ShillServiceClientStub::ShillServiceClientStub() : weak_ptr_factory_(this) {
45 SetDefaultProperties();
48 ShillServiceClientStub::~ShillServiceClientStub() {
49 STLDeleteContainerPairSecondPointers(
50 observer_list_.begin(), observer_list_.end());
53 // ShillServiceClient overrides.
55 void ShillServiceClientStub::AddPropertyChangedObserver(
56 const dbus::ObjectPath& service_path,
57 ShillPropertyChangedObserver* observer) {
58 GetObserverList(service_path).AddObserver(observer);
61 void ShillServiceClientStub::RemovePropertyChangedObserver(
62 const dbus::ObjectPath& service_path,
63 ShillPropertyChangedObserver* observer) {
64 GetObserverList(service_path).RemoveObserver(observer);
67 void ShillServiceClientStub::GetProperties(
68 const dbus::ObjectPath& service_path,
69 const DictionaryValueCallback& callback) {
70 if (callback.is_null())
71 return;
73 base::DictionaryValue* nested_dict = NULL;
74 scoped_ptr<base::DictionaryValue> result_properties;
75 DBusMethodCallStatus call_status;
76 stub_services_.GetDictionaryWithoutPathExpansion(service_path.value(),
77 &nested_dict);
78 if (nested_dict) {
79 result_properties.reset(nested_dict->DeepCopy());
80 // Remove credentials that Shill wouldn't send.
81 result_properties->RemoveWithoutPathExpansion(flimflam::kPassphraseProperty,
82 NULL);
83 call_status = DBUS_METHOD_CALL_SUCCESS;
84 } else {
85 result_properties.reset(new base::DictionaryValue);
86 call_status = DBUS_METHOD_CALL_FAILURE;
89 base::MessageLoop::current()->PostTask(
90 FROM_HERE,
91 base::Bind(&PassStubServiceProperties,
92 callback,
93 call_status,
94 base::Owned(result_properties.release())));
97 void ShillServiceClientStub::SetProperty(const dbus::ObjectPath& service_path,
98 const std::string& name,
99 const base::Value& value,
100 const base::Closure& callback,
101 const ErrorCallback& error_callback) {
102 base::DictionaryValue* dict = NULL;
103 if (!stub_services_.GetDictionaryWithoutPathExpansion(
104 service_path.value(), &dict)) {
105 LOG(ERROR) << "Service not found: " << service_path.value();
106 error_callback.Run("Error.InvalidService", "Invalid Service");
107 return;
109 VLOG(1) << "Service.SetProperty: " << name << " = " << value
110 << " For: " << service_path.value();
111 if (name == flimflam::kStateProperty) {
112 // If the service went into a connected state, then move it to the top of
113 // the list in the manager client.
114 // TODO(gauravsh): Generalize to sort services properly to allow for testing
115 // more complex scenarios.
116 std::string state;
117 if (value.GetAsString(&state) && (state == flimflam::kStateOnline ||
118 state == flimflam::kStatePortal)) {
119 ShillManagerClient* manager_client =
120 DBusThreadManager::Get()->GetShillManagerClient();
121 manager_client->GetTestInterface()->MoveServiceToIndex(
122 service_path.value(), 0, true);
125 dict->SetWithoutPathExpansion(name, value.DeepCopy());
126 base::MessageLoop::current()->PostTask(
127 FROM_HERE,
128 base::Bind(&ShillServiceClientStub::NotifyObserversPropertyChanged,
129 weak_ptr_factory_.GetWeakPtr(), service_path, name));
130 if (callback.is_null())
131 return;
132 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
135 void ShillServiceClientStub::ClearProperty(
136 const dbus::ObjectPath& service_path,
137 const std::string& name,
138 const base::Closure& callback,
139 const ErrorCallback& error_callback) {
140 base::DictionaryValue* dict = NULL;
141 if (!stub_services_.GetDictionaryWithoutPathExpansion(
142 service_path.value(), &dict)) {
143 error_callback.Run("Error.InvalidService", "Invalid Service");
144 return;
146 dict->Remove(name, NULL);
147 base::MessageLoop::current()->PostTask(
148 FROM_HERE,
149 base::Bind(&ShillServiceClientStub::NotifyObserversPropertyChanged,
150 weak_ptr_factory_.GetWeakPtr(), service_path, name));
151 if (callback.is_null())
152 return;
153 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
156 void ShillServiceClientStub::ClearProperties(
157 const dbus::ObjectPath& service_path,
158 const std::vector<std::string>& names,
159 const ListValueCallback& callback,
160 const ErrorCallback& error_callback) {
161 base::DictionaryValue* dict = NULL;
162 if (!stub_services_.GetDictionaryWithoutPathExpansion(
163 service_path.value(), &dict)) {
164 error_callback.Run("Error.InvalidService", "Invalid Service");
165 return;
167 scoped_ptr<base::ListValue> results(new base::ListValue);
168 for (std::vector<std::string>::const_iterator iter = names.begin();
169 iter != names.end(); ++iter) {
170 dict->Remove(*iter, NULL);
171 results->AppendBoolean(true);
173 for (std::vector<std::string>::const_iterator iter = names.begin();
174 iter != names.end(); ++iter) {
175 base::MessageLoop::current()->PostTask(
176 FROM_HERE,
177 base::Bind(
178 &ShillServiceClientStub::NotifyObserversPropertyChanged,
179 weak_ptr_factory_.GetWeakPtr(), service_path, *iter));
181 if (callback.is_null())
182 return;
183 base::MessageLoop::current()->PostTask(
184 FROM_HERE,
185 base::Bind(&PassStubListValue,
186 callback, base::Owned(results.release())));
189 void ShillServiceClientStub::Connect(const dbus::ObjectPath& service_path,
190 const base::Closure& callback,
191 const ErrorCallback& error_callback) {
192 VLOG(1) << "ShillServiceClientStub::Connect: " << service_path.value();
193 base::Value* service;
194 if (!stub_services_.Get(service_path.value(), &service)) {
195 LOG(ERROR) << "Service not found: " << service_path.value();
196 error_callback.Run("Error.InvalidService", "Invalid Service");
197 return;
199 base::TimeDelta delay;
200 // Set Associating
201 base::StringValue associating_value(flimflam::kStateAssociation);
202 SetServiceProperty(service_path.value(),
203 flimflam::kStateProperty,
204 associating_value);
205 if (CommandLine::ForCurrentProcess()->HasSwitch(
206 chromeos::switches::kEnableStubInteractive)) {
207 const int kConnectDelaySeconds = 5;
208 delay = base::TimeDelta::FromSeconds(kConnectDelaySeconds);
210 // Set Online after a delay
211 base::StringValue online_value(flimflam::kStateOnline);
212 base::MessageLoop::current()->PostDelayedTask(
213 FROM_HERE,
214 base::Bind(&ShillServiceClientStub::SetProperty,
215 weak_ptr_factory_.GetWeakPtr(),
216 service_path,
217 flimflam::kStateProperty,
218 online_value,
219 base::Bind(&base::DoNothing),
220 error_callback),
221 delay);
222 callback.Run();
225 void ShillServiceClientStub::Disconnect(const dbus::ObjectPath& service_path,
226 const base::Closure& callback,
227 const ErrorCallback& error_callback) {
228 base::Value* service;
229 if (!stub_services_.Get(service_path.value(), &service)) {
230 error_callback.Run("Error.InvalidService", "Invalid Service");
231 return;
233 base::TimeDelta delay;
234 if (CommandLine::ForCurrentProcess()->HasSwitch(
235 chromeos::switches::kEnableStubInteractive)) {
236 const int kConnectDelaySeconds = 2;
237 delay = base::TimeDelta::FromSeconds(kConnectDelaySeconds);
239 // Set Idle after a delay
240 base::StringValue idle_value(flimflam::kStateIdle);
241 base::MessageLoop::current()->PostDelayedTask(
242 FROM_HERE,
243 base::Bind(&ShillServiceClientStub::SetProperty,
244 weak_ptr_factory_.GetWeakPtr(),
245 service_path,
246 flimflam::kStateProperty,
247 idle_value,
248 base::Bind(&base::DoNothing),
249 error_callback),
250 delay);
251 callback.Run();
254 void ShillServiceClientStub::Remove(const dbus::ObjectPath& service_path,
255 const base::Closure& callback,
256 const ErrorCallback& error_callback) {
257 if (callback.is_null())
258 return;
259 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
262 void ShillServiceClientStub::ActivateCellularModem(
263 const dbus::ObjectPath& service_path,
264 const std::string& carrier,
265 const base::Closure& callback,
266 const ErrorCallback& error_callback) {
267 if (callback.is_null())
268 return;
269 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
272 void ShillServiceClientStub::CompleteCellularActivation(
273 const dbus::ObjectPath& service_path,
274 const base::Closure& callback,
275 const ErrorCallback& error_callback) {
276 if (callback.is_null())
277 return;
278 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
281 bool ShillServiceClientStub::CallActivateCellularModemAndBlock(
282 const dbus::ObjectPath& service_path,
283 const std::string& carrier) {
284 return true;
287 ShillServiceClient::TestInterface* ShillServiceClientStub::GetTestInterface() {
288 return this;
291 // ShillServiceClient::TestInterface overrides.
293 void ShillServiceClientStub::AddService(const std::string& service_path,
294 const std::string& name,
295 const std::string& type,
296 const std::string& state,
297 bool add_to_watch_list) {
298 AddServiceWithIPConfig(service_path, name, type, state, "",
299 add_to_watch_list);
302 void ShillServiceClientStub::AddServiceWithIPConfig(
303 const std::string& service_path,
304 const std::string& name,
305 const std::string& type,
306 const std::string& state,
307 const std::string& ipconfig_path,
308 bool add_to_watch_list) {
309 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
310 AddManagerService(service_path, add_to_watch_list);
312 base::DictionaryValue* properties =
313 GetModifiableServiceProperties(service_path);
314 properties->SetWithoutPathExpansion(
315 flimflam::kSSIDProperty,
316 base::Value::CreateStringValue(service_path));
317 properties->SetWithoutPathExpansion(
318 flimflam::kNameProperty,
319 base::Value::CreateStringValue(name));
320 properties->SetWithoutPathExpansion(
321 flimflam::kTypeProperty,
322 base::Value::CreateStringValue(type));
323 properties->SetWithoutPathExpansion(
324 flimflam::kStateProperty,
325 base::Value::CreateStringValue(state));
326 if (!ipconfig_path.empty())
327 properties->SetWithoutPathExpansion(
328 shill::kIPConfigProperty,
329 base::Value::CreateStringValue(ipconfig_path));
332 void ShillServiceClientStub::RemoveService(const std::string& service_path) {
333 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
334 RemoveManagerService(service_path);
336 stub_services_.RemoveWithoutPathExpansion(service_path, NULL);
339 void ShillServiceClientStub::SetServiceProperty(const std::string& service_path,
340 const std::string& property,
341 const base::Value& value) {
342 SetProperty(dbus::ObjectPath(service_path), property, value,
343 base::Bind(&base::DoNothing),
344 base::Bind(&ErrorFunction));
347 const base::DictionaryValue* ShillServiceClientStub::GetServiceProperties(
348 const std::string& service_path) const {
349 const base::DictionaryValue* properties = NULL;
350 stub_services_.GetDictionaryWithoutPathExpansion(service_path, &properties);
351 return properties;
354 void ShillServiceClientStub::ClearServices() {
355 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
356 ClearManagerServices();
358 stub_services_.Clear();
361 void ShillServiceClientStub::SetDefaultProperties() {
362 const bool add_to_watchlist = true;
364 if (!CommandLine::ForCurrentProcess()->HasSwitch(
365 chromeos::switches::kDisableStubEthernet)) {
366 AddService("eth1", "eth1",
367 flimflam::kTypeEthernet,
368 flimflam::kStateOnline,
369 add_to_watchlist);
372 AddService("wifi1", "wifi1",
373 flimflam::kTypeWifi,
374 flimflam::kStateOnline,
375 add_to_watchlist);
376 SetServiceProperty("wifi1",
377 flimflam::kSecurityProperty,
378 base::StringValue(flimflam::kSecurityWep));
380 AddService("wifi2", "wifi2_PSK",
381 flimflam::kTypeWifi,
382 flimflam::kStateIdle,
383 add_to_watchlist);
384 SetServiceProperty("wifi2",
385 flimflam::kSecurityProperty,
386 base::StringValue(flimflam::kSecurityPsk));
387 base::FundamentalValue strength_value(80);
388 SetServiceProperty("wifi2",
389 flimflam::kSignalStrengthProperty,
390 strength_value);
392 AddService("cellular1", "cellular1",
393 flimflam::kTypeCellular,
394 flimflam::kStateIdle,
395 add_to_watchlist);
396 base::StringValue technology_value(flimflam::kNetworkTechnologyGsm);
397 SetServiceProperty("cellular1",
398 flimflam::kNetworkTechnologyProperty,
399 technology_value);
400 SetServiceProperty("cellular1",
401 flimflam::kActivationStateProperty,
402 base::StringValue(flimflam::kActivationStateNotActivated));
403 SetServiceProperty("cellular1",
404 flimflam::kRoamingStateProperty,
405 base::StringValue(flimflam::kRoamingStateHome));
407 AddService("vpn1", "vpn1",
408 flimflam::kTypeVPN,
409 flimflam::kStateOnline,
410 add_to_watchlist);
412 AddService("vpn2", "vpn2",
413 flimflam::kTypeVPN,
414 flimflam::kStateOffline,
415 add_to_watchlist);
418 void ShillServiceClientStub::NotifyObserversPropertyChanged(
419 const dbus::ObjectPath& service_path,
420 const std::string& property) {
421 base::DictionaryValue* dict = NULL;
422 std::string path = service_path.value();
423 if (!stub_services_.GetDictionaryWithoutPathExpansion(path, &dict)) {
424 LOG(ERROR) << "Notify for unknown service: " << path;
425 return;
427 base::Value* value = NULL;
428 if (!dict->GetWithoutPathExpansion(property, &value)) {
429 LOG(ERROR) << "Notify for unknown property: "
430 << path << " : " << property;
431 return;
433 FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
434 GetObserverList(service_path),
435 OnPropertyChanged(property, *value));
438 base::DictionaryValue* ShillServiceClientStub::GetModifiableServiceProperties(
439 const std::string& service_path) {
440 base::DictionaryValue* properties = NULL;
441 if (!stub_services_.GetDictionaryWithoutPathExpansion(
442 service_path, &properties)) {
443 properties = new base::DictionaryValue;
444 stub_services_.Set(service_path, properties);
446 return properties;
449 ShillServiceClientStub::PropertyObserverList&
450 ShillServiceClientStub::GetObserverList(const dbus::ObjectPath& device_path) {
451 std::map<dbus::ObjectPath, PropertyObserverList*>::iterator iter =
452 observer_list_.find(device_path);
453 if (iter != observer_list_.end())
454 return *(iter->second);
455 PropertyObserverList* observer_list = new PropertyObserverList();
456 observer_list_[device_path] = observer_list;
457 return *observer_list;
460 } // namespace chromeos