Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "dbus/bus.h" | 5 #include "dbus/bus.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| 11 #include "base/stringprintf.h" | 11 #include "base/stringprintf.h" |
| 12 #include "base/strings/string_piece.h" | 12 #include "base/strings/string_piece.h" |
| 13 #include "base/threading/thread.h" | 13 #include "base/threading/thread.h" |
| 14 #include "base/threading/thread_restrictions.h" | 14 #include "base/threading/thread_restrictions.h" |
| 15 #include "dbus/dbus_statistics.h" | 15 #include "dbus/dbus_statistics.h" |
| 16 #include "dbus/message.h" | 16 #include "dbus/message.h" |
| 17 #include "dbus/object_path.h" | 17 #include "dbus/object_path.h" |
| 18 #include "dbus/object_proxy.h" | 18 #include "dbus/object_proxy.h" |
| 19 #include "dbus/scoped_dbus_error.h" | 19 #include "dbus/scoped_dbus_error.h" |
| 20 | 20 |
| 21 namespace dbus { | |
| 22 | |
| 21 namespace { | 23 namespace { |
| 22 | 24 |
| 23 const char kErrorServiceUnknown[] = "org.freedesktop.DBus.Error.ServiceUnknown"; | 25 const char kErrorServiceUnknown[] = "org.freedesktop.DBus.Error.ServiceUnknown"; |
| 24 | 26 |
| 25 // Used for success ratio histograms. 1 for success, 0 for failure. | 27 // Used for success ratio histograms. 1 for success, 0 for failure. |
| 26 const int kSuccessRatioHistogramMaxValue = 2; | 28 const int kSuccessRatioHistogramMaxValue = 2; |
| 27 | 29 |
| 28 // The path of D-Bus Object sending NameOwnerChanged signal. | 30 // The path of D-Bus Object sending NameOwnerChanged signal. |
| 29 const char kDBusSystemObjectPath[] = "/org/freedesktop/DBus"; | 31 const char kDBusSystemObjectPath[] = "/org/freedesktop/DBus"; |
| 30 | 32 |
| 33 // The D-Bus Object interface. | |
| 34 const char kDBusSystemObjectInterface[] = "org.freedesktop.DBus"; | |
| 35 | |
| 36 // The D-Bus Object address. | |
| 37 const char kDBusSystemObjectAddress[] = "org.freedesktop.DBus"; | |
| 38 | |
| 39 // The NameOwnerChanged member in |kDBusSystemObjectInterface|. | |
| 40 const char kNameOwnerChangedMember[] = "NameOwnerChanged"; | |
| 41 | |
| 31 // Gets the absolute signal name by concatenating the interface name and | 42 // Gets the absolute signal name by concatenating the interface name and |
| 32 // the signal name. Used for building keys for method_table_ in | 43 // the signal name. Used for building keys for method_table_ in |
| 33 // ObjectProxy. | 44 // ObjectProxy. |
| 34 std::string GetAbsoluteSignalName( | 45 std::string GetAbsoluteSignalName( |
| 35 const std::string& interface_name, | 46 const std::string& interface_name, |
| 36 const std::string& signal_name) { | 47 const std::string& signal_name) { |
| 37 return interface_name + "." + signal_name; | 48 return interface_name + "." + signal_name; |
| 38 } | 49 } |
| 39 | 50 |
| 40 // An empty function used for ObjectProxy::EmptyResponseCallback(). | 51 // An empty function used for ObjectProxy::EmptyResponseCallback(). |
| 41 void EmptyResponseCallbackBody(dbus::Response* unused_response) { | 52 void EmptyResponseCallbackBody(Response* unused_response) { |
| 53 } | |
| 54 | |
| 55 // Gets the owner for |service_name| on |bus|. On success, returns true and | |
| 56 // write the owner name to |service_name_owner|. | |
| 57 // Set |suppress_errors| to true to avoid printing error messages. | |
| 58 bool GetServiceOwner(Bus* bus, | |
| 59 const std::string& service_name, | |
| 60 bool suppress_errors, | |
| 61 std::string* service_name_owner) { | |
| 62 bus->AssertOnDBusThread(); | |
| 63 | |
| 64 MethodCall get_name_owner_call(kDBusSystemObjectInterface, "GetNameOwner"); | |
| 65 MessageWriter writer(&get_name_owner_call); | |
| 66 writer.AppendString(service_name); | |
| 67 VLOG(1) << "Method call: " << get_name_owner_call.ToString(); | |
| 68 | |
| 69 const ObjectPath obj_path(kDBusSystemObjectPath); | |
| 70 if (!get_name_owner_call.SetDestination(kDBusSystemObjectAddress) || | |
| 71 !get_name_owner_call.SetPath(obj_path)) { | |
| 72 if (!suppress_errors) | |
| 73 LOG(ERROR) << "Failed to get name owner."; | |
| 74 return false; | |
| 75 } | |
| 76 | |
| 77 ScopedDBusError error; | |
| 78 DBusMessage* response_message = bus->SendWithReplyAndBlock( | |
| 79 get_name_owner_call.raw_message(), | |
| 80 ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 81 error.get()); | |
| 82 if (!response_message) { | |
| 83 if (!suppress_errors) { | |
| 84 LOG(ERROR) << "Failed to get name owner. Got " << error.name() << ": " | |
| 85 << error.message(); | |
| 86 } | |
| 87 return false; | |
| 88 } | |
| 89 | |
| 90 scoped_ptr<Response> response(Response::FromRawMessage(response_message)); | |
| 91 MessageReader reader(response.get()); | |
| 92 | |
| 93 if (!reader.PopString(service_name_owner)) | |
| 94 service_name_owner->clear(); | |
| 95 return true; | |
| 42 } | 96 } |
| 43 | 97 |
| 44 } // namespace | 98 } // namespace |
| 45 | 99 |
| 46 namespace dbus { | |
| 47 | |
| 48 ObjectProxy::ObjectProxy(Bus* bus, | 100 ObjectProxy::ObjectProxy(Bus* bus, |
| 49 const std::string& service_name, | 101 const std::string& service_name, |
| 50 const ObjectPath& object_path, | 102 const ObjectPath& object_path, |
| 51 int options) | 103 int options) |
| 52 : bus_(bus), | 104 : bus_(bus), |
| 53 service_name_(service_name), | 105 service_name_(service_name), |
| 54 object_path_(object_path), | 106 object_path_(object_path), |
| 55 filter_added_(false), | 107 filter_added_(false), |
| 56 ignore_service_unknown_errors_( | 108 ignore_service_unknown_errors_( |
| 57 options & IGNORE_SERVICE_UNKNOWN_ERRORS) { | 109 options & IGNORE_SERVICE_UNKNOWN_ERRORS) { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 186 bus_->RemoveMatch(*iter, error.get()); | 238 bus_->RemoveMatch(*iter, error.get()); |
| 187 if (error.is_set()) { | 239 if (error.is_set()) { |
| 188 // There is nothing we can do to recover, so just print the error. | 240 // There is nothing we can do to recover, so just print the error. |
| 189 LOG(ERROR) << "Failed to remove match rule: " << *iter; | 241 LOG(ERROR) << "Failed to remove match rule: " << *iter; |
| 190 } | 242 } |
| 191 } | 243 } |
| 192 match_rules_.clear(); | 244 match_rules_.clear(); |
| 193 } | 245 } |
| 194 | 246 |
| 195 // static | 247 // static |
| 248 bool ObjectProxy::ServiceHasOwner(dbus::Bus* bus, | |
| 249 const std::string& service_name) { | |
|
satorux1
2013/04/30 01:53:10
thread checking is missing. bus_->AssertOnDBusThre
| |
| 250 if (!bus->Connect()) | |
| 251 return false; | |
| 252 | |
| 253 std::string service_name_owner; | |
| 254 if (!GetServiceOwner(bus, service_name, true, &service_name_owner)) | |
| 255 return false; | |
| 256 return !service_name_owner.empty(); | |
| 257 } | |
| 258 | |
| 259 // static | |
| 196 ObjectProxy::ResponseCallback ObjectProxy::EmptyResponseCallback() { | 260 ObjectProxy::ResponseCallback ObjectProxy::EmptyResponseCallback() { |
| 197 return base::Bind(&EmptyResponseCallbackBody); | 261 return base::Bind(&EmptyResponseCallbackBody); |
| 198 } | 262 } |
| 199 | 263 |
| 200 ObjectProxy::OnPendingCallIsCompleteData::OnPendingCallIsCompleteData( | 264 ObjectProxy::OnPendingCallIsCompleteData::OnPendingCallIsCompleteData( |
| 201 ObjectProxy* in_object_proxy, | 265 ObjectProxy* in_object_proxy, |
| 202 ResponseCallback in_response_callback, | 266 ResponseCallback in_response_callback, |
| 203 ErrorCallback in_error_callback, | 267 ErrorCallback in_error_callback, |
| 204 base::TimeTicks in_start_time) | 268 base::TimeTicks in_start_time) |
| 205 : object_proxy(in_object_proxy), | 269 : object_proxy(in_object_proxy), |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 278 DBusMessage* response_message) { | 342 DBusMessage* response_message) { |
| 279 bus_->AssertOnOriginThread(); | 343 bus_->AssertOnOriginThread(); |
| 280 | 344 |
| 281 bool method_call_successful = false; | 345 bool method_call_successful = false; |
| 282 if (!response_message) { | 346 if (!response_message) { |
| 283 // The response is not received. | 347 // The response is not received. |
| 284 error_callback.Run(NULL); | 348 error_callback.Run(NULL); |
| 285 } else if (dbus_message_get_type(response_message) == | 349 } else if (dbus_message_get_type(response_message) == |
| 286 DBUS_MESSAGE_TYPE_ERROR) { | 350 DBUS_MESSAGE_TYPE_ERROR) { |
| 287 // This will take |response_message| and release (unref) it. | 351 // This will take |response_message| and release (unref) it. |
| 288 scoped_ptr<dbus::ErrorResponse> error_response( | 352 scoped_ptr<ErrorResponse> error_response( |
| 289 dbus::ErrorResponse::FromRawMessage(response_message)); | 353 ErrorResponse::FromRawMessage(response_message)); |
| 290 error_callback.Run(error_response.get()); | 354 error_callback.Run(error_response.get()); |
| 291 // Delete the message on the D-Bus thread. See below for why. | 355 // Delete the message on the D-Bus thread. See below for why. |
| 292 bus_->PostTaskToDBusThread( | 356 bus_->PostTaskToDBusThread( |
| 293 FROM_HERE, | 357 FROM_HERE, |
| 294 base::Bind(&base::DeletePointer<dbus::ErrorResponse>, | 358 base::Bind(&base::DeletePointer<ErrorResponse>, |
| 295 error_response.release())); | 359 error_response.release())); |
| 296 } else { | 360 } else { |
| 297 // This will take |response_message| and release (unref) it. | 361 // This will take |response_message| and release (unref) it. |
| 298 scoped_ptr<dbus::Response> response( | 362 scoped_ptr<Response> response(Response::FromRawMessage(response_message)); |
| 299 dbus::Response::FromRawMessage(response_message)); | |
| 300 // The response is successfully received. | 363 // The response is successfully received. |
| 301 response_callback.Run(response.get()); | 364 response_callback.Run(response.get()); |
| 302 // The message should be deleted on the D-Bus thread for a complicated | 365 // The message should be deleted on the D-Bus thread for a complicated |
| 303 // reason: | 366 // reason: |
| 304 // | 367 // |
| 305 // libdbus keeps track of the number of bytes in the incoming message | 368 // libdbus keeps track of the number of bytes in the incoming message |
| 306 // queue to ensure that the data size in the queue is manageable. The | 369 // queue to ensure that the data size in the queue is manageable. The |
| 307 // bookkeeping is partly done via dbus_message_unref(), and immediately | 370 // bookkeeping is partly done via dbus_message_unref(), and immediately |
| 308 // asks the client code (Chrome) to stop monitoring the underlying | 371 // asks the client code (Chrome) to stop monitoring the underlying |
| 309 // socket, if the number of bytes exceeds a certian number, which is set | 372 // socket, if the number of bytes exceeds a certian number, which is set |
| 310 // to 63MB, per dbus-transport.cc: | 373 // to 63MB, per dbus-transport.cc: |
| 311 // | 374 // |
| 312 // /* Try to default to something that won't totally hose the system, | 375 // /* Try to default to something that won't totally hose the system, |
| 313 // * but doesn't impose too much of a limitation. | 376 // * but doesn't impose too much of a limitation. |
| 314 // */ | 377 // */ |
| 315 // transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63; | 378 // transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63; |
| 316 // | 379 // |
| 317 // The monitoring of the socket is done on the D-Bus thread (see Watch | 380 // The monitoring of the socket is done on the D-Bus thread (see Watch |
| 318 // class in bus.cc), hence we should stop the monitoring from D-Bus | 381 // class in bus.cc), hence we should stop the monitoring from D-Bus |
| 319 // thread, not from the current thread here, which is likely UI thread. | 382 // thread, not from the current thread here, which is likely UI thread. |
| 320 bus_->PostTaskToDBusThread( | 383 bus_->PostTaskToDBusThread( |
| 321 FROM_HERE, | 384 FROM_HERE, |
| 322 base::Bind(&base::DeletePointer<dbus::Response>, | 385 base::Bind(&base::DeletePointer<Response>, response.release())); |
| 323 response.release())); | |
| 324 | 386 |
| 325 method_call_successful = true; | 387 method_call_successful = true; |
| 326 // Record time spent for the method call. Don't include failures. | 388 // Record time spent for the method call. Don't include failures. |
| 327 UMA_HISTOGRAM_TIMES("DBus.AsyncMethodCallTime", | 389 UMA_HISTOGRAM_TIMES("DBus.AsyncMethodCallTime", |
| 328 base::TimeTicks::Now() - start_time); | 390 base::TimeTicks::Now() - start_time); |
| 329 } | 391 } |
| 330 // Record if the method call is successful, or not. 1 if successful. | 392 // Record if the method call is successful, or not. 1 if successful. |
| 331 UMA_HISTOGRAM_ENUMERATION("DBus.AsyncMethodCallSuccess", | 393 UMA_HISTOGRAM_ENUMERATION("DBus.AsyncMethodCallSuccess", |
| 332 method_call_successful, | 394 method_call_successful, |
| 333 kSuccessRatioHistogramMaxValue); | 395 kSuccessRatioHistogramMaxValue); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 432 | 494 |
| 433 // raw_message will be unrefed on exit of the function. Increment the | 495 // raw_message will be unrefed on exit of the function. Increment the |
| 434 // reference so we can use it in Signal. | 496 // reference so we can use it in Signal. |
| 435 dbus_message_ref(raw_message); | 497 dbus_message_ref(raw_message); |
| 436 scoped_ptr<Signal> signal( | 498 scoped_ptr<Signal> signal( |
| 437 Signal::FromRawMessage(raw_message)); | 499 Signal::FromRawMessage(raw_message)); |
| 438 | 500 |
| 439 // Verify the signal comes from the object we're proxying for, this is | 501 // Verify the signal comes from the object we're proxying for, this is |
| 440 // our last chance to return DBUS_HANDLER_RESULT_NOT_YET_HANDLED and | 502 // our last chance to return DBUS_HANDLER_RESULT_NOT_YET_HANDLED and |
| 441 // allow other object proxies to handle instead. | 503 // allow other object proxies to handle instead. |
| 442 const dbus::ObjectPath path = signal->GetPath(); | 504 const ObjectPath path = signal->GetPath(); |
| 443 if (path != object_path_) { | 505 if (path != object_path_) { |
| 444 if (path.value() == kDBusSystemObjectPath && | 506 if (path.value() == kDBusSystemObjectPath && |
| 445 signal->GetMember() == "NameOwnerChanged") { | 507 signal->GetMember() == kNameOwnerChangedMember) { |
| 446 // Handle NameOwnerChanged separately | 508 // Handle NameOwnerChanged separately |
| 447 return HandleNameOwnerChanged(signal.Pass()); | 509 return HandleNameOwnerChanged(signal.Pass()); |
| 448 } | 510 } |
| 449 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 511 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 450 } | 512 } |
| 451 | 513 |
| 452 const std::string interface = signal->GetInterface(); | 514 const std::string interface = signal->GetInterface(); |
| 453 const std::string member = signal->GetMember(); | 515 const std::string member = signal->GetMember(); |
| 454 | 516 |
| 455 statistics::AddReceivedSignal(service_name_, interface, member); | 517 statistics::AddReceivedSignal(service_name_, interface, member); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 bus_->AssertOnOriginThread(); | 562 bus_->AssertOnOriginThread(); |
| 501 | 563 |
| 502 for (std::vector<SignalCallback>::iterator iter = signal_callbacks.begin(); | 564 for (std::vector<SignalCallback>::iterator iter = signal_callbacks.begin(); |
| 503 iter != signal_callbacks.end(); ++iter) | 565 iter != signal_callbacks.end(); ++iter) |
| 504 iter->Run(signal); | 566 iter->Run(signal); |
| 505 | 567 |
| 506 // Delete the message on the D-Bus thread. See comments in | 568 // Delete the message on the D-Bus thread. See comments in |
| 507 // RunResponseCallback(). | 569 // RunResponseCallback(). |
| 508 bus_->PostTaskToDBusThread( | 570 bus_->PostTaskToDBusThread( |
| 509 FROM_HERE, | 571 FROM_HERE, |
| 510 base::Bind(&base::DeletePointer<dbus::Signal>, signal)); | 572 base::Bind(&base::DeletePointer<Signal>, signal)); |
| 511 | 573 |
| 512 // Record time spent for handling the signal. | 574 // Record time spent for handling the signal. |
| 513 UMA_HISTOGRAM_TIMES("DBus.SignalHandleTime", | 575 UMA_HISTOGRAM_TIMES("DBus.SignalHandleTime", |
| 514 base::TimeTicks::Now() - start_time); | 576 base::TimeTicks::Now() - start_time); |
| 515 } | 577 } |
| 516 | 578 |
| 517 DBusHandlerResult ObjectProxy::HandleMessageThunk( | 579 DBusHandlerResult ObjectProxy::HandleMessageThunk( |
| 518 DBusConnection* connection, | 580 DBusConnection* connection, |
| 519 DBusMessage* raw_message, | 581 DBusMessage* raw_message, |
| 520 void* user_data) { | 582 void* user_data) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 534 << ": object_path= " << object_path_.value() | 596 << ": object_path= " << object_path_.value() |
| 535 << ": " << error_name << ": " << error_message; | 597 << ": " << error_name << ": " << error_message; |
| 536 } | 598 } |
| 537 | 599 |
| 538 void ObjectProxy::OnCallMethodError(const std::string& interface_name, | 600 void ObjectProxy::OnCallMethodError(const std::string& interface_name, |
| 539 const std::string& method_name, | 601 const std::string& method_name, |
| 540 ResponseCallback response_callback, | 602 ResponseCallback response_callback, |
| 541 ErrorResponse* error_response) { | 603 ErrorResponse* error_response) { |
| 542 if (error_response) { | 604 if (error_response) { |
| 543 // Error message may contain the error message as string. | 605 // Error message may contain the error message as string. |
| 544 dbus::MessageReader reader(error_response); | 606 MessageReader reader(error_response); |
| 545 std::string error_message; | 607 std::string error_message; |
| 546 reader.PopString(&error_message); | 608 reader.PopString(&error_message); |
| 547 LogMethodCallFailure(interface_name, | 609 LogMethodCallFailure(interface_name, |
| 548 method_name, | 610 method_name, |
| 549 error_response->GetErrorName(), | 611 error_response->GetErrorName(), |
| 550 error_message); | 612 error_message); |
| 551 } | 613 } |
| 552 response_callback.Run(NULL); | 614 response_callback.Run(NULL); |
| 553 } | 615 } |
| 554 | 616 |
| 555 bool ObjectProxy::AddMatchRuleWithCallback( | 617 bool ObjectProxy::AddMatchRuleWithCallback( |
| 556 const std::string& match_rule, | 618 const std::string& match_rule, |
| 557 const std::string& absolute_signal_name, | 619 const std::string& absolute_signal_name, |
| 558 SignalCallback signal_callback) { | 620 SignalCallback signal_callback) { |
| 559 DCHECK(!match_rule.empty()); | 621 DCHECK(!match_rule.empty()); |
| 560 DCHECK(!absolute_signal_name.empty()); | 622 DCHECK(!absolute_signal_name.empty()); |
| 561 bus_->AssertOnDBusThread(); | 623 bus_->AssertOnDBusThread(); |
| 562 | 624 |
| 563 if (match_rules_.find(match_rule) == match_rules_.end()) { | 625 if (match_rules_.find(match_rule) == match_rules_.end()) { |
| 564 ScopedDBusError error; | 626 ScopedDBusError error; |
| 565 bus_->AddMatch(match_rule, error.get()); | 627 bus_->AddMatch(match_rule, error.get()); |
| 566 if (error.is_set()) { | 628 if (error.is_set()) { |
| 567 LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " << | 629 LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " |
| 568 error.name() << ": " << error.message(); | 630 << error.name() << ": " << error.message(); |
| 569 return false; | 631 return false; |
| 570 } else { | 632 } else { |
| 571 // Store the match rule, so that we can remove this in Detach(). | 633 // Store the match rule, so that we can remove this in Detach(). |
| 572 match_rules_.insert(match_rule); | 634 match_rules_.insert(match_rule); |
| 573 // Add the signal callback to the method table. | 635 // Add the signal callback to the method table. |
| 574 method_table_[absolute_signal_name].push_back(signal_callback); | 636 method_table_[absolute_signal_name].push_back(signal_callback); |
| 575 return true; | 637 return true; |
| 576 } | 638 } |
| 577 } else { | 639 } else { |
| 578 // We already have the match rule. | 640 // We already have the match rule. |
| 579 method_table_[absolute_signal_name].push_back(signal_callback); | 641 method_table_[absolute_signal_name].push_back(signal_callback); |
| 580 return true; | 642 return true; |
| 581 } | 643 } |
| 582 } | 644 } |
| 583 | 645 |
| 584 bool ObjectProxy::AddMatchRuleWithoutCallback( | 646 bool ObjectProxy::AddMatchRuleWithoutCallback( |
| 585 const std::string& match_rule, | 647 const std::string& match_rule, |
| 586 const std::string& absolute_signal_name) { | 648 const std::string& absolute_signal_name) { |
| 587 DCHECK(!match_rule.empty()); | 649 DCHECK(!match_rule.empty()); |
| 588 DCHECK(!absolute_signal_name.empty()); | 650 DCHECK(!absolute_signal_name.empty()); |
| 589 bus_->AssertOnDBusThread(); | 651 bus_->AssertOnDBusThread(); |
| 590 | 652 |
| 591 if (match_rules_.find(match_rule) != match_rules_.end()) | 653 if (match_rules_.find(match_rule) != match_rules_.end()) |
| 592 return true; | 654 return true; |
| 593 | 655 |
| 594 ScopedDBusError error; | 656 ScopedDBusError error; |
| 595 bus_->AddMatch(match_rule, error.get()); | 657 bus_->AddMatch(match_rule, error.get()); |
| 596 if (error.is_set()) { | 658 if (error.is_set()) { |
| 597 LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " << | 659 LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " |
| 598 error.name() << ": " << error.message(); | 660 << error.name() << ": " << error.message(); |
| 599 return false; | 661 return false; |
| 600 } | 662 } |
| 601 // Store the match rule, so that we can remove this in Detach(). | 663 // Store the match rule, so that we can remove this in Detach(). |
| 602 match_rules_.insert(match_rule); | 664 match_rules_.insert(match_rule); |
| 603 return true; | 665 return true; |
| 604 } | 666 } |
| 605 | 667 |
| 606 void ObjectProxy::UpdateNameOwnerAndBlock() { | 668 void ObjectProxy::UpdateNameOwnerAndBlock() { |
| 607 bus_->AssertOnDBusThread(); | 669 GetServiceOwner(bus_, service_name_, false, &service_name_owner_); |
| 608 | |
| 609 MethodCall get_name_owner_call("org.freedesktop.DBus", "GetNameOwner"); | |
| 610 MessageWriter writer(&get_name_owner_call); | |
| 611 writer.AppendString(service_name_); | |
| 612 VLOG(1) << "Method call: " << get_name_owner_call.ToString(); | |
| 613 | |
| 614 const dbus::ObjectPath obj_path("/org/freedesktop/DBus"); | |
| 615 ScopedDBusError error; | |
| 616 if (!get_name_owner_call.SetDestination("org.freedesktop.DBus") || | |
| 617 !get_name_owner_call.SetPath(obj_path)) { | |
| 618 LOG(ERROR) << "Failed to get name owner."; | |
| 619 return; | |
| 620 } | |
| 621 | |
| 622 DBusMessage* response_message = bus_->SendWithReplyAndBlock( | |
| 623 get_name_owner_call.raw_message(), | |
| 624 TIMEOUT_USE_DEFAULT, | |
| 625 error.get()); | |
| 626 if (!response_message) { | |
| 627 LOG(ERROR) << "Failed to get name owner. Got " << error.name() << ": " << | |
| 628 error.message(); | |
| 629 return; | |
| 630 } | |
| 631 scoped_ptr<Response> response(Response::FromRawMessage(response_message)); | |
| 632 MessageReader reader(response.get()); | |
| 633 | |
| 634 std::string new_service_name_owner; | |
| 635 if (reader.PopString(&new_service_name_owner)) | |
| 636 service_name_owner_ = new_service_name_owner; | |
| 637 else | |
| 638 service_name_owner_.clear(); | |
| 639 } | 670 } |
| 640 | 671 |
| 641 DBusHandlerResult ObjectProxy::HandleNameOwnerChanged( | 672 DBusHandlerResult ObjectProxy::HandleNameOwnerChanged( |
| 642 scoped_ptr<Signal> signal) { | 673 scoped_ptr<Signal> signal) { |
| 643 DCHECK(signal); | 674 DCHECK(signal); |
| 644 bus_->AssertOnDBusThread(); | 675 bus_->AssertOnDBusThread(); |
| 645 | 676 |
| 646 // Confirm the validity of the NameOwnerChanged signal. | 677 // Confirm the validity of the NameOwnerChanged signal. |
| 647 if (signal->GetMember() == "NameOwnerChanged" && | 678 if (signal->GetMember() == kNameOwnerChangedMember && |
| 648 signal->GetInterface() == "org.freedesktop.DBus" && | 679 signal->GetInterface() == kDBusSystemObjectInterface && |
| 649 signal->GetSender() == "org.freedesktop.DBus") { | 680 signal->GetSender() == kDBusSystemObjectAddress) { |
| 650 MessageReader reader(signal.get()); | 681 MessageReader reader(signal.get()); |
| 651 std::string name, old_owner, new_owner; | 682 std::string name, old_owner, new_owner; |
| 652 if (reader.PopString(&name) && | 683 if (reader.PopString(&name) && |
| 653 reader.PopString(&old_owner) && | 684 reader.PopString(&old_owner) && |
| 654 reader.PopString(&new_owner) && | 685 reader.PopString(&new_owner) && |
| 655 name == service_name_) { | 686 name == service_name_) { |
| 656 service_name_owner_ = new_owner; | 687 service_name_owner_ = new_owner; |
| 657 if (!name_owner_changed_callback_.is_null()) { | 688 if (!name_owner_changed_callback_.is_null()) { |
| 658 const base::TimeTicks start_time = base::TimeTicks::Now(); | 689 const base::TimeTicks start_time = base::TimeTicks::Now(); |
| 659 Signal* released_signal = signal.release(); | 690 Signal* released_signal = signal.release(); |
| 660 std::vector<SignalCallback> callbacks; | 691 std::vector<SignalCallback> callbacks; |
| 661 callbacks.push_back(name_owner_changed_callback_); | 692 callbacks.push_back(name_owner_changed_callback_); |
| 662 bus_->PostTaskToOriginThread(FROM_HERE, | 693 bus_->PostTaskToOriginThread(FROM_HERE, |
| 663 base::Bind(&ObjectProxy::RunMethod, | 694 base::Bind(&ObjectProxy::RunMethod, |
| 664 this, | 695 this, |
| 665 start_time, | 696 start_time, |
| 666 callbacks, | 697 callbacks, |
| 667 released_signal)); | 698 released_signal)); |
| 668 } | 699 } |
| 669 } | 700 } |
| 670 } | 701 } |
| 671 | 702 |
| 672 // Always return unhandled to let other object proxies handle the same | 703 // Always return unhandled to let other object proxies handle the same |
| 673 // signal. | 704 // signal. |
| 674 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 705 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 675 } | 706 } |
| 676 | 707 |
| 677 } // namespace dbus | 708 } // namespace dbus |
| OLD | NEW |