Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011 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 // D-Bus library for Chrome. | |
| 6 | |
| 7 #ifndef NET_DBUS_DBUS_H_ | |
| 8 #define NET_DBUS_DBUS_H_ | |
| 9 #pragma once | |
| 10 | |
| 11 #include <string> | |
| 12 #include <vector> | |
| 13 #include <dbus/dbus.h> | |
| 14 | |
| 15 #include "base/callback.h" | |
| 16 | |
| 17 class MessageLoop; | |
| 18 | |
| 19 namespace net { | |
| 20 namespace dbus { | |
| 21 | |
| 22 class ObjectProxy; | |
| 23 | |
| 24 // Bus is used to establish a connection with D-Bus, and create object | |
| 25 // proxies. | |
| 26 class Bus { | |
| 27 public: | |
| 28 // Specifies the bus type. SESSION is used to communicate with per-user | |
| 29 // services like GNOME applications. SYSTEM is used to communicate with | |
| 30 // system-wide services like NetworkManager. | |
| 31 enum BusType { | |
| 32 SESSION = DBUS_BUS_SESSION, | |
| 33 SYSTEM = DBUS_BUS_SYSTEM, | |
| 34 }; | |
| 35 | |
| 36 // Specifies the connection type. PRIVATE should usually be used unless | |
| 37 // you are sure that SHARED is safe for you. PRIVATE gives you a private | |
| 38 // connection, that won't be shared with other Bus objects. SHARED gives | |
| 39 // you a connection shared among other Bus objects, which is unsafe if | |
| 40 // the connection is shared with multiple threads. | |
| 41 enum ConnectionType { | |
| 42 PRIVATE, | |
|
satorux1
2011/07/20 00:08:59
John, the patch is still far from code-review-read
| |
| 43 SHARED, | |
| 44 }; | |
| 45 | |
| 46 // Options used to create a Bus object. | |
| 47 struct Options { | |
| 48 Options() : bus_type(SESSION), connection_type(PRIVATE) {} | |
| 49 | |
| 50 BusType bus_type; | |
| 51 ConnectionType connection_type; | |
| 52 // May add other options like timeout. | |
| 53 }; | |
| 54 | |
| 55 // Creates a Bus object. The actual connection will be established when | |
| 56 // Init() is called. | |
| 57 Bus(const Options& options); | |
| 58 virtual ~Bus(); | |
| 59 | |
| 60 // Gets the object proxy for the given service name and the object path. | |
| 61 // |service_name| looks like "org.freedesktop.NetworkManager", and | |
| 62 // |object_path| looks like "/org/freedesktop/NetworkManager/Devices/0". | |
| 63 // | |
| 64 // This method never returns NULL. The caller should delete the object. | |
| 65 virtual ObjectProxy* GetObjectProxy(const std::string& service_name, | |
| 66 const std::string& object_path); | |
| 67 | |
| 68 | |
| 69 private: | |
| 70 friend class ObjectProxy; | |
| 71 DBusConnection* connection() { return connection_; } | |
| 72 | |
| 73 // Initializes the bus by establishing a connection with the D-Bus. | |
| 74 // Returns true on success. | |
| 75 // | |
| 76 // This is a bit tricky but we off calling this function until when we | |
| 77 // first send a message to the D-Bus, as connecting to D-Bus is | |
| 78 // expensive(actually a blocking call), and we don't want to do this | |
| 79 // when the Bus object is created (that can be in the UI thread). | |
| 80 bool Init(); | |
| 81 | |
| 82 const BusType bus_type_; | |
| 83 const ConnectionType connection_type_; | |
| 84 DBusConnection* connection_; | |
| 85 DISALLOW_COPY_AND_ASSIGN(Bus); | |
| 86 }; | |
| 87 | |
| 88 class MethodCall; | |
| 89 class Response; | |
| 90 | |
| 91 // ObjectProxy is used to communicate with remote objects, such as calling | |
| 92 // methods and sending signals. | |
| 93 class ObjectProxy { | |
| 94 public: | |
| 95 virtual ~ObjectProxy(); | |
| 96 // Used for CallMethodAsync(). | |
| 97 typedef base::Callback<void(Response*)> ResponseCallback; | |
| 98 | |
| 99 // Synchronously calls the method of the remote object. This is a | |
| 100 // blocking call hence shouldn't be called from the UI thread. | |
| 101 virtual bool CallMethodSync(MethodCall* method_call, | |
| 102 Response* response); | |
| 103 | |
| 104 // Asynchronously calls the method of the remote object. |callback| will | |
| 105 // be called in message loop of the same thread that calls this | |
| 106 // function. If the method call is successful, a valid Response object | |
| 107 // will be passed to the callback, and the callback needs to delete it. | |
| 108 // If the method call is unsuccessful, NULL will be passed to the callback. | |
| 109 // | |
| 110 // This is not a blocking call (this function just posts a task to the | |
| 111 // IO thread), hence it's safe to be called from the UI thread. | |
| 112 virtual void CallMethodAsync(MethodCall* method_call, | |
| 113 ResponseCallback callback); | |
| 114 | |
| 115 const std::string& service_name() const { return service_name_; } | |
| 116 const std::string& object_path() const { return object_path_; } | |
| 117 | |
| 118 private: | |
| 119 // Starts the async method call. | |
| 120 void StartAsyncMethodCall(void* request_message, | |
| 121 MessageLoop* origin_loop, | |
| 122 ResponseCallback response_callback); | |
| 123 | |
| 124 // Runs the response callback with the given response object. | |
| 125 static void RunResponseCallback(ResponseCallback response_callback, | |
| 126 Response* response); | |
| 127 | |
| 128 // ... | |
| 129 struct OnPendingCallIsCompleteData { | |
| 130 OnPendingCallIsCompleteData(MessageLoop* in_origin_loop, | |
| 131 ResponseCallback in_response_callback); | |
| 132 MessageLoop* origin_loop; | |
| 133 ResponseCallback response_callback; | |
| 134 }; | |
| 135 | |
| 136 // ... | |
| 137 static void OnPendingCallIsComplete(DBusPendingCall* pending_call, | |
| 138 void* user_data); | |
| 139 | |
| 140 friend class Bus; | |
| 141 | |
| 142 // The object proxy can only be created by Bus. | |
| 143 ObjectProxy(Bus* bus, | |
| 144 const std::string& service_name, | |
| 145 const std::string& object_path); | |
| 146 | |
| 147 Bus* bus_; | |
| 148 std::string service_name_; | |
| 149 std::string object_path_; | |
| 150 | |
| 151 DISALLOW_COPY_AND_ASSIGN(ObjectProxy); | |
| 152 }; | |
| 153 | |
| 154 class MessageWriter; | |
| 155 class MessageReader; | |
| 156 | |
| 157 // Message is the base class of D-Bus message types. Client code should | |
| 158 // usually use sub classes such as MethodCall and Response instead. | |
| 159 class Message { | |
| 160 public: | |
| 161 // Creates a Message. The internal raw message is NULL until it's set | |
| 162 // from outside by reset_raw_message(). | |
| 163 Message(); | |
| 164 virtual ~Message(); | |
| 165 | |
| 166 DBusMessage* raw_message() { return raw_message_; } | |
| 167 // Takes the ownership of raw_message. | |
| 168 void reset_raw_message(DBusMessage* raw_message); | |
| 169 | |
| 170 private: | |
| 171 DBusMessage* raw_message_; | |
| 172 DISALLOW_COPY_AND_ASSIGN(Message); | |
| 173 }; | |
| 174 | |
| 175 // MessageCall is a type of message used for calling a method via D-Bus. | |
| 176 class MethodCall : public Message { | |
| 177 public: | |
| 178 // Creates a method call message for the specified interface name and | |
| 179 // the method name. | |
| 180 // | |
| 181 // For instance, to call "Get" method of DBUS_INTERFACE_INTROSPECTABLE | |
| 182 // interface ("org.freedesktop.DBus.Introspectable"), create a method | |
| 183 // call like this: | |
| 184 // | |
| 185 // MethodCall method_call(DBUS_INTERFACE_INTROSPECTABLE, "Get"); | |
| 186 // | |
| 187 MethodCall(const std::string& interface_name, | |
| 188 const std::string& method_name); | |
| 189 | |
| 190 private: | |
| 191 friend class ObjectProxy; | |
| 192 | |
| 193 // Sets the service name. This will be handled by the object proxy. | |
| 194 void SetServiceName(const std::string& service_name); | |
| 195 // Sets the object path. This will be handled by the object proxy. | |
| 196 void SetObjectPath(const std::string& object_path); | |
| 197 | |
| 198 DISALLOW_COPY_AND_ASSIGN(MethodCall); | |
| 199 }; | |
| 200 | |
| 201 // Response is a type of message used for receiving a response from a | |
| 202 // method via D-Bus. | |
| 203 class Response : public Message { | |
| 204 public: | |
| 205 Response(); | |
| 206 | |
| 207 private: | |
| 208 DISALLOW_COPY_AND_ASSIGN(Response); | |
| 209 }; | |
| 210 | |
| 211 // MessageWriter is used to create outgoing messages for calling methods | |
| 212 // and sending signals. | |
| 213 class MessageWriter { | |
| 214 public: | |
| 215 // The data will be written into the given message. | |
| 216 MessageWriter(Message* message); | |
| 217 ~MessageWriter(); | |
| 218 | |
| 219 // Appends a byte to the message. | |
| 220 void AppendByte(uint8 value); | |
| 221 // The following functions do the same for other basic types. | |
| 222 void AppendBool(bool value); | |
| 223 void AppendInt16(int16 value); | |
| 224 void AppendUint16(uint16 value); | |
| 225 void AppendInt32(int32 value); | |
| 226 void AppendUint32(uint32 value); | |
| 227 void AppendInt64(int64 value); | |
| 228 void AppendUint64(uint64 value); | |
| 229 void AppendDouble(double value); | |
| 230 void AppendString(const std::string& value); | |
| 231 void AppendObjectPath(const std::string& value); | |
| 232 // Add support for ARRAY, STRUCT, DICT_ENTRY, VARIANT as needed. | |
| 233 | |
| 234 private: | |
| 235 Message* message_; | |
| 236 DBusMessageIter raw_message_iter_; | |
| 237 | |
| 238 DISALLOW_COPY_AND_ASSIGN(MessageWriter); | |
| 239 }; | |
| 240 | |
| 241 // MessageReader is used to read incoming messages such as responses for | |
| 242 // method calls. | |
| 243 // | |
| 244 // MessageReader manages an internal iterator to read data. All functions | |
| 245 // starting with Pop advance the iterator on success. | |
| 246 class MessageReader { | |
| 247 public: | |
| 248 // The data will be read from the given message. | |
| 249 MessageReader(Message* message); | |
| 250 ~MessageReader(); | |
| 251 | |
| 252 // Returns true if the reader has more data to read. The function is | |
| 253 // used to iterate contents in a container like: | |
| 254 // | |
| 255 // while (reader.HasMore()) | |
| 256 // reader.PopString(&value); | |
| 257 bool HasMore(); | |
| 258 | |
| 259 // Gets the byte at the current iterator position. On success, advances | |
| 260 // the iterator and returns true. It's an error if the actual data type | |
| 261 // is not a byte, so false will be returned in this case. | |
| 262 bool PopByte(uint8* value); | |
| 263 // The following functions do the same for other basic types. | |
| 264 bool PopBool(bool* value); | |
| 265 bool PopInt16(int16* value); | |
| 266 bool PopUint16(uint16* value); | |
| 267 bool PopInt32(int32* value); | |
| 268 bool PopUint32(uint32* value); | |
| 269 bool PopInt64(int64* value); | |
| 270 bool PopUint64(uint64* value); | |
| 271 bool PopDouble(double* value); | |
| 272 bool PopString(std::string* value); | |
| 273 bool PopObjectPath(std::string* value); | |
| 274 | |
| 275 // Sets up the given message reader to read an array at the current | |
| 276 // iterator position. On success, advances the iterator and returns | |
| 277 // true. It's an error if the actual data type is not an array, so false | |
| 278 // will be returned in this case. | |
| 279 bool PopArray(MessageReader* array_reader); | |
| 280 // The following functions do the same for other container types. | |
| 281 bool PopStruct(MessageReader* struct_reader); | |
| 282 bool PopDictEntry(MessageReader* dict_entry_reader); | |
| 283 bool PopVariant(MessageReader* variant_reader); | |
| 284 | |
| 285 // Gets the array of bytes at the current iterator positio. On success, | |
| 286 // advances the iterator and returns true. Arrays of bytes are often | |
| 287 // used for exchanging binary blobs hence it's worth having a | |
| 288 // specialized function. | |
| 289 bool PopArrayOfBytes(std::vector<uint8>* bytes); | |
| 290 | |
| 291 // Gets the array of object paths at the current iterator positio. On | |
| 292 // success, advances the iterator and returns true. Arrays of object | |
| 293 // paths are often used to communicate with D-Bus services like | |
| 294 // NetworkManager, hence it's worth having a specialized function. | |
| 295 bool PopArrayOfObjectPaths(std::vector<std::string>* object_paths); | |
| 296 | |
| 297 // Gets the byte from the variant data container at the current iterator | |
| 298 // position. On success, returns true and advances the | |
| 299 // iterator. Variants are widely used in D-Bus services so it's worth | |
| 300 // having a specialized function. For instance, The return value type of | |
| 301 // "org.freedesktop.DBus.Introspectable.Get" is a variant. | |
| 302 bool PopVariantOfByte(uint8* value); | |
| 303 // The following functions do the same for other basic types. | |
| 304 bool PopVariantOfBool(bool* value); | |
| 305 bool PopVariantOfInt16(int16* value); | |
| 306 bool PopVariantOfUint16(uint16* value); | |
| 307 bool PopVariantOfInt32(int32* value); | |
| 308 bool PopVariantOfUint32(uint32* value); | |
| 309 bool PopVariantOfInt64(int64* value); | |
| 310 bool PopVariantOfUint64(uint64* value); | |
| 311 bool PopVariantOfDouble(double* value); | |
| 312 bool PopVariantOfString(std::string* value); | |
| 313 bool PopVariantOfObjectPath(std::string* value); | |
| 314 | |
| 315 private: | |
| 316 // Returns true if the data type at the current iterator position | |
| 317 // matches the given D-Bus type, such as DBUS_TYPE_BYTE. | |
| 318 bool CheckType(int dbus_type); | |
| 319 | |
| 320 // Helper function used to implement PopByte() etc. | |
| 321 bool PopBasic(int dbus_type, void *value); | |
| 322 | |
| 323 // Helper function used to implement PopArray() etc. | |
| 324 bool PopContainer(int dbus_type, MessageReader* sub_reader); | |
| 325 | |
| 326 // Helper function used to implement PopVariantOfByte() etc. | |
| 327 bool PopVariantOfBasic(int dbus_type, void* value); | |
| 328 | |
| 329 Message* message_; | |
| 330 DBusMessageIter raw_message_iter_; | |
| 331 | |
| 332 DISALLOW_COPY_AND_ASSIGN(MessageReader); | |
| 333 }; | |
| 334 | |
| 335 } // namespace dbus | |
| 336 } // namespace net | |
| 337 | |
| 338 #endif // NET_DBUS_DBUS_H_ | |
| OLD | NEW |