Home | History | Annotate | Download | only in dbus
      1 // Copyright 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.
      4 
      5 #ifndef CHROMEOS_DBUS_NFC_CLIENT_HELPERS_H_
      6 #define CHROMEOS_DBUS_NFC_CLIENT_HELPERS_H_
      7 
      8 #include <map>
      9 #include <string>
     10 #include <utility>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/callback.h"
     14 #include "base/values.h"
     15 #include "chromeos/chromeos_export.h"
     16 #include "chromeos/dbus/nfc_property_set.h"
     17 #include "dbus/bus.h"
     18 #include "dbus/message.h"
     19 #include "dbus/object_path.h"
     20 #include "dbus/object_proxy.h"
     21 
     22 namespace chromeos {
     23 namespace nfc_client_helpers {
     24 
     25 // Constants used to indicate exceptional error conditions.
     26 CHROMEOS_EXPORT extern const char kNoResponseError[];
     27 CHROMEOS_EXPORT extern const char kUnknownObjectError[];
     28 
     29 // The ErrorCallback is used by D-Bus methods to indicate failure.
     30 // It receives two arguments: the name of the error in |error_name| and
     31 // an optional message in |error_message|.
     32 typedef base::Callback<void(const std::string& error_name,
     33                             const std::string& error_message)> ErrorCallback;
     34 
     35 // A vector of object paths is used frequently among the NFC client classes.
     36 // This typedef makes the type specifier a little less verbose.
     37 typedef std::vector<dbus::ObjectPath> ObjectPathVector;
     38 
     39 // Called when a response for a successful method call is received.
     40 CHROMEOS_EXPORT void OnSuccess(const base::Closure& callback,
     41                                dbus::Response* response);
     42 
     43 // Extracts the error data from |response| and invokes |error_callback| with
     44 // the resulting error name and error message.
     45 CHROMEOS_EXPORT void OnError(const ErrorCallback& error_callback,
     46                              dbus::ErrorResponse* response);
     47 
     48 // Appends any value (basic types and nested types) represented by |value| to
     49 // the writer |writer| as a variant type.
     50 // TODO(armansito): Consider moving this to dbus/values_util.h"
     51 CHROMEOS_EXPORT void AppendValueDataAsVariant(dbus::MessageWriter* writer,
     52                                               const base::Value& value);
     53 
     54 // DBusObjectMap is a simple data structure that facilitates keeping track of
     55 // D-Bus object proxies and properties. It maintains a mapping from object
     56 // paths to object proxy - property structure pairs.
     57 // TODO(armansito): This is only needed until neard implements the D-Bus
     58 // org.freedesktop.DBus.ObjectManager interface. Remove this once we upgrade
     59 // to neard-0.14.
     60 class CHROMEOS_EXPORT DBusObjectMap {
     61  public:
     62   // DBusObjectMap::Delegate must be implemented by classes that use an
     63   // instance of DBusObjectMap to manage object proxies.
     64   class Delegate {
     65    public:
     66     virtual ~Delegate() {}
     67 
     68     // Called by DBusObjectMap to create a Properties structure for the remote
     69     // D-Bus object accessible through |object_proxy|. The implementation class
     70     // should create and return an instance of its own subclass of
     71     // ::chromeos::NfcPropertySet. DBusObjectMap will handle connecting the
     72     // signals and update the properties.
     73     virtual NfcPropertySet* CreateProperties(
     74         dbus::ObjectProxy* object_proxy) = 0;
     75 
     76     // Notifies the delegate that an object was added with object path
     77     // |object_path|.
     78     virtual void ObjectAdded(const dbus::ObjectPath& object_path) {}
     79 
     80     // Notifies the delegate that an object was removed with object path
     81     // |object_path|. The object proxy will still be valid before this method
     82     // returns, so that delegates can perform any clean up that use the object
     83     // properties. Note that the remote object will no longer be available,
     84     // but the delegates can still access the cached properties of the object.
     85     virtual void ObjectRemoved(const dbus::ObjectPath& object_path) {}
     86   };
     87 
     88   // Constructor takes in the D-Bus service name the proxies belong to and
     89   // the delegate which will be used to construct properties structures.
     90   // |service_name| must be a valid D-Bus service name, and |delegate| cannot
     91   // be NULL.
     92   DBusObjectMap(const std::string& service_name,
     93                 Delegate* delegate,
     94                 dbus::Bus* bus);
     95 
     96   // Destructor destroys all managed object proxies and notifies the delegate
     97   // for each removed object.
     98   virtual ~DBusObjectMap();
     99 
    100   // Returns the object proxy for object path |object_path|. If no object proxy
    101   // exists for |object_path|, returns NULL.
    102   dbus::ObjectProxy* GetObjectProxy(const dbus::ObjectPath& object_path);
    103 
    104   // Returns the properties structure for remote object with object path
    105   // |object_path|. If no properties structure exists for |object_path|,
    106   // returns NULL.
    107   NfcPropertySet* GetObjectProperties(const dbus::ObjectPath& object_path);
    108 
    109   // Updates the object proxies from the given list of object paths
    110   // |object_paths|. It notifies the delegate of each added and removed object
    111   // via |Delegate::ObjectAdded| and |Delegate::ObjectRemoved|.
    112   void UpdateObjects(const ObjectPathVector& object_paths);
    113 
    114   // Creates and stores an object proxy and properties structure for a remote
    115   // object with object path |object_path|. If an object proxy was already
    116   // created, this operation returns false; returns true otherwise.
    117   bool AddObject(const dbus::ObjectPath& object_path);
    118 
    119   // Removes the D-Bus object proxy and the properties structure for the
    120   // remote object with object path |object_path|. If no known proxy for
    121   // |object_path| exists, then this operation is a no-op.
    122   void RemoveObject(const dbus::ObjectPath& object_path);
    123 
    124   // Invokes GetAll on the property structure belonging to object path
    125   // |object_path|. If |object_path| is unknown, this method is a no-op.
    126   void RefreshProperties(const dbus::ObjectPath& object_path);
    127 
    128   // Invokes GetAll on the property structures belonging to all object paths
    129   // that are managed by this instance.
    130   void RefreshAllProperties();
    131 
    132   // Returns a list containing the object paths of all remote objects that are
    133   // managed by this instance.
    134   ObjectPathVector GetObjectPaths();
    135 
    136  private:
    137   typedef std::pair<dbus::ObjectProxy*, NfcPropertySet*> ObjectPropertyPair;
    138   typedef std::map<dbus::ObjectPath, ObjectPropertyPair> ObjectMap;
    139 
    140   // Returns an instance of ObjectPropertyPair by looking up |object_path| in
    141   // |object_map_|. If no entry is found, returns an instance that contains
    142   // NULL pointers.
    143   ObjectPropertyPair GetObjectPropertyPair(const dbus::ObjectPath& object_path);
    144 
    145   // Cleans up the object proxy and properties structure in |pair|. This method
    146   // will remove the object proxy by calling |dbus::Bus::RemoveObjectProxy| and
    147   // explicitly deallocate the properties structure. Once this method exits,
    148   // both pointers stored by |pair| will become invalid and should not be used.
    149   // If |pair| contains invalid pointers at the time when this method is called
    150   // memory errors are likely to happen, so only valid pointers should be
    151   // passed.
    152   void CleanUpObjectPropertyPair(const ObjectPropertyPair& pair);
    153 
    154   dbus::Bus* bus_;
    155   ObjectMap object_map_;
    156   std::string service_name_;
    157   Delegate* delegate_;
    158 
    159   DISALLOW_COPY_AND_ASSIGN(DBusObjectMap);
    160 };
    161 
    162 // Most NFC D-Bus client classes need to be able to look up object proxies by
    163 // the path of the object that owns them. For example, NfcTagClient updates tag
    164 // proxies based on the adapter that owns them. ObjectProxyTree is a two-level
    165 // mapping that makes this management easy.
    166 class ObjectProxyTree {
    167  public:
    168   ObjectProxyTree();
    169 
    170   // The destructor destroys all contained DBusObjectMap instances. This will
    171   // cause the delegate to get notified for each removed object proxy according
    172   // to the DBusObjectMap destructor.
    173   virtual ~ObjectProxyTree();
    174 
    175   // Creates a DBusObjectMap instance at object path |object_path|.
    176   // |service_name|, |delegate|, and |bus| are passed to the constructor of the
    177   // DBusObjectMap that is created. If a DBusObjectMap for |object_path| was
    178   // already assigned, returns false and does nothing. Otherwise, if a new
    179   // DBusObjectMap was created, returns true.
    180   bool CreateObjectMap(const dbus::ObjectPath& object_path,
    181                        const std::string& service_name,
    182                        DBusObjectMap::Delegate* delegate,
    183                        dbus::Bus* bus);
    184 
    185   // Destroys the DBusObjectMap instance at object path |object_path|.
    186   void RemoveObjectMap(const dbus::ObjectPath& object_path);
    187 
    188   // Returns the DBusObjectMap instance at object path |object_path|, or NULL
    189   // if no such instance exists.
    190   DBusObjectMap* GetObjectMap(const dbus::ObjectPath& object_path);
    191 
    192   // Returns the object proxy by searching all stored DBusObjectMap instances
    193   // for |object_proxy_path|. Returns NULL, if nothing is found.
    194   dbus::ObjectProxy* FindObjectProxy(
    195       const dbus::ObjectPath& object_proxy_path);
    196 
    197   // Returns the object property structure by searching all stored DBusObjectMap
    198   // instances for |object_proxy_path|. Returns NULL, if nothing is found.
    199   NfcPropertySet* FindObjectProperties(
    200       const dbus::ObjectPath& object_proxy_path);
    201 
    202  private:
    203   typedef std::map<dbus::ObjectPath, DBusObjectMap*> PathsToObjectMapsType;
    204   PathsToObjectMapsType paths_to_object_maps_;
    205 
    206   DISALLOW_COPY_AND_ASSIGN(ObjectProxyTree);
    207 };
    208 
    209 }  // namespace nfc_client_helpers
    210 }  // namespace chromeos
    211 
    212 #endif  // CHROMEOS_DBUS_NFC_CLIENT_HELPERS_H_
    213