| 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* /*response*/) { |
| 42 } | 53 } |
| 43 | 54 |
| 44 } // namespace | 55 } // namespace |
| 45 | 56 |
| 46 namespace dbus { | |
| 47 | |
| 48 ObjectProxy::ObjectProxy(Bus* bus, | 57 ObjectProxy::ObjectProxy(Bus* bus, |
| 49 const std::string& service_name, | 58 const std::string& service_name, |
| 50 const ObjectPath& object_path, | 59 const ObjectPath& object_path, |
| 51 int options) | 60 int options) |
| 52 : bus_(bus), | 61 : bus_(bus), |
| 53 service_name_(service_name), | 62 service_name_(service_name), |
| 54 object_path_(object_path), | 63 object_path_(object_path), |
| 55 filter_added_(false), | 64 filter_added_(false), |
| 56 ignore_service_unknown_errors_( | 65 ignore_service_unknown_errors_( |
| 57 options & IGNORE_SERVICE_UNKNOWN_ERRORS) { | 66 options & IGNORE_SERVICE_UNKNOWN_ERRORS) { |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 DBusMessage* response_message) { | 287 DBusMessage* response_message) { |
| 279 bus_->AssertOnOriginThread(); | 288 bus_->AssertOnOriginThread(); |
| 280 | 289 |
| 281 bool method_call_successful = false; | 290 bool method_call_successful = false; |
| 282 if (!response_message) { | 291 if (!response_message) { |
| 283 // The response is not received. | 292 // The response is not received. |
| 284 error_callback.Run(NULL); | 293 error_callback.Run(NULL); |
| 285 } else if (dbus_message_get_type(response_message) == | 294 } else if (dbus_message_get_type(response_message) == |
| 286 DBUS_MESSAGE_TYPE_ERROR) { | 295 DBUS_MESSAGE_TYPE_ERROR) { |
| 287 // This will take |response_message| and release (unref) it. | 296 // This will take |response_message| and release (unref) it. |
| 288 scoped_ptr<dbus::ErrorResponse> error_response( | 297 scoped_ptr<ErrorResponse> error_response( |
| 289 dbus::ErrorResponse::FromRawMessage(response_message)); | 298 ErrorResponse::FromRawMessage(response_message)); |
| 290 error_callback.Run(error_response.get()); | 299 error_callback.Run(error_response.get()); |
| 291 // Delete the message on the D-Bus thread. See below for why. | 300 // Delete the message on the D-Bus thread. See below for why. |
| 292 bus_->PostTaskToDBusThread( | 301 bus_->PostTaskToDBusThread( |
| 293 FROM_HERE, | 302 FROM_HERE, |
| 294 base::Bind(&base::DeletePointer<dbus::ErrorResponse>, | 303 base::Bind(&base::DeletePointer<ErrorResponse>, |
| 295 error_response.release())); | 304 error_response.release())); |
| 296 } else { | 305 } else { |
| 297 // This will take |response_message| and release (unref) it. | 306 // This will take |response_message| and release (unref) it. |
| 298 scoped_ptr<dbus::Response> response( | 307 scoped_ptr<Response> response(Response::FromRawMessage(response_message)); |
| 299 dbus::Response::FromRawMessage(response_message)); | |
| 300 // The response is successfully received. | 308 // The response is successfully received. |
| 301 response_callback.Run(response.get()); | 309 response_callback.Run(response.get()); |
| 302 // The message should be deleted on the D-Bus thread for a complicated | 310 // The message should be deleted on the D-Bus thread for a complicated |
| 303 // reason: | 311 // reason: |
| 304 // | 312 // |
| 305 // libdbus keeps track of the number of bytes in the incoming message | 313 // 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 | 314 // queue to ensure that the data size in the queue is manageable. The |
| 307 // bookkeeping is partly done via dbus_message_unref(), and immediately | 315 // bookkeeping is partly done via dbus_message_unref(), and immediately |
| 308 // asks the client code (Chrome) to stop monitoring the underlying | 316 // asks the client code (Chrome) to stop monitoring the underlying |
| 309 // socket, if the number of bytes exceeds a certian number, which is set | 317 // socket, if the number of bytes exceeds a certian number, which is set |
| 310 // to 63MB, per dbus-transport.cc: | 318 // to 63MB, per dbus-transport.cc: |
| 311 // | 319 // |
| 312 // /* Try to default to something that won't totally hose the system, | 320 // /* Try to default to something that won't totally hose the system, |
| 313 // * but doesn't impose too much of a limitation. | 321 // * but doesn't impose too much of a limitation. |
| 314 // */ | 322 // */ |
| 315 // transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63; | 323 // transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63; |
| 316 // | 324 // |
| 317 // The monitoring of the socket is done on the D-Bus thread (see Watch | 325 // 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 | 326 // 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. | 327 // thread, not from the current thread here, which is likely UI thread. |
| 320 bus_->PostTaskToDBusThread( | 328 bus_->PostTaskToDBusThread( |
| 321 FROM_HERE, | 329 FROM_HERE, |
| 322 base::Bind(&base::DeletePointer<dbus::Response>, | 330 base::Bind(&base::DeletePointer<Response>, response.release())); |
| 323 response.release())); | |
| 324 | 331 |
| 325 method_call_successful = true; | 332 method_call_successful = true; |
| 326 // Record time spent for the method call. Don't include failures. | 333 // Record time spent for the method call. Don't include failures. |
| 327 UMA_HISTOGRAM_TIMES("DBus.AsyncMethodCallTime", | 334 UMA_HISTOGRAM_TIMES("DBus.AsyncMethodCallTime", |
| 328 base::TimeTicks::Now() - start_time); | 335 base::TimeTicks::Now() - start_time); |
| 329 } | 336 } |
| 330 // Record if the method call is successful, or not. 1 if successful. | 337 // Record if the method call is successful, or not. 1 if successful. |
| 331 UMA_HISTOGRAM_ENUMERATION("DBus.AsyncMethodCallSuccess", | 338 UMA_HISTOGRAM_ENUMERATION("DBus.AsyncMethodCallSuccess", |
| 332 method_call_successful, | 339 method_call_successful, |
| 333 kSuccessRatioHistogramMaxValue); | 340 kSuccessRatioHistogramMaxValue); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 | 439 |
| 433 // raw_message will be unrefed on exit of the function. Increment the | 440 // raw_message will be unrefed on exit of the function. Increment the |
| 434 // reference so we can use it in Signal. | 441 // reference so we can use it in Signal. |
| 435 dbus_message_ref(raw_message); | 442 dbus_message_ref(raw_message); |
| 436 scoped_ptr<Signal> signal( | 443 scoped_ptr<Signal> signal( |
| 437 Signal::FromRawMessage(raw_message)); | 444 Signal::FromRawMessage(raw_message)); |
| 438 | 445 |
| 439 // Verify the signal comes from the object we're proxying for, this is | 446 // 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 | 447 // our last chance to return DBUS_HANDLER_RESULT_NOT_YET_HANDLED and |
| 441 // allow other object proxies to handle instead. | 448 // allow other object proxies to handle instead. |
| 442 const dbus::ObjectPath path = signal->GetPath(); | 449 const ObjectPath path = signal->GetPath(); |
| 443 if (path != object_path_) { | 450 if (path != object_path_) { |
| 444 if (path.value() == kDBusSystemObjectPath && | 451 if (path.value() == kDBusSystemObjectPath && |
| 445 signal->GetMember() == "NameOwnerChanged") { | 452 signal->GetMember() == kNameOwnerChangedMember) { |
| 446 // Handle NameOwnerChanged separately | 453 // Handle NameOwnerChanged separately |
| 447 return HandleNameOwnerChanged(signal.Pass()); | 454 return HandleNameOwnerChanged(signal.Pass()); |
| 448 } | 455 } |
| 449 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 456 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 450 } | 457 } |
| 451 | 458 |
| 452 const std::string interface = signal->GetInterface(); | 459 const std::string interface = signal->GetInterface(); |
| 453 const std::string member = signal->GetMember(); | 460 const std::string member = signal->GetMember(); |
| 454 | 461 |
| 455 statistics::AddReceivedSignal(service_name_, interface, member); | 462 statistics::AddReceivedSignal(service_name_, interface, member); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 bus_->AssertOnOriginThread(); | 507 bus_->AssertOnOriginThread(); |
| 501 | 508 |
| 502 for (std::vector<SignalCallback>::iterator iter = signal_callbacks.begin(); | 509 for (std::vector<SignalCallback>::iterator iter = signal_callbacks.begin(); |
| 503 iter != signal_callbacks.end(); ++iter) | 510 iter != signal_callbacks.end(); ++iter) |
| 504 iter->Run(signal); | 511 iter->Run(signal); |
| 505 | 512 |
| 506 // Delete the message on the D-Bus thread. See comments in | 513 // Delete the message on the D-Bus thread. See comments in |
| 507 // RunResponseCallback(). | 514 // RunResponseCallback(). |
| 508 bus_->PostTaskToDBusThread( | 515 bus_->PostTaskToDBusThread( |
| 509 FROM_HERE, | 516 FROM_HERE, |
| 510 base::Bind(&base::DeletePointer<dbus::Signal>, signal)); | 517 base::Bind(&base::DeletePointer<Signal>, signal)); |
| 511 | 518 |
| 512 // Record time spent for handling the signal. | 519 // Record time spent for handling the signal. |
| 513 UMA_HISTOGRAM_TIMES("DBus.SignalHandleTime", | 520 UMA_HISTOGRAM_TIMES("DBus.SignalHandleTime", |
| 514 base::TimeTicks::Now() - start_time); | 521 base::TimeTicks::Now() - start_time); |
| 515 } | 522 } |
| 516 | 523 |
| 517 DBusHandlerResult ObjectProxy::HandleMessageThunk( | 524 DBusHandlerResult ObjectProxy::HandleMessageThunk( |
| 518 DBusConnection* connection, | 525 DBusConnection* connection, |
| 519 DBusMessage* raw_message, | 526 DBusMessage* raw_message, |
| 520 void* user_data) { | 527 void* user_data) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 534 << ": object_path= " << object_path_.value() | 541 << ": object_path= " << object_path_.value() |
| 535 << ": " << error_name << ": " << error_message; | 542 << ": " << error_name << ": " << error_message; |
| 536 } | 543 } |
| 537 | 544 |
| 538 void ObjectProxy::OnCallMethodError(const std::string& interface_name, | 545 void ObjectProxy::OnCallMethodError(const std::string& interface_name, |
| 539 const std::string& method_name, | 546 const std::string& method_name, |
| 540 ResponseCallback response_callback, | 547 ResponseCallback response_callback, |
| 541 ErrorResponse* error_response) { | 548 ErrorResponse* error_response) { |
| 542 if (error_response) { | 549 if (error_response) { |
| 543 // Error message may contain the error message as string. | 550 // Error message may contain the error message as string. |
| 544 dbus::MessageReader reader(error_response); | 551 MessageReader reader(error_response); |
| 545 std::string error_message; | 552 std::string error_message; |
| 546 reader.PopString(&error_message); | 553 reader.PopString(&error_message); |
| 547 LogMethodCallFailure(interface_name, | 554 LogMethodCallFailure(interface_name, |
| 548 method_name, | 555 method_name, |
| 549 error_response->GetErrorName(), | 556 error_response->GetErrorName(), |
| 550 error_message); | 557 error_message); |
| 551 } | 558 } |
| 552 response_callback.Run(NULL); | 559 response_callback.Run(NULL); |
| 553 } | 560 } |
| 554 | 561 |
| 555 bool ObjectProxy::AddMatchRuleWithCallback( | 562 bool ObjectProxy::AddMatchRuleWithCallback( |
| 556 const std::string& match_rule, | 563 const std::string& match_rule, |
| 557 const std::string& absolute_signal_name, | 564 const std::string& absolute_signal_name, |
| 558 SignalCallback signal_callback) { | 565 SignalCallback signal_callback) { |
| 559 DCHECK(!match_rule.empty()); | 566 DCHECK(!match_rule.empty()); |
| 560 DCHECK(!absolute_signal_name.empty()); | 567 DCHECK(!absolute_signal_name.empty()); |
| 561 bus_->AssertOnDBusThread(); | 568 bus_->AssertOnDBusThread(); |
| 562 | 569 |
| 563 if (match_rules_.find(match_rule) == match_rules_.end()) { | 570 if (match_rules_.find(match_rule) == match_rules_.end()) { |
| 564 ScopedDBusError error; | 571 ScopedDBusError error; |
| 565 bus_->AddMatch(match_rule, error.get()); | 572 bus_->AddMatch(match_rule, error.get()); |
| 566 if (error.is_set()) { | 573 if (error.is_set()) { |
| 567 LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " << | 574 LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " |
| 568 error.name() << ": " << error.message(); | 575 << error.name() << ": " << error.message(); |
| 569 return false; | 576 return false; |
| 570 } else { | 577 } else { |
| 571 // Store the match rule, so that we can remove this in Detach(). | 578 // Store the match rule, so that we can remove this in Detach(). |
| 572 match_rules_.insert(match_rule); | 579 match_rules_.insert(match_rule); |
| 573 // Add the signal callback to the method table. | 580 // Add the signal callback to the method table. |
| 574 method_table_[absolute_signal_name].push_back(signal_callback); | 581 method_table_[absolute_signal_name].push_back(signal_callback); |
| 575 return true; | 582 return true; |
| 576 } | 583 } |
| 577 } else { | 584 } else { |
| 578 // We already have the match rule. | 585 // We already have the match rule. |
| 579 method_table_[absolute_signal_name].push_back(signal_callback); | 586 method_table_[absolute_signal_name].push_back(signal_callback); |
| 580 return true; | 587 return true; |
| 581 } | 588 } |
| 582 } | 589 } |
| 583 | 590 |
| 584 bool ObjectProxy::AddMatchRuleWithoutCallback( | 591 bool ObjectProxy::AddMatchRuleWithoutCallback( |
| 585 const std::string& match_rule, | 592 const std::string& match_rule, |
| 586 const std::string& absolute_signal_name) { | 593 const std::string& absolute_signal_name) { |
| 587 DCHECK(!match_rule.empty()); | 594 DCHECK(!match_rule.empty()); |
| 588 DCHECK(!absolute_signal_name.empty()); | 595 DCHECK(!absolute_signal_name.empty()); |
| 589 bus_->AssertOnDBusThread(); | 596 bus_->AssertOnDBusThread(); |
| 590 | 597 |
| 591 if (match_rules_.find(match_rule) != match_rules_.end()) | 598 if (match_rules_.find(match_rule) != match_rules_.end()) |
| 592 return true; | 599 return true; |
| 593 | 600 |
| 594 ScopedDBusError error; | 601 ScopedDBusError error; |
| 595 bus_->AddMatch(match_rule, error.get()); | 602 bus_->AddMatch(match_rule, error.get()); |
| 596 if (error.is_set()) { | 603 if (error.is_set()) { |
| 597 LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " << | 604 LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " |
| 598 error.name() << ": " << error.message(); | 605 << error.name() << ": " << error.message(); |
| 599 return false; | 606 return false; |
| 600 } | 607 } |
| 601 // Store the match rule, so that we can remove this in Detach(). | 608 // Store the match rule, so that we can remove this in Detach(). |
| 602 match_rules_.insert(match_rule); | 609 match_rules_.insert(match_rule); |
| 603 return true; | 610 return true; |
| 604 } | 611 } |
| 605 | 612 |
| 606 void ObjectProxy::UpdateNameOwnerAndBlock() { | 613 void ObjectProxy::UpdateNameOwnerAndBlock() { |
| 607 bus_->AssertOnDBusThread(); | 614 bus_->AssertOnDBusThread(); |
| 608 | 615 service_name_owner_ = |
| 609 MethodCall get_name_owner_call("org.freedesktop.DBus", "GetNameOwner"); | 616 bus_->GetServiceOwnerAndBlock(service_name_, Bus::SUPPRESS_ERRORS); |
| 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 } | 617 } |
| 640 | 618 |
| 641 DBusHandlerResult ObjectProxy::HandleNameOwnerChanged( | 619 DBusHandlerResult ObjectProxy::HandleNameOwnerChanged( |
| 642 scoped_ptr<Signal> signal) { | 620 scoped_ptr<Signal> signal) { |
| 643 DCHECK(signal); | 621 DCHECK(signal); |
| 644 bus_->AssertOnDBusThread(); | 622 bus_->AssertOnDBusThread(); |
| 645 | 623 |
| 646 // Confirm the validity of the NameOwnerChanged signal. | 624 // Confirm the validity of the NameOwnerChanged signal. |
| 647 if (signal->GetMember() == "NameOwnerChanged" && | 625 if (signal->GetMember() == kNameOwnerChangedMember && |
| 648 signal->GetInterface() == "org.freedesktop.DBus" && | 626 signal->GetInterface() == kDBusSystemObjectInterface && |
| 649 signal->GetSender() == "org.freedesktop.DBus") { | 627 signal->GetSender() == kDBusSystemObjectAddress) { |
| 650 MessageReader reader(signal.get()); | 628 MessageReader reader(signal.get()); |
| 651 std::string name, old_owner, new_owner; | 629 std::string name, old_owner, new_owner; |
| 652 if (reader.PopString(&name) && | 630 if (reader.PopString(&name) && |
| 653 reader.PopString(&old_owner) && | 631 reader.PopString(&old_owner) && |
| 654 reader.PopString(&new_owner) && | 632 reader.PopString(&new_owner) && |
| 655 name == service_name_) { | 633 name == service_name_) { |
| 656 service_name_owner_ = new_owner; | 634 service_name_owner_ = new_owner; |
| 657 if (!name_owner_changed_callback_.is_null()) { | 635 if (!name_owner_changed_callback_.is_null()) { |
| 658 const base::TimeTicks start_time = base::TimeTicks::Now(); | 636 const base::TimeTicks start_time = base::TimeTicks::Now(); |
| 659 Signal* released_signal = signal.release(); | 637 Signal* released_signal = signal.release(); |
| 660 std::vector<SignalCallback> callbacks; | 638 std::vector<SignalCallback> callbacks; |
| 661 callbacks.push_back(name_owner_changed_callback_); | 639 callbacks.push_back(name_owner_changed_callback_); |
| 662 bus_->PostTaskToOriginThread(FROM_HERE, | 640 bus_->PostTaskToOriginThread(FROM_HERE, |
| 663 base::Bind(&ObjectProxy::RunMethod, | 641 base::Bind(&ObjectProxy::RunMethod, |
| 664 this, | 642 this, |
| 665 start_time, | 643 start_time, |
| 666 callbacks, | 644 callbacks, |
| 667 released_signal)); | 645 released_signal)); |
| 668 } | 646 } |
| 669 } | 647 } |
| 670 } | 648 } |
| 671 | 649 |
| 672 // Always return unhandled to let other object proxies handle the same | 650 // Always return unhandled to let other object proxies handle the same |
| 673 // signal. | 651 // signal. |
| 674 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 652 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 675 } | 653 } |
| 676 | 654 |
| 677 } // namespace dbus | 655 } // namespace dbus |
| OLD | NEW |