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