Revert 217860 "Implement per-browser crash throttling for NaCl p..." which broke...
[chromium-blink-merge.git] / chromeos / dbus / shill_service_client_stub.cc
blob19dc65e2c26b8af0e16eeef7e375a25fa3c1928d
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/message_loop.h"
10 #include "base/stl_util.h"
11 #include "base/strings/string_util.h"
12 #include "base/values.h"
13 #include "chromeos/chromeos_switches.h"
14 #include "chromeos/dbus/dbus_thread_manager.h"
15 #include "chromeos/dbus/shill_manager_client.h"
16 #include "chromeos/dbus/shill_profile_client_stub.h"
17 #include "chromeos/dbus/shill_property_changed_observer.h"
18 #include "dbus/bus.h"
19 #include "dbus/message.h"
20 #include "dbus/object_proxy.h"
21 #include "third_party/cros_system_api/dbus/service_constants.h"
23 namespace chromeos {
25 namespace {
27 const char kStubPortalledWifiPath[] = "portalled_wifi";
28 const char kStubPortalledWifiName[] = "Portalled Wifi";
30 void ErrorFunction(const std::string& error_name,
31 const std::string& error_message) {
32 LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message;
35 void PassStubListValue(const ShillServiceClient::ListValueCallback& callback,
36 base::ListValue* value) {
37 callback.Run(*value);
40 void PassStubServiceProperties(
41 const ShillServiceClient::DictionaryValueCallback& callback,
42 DBusMethodCallStatus call_status,
43 const base::DictionaryValue* properties) {
44 callback.Run(call_status, *properties);
47 } // namespace
49 ShillServiceClientStub::ShillServiceClientStub() : weak_ptr_factory_(this) {
52 ShillServiceClientStub::~ShillServiceClientStub() {
53 STLDeleteContainerPairSecondPointers(
54 observer_list_.begin(), observer_list_.end());
57 // static
58 bool ShillServiceClientStub::IsStubPortalledWifiEnabled(
59 const std::string& path) {
60 if (!CommandLine::ForCurrentProcess()->HasSwitch(
61 chromeos::switches::kEnableStubPortalledWifi)) {
62 return false;
64 return path == kStubPortalledWifiPath;
67 // ShillServiceClient overrides.
69 void ShillServiceClientStub::AddPropertyChangedObserver(
70 const dbus::ObjectPath& service_path,
71 ShillPropertyChangedObserver* observer) {
72 GetObserverList(service_path).AddObserver(observer);
75 void ShillServiceClientStub::RemovePropertyChangedObserver(
76 const dbus::ObjectPath& service_path,
77 ShillPropertyChangedObserver* observer) {
78 GetObserverList(service_path).RemoveObserver(observer);
81 void ShillServiceClientStub::GetProperties(
82 const dbus::ObjectPath& service_path,
83 const DictionaryValueCallback& callback) {
84 base::DictionaryValue* nested_dict = NULL;
85 scoped_ptr<base::DictionaryValue> result_properties;
86 DBusMethodCallStatus call_status;
87 stub_services_.GetDictionaryWithoutPathExpansion(service_path.value(),
88 &nested_dict);
89 if (nested_dict) {
90 result_properties.reset(nested_dict->DeepCopy());
91 // Remove credentials that Shill wouldn't send.
92 result_properties->RemoveWithoutPathExpansion(flimflam::kPassphraseProperty,
93 NULL);
94 call_status = DBUS_METHOD_CALL_SUCCESS;
95 } else {
96 result_properties.reset(new base::DictionaryValue);
97 call_status = DBUS_METHOD_CALL_FAILURE;
100 base::MessageLoop::current()->PostTask(
101 FROM_HERE,
102 base::Bind(&PassStubServiceProperties,
103 callback,
104 call_status,
105 base::Owned(result_properties.release())));
108 void ShillServiceClientStub::SetProperty(const dbus::ObjectPath& service_path,
109 const std::string& name,
110 const base::Value& value,
111 const base::Closure& callback,
112 const ErrorCallback& error_callback) {
113 if (!SetServiceProperty(service_path.value(), name, value)) {
114 LOG(ERROR) << "Service not found: " << service_path.value();
115 error_callback.Run("Error.InvalidService", "Invalid Service");
116 return;
118 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
121 void ShillServiceClientStub::SetProperties(
122 const dbus::ObjectPath& service_path,
123 const base::DictionaryValue& properties,
124 const base::Closure& callback,
125 const ErrorCallback& error_callback) {
126 for (base::DictionaryValue::Iterator iter(properties);
127 !iter.IsAtEnd(); iter.Advance()) {
128 if (!SetServiceProperty(service_path.value(), iter.key(), iter.value())) {
129 LOG(ERROR) << "Service not found: " << service_path.value();
130 error_callback.Run("Error.InvalidService", "Invalid Service");
131 return;
134 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
137 void ShillServiceClientStub::ClearProperty(
138 const dbus::ObjectPath& service_path,
139 const std::string& name,
140 const base::Closure& callback,
141 const ErrorCallback& error_callback) {
142 base::DictionaryValue* dict = NULL;
143 if (!stub_services_.GetDictionaryWithoutPathExpansion(
144 service_path.value(), &dict)) {
145 error_callback.Run("Error.InvalidService", "Invalid Service");
146 return;
148 dict->RemoveWithoutPathExpansion(name, NULL);
149 // Note: Shill does not send notifications when properties are cleared.
150 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
153 void ShillServiceClientStub::ClearProperties(
154 const dbus::ObjectPath& service_path,
155 const std::vector<std::string>& names,
156 const ListValueCallback& callback,
157 const ErrorCallback& error_callback) {
158 base::DictionaryValue* dict = NULL;
159 if (!stub_services_.GetDictionaryWithoutPathExpansion(
160 service_path.value(), &dict)) {
161 error_callback.Run("Error.InvalidService", "Invalid Service");
162 return;
164 scoped_ptr<base::ListValue> results(new base::ListValue);
165 for (std::vector<std::string>::const_iterator iter = names.begin();
166 iter != names.end(); ++iter) {
167 dict->RemoveWithoutPathExpansion(*iter, NULL);
168 // Note: Shill does not send notifications when properties are cleared.
169 results->AppendBoolean(true);
171 base::MessageLoop::current()->PostTask(
172 FROM_HERE,
173 base::Bind(&PassStubListValue,
174 callback, base::Owned(results.release())));
177 void ShillServiceClientStub::Connect(const dbus::ObjectPath& service_path,
178 const base::Closure& callback,
179 const ErrorCallback& error_callback) {
180 VLOG(1) << "ShillServiceClientStub::Connect: " << service_path.value();
181 base::DictionaryValue* service_properties;
182 if (!stub_services_.GetDictionary(
183 service_path.value(), &service_properties)) {
184 LOG(ERROR) << "Service not found: " << service_path.value();
185 error_callback.Run("Error.InvalidService", "Invalid Service");
186 return;
189 // Set any other services of the same Type to 'offline' first, before setting
190 // State to Association which will trigger sorting Manager.Services and
191 // sending an update.
192 SetOtherServicesOffline(service_path.value());
194 // Set Associating.
195 base::StringValue associating_value(flimflam::kStateAssociation);
196 SetServiceProperty(service_path.value(),
197 flimflam::kStateProperty,
198 associating_value);
200 // Set Online after a delay.
201 base::TimeDelta delay;
202 if (CommandLine::ForCurrentProcess()->HasSwitch(
203 chromeos::switches::kEnableStubInteractive)) {
204 const int kConnectDelaySeconds = 5;
205 delay = base::TimeDelta::FromSeconds(kConnectDelaySeconds);
207 base::StringValue online_value(flimflam::kStateOnline);
208 if (service_path.value() == kStubPortalledWifiPath)
209 online_value = base::StringValue(flimflam::kStatePortal);
210 std::string passphrase;
211 service_properties->GetStringWithoutPathExpansion(
212 flimflam::kPassphraseProperty, &passphrase);
213 if (passphrase == "failure")
214 online_value = base::StringValue(flimflam::kStateFailure);
215 base::MessageLoop::current()->PostDelayedTask(
216 FROM_HERE,
217 base::Bind(&ShillServiceClientStub::SetProperty,
218 weak_ptr_factory_.GetWeakPtr(),
219 service_path,
220 flimflam::kStateProperty,
221 online_value,
222 base::Bind(&base::DoNothing),
223 error_callback),
224 delay);
225 callback.Run();
226 // On failure, also set the Error property.
227 if (passphrase == "failure") {
228 base::MessageLoop::current()->PostDelayedTask(
229 FROM_HERE,
230 base::Bind(&ShillServiceClientStub::SetProperty,
231 weak_ptr_factory_.GetWeakPtr(),
232 service_path,
233 flimflam::kErrorProperty,
234 base::StringValue(flimflam::kErrorBadPassphrase),
235 base::Bind(&base::DoNothing),
236 error_callback),
237 delay);
241 void ShillServiceClientStub::Disconnect(const dbus::ObjectPath& service_path,
242 const base::Closure& callback,
243 const ErrorCallback& error_callback) {
244 base::Value* service;
245 if (!stub_services_.Get(service_path.value(), &service)) {
246 error_callback.Run("Error.InvalidService", "Invalid Service");
247 return;
249 base::TimeDelta delay;
250 if (CommandLine::ForCurrentProcess()->HasSwitch(
251 chromeos::switches::kEnableStubInteractive)) {
252 const int kConnectDelaySeconds = 2;
253 delay = base::TimeDelta::FromSeconds(kConnectDelaySeconds);
255 // Set Idle after a delay
256 base::StringValue idle_value(flimflam::kStateIdle);
257 base::MessageLoop::current()->PostDelayedTask(
258 FROM_HERE,
259 base::Bind(&ShillServiceClientStub::SetProperty,
260 weak_ptr_factory_.GetWeakPtr(),
261 service_path,
262 flimflam::kStateProperty,
263 idle_value,
264 base::Bind(&base::DoNothing),
265 error_callback),
266 delay);
267 callback.Run();
270 void ShillServiceClientStub::Remove(const dbus::ObjectPath& service_path,
271 const base::Closure& callback,
272 const ErrorCallback& error_callback) {
273 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
276 void ShillServiceClientStub::ActivateCellularModem(
277 const dbus::ObjectPath& service_path,
278 const std::string& carrier,
279 const base::Closure& callback,
280 const ErrorCallback& error_callback) {
281 base::DictionaryValue* service_properties =
282 GetModifiableServiceProperties(service_path.value());
283 if (!service_properties) {
284 LOG(ERROR) << "Service not found: " << service_path.value();
285 error_callback.Run("Error.InvalidService", "Invalid Service");
287 SetServiceProperty(service_path.value(),
288 flimflam::kActivationStateProperty,
289 base::StringValue(flimflam::kActivationStateActivating));
290 base::TimeDelta delay;
291 if (CommandLine::ForCurrentProcess()->HasSwitch(
292 chromeos::switches::kEnableStubInteractive)) {
293 const int kConnectDelaySeconds = 2;
294 delay = base::TimeDelta::FromSeconds(kConnectDelaySeconds);
296 // Set Activated after a delay
297 base::MessageLoop::current()->PostDelayedTask(
298 FROM_HERE,
299 base::Bind(&ShillServiceClientStub::SetCellularActivated,
300 weak_ptr_factory_.GetWeakPtr(),
301 service_path,
302 error_callback),
303 delay);
305 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
308 void ShillServiceClientStub::CompleteCellularActivation(
309 const dbus::ObjectPath& service_path,
310 const base::Closure& callback,
311 const ErrorCallback& error_callback) {
312 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
315 bool ShillServiceClientStub::CallActivateCellularModemAndBlock(
316 const dbus::ObjectPath& service_path,
317 const std::string& carrier) {
318 return true;
321 void ShillServiceClientStub::GetLoadableProfileEntries(
322 const dbus::ObjectPath& service_path,
323 const DictionaryValueCallback& callback) {
324 // Provide a dictionary with a single { profile_path, service_path } entry
325 // if the Profile property is set, or an empty dictionary.
326 scoped_ptr<base::DictionaryValue> result_properties(
327 new base::DictionaryValue);
328 base::DictionaryValue* service_properties =
329 GetModifiableServiceProperties(service_path.value());
330 if (service_properties) {
331 std::string profile_path;
332 if (service_properties->GetStringWithoutPathExpansion(
333 flimflam::kProfileProperty, &profile_path)) {
334 result_properties->SetStringWithoutPathExpansion(
335 profile_path, service_path.value());
337 } else {
338 LOG(WARNING) << "Service not in profile: " << service_path.value();
341 DBusMethodCallStatus call_status = DBUS_METHOD_CALL_SUCCESS;
342 base::MessageLoop::current()->PostTask(
343 FROM_HERE,
344 base::Bind(&PassStubServiceProperties,
345 callback,
346 call_status,
347 base::Owned(result_properties.release())));
350 ShillServiceClient::TestInterface* ShillServiceClientStub::GetTestInterface() {
351 return this;
354 // ShillServiceClient::TestInterface overrides.
356 void ShillServiceClientStub::AddService(const std::string& service_path,
357 const std::string& name,
358 const std::string& type,
359 const std::string& state,
360 bool add_to_visible_list,
361 bool add_to_watch_list) {
362 std::string nstate = state;
363 if (CommandLine::ForCurrentProcess()->HasSwitch(
364 chromeos::switches::kDefaultStubNetworkStateIdle)) {
365 nstate = flimflam::kStateIdle;
367 AddServiceWithIPConfig(service_path, name, type, nstate, "",
368 add_to_visible_list, add_to_watch_list);
371 void ShillServiceClientStub::AddServiceWithIPConfig(
372 const std::string& service_path,
373 const std::string& name,
374 const std::string& type,
375 const std::string& state,
376 const std::string& ipconfig_path,
377 bool add_to_visible_list,
378 bool add_to_watch_list) {
379 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
380 AddManagerService(service_path, add_to_visible_list, add_to_watch_list);
382 base::DictionaryValue* properties =
383 GetModifiableServiceProperties(service_path);
384 properties->SetWithoutPathExpansion(
385 flimflam::kSSIDProperty,
386 base::Value::CreateStringValue(service_path));
387 properties->SetWithoutPathExpansion(
388 flimflam::kNameProperty,
389 base::Value::CreateStringValue(name));
390 properties->SetWithoutPathExpansion(
391 flimflam::kTypeProperty,
392 base::Value::CreateStringValue(type));
393 properties->SetWithoutPathExpansion(
394 flimflam::kStateProperty,
395 base::Value::CreateStringValue(state));
396 if (!ipconfig_path.empty())
397 properties->SetWithoutPathExpansion(
398 shill::kIPConfigProperty,
399 base::Value::CreateStringValue(ipconfig_path));
402 void ShillServiceClientStub::RemoveService(const std::string& service_path) {
403 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
404 RemoveManagerService(service_path);
406 stub_services_.RemoveWithoutPathExpansion(service_path, NULL);
409 bool ShillServiceClientStub::SetServiceProperty(const std::string& service_path,
410 const std::string& property,
411 const base::Value& value) {
412 base::DictionaryValue* dict = NULL;
413 if (!stub_services_.GetDictionaryWithoutPathExpansion(service_path, &dict))
414 return false;
416 VLOG(1) << "Service.SetProperty: " << property << " = " << value
417 << " For: " << service_path;
419 base::DictionaryValue new_properties;
420 std::string changed_property;
421 bool case_sensitive = true;
422 if (StartsWithASCII(property, "Provider.", case_sensitive) ||
423 StartsWithASCII(property, "OpenVPN.", case_sensitive) ||
424 StartsWithASCII(property, "L2TPIPsec.", case_sensitive)) {
425 // These properties are only nested within the Provider dictionary if read
426 // from Shill.
427 base::DictionaryValue* provider = new base::DictionaryValue;
428 provider->SetWithoutPathExpansion(property, value.DeepCopy());
429 new_properties.SetWithoutPathExpansion(flimflam::kProviderProperty,
430 provider);
431 changed_property = flimflam::kProviderProperty;
432 } else {
433 new_properties.SetWithoutPathExpansion(property, value.DeepCopy());
434 changed_property = property;
437 dict->MergeDictionary(&new_properties);
439 if (property == flimflam::kStateProperty) {
440 // When State changes the sort order of Services may change.
441 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
442 SortManagerServices();
445 base::MessageLoop::current()->PostTask(
446 FROM_HERE,
447 base::Bind(&ShillServiceClientStub::NotifyObserversPropertyChanged,
448 weak_ptr_factory_.GetWeakPtr(),
449 dbus::ObjectPath(service_path), changed_property));
450 return true;
453 const base::DictionaryValue* ShillServiceClientStub::GetServiceProperties(
454 const std::string& service_path) const {
455 const base::DictionaryValue* properties = NULL;
456 stub_services_.GetDictionaryWithoutPathExpansion(service_path, &properties);
457 return properties;
460 void ShillServiceClientStub::ClearServices() {
461 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
462 ClearManagerServices();
464 stub_services_.Clear();
467 void ShillServiceClientStub::AddDefaultServices() {
468 const bool add_to_visible = true;
469 const bool add_to_watchlist = true;
471 if (!CommandLine::ForCurrentProcess()->HasSwitch(
472 chromeos::switches::kDisableStubEthernet)) {
473 AddService("eth1", "eth1",
474 flimflam::kTypeEthernet,
475 flimflam::kStateOnline,
476 add_to_visible, add_to_watchlist);
479 // Wifi
481 AddService("wifi1", "wifi1",
482 flimflam::kTypeWifi,
483 flimflam::kStateOnline,
484 add_to_visible, add_to_watchlist);
485 SetServiceProperty("wifi1",
486 flimflam::kSecurityProperty,
487 base::StringValue(flimflam::kSecurityWep));
489 AddService("wifi2", "wifi2_PSK",
490 flimflam::kTypeWifi,
491 flimflam::kStateIdle,
492 add_to_visible, add_to_watchlist);
493 SetServiceProperty("wifi2",
494 flimflam::kSecurityProperty,
495 base::StringValue(flimflam::kSecurityPsk));
496 base::FundamentalValue strength_value(80);
497 SetServiceProperty("wifi2",
498 flimflam::kSignalStrengthProperty,
499 strength_value);
501 if (CommandLine::ForCurrentProcess()->HasSwitch(
502 chromeos::switches::kEnableStubPortalledWifi)) {
503 AddService(kStubPortalledWifiPath, kStubPortalledWifiName,
504 flimflam::kTypeWifi,
505 flimflam::kStatePortal,
506 add_to_visible, add_to_watchlist);
507 SetServiceProperty(kStubPortalledWifiPath,
508 flimflam::kSecurityProperty,
509 base::StringValue(flimflam::kSecurityNone));
512 // Wimax
514 AddService("wimax1", "wimax1",
515 flimflam::kTypeWimax,
516 flimflam::kStateIdle,
517 add_to_visible, add_to_watchlist);
518 SetServiceProperty("wimax1",
519 flimflam::kConnectableProperty,
520 base::FundamentalValue(true));
522 // Cellular
524 AddService("cellular1", "cellular1",
525 flimflam::kTypeCellular,
526 flimflam::kStateIdle,
527 add_to_visible, add_to_watchlist);
528 base::StringValue technology_value(flimflam::kNetworkTechnologyGsm);
529 SetServiceProperty("cellular1",
530 flimflam::kNetworkTechnologyProperty,
531 technology_value);
532 SetServiceProperty("cellular1",
533 flimflam::kActivationStateProperty,
534 base::StringValue(flimflam::kActivationStateNotActivated));
535 SetServiceProperty("cellular1",
536 flimflam::kRoamingStateProperty,
537 base::StringValue(flimflam::kRoamingStateHome));
539 // VPN
541 // Set the "Provider" dictionary properties. Note: when setting these in
542 // Shill, "Provider.Type", etc keys are used, but when reading the values
543 // "Provider" . "Type", etc keys are used. Here we are setting the values
544 // that will be read (by the UI, tests, etc).
545 base::DictionaryValue provider_properties;
546 provider_properties.SetString(flimflam::kTypeProperty,
547 flimflam::kProviderOpenVpn);
548 provider_properties.SetString(flimflam::kHostProperty, "vpn_host");
550 AddService("vpn1", "vpn1",
551 flimflam::kTypeVPN,
552 flimflam::kStateOnline,
553 add_to_visible, add_to_watchlist);
554 SetServiceProperty("vpn1",
555 flimflam::kProviderProperty,
556 provider_properties);
558 AddService("vpn2", "vpn2",
559 flimflam::kTypeVPN,
560 flimflam::kStateOffline,
561 add_to_visible, add_to_watchlist);
562 SetServiceProperty("vpn2",
563 flimflam::kProviderProperty,
564 provider_properties);
566 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface()->
567 AddService(ShillProfileClientStub::kSharedProfilePath, "wifi2");
569 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
570 SortManagerServices();
573 void ShillServiceClientStub::NotifyObserversPropertyChanged(
574 const dbus::ObjectPath& service_path,
575 const std::string& property) {
576 base::DictionaryValue* dict = NULL;
577 std::string path = service_path.value();
578 if (!stub_services_.GetDictionaryWithoutPathExpansion(path, &dict)) {
579 LOG(ERROR) << "Notify for unknown service: " << path;
580 return;
582 base::Value* value = NULL;
583 if (!dict->GetWithoutPathExpansion(property, &value)) {
584 LOG(ERROR) << "Notify for unknown property: "
585 << path << " : " << property;
586 return;
588 FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
589 GetObserverList(service_path),
590 OnPropertyChanged(property, *value));
593 base::DictionaryValue* ShillServiceClientStub::GetModifiableServiceProperties(
594 const std::string& service_path) {
595 base::DictionaryValue* properties = NULL;
596 if (!stub_services_.GetDictionaryWithoutPathExpansion(
597 service_path, &properties)) {
598 properties = new base::DictionaryValue;
599 stub_services_.Set(service_path, properties);
601 return properties;
604 ShillServiceClientStub::PropertyObserverList&
605 ShillServiceClientStub::GetObserverList(const dbus::ObjectPath& device_path) {
606 std::map<dbus::ObjectPath, PropertyObserverList*>::iterator iter =
607 observer_list_.find(device_path);
608 if (iter != observer_list_.end())
609 return *(iter->second);
610 PropertyObserverList* observer_list = new PropertyObserverList();
611 observer_list_[device_path] = observer_list;
612 return *observer_list;
615 void ShillServiceClientStub::SetOtherServicesOffline(
616 const std::string& service_path) {
617 const base::DictionaryValue* service_properties = GetServiceProperties(
618 service_path);
619 if (!service_properties) {
620 LOG(ERROR) << "Missing service: " << service_path;
621 return;
623 std::string service_type;
624 service_properties->GetString(flimflam::kTypeProperty, &service_type);
625 // Set all other services of the same type to offline (Idle).
626 for (base::DictionaryValue::Iterator iter(stub_services_);
627 !iter.IsAtEnd(); iter.Advance()) {
628 std::string path = iter.key();
629 if (path == service_path)
630 continue;
631 base::DictionaryValue* properties;
632 if (!stub_services_.GetDictionaryWithoutPathExpansion(path, &properties))
633 NOTREACHED();
635 std::string type;
636 properties->GetString(flimflam::kTypeProperty, &type);
637 if (type != service_type)
638 continue;
639 properties->SetWithoutPathExpansion(
640 flimflam::kStateProperty,
641 base::Value::CreateStringValue(flimflam::kStateIdle));
645 void ShillServiceClientStub::SetCellularActivated(
646 const dbus::ObjectPath& service_path,
647 const ErrorCallback& error_callback) {
648 SetProperty(service_path,
649 flimflam::kActivationStateProperty,
650 base::StringValue(flimflam::kActivationStateActivated),
651 base::Bind(&base::DoNothing),
652 error_callback);
653 SetProperty(service_path,
654 flimflam::kConnectableProperty,
655 base::FundamentalValue(true),
656 base::Bind(&base::DoNothing),
657 error_callback);
660 } // namespace chromeos