Home | History | Annotate | Download | only in dbus
      1 // Copyright (c) 2012 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.
      4 
      5 #include "chromeos/dbus/shill_ipconfig_client.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/stl_util.h"
     10 #include "base/values.h"
     11 #include "chromeos/dbus/shill_property_changed_observer.h"
     12 #include "dbus/bus.h"
     13 #include "dbus/message.h"
     14 #include "dbus/object_path.h"
     15 #include "dbus/object_proxy.h"
     16 #include "dbus/values_util.h"
     17 #include "third_party/cros_system_api/dbus/service_constants.h"
     18 
     19 namespace chromeos {
     20 
     21 namespace {
     22 
     23 // The ShillIPConfigClient implementation.
     24 class ShillIPConfigClientImpl : public ShillIPConfigClient {
     25  public:
     26   ShillIPConfigClientImpl();
     27 
     28   ////////////////////////////////////
     29   // ShillIPConfigClient overrides.
     30   virtual void AddPropertyChangedObserver(
     31       const dbus::ObjectPath& ipconfig_path,
     32       ShillPropertyChangedObserver* observer) OVERRIDE {
     33     GetHelper(ipconfig_path)->AddPropertyChangedObserver(observer);
     34   }
     35 
     36   virtual void RemovePropertyChangedObserver(
     37       const dbus::ObjectPath& ipconfig_path,
     38       ShillPropertyChangedObserver* observer) OVERRIDE {
     39     GetHelper(ipconfig_path)->RemovePropertyChangedObserver(observer);
     40   }
     41   virtual void Refresh(const dbus::ObjectPath& ipconfig_path,
     42                        const VoidDBusMethodCallback& callback) OVERRIDE;
     43   virtual void GetProperties(const dbus::ObjectPath& ipconfig_path,
     44                              const DictionaryValueCallback& callback) OVERRIDE;
     45   virtual void SetProperty(const dbus::ObjectPath& ipconfig_path,
     46                            const std::string& name,
     47                            const base::Value& value,
     48                            const VoidDBusMethodCallback& callback) OVERRIDE;
     49   virtual void ClearProperty(const dbus::ObjectPath& ipconfig_path,
     50                              const std::string& name,
     51                              const VoidDBusMethodCallback& callback) OVERRIDE;
     52   virtual void Remove(const dbus::ObjectPath& ipconfig_path,
     53                       const VoidDBusMethodCallback& callback) OVERRIDE;
     54 
     55  protected:
     56   virtual void Init(dbus::Bus* bus) OVERRIDE {
     57     bus_ = bus;
     58   }
     59 
     60  private:
     61   typedef std::map<std::string, ShillClientHelper*> HelperMap;
     62 
     63   // Returns the corresponding ShillClientHelper for the profile.
     64   ShillClientHelper* GetHelper(const dbus::ObjectPath& ipconfig_path) {
     65     HelperMap::iterator it = helpers_.find(ipconfig_path.value());
     66     if (it != helpers_.end())
     67       return it->second;
     68 
     69     // There is no helper for the profile, create it.
     70     dbus::ObjectProxy* object_proxy =
     71         bus_->GetObjectProxy(shill::kFlimflamServiceName, ipconfig_path);
     72     ShillClientHelper* helper = new ShillClientHelper(object_proxy);
     73     helper->MonitorPropertyChanged(shill::kFlimflamIPConfigInterface);
     74     helpers_.insert(HelperMap::value_type(ipconfig_path.value(), helper));
     75     return helper;
     76   }
     77 
     78   dbus::Bus* bus_;
     79   HelperMap helpers_;
     80   STLValueDeleter<HelperMap> helpers_deleter_;
     81 
     82   DISALLOW_COPY_AND_ASSIGN(ShillIPConfigClientImpl);
     83 };
     84 
     85 ShillIPConfigClientImpl::ShillIPConfigClientImpl()
     86     : bus_(NULL),
     87       helpers_deleter_(&helpers_) {
     88 }
     89 
     90 void ShillIPConfigClientImpl::GetProperties(
     91     const dbus::ObjectPath& ipconfig_path,
     92     const DictionaryValueCallback& callback) {
     93   dbus::MethodCall method_call(shill::kFlimflamIPConfigInterface,
     94                                shill::kGetPropertiesFunction);
     95   GetHelper(ipconfig_path)->CallDictionaryValueMethod(&method_call, callback);
     96 }
     97 
     98 void ShillIPConfigClientImpl::Refresh(
     99     const dbus::ObjectPath& ipconfig_path,
    100     const VoidDBusMethodCallback& callback) {
    101   dbus::MethodCall method_call(shill::kFlimflamIPConfigInterface,
    102                                shill::kRefreshFunction);
    103   GetHelper(ipconfig_path)->CallVoidMethod(&method_call, callback);
    104 }
    105 
    106 void ShillIPConfigClientImpl::SetProperty(
    107     const dbus::ObjectPath& ipconfig_path,
    108     const std::string& name,
    109     const base::Value& value,
    110     const VoidDBusMethodCallback& callback) {
    111   dbus::MethodCall method_call(shill::kFlimflamIPConfigInterface,
    112                                shill::kSetPropertyFunction);
    113   dbus::MessageWriter writer(&method_call);
    114   writer.AppendString(name);
    115   // IPConfig supports writing basic type and string array properties.
    116   switch (value.GetType()) {
    117     case base::Value::TYPE_LIST: {
    118       const base::ListValue* list_value = NULL;
    119       value.GetAsList(&list_value);
    120       dbus::MessageWriter variant_writer(NULL);
    121       writer.OpenVariant("as", &variant_writer);
    122       dbus::MessageWriter array_writer(NULL);
    123       variant_writer.OpenArray("s", &array_writer);
    124       for (base::ListValue::const_iterator it = list_value->begin();
    125            it != list_value->end();
    126            ++it) {
    127         DLOG_IF(ERROR, (*it)->GetType() != base::Value::TYPE_STRING)
    128             << "Unexpected type " << (*it)->GetType();
    129         std::string str;
    130         (*it)->GetAsString(&str);
    131         array_writer.AppendString(str);
    132       }
    133       variant_writer.CloseContainer(&array_writer);
    134       writer.CloseContainer(&variant_writer);
    135     }
    136     case base::Value::TYPE_BOOLEAN:
    137     case base::Value::TYPE_INTEGER:
    138     case base::Value::TYPE_DOUBLE:
    139     case base::Value::TYPE_STRING:
    140       dbus::AppendBasicTypeValueDataAsVariant(&writer, value);
    141       break;
    142     default:
    143       DLOG(ERROR) << "Unexpected type " << value.GetType();
    144   }
    145   GetHelper(ipconfig_path)->CallVoidMethod(&method_call, callback);
    146 }
    147 
    148 void ShillIPConfigClientImpl::ClearProperty(
    149     const dbus::ObjectPath& ipconfig_path,
    150     const std::string& name,
    151     const VoidDBusMethodCallback& callback) {
    152   dbus::MethodCall method_call(shill::kFlimflamIPConfigInterface,
    153                                shill::kClearPropertyFunction);
    154   dbus::MessageWriter writer(&method_call);
    155   writer.AppendString(name);
    156   GetHelper(ipconfig_path)->CallVoidMethod(&method_call, callback);
    157 }
    158 
    159 void ShillIPConfigClientImpl::Remove(
    160     const dbus::ObjectPath& ipconfig_path,
    161     const VoidDBusMethodCallback& callback) {
    162   dbus::MethodCall method_call(shill::kFlimflamIPConfigInterface,
    163                                shill::kRemoveConfigFunction);
    164   GetHelper(ipconfig_path)->CallVoidMethod(&method_call, callback);
    165 }
    166 
    167 }  // namespace
    168 
    169 ShillIPConfigClient::ShillIPConfigClient() {}
    170 
    171 ShillIPConfigClient::~ShillIPConfigClient() {}
    172 
    173 // static
    174 ShillIPConfigClient* ShillIPConfigClient::Create() {
    175   return new ShillIPConfigClientImpl();
    176 }
    177 
    178 }  // namespace chromeos
    179