17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// found in the LICENSE file.
47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chromeos/dbus/fake_shill_device_client.h"
67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/bind.h"
88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/message_loop/message_loop.h"
98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/stl_util.h"
108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/values.h"
118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/dbus/shill_manager_client.h"
138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/dbus/shill_property_changed_observer.h"
148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "dbus/bus.h"
158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "dbus/message.h"
168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "dbus/object_path.h"
178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "dbus/object_proxy.h"
188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "dbus/values_util.h"
198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace chromeos {
227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace {
248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)std::string kSimPin = "1111";
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void ErrorFunction(const std::string& device_path,
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                   const std::string& error_name,
298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                   const std::string& error_message) {
308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  LOG(ERROR) << "Shill Error for: " << device_path
318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)             << ": " << error_name << " : " << error_message;
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PostDeviceNotFoundError(
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const ShillDeviceClient::ErrorCallback& error_callback) {
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string error_message("Failed");
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FROM_HERE,
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(error_callback, shill::kErrorResultNotFound, error_message));
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace
438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FakeShillDeviceClient::FakeShillDeviceClient()
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : tdls_busy_count_(0),
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      weak_ptr_factory_(this) {
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)FakeShillDeviceClient::~FakeShillDeviceClient() {
508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  STLDeleteContainerPairSecondPointers(
518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      observer_list_.begin(), observer_list_.end());
52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// ShillDeviceClient overrides.
558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillDeviceClient::Init(dbus::Bus* bus) {}
578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeShillDeviceClient::AddPropertyChangedObserver(
597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const dbus::ObjectPath& device_path,
607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    ShillPropertyChangedObserver* observer) {
618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  GetObserverList(device_path).AddObserver(observer);
627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeShillDeviceClient::RemovePropertyChangedObserver(
657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const dbus::ObjectPath& device_path,
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    ShillPropertyChangedObserver* observer) {
678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  GetObserverList(device_path).RemoveObserver(observer);
687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeShillDeviceClient::GetProperties(
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const dbus::ObjectPath& device_path,
727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const DictionaryValueCallback& callback) {
738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE,
758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::Bind(&FakeShillDeviceClient::PassStubDeviceProperties,
768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 device_path, callback));
787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeShillDeviceClient::ProposeScan(
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const dbus::ObjectPath& device_path,
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const VoidDBusMethodCallback& callback) {
838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PostVoidCallback(callback, DBUS_METHOD_CALL_SUCCESS);
847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeShillDeviceClient::SetProperty(const dbus::ObjectPath& device_path,
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                        const std::string& name,
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                        const base::Value& value,
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                        const base::Closure& callback,
907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                        const ErrorCallback& error_callback) {
918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::DictionaryValue* device_properties = NULL;
928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!stub_devices_.GetDictionaryWithoutPathExpansion(device_path.value(),
938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                                       &device_properties)) {
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PostDeviceNotFoundError(error_callback);
958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  device_properties->SetWithoutPathExpansion(name, value.DeepCopy());
988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE,
1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::Bind(&FakeShillDeviceClient::NotifyObserversPropertyChanged,
1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(), device_path, name));
1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeShillDeviceClient::ClearProperty(
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const dbus::ObjectPath& device_path,
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& name,
1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const VoidDBusMethodCallback& callback) {
1098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::DictionaryValue* device_properties = NULL;
1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!stub_devices_.GetDictionaryWithoutPathExpansion(device_path.value(),
1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                                       &device_properties)) {
1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    PostVoidCallback(callback, DBUS_METHOD_CALL_FAILURE);
1138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  device_properties->RemoveWithoutPathExpansion(name, NULL);
1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PostVoidCallback(callback, DBUS_METHOD_CALL_SUCCESS);
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeShillDeviceClient::AddIPConfig(
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const dbus::ObjectPath& device_path,
1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& method,
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const ObjectPathDBusMethodCallback& callback) {
1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE,
1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                         base::Bind(callback,
1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                                    DBUS_METHOD_CALL_SUCCESS,
1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                                    dbus::ObjectPath()));
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeShillDeviceClient::RequirePin(const dbus::ObjectPath& device_path,
1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       const std::string& pin,
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       bool require,
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       const base::Closure& callback,
1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       const ErrorCallback& error_callback) {
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  VLOG(1) << "RequirePin: " << device_path.value();
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (pin != kSimPin) {
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        FROM_HERE,
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(error_callback, shill::kErrorResultIncorrectPin, ""));
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::DictionaryValue* device_properties = NULL;
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!stub_devices_.GetDictionaryWithoutPathExpansion(device_path.value(),
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                       &device_properties)) {
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PostDeviceNotFoundError(error_callback);
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::DictionaryValue* simlock_dict = NULL;
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!device_properties->GetDictionaryWithoutPathExpansion(
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          shill::kSIMLockStatusProperty, &simlock_dict)) {
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    simlock_dict = new base::DictionaryValue;
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    device_properties->SetWithoutPathExpansion(
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        shill::kSIMLockStatusProperty, simlock_dict);
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  simlock_dict->Clear();
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  simlock_dict->SetBoolean(shill::kSIMLockEnabledProperty, require);
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // TODO(stevenjb): Investigate why non-empty value breaks UI.
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string lock_type = "";  // shill::kSIMLockPin
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  simlock_dict->SetString(shill::kSIMLockTypeProperty, lock_type);
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  simlock_dict->SetInteger(shill::kSIMLockRetriesLeftProperty, 5);
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NotifyObserversPropertyChanged(device_path, shill::kSIMLockStatusProperty);
1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeShillDeviceClient::EnterPin(const dbus::ObjectPath& device_path,
1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                     const std::string& pin,
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                     const base::Closure& callback,
1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                     const ErrorCallback& error_callback) {
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  VLOG(1) << "EnterPin: " << device_path.value();
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (pin != kSimPin) {
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        FROM_HERE,
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(error_callback, shill::kErrorResultIncorrectPin, ""));
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!stub_devices_.HasKey(device_path.value())) {
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PostDeviceNotFoundError(error_callback);
178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
1808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeShillDeviceClient::UnblockPin(const dbus::ObjectPath& device_path,
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       const std::string& puk,
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       const std::string& pin,
1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       const base::Closure& callback,
1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       const ErrorCallback& error_callback) {
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  VLOG(1) << "UnblockPin: " << device_path.value();
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!stub_devices_.HasKey(device_path.value())) {
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PostDeviceNotFoundError(error_callback);
191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeShillDeviceClient::ChangePin(const dbus::ObjectPath& device_path,
1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                      const std::string& old_pin,
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                      const std::string& new_pin,
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                      const base::Closure& callback,
2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                      const ErrorCallback& error_callback) {
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  VLOG(1) << "ChangePin: " << device_path.value();
202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!stub_devices_.HasKey(device_path.value())) {
203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PostDeviceNotFoundError(error_callback);
204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeShillDeviceClient::Register(const dbus::ObjectPath& device_path,
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                     const std::string& network_id,
2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                     const base::Closure& callback,
2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                     const ErrorCallback& error_callback) {
213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!stub_devices_.HasKey(device_path.value())) {
214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PostDeviceNotFoundError(error_callback);
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeShillDeviceClient::SetCarrier(const dbus::ObjectPath& device_path,
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       const std::string& carrier,
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       const base::Closure& callback,
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       const ErrorCallback& error_callback) {
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!stub_devices_.HasKey(device_path.value())) {
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PostDeviceNotFoundError(error_callback);
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeShillDeviceClient::Reset(const dbus::ObjectPath& device_path,
2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                  const base::Closure& callback,
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                  const ErrorCallback& error_callback) {
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!stub_devices_.HasKey(device_path.value())) {
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PostDeviceNotFoundError(error_callback);
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
2398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FakeShillDeviceClient::PerformTDLSOperation(
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const dbus::ObjectPath& device_path,
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& operation,
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& peer,
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const StringCallback& callback,
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ErrorCallback& error_callback) {
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!stub_devices_.HasKey(device_path.value())) {
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PostDeviceNotFoundError(error_callback);
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (tdls_busy_count_) {
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    --tdls_busy_count_;
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string error_message("In-Progress");
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(error_callback,
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   shill::kErrorResultInProgress, error_message));
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string result;
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (operation == shill::kTDLSStatusOperation)
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result = shill::kTDLSConnectedState;
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE,
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                         base::Bind(callback, result));
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ShillDeviceClient::TestInterface* FakeShillDeviceClient::GetTestInterface() {
2688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return this;
2698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// ShillDeviceClient::TestInterface overrides.
2728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillDeviceClient::AddDevice(const std::string& device_path,
2748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                      const std::string& type,
27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                      const std::string& name) {
2768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
2778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      AddDevice(device_path);
2788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::DictionaryValue* properties = GetDeviceProperties(device_path);
280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  properties->SetStringWithoutPathExpansion(shill::kTypeProperty, type);
281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  properties->SetStringWithoutPathExpansion(shill::kNameProperty, name);
282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  properties->SetStringWithoutPathExpansion(shill::kDBusObjectProperty,
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            device_path);
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  properties->SetStringWithoutPathExpansion(
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      shill::kDBusServiceProperty, modemmanager::kModemManager1ServiceName);
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (type == shill::kTypeCellular) {
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    properties->SetBooleanWithoutPathExpansion(
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        shill::kCellularAllowRoamingProperty, false);
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillDeviceClient::RemoveDevice(const std::string& device_path) {
2938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
2948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      RemoveDevice(device_path);
2958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  stub_devices_.RemoveWithoutPathExpansion(device_path, NULL);
2978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillDeviceClient::ClearDevices() {
3008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
3018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      ClearDevices();
3028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  stub_devices_.Clear();
3048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillDeviceClient::SetDeviceProperty(const std::string& device_path,
3078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                              const std::string& name,
3088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                              const base::Value& value) {
3098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  VLOG(1) << "SetDeviceProperty: " << device_path
3108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          << ": " << name << " = " << value;
3118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SetProperty(dbus::ObjectPath(device_path), name, value,
3128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)              base::Bind(&base::DoNothing),
3138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)              base::Bind(&ErrorFunction, device_path));
3148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string FakeShillDeviceClient::GetDevicePathForType(
3178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& type) {
3188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (base::DictionaryValue::Iterator iter(stub_devices_);
3198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)       !iter.IsAtEnd(); iter.Advance()) {
3208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const base::DictionaryValue* properties = NULL;
3218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (!iter.value().GetAsDictionary(&properties))
3228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      continue;
3238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    std::string prop_type;
3248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (!properties->GetStringWithoutPathExpansion(
3258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            shill::kTypeProperty, &prop_type) ||
3268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        prop_type != type)
3278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      continue;
3288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return iter.key();
3298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return std::string();
3318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillDeviceClient::PassStubDeviceProperties(
3348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const dbus::ObjectPath& device_path,
3358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const DictionaryValueCallback& callback) const {
3368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const base::DictionaryValue* device_properties = NULL;
3378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!stub_devices_.GetDictionaryWithoutPathExpansion(
3388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      device_path.value(), &device_properties)) {
3398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::DictionaryValue empty_dictionary;
3408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    callback.Run(DBUS_METHOD_CALL_FAILURE, empty_dictionary);
3418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
3428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  callback.Run(DBUS_METHOD_CALL_SUCCESS, *device_properties);
3448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Posts a task to run a void callback with status code |status|.
3478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillDeviceClient::PostVoidCallback(
3488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const VoidDBusMethodCallback& callback,
3498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    DBusMethodCallStatus status) {
3508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE,
3518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                         base::Bind(callback, status));
3528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void FakeShillDeviceClient::NotifyObserversPropertyChanged(
3558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const dbus::ObjectPath& device_path,
3568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& property) {
3578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::DictionaryValue* dict = NULL;
3588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string path = device_path.value();
3598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!stub_devices_.GetDictionaryWithoutPathExpansion(path, &dict)) {
3608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    LOG(ERROR) << "Notify for unknown service: " << path;
3618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
3628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::Value* value = NULL;
3648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!dict->GetWithoutPathExpansion(property, &value)) {
3658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    LOG(ERROR) << "Notify for unknown property: "
3668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        << path << " : " << property;
3678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
3688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
3708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                    GetObserverList(device_path),
3718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                    OnPropertyChanged(property, *value));
3728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)base::DictionaryValue* FakeShillDeviceClient::GetDeviceProperties(
3758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& device_path) {
3768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::DictionaryValue* properties = NULL;
3778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!stub_devices_.GetDictionaryWithoutPathExpansion(
3788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      device_path, &properties)) {
3798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    properties = new base::DictionaryValue;
3808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    stub_devices_.SetWithoutPathExpansion(device_path, properties);
3818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return properties;
3837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)FakeShillDeviceClient::PropertyObserverList&
3868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)FakeShillDeviceClient::GetObserverList(const dbus::ObjectPath& device_path) {
3878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::map<dbus::ObjectPath, PropertyObserverList*>::iterator iter =
3888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      observer_list_.find(device_path);
3898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (iter != observer_list_.end())
3908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return *(iter->second);
3918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PropertyObserverList* observer_list = new PropertyObserverList();
3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  observer_list_[device_path] = observer_list;
3938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return *observer_list;
3947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace chromeos
397