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 #include "net/dbus/dbus.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 | |
| 9 namespace net { | |
| 10 namespace dbus { | |
| 11 | |
| 12 // | |
| 13 // Bus implementation. | |
| 14 // | |
| 15 | |
| 16 Bus::Bus(Type type) | |
| 17 : type_(type), | |
| 18 connection_(NULL) { | |
| 19 } | |
| 20 | |
| 21 Bus::~Bus() { | |
| 22 } | |
| 23 | |
| 24 bool Bus::Init() { | |
| 25 // Check if it's already initialized. | |
| 26 if (connection_) | |
| 27 return true; | |
| 28 | |
| 29 DBusError error = {}; | |
| 30 dbus_error_init(&error); | |
| 31 | |
| 32 // If returning a newly-created connection, this function will block | |
| 33 // until authentication and bus registration are complete. | |
| 34 connection_ = dbus_bus_get(static_cast<DBusBusType>(type_), &error); | |
|
John Knottenbelt
2011/07/19 09:34:01
Reading the docs for bus, this will return an exis
satorux1
2011/07/19 16:45:06
That's a good point. I'm going to provide an optio
| |
| 35 if (!connection_) { | |
| 36 if (dbus_error_is_set(&error)) { | |
| 37 LOG(ERROR) << error.message; | |
| 38 } | |
| 39 return false; | |
| 40 } | |
| 41 | |
| 42 return true; | |
| 43 } | |
| 44 | |
| 45 ObjectProxy* Bus::GetObjectProxy(const std::string& service_name, | |
| 46 const std::string& object_path) { | |
| 47 return new ObjectProxy(this, service_name, object_path); | |
| 48 } | |
| 49 | |
| 50 // | |
| 51 // Message implementation. | |
| 52 // | |
| 53 | |
| 54 Message::Message() | |
| 55 : raw_message_(NULL) { | |
| 56 } | |
| 57 | |
| 58 Message::~Message() { | |
| 59 dbus_message_unref(raw_message_); | |
| 60 } | |
| 61 | |
| 62 void Message::reset_raw_message(DBusMessage* raw_message) { | |
| 63 if (raw_message_) | |
| 64 dbus_message_unref(raw_message_); | |
| 65 raw_message_ = raw_message; | |
| 66 } | |
| 67 | |
| 68 MethodCall::MethodCall() : Message() { | |
| 69 reset_raw_message(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL)); | |
| 70 } | |
| 71 | |
| 72 Response::Response() : Message() { | |
| 73 } | |
| 74 | |
| 75 // | |
| 76 // MessageBuilder implementation. | |
| 77 // | |
| 78 | |
| 79 MessageBuilder::MessageBuilder(Message* message) : | |
| 80 message_(message) { | |
| 81 dbus_message_iter_init_append(message_->raw_message(), &raw_message_iter_); | |
| 82 } | |
| 83 | |
| 84 | |
| 85 MessageBuilder::~MessageBuilder() { | |
| 86 } | |
| 87 | |
| 88 void MessageBuilder::AppendByte(uint8 value) { | |
| 89 dbus_message_iter_append_basic( | |
| 90 &raw_message_iter_, DBUS_TYPE_BYTE, &value); | |
| 91 } | |
| 92 | |
| 93 void MessageBuilder::AppendBool(bool value) { | |
| 94 dbus_message_iter_append_basic( | |
| 95 &raw_message_iter_, DBUS_TYPE_BOOLEAN, &value); | |
| 96 } | |
| 97 | |
| 98 void MessageBuilder::AppendInt16(int16 value) { | |
| 99 dbus_message_iter_append_basic( | |
| 100 &raw_message_iter_, DBUS_TYPE_INT16, &value); | |
| 101 } | |
| 102 | |
| 103 void MessageBuilder::AppendUint16(uint16 value) { | |
| 104 dbus_message_iter_append_basic( | |
| 105 &raw_message_iter_, DBUS_TYPE_UINT16, &value); | |
| 106 } | |
| 107 | |
| 108 void MessageBuilder::AppendInt32(int32 value) { | |
| 109 dbus_message_iter_append_basic( | |
| 110 &raw_message_iter_, DBUS_TYPE_INT32, &value); | |
| 111 } | |
| 112 | |
| 113 void MessageBuilder::AppendUint32(uint32 value) { | |
| 114 dbus_message_iter_append_basic( | |
| 115 &raw_message_iter_, DBUS_TYPE_UINT32, &value); | |
| 116 } | |
| 117 | |
| 118 void MessageBuilder::AppendInt64(int64 value) { | |
| 119 dbus_message_iter_append_basic( | |
| 120 &raw_message_iter_, DBUS_TYPE_INT64, &value); | |
| 121 } | |
| 122 | |
| 123 void MessageBuilder::AppendUint64(uint64 value) { | |
| 124 dbus_message_iter_append_basic( | |
| 125 &raw_message_iter_, DBUS_TYPE_UINT64, &value); | |
| 126 } | |
| 127 | |
| 128 void MessageBuilder::AppendDouble(double value) { | |
| 129 dbus_message_iter_append_basic( | |
| 130 &raw_message_iter_, DBUS_TYPE_DOUBLE, &value); | |
| 131 } | |
| 132 | |
| 133 void MessageBuilder::AppendString(const std::string& value) { | |
| 134 const char* pointer = value.c_str(); | |
| 135 dbus_message_iter_append_basic( | |
| 136 &raw_message_iter_, DBUS_TYPE_STRING, &pointer); | |
| 137 } | |
| 138 | |
| 139 void MessageBuilder::AppendObjectPath(const std::string& value) { | |
| 140 const char* pointer = value.c_str(); | |
| 141 dbus_message_iter_append_basic( | |
| 142 &raw_message_iter_, DBUS_TYPE_OBJECT_PATH, &pointer); | |
| 143 } | |
| 144 | |
| 145 // | |
| 146 // MessageReader implementation. | |
| 147 // | |
| 148 | |
| 149 MessageReader::MessageReader(Message* message) | |
| 150 : message_(message) { | |
| 151 dbus_message_iter_init(message_->raw_message(), &raw_message_iter_); | |
| 152 } | |
| 153 | |
| 154 | |
| 155 MessageReader::~MessageReader() { | |
| 156 } | |
| 157 | |
| 158 bool MessageReader::HasMore() { | |
| 159 const int dbus_type = dbus_message_iter_get_arg_type(&raw_message_iter_); | |
| 160 return dbus_type != DBUS_TYPE_INVALID; | |
| 161 } | |
| 162 | |
| 163 bool MessageReader::PopByte(uint8* value) { | |
| 164 return PopBasic(DBUS_TYPE_BYTE, value); | |
| 165 } | |
| 166 | |
| 167 bool MessageReader::PopBool(bool* value) { | |
| 168 return PopBasic(DBUS_TYPE_BOOLEAN, value); | |
| 169 } | |
| 170 | |
| 171 bool MessageReader::PopInt16(int16* value) { | |
| 172 return PopBasic(DBUS_TYPE_INT16, value); | |
| 173 } | |
| 174 | |
| 175 bool MessageReader::PopUint16(uint16* value) { | |
| 176 return PopBasic(DBUS_TYPE_UINT16, value); | |
| 177 } | |
| 178 | |
| 179 bool MessageReader::PopInt32(int32* value) { | |
| 180 return PopBasic(DBUS_TYPE_INT32, value); | |
| 181 } | |
| 182 | |
| 183 bool MessageReader::PopUint32(uint32* value) { | |
| 184 return PopBasic(DBUS_TYPE_UINT32, value); | |
| 185 } | |
| 186 | |
| 187 bool MessageReader::PopInt64(int64* value) { | |
| 188 return PopBasic(DBUS_TYPE_INT64, value); | |
| 189 } | |
| 190 | |
| 191 bool MessageReader::PopUint64(uint64* value) { | |
| 192 return PopBasic(DBUS_TYPE_UINT64, value); | |
| 193 } | |
| 194 | |
| 195 bool MessageReader::PopDouble(double* value) { | |
| 196 return PopBasic(DBUS_TYPE_DOUBLE, value); | |
| 197 } | |
| 198 | |
| 199 bool MessageReader::PopString(std::string* value) { | |
| 200 char* tmp_value = NULL; | |
| 201 const bool success = PopBasic(DBUS_TYPE_STRING, &tmp_value); | |
| 202 if (success) | |
| 203 *value = tmp_value; // Copy the string. | |
| 204 return success; | |
| 205 } | |
| 206 | |
| 207 bool MessageReader::PopObjectPath(std::string* value) { | |
| 208 char* tmp_value = NULL; | |
| 209 const bool success = PopBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value); | |
| 210 if (success) | |
| 211 *value = tmp_value; // Copy the string. | |
| 212 return success; | |
| 213 } | |
| 214 | |
| 215 bool MessageReader::PopArray(MessageReader* sub_reader) { | |
| 216 return PopContainer(DBUS_TYPE_ARRAY, sub_reader); | |
| 217 } | |
| 218 | |
| 219 bool MessageReader::PopStruct(MessageReader* sub_reader) { | |
| 220 return PopContainer(DBUS_TYPE_STRUCT, sub_reader); | |
| 221 } | |
| 222 | |
| 223 bool MessageReader::PopDictEntry(MessageReader* sub_reader) { | |
| 224 return PopContainer(DBUS_TYPE_DICT_ENTRY, sub_reader); | |
| 225 } | |
| 226 | |
| 227 bool MessageReader::PopVariant(MessageReader* sub_reader) { | |
| 228 return PopContainer(DBUS_TYPE_VARIANT, sub_reader); | |
| 229 } | |
| 230 | |
| 231 bool MessageReader::PopArrayOfObjectPaths( | |
| 232 std::vector<std::string> *object_paths) { | |
| 233 MessageReader array_reader(message_); | |
| 234 if (!PopArray(&array_reader)) | |
| 235 return false; | |
| 236 while (array_reader.HasMore()) { | |
| 237 std::string object_path; | |
| 238 if (!array_reader.PopObjectPath(&object_path)) | |
| 239 return false; | |
| 240 object_paths->push_back(object_path); | |
| 241 } | |
| 242 return true; | |
| 243 } | |
| 244 | |
| 245 bool MessageReader::PopVariantOfByte(uint8* value) { | |
| 246 return PopVariantOfBasic(DBUS_TYPE_BYTE, value); | |
| 247 } | |
| 248 | |
| 249 bool MessageReader::PopVariantOfBool(bool* value) { | |
| 250 return PopVariantOfBasic(DBUS_TYPE_BOOLEAN, value); | |
| 251 } | |
| 252 | |
| 253 bool MessageReader::PopVariantOfInt16(int16* value) { | |
| 254 return PopVariantOfBasic(DBUS_TYPE_INT16, value); | |
| 255 } | |
| 256 | |
| 257 bool MessageReader::PopVariantOfUint16(uint16* value) { | |
| 258 return PopVariantOfBasic(DBUS_TYPE_UINT16, value); | |
| 259 } | |
| 260 | |
| 261 bool MessageReader::PopVariantOfInt32(int32* value) { | |
| 262 return PopVariantOfBasic(DBUS_TYPE_INT32, value); | |
| 263 } | |
| 264 | |
| 265 bool MessageReader::PopVariantOfUint32(uint32* value) { | |
| 266 return PopVariantOfBasic(DBUS_TYPE_UINT32, value); | |
| 267 } | |
| 268 | |
| 269 bool MessageReader::PopVariantOfInt64(int64* value) { | |
| 270 return PopVariantOfBasic(DBUS_TYPE_INT64, value); | |
| 271 } | |
| 272 | |
| 273 bool MessageReader::PopVariantOfUint64(uint64* value) { | |
| 274 return PopVariantOfBasic(DBUS_TYPE_UINT64, value); | |
| 275 } | |
| 276 | |
| 277 bool MessageReader::PopVariantOfDouble(double* value) { | |
| 278 return PopVariantOfBasic(DBUS_TYPE_DOUBLE, value); | |
| 279 } | |
| 280 | |
| 281 bool MessageReader::PopVariantOfString(std::string* value) { | |
| 282 char* tmp_value = NULL; | |
| 283 const bool success = PopVariantOfBasic(DBUS_TYPE_STRING, &tmp_value); | |
| 284 if (success) | |
| 285 *value = tmp_value; // Copy the string. | |
| 286 return success; | |
| 287 } | |
| 288 | |
| 289 bool MessageReader::PopVariantOfObjectPath(std::string* value) { | |
| 290 char* tmp_value = NULL; | |
| 291 const bool success = PopVariantOfBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value); | |
| 292 if (success) | |
| 293 *value = tmp_value; // Copy the string. | |
| 294 return success; | |
| 295 } | |
| 296 | |
| 297 bool MessageReader::CheckType(int dbus_type) { | |
| 298 const int actual_type = dbus_message_iter_get_arg_type(&raw_message_iter_); | |
| 299 if (actual_type != dbus_type) { | |
| 300 LOG(ERROR) << "Type " << dbus_type << " is expected but got " | |
| 301 << actual_type; | |
| 302 return false; | |
| 303 } | |
| 304 return true; | |
| 305 } | |
| 306 | |
| 307 bool MessageReader::PopBasic(int dbus_type, void* value) { | |
| 308 if (!CheckType(dbus_type)) | |
| 309 return false; | |
| 310 dbus_message_iter_get_basic(&raw_message_iter_, value); | |
| 311 dbus_message_iter_next(&raw_message_iter_); | |
| 312 return true; | |
| 313 } | |
| 314 | |
| 315 bool MessageReader::PopContainer(int dbus_type, MessageReader* sub_reader) { | |
| 316 CHECK_NE(this, sub_reader); | |
| 317 if (!CheckType(dbus_type)) | |
| 318 return false; | |
| 319 dbus_message_iter_recurse(&raw_message_iter_, | |
| 320 &sub_reader->raw_message_iter_); | |
| 321 dbus_message_iter_next(&raw_message_iter_); | |
| 322 return true; | |
| 323 } | |
| 324 | |
| 325 bool MessageReader::PopVariantOfBasic(int dbus_type, void* value) { | |
| 326 net::dbus::MessageReader variant_reader(message_); | |
| 327 if (!PopVariant(&variant_reader)) | |
| 328 return false; | |
| 329 return variant_reader.PopBasic(dbus_type, value); | |
| 330 } | |
| 331 | |
| 332 // | |
| 333 // ObjectProxy implementation. | |
| 334 // | |
| 335 | |
| 336 ObjectProxy::ObjectProxy(Bus* bus, | |
| 337 const std::string& service_name, | |
| 338 const std::string& object_path) | |
| 339 : bus_(bus), | |
| 340 service_name_(service_name), | |
| 341 object_path_(object_path) { | |
| 342 } | |
| 343 | |
| 344 ObjectProxy::~ObjectProxy() { | |
| 345 } | |
| 346 | |
| 347 bool ObjectProxy::CallMethodSync(const std::string interface_name, | |
| 348 const std::string method_name, | |
| 349 MethodCall* request, | |
| 350 Response* response) { | |
| 351 if (!bus_->Init()) | |
| 352 return false; | |
| 353 | |
| 354 DBusMessage* request_message = request->raw_message(); | |
| 355 if (!dbus_message_set_destination(request_message, service_name_.c_str())) | |
| 356 return false; | |
| 357 if (!dbus_message_set_path(request_message, object_path_.c_str())) | |
| 358 return false; | |
| 359 if (!dbus_message_set_interface(request_message, interface_name.c_str())) | |
| 360 return false; | |
| 361 if (!dbus_message_set_member(request_message, method_name.c_str())) | |
| 362 return false; | |
| 363 | |
| 364 const int timeout_ms = -1; // Default timeout. | |
| 365 DBusError error = {}; | |
| 366 dbus_error_init(&error); | |
| 367 | |
| 368 // Send the message synchronously. | |
| 369 DBusMessage* response_message = dbus_connection_send_with_reply_and_block( | |
| 370 bus_->connection(), request_message, timeout_ms, &error); | |
| 371 | |
| 372 if (!response_message) { | |
| 373 if (dbus_error_is_set(&error)) { | |
| 374 LOG(ERROR) << error.message; | |
| 375 } | |
| 376 return false; | |
| 377 } | |
| 378 response->reset_raw_message(response_message); | |
| 379 | |
| 380 return true; | |
| 381 } | |
| 382 | |
| 383 } // namespace dbus | |
| 384 } // namespace net | |
| OLD | NEW |