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