15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/shill_ipconfig_client.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/shill_property_changed_observer.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/bus.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/message.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_path.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_proxy.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/values_util.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The ShillIPConfigClient implementation.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ShillIPConfigClientImpl : public ShillIPConfigClient {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ShillIPConfigClientImpl();
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ////////////////////////////////////
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ShillIPConfigClient overrides.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AddPropertyChangedObserver(
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const dbus::ObjectPath& ipconfig_path,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ShillPropertyChangedObserver* observer) OVERRIDE {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetHelper(ipconfig_path)->AddPropertyChangedObserver(observer);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RemovePropertyChangedObserver(
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const dbus::ObjectPath& ipconfig_path,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ShillPropertyChangedObserver* observer) OVERRIDE {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetHelper(ipconfig_path)->RemovePropertyChangedObserver(observer);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Refresh(const dbus::ObjectPath& ipconfig_path,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const VoidDBusMethodCallback& callback) OVERRIDE;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetProperties(const dbus::ObjectPath& ipconfig_path,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const DictionaryValueCallback& callback) OVERRIDE;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetProperty(const dbus::ObjectPath& ipconfig_path,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const std::string& name,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const base::Value& value,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const VoidDBusMethodCallback& callback) OVERRIDE;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ClearProperty(const dbus::ObjectPath& ipconfig_path,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const std::string& name,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const VoidDBusMethodCallback& callback) OVERRIDE;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Remove(const dbus::ObjectPath& ipconfig_path,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const VoidDBusMethodCallback& callback) OVERRIDE;
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual ShillIPConfigClient::TestInterface* GetTestInterface() OVERRIDE;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) protected:
57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void Init(dbus::Bus* bus) OVERRIDE {
58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    bus_ = bus;
59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<std::string, ShillClientHelper*> HelperMap;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the corresponding ShillClientHelper for the profile.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShillClientHelper* GetHelper(const dbus::ObjectPath& ipconfig_path) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HelperMap::iterator it = helpers_.find(ipconfig_path.value());
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it != helpers_.end())
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return it->second;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // There is no helper for the profile, create it.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::ObjectProxy* object_proxy =
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        bus_->GetObjectProxy(shill::kFlimflamServiceName, ipconfig_path);
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ShillClientHelper* helper = new ShillClientHelper(object_proxy);
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    helper->MonitorPropertyChanged(shill::kFlimflamIPConfigInterface);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helpers_.insert(HelperMap::value_type(ipconfig_path.value(), helper));
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return helper;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dbus::Bus* bus_;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HelperMap helpers_;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLValueDeleter<HelperMap> helpers_deleter_;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ShillIPConfigClientImpl);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)ShillIPConfigClientImpl::ShillIPConfigClientImpl()
87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    : bus_(NULL),
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      helpers_deleter_(&helpers_) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShillIPConfigClientImpl::GetProperties(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const dbus::ObjectPath& ipconfig_path,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const DictionaryValueCallback& callback) {
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  dbus::MethodCall method_call(shill::kFlimflamIPConfigInterface,
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                               shill::kGetPropertiesFunction);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetHelper(ipconfig_path)->CallDictionaryValueMethod(&method_call, callback);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShillIPConfigClientImpl::Refresh(
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const dbus::ObjectPath& ipconfig_path,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const VoidDBusMethodCallback& callback) {
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  dbus::MethodCall method_call(shill::kFlimflamIPConfigInterface,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               shill::kRefreshFunction);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetHelper(ipconfig_path)->CallVoidMethod(&method_call, callback);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShillIPConfigClientImpl::SetProperty(
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const dbus::ObjectPath& ipconfig_path,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& name,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Value& value,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const VoidDBusMethodCallback& callback) {
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  dbus::MethodCall method_call(shill::kFlimflamIPConfigInterface,
11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                               shill::kSetPropertyFunction);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dbus::MessageWriter writer(&method_call);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  writer.AppendString(name);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IPConfig supports writing basic type and string array properties.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (value.GetType()) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::Value::TYPE_LIST: {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const base::ListValue* list_value = NULL;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      value.GetAsList(&list_value);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::MessageWriter variant_writer(NULL);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writer.OpenVariant("as", &variant_writer);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::MessageWriter array_writer(NULL);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      variant_writer.OpenArray("s", &array_writer);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (base::ListValue::const_iterator it = list_value->begin();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           it != list_value->end();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           ++it) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DLOG_IF(ERROR, (*it)->GetType() != base::Value::TYPE_STRING)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << "Unexpected type " << (*it)->GetType();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string str;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (*it)->GetAsString(&str);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        array_writer.AppendString(str);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      variant_writer.CloseContainer(&array_writer);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writer.CloseContainer(&variant_writer);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::Value::TYPE_BOOLEAN:
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::Value::TYPE_INTEGER:
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::Value::TYPE_DOUBLE:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::Value::TYPE_STRING:
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::AppendBasicTypeValueDataAsVariant(&writer, value);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(ERROR) << "Unexpected type " << value.GetType();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetHelper(ipconfig_path)->CallVoidMethod(&method_call, callback);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShillIPConfigClientImpl::ClearProperty(
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const dbus::ObjectPath& ipconfig_path,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& name,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const VoidDBusMethodCallback& callback) {
15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  dbus::MethodCall method_call(shill::kFlimflamIPConfigInterface,
15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                               shill::kClearPropertyFunction);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dbus::MessageWriter writer(&method_call);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  writer.AppendString(name);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetHelper(ipconfig_path)->CallVoidMethod(&method_call, callback);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShillIPConfigClientImpl::Remove(
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const dbus::ObjectPath& ipconfig_path,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const VoidDBusMethodCallback& callback) {
16368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  dbus::MethodCall method_call(shill::kFlimflamIPConfigInterface,
16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                               shill::kRemoveConfigFunction);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetHelper(ipconfig_path)->CallVoidMethod(&method_call, callback);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ShillIPConfigClient::TestInterface*
169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ShillIPConfigClientImpl::GetTestInterface() {
170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return NULL;
171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShillIPConfigClient::ShillIPConfigClient() {}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShillIPConfigClient::~ShillIPConfigClient() {}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ShillIPConfigClient* ShillIPConfigClient::Create() {
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return new ShillIPConfigClientImpl();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
185