| 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/object_proxy.h" | 5 #include "dbus/object_proxy.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 options & IGNORE_SERVICE_UNKNOWN_ERRORS) { | 62 options & IGNORE_SERVICE_UNKNOWN_ERRORS) { |
| 63 } | 63 } |
| 64 | 64 |
| 65 ObjectProxy::~ObjectProxy() { | 65 ObjectProxy::~ObjectProxy() { |
| 66 DCHECK(pending_calls_.empty()); | 66 DCHECK(pending_calls_.empty()); |
| 67 } | 67 } |
| 68 | 68 |
| 69 // Originally we tried to make |method_call| a const reference, but we | 69 // Originally we tried to make |method_call| a const reference, but we |
| 70 // gave up as dbus_connection_send_with_reply_and_block() takes a | 70 // gave up as dbus_connection_send_with_reply_and_block() takes a |
| 71 // non-const pointer of DBusMessage as the second parameter. | 71 // non-const pointer of DBusMessage as the second parameter. |
| 72 scoped_ptr<Response> ObjectProxy::CallMethodAndBlockWithErrorDetails( | 72 std::unique_ptr<Response> ObjectProxy::CallMethodAndBlockWithErrorDetails( |
| 73 MethodCall* method_call, int timeout_ms, ScopedDBusError* error) { | 73 MethodCall* method_call, |
| 74 int timeout_ms, |
| 75 ScopedDBusError* error) { |
| 74 bus_->AssertOnDBusThread(); | 76 bus_->AssertOnDBusThread(); |
| 75 | 77 |
| 76 if (!bus_->Connect() || | 78 if (!bus_->Connect() || |
| 77 !method_call->SetDestination(service_name_) || | 79 !method_call->SetDestination(service_name_) || |
| 78 !method_call->SetPath(object_path_)) | 80 !method_call->SetPath(object_path_)) |
| 79 return scoped_ptr<Response>(); | 81 return std::unique_ptr<Response>(); |
| 80 | 82 |
| 81 DBusMessage* request_message = method_call->raw_message(); | 83 DBusMessage* request_message = method_call->raw_message(); |
| 82 | 84 |
| 83 // Send the message synchronously. | 85 // Send the message synchronously. |
| 84 const base::TimeTicks start_time = base::TimeTicks::Now(); | 86 const base::TimeTicks start_time = base::TimeTicks::Now(); |
| 85 DBusMessage* response_message = | 87 DBusMessage* response_message = |
| 86 bus_->SendWithReplyAndBlock(request_message, timeout_ms, error->get()); | 88 bus_->SendWithReplyAndBlock(request_message, timeout_ms, error->get()); |
| 87 // Record if the method call is successful, or not. 1 if successful. | 89 // Record if the method call is successful, or not. 1 if successful. |
| 88 UMA_HISTOGRAM_ENUMERATION("DBus.SyncMethodCallSuccess", | 90 UMA_HISTOGRAM_ENUMERATION("DBus.SyncMethodCallSuccess", |
| 89 response_message ? 1 : 0, | 91 response_message ? 1 : 0, |
| 90 kSuccessRatioHistogramMaxValue); | 92 kSuccessRatioHistogramMaxValue); |
| 91 statistics::AddBlockingSentMethodCall(service_name_, | 93 statistics::AddBlockingSentMethodCall(service_name_, |
| 92 method_call->GetInterface(), | 94 method_call->GetInterface(), |
| 93 method_call->GetMember()); | 95 method_call->GetMember()); |
| 94 | 96 |
| 95 if (!response_message) { | 97 if (!response_message) { |
| 96 LogMethodCallFailure(method_call->GetInterface(), | 98 LogMethodCallFailure(method_call->GetInterface(), |
| 97 method_call->GetMember(), | 99 method_call->GetMember(), |
| 98 error->is_set() ? error->name() : "unknown error type", | 100 error->is_set() ? error->name() : "unknown error type", |
| 99 error->is_set() ? error->message() : ""); | 101 error->is_set() ? error->message() : ""); |
| 100 return scoped_ptr<Response>(); | 102 return std::unique_ptr<Response>(); |
| 101 } | 103 } |
| 102 // Record time spent for the method call. Don't include failures. | 104 // Record time spent for the method call. Don't include failures. |
| 103 UMA_HISTOGRAM_TIMES("DBus.SyncMethodCallTime", | 105 UMA_HISTOGRAM_TIMES("DBus.SyncMethodCallTime", |
| 104 base::TimeTicks::Now() - start_time); | 106 base::TimeTicks::Now() - start_time); |
| 105 | 107 |
| 106 return Response::FromRawMessage(response_message); | 108 return Response::FromRawMessage(response_message); |
| 107 } | 109 } |
| 108 | 110 |
| 109 scoped_ptr<Response> ObjectProxy::CallMethodAndBlock(MethodCall* method_call, | 111 std::unique_ptr<Response> ObjectProxy::CallMethodAndBlock( |
| 110 int timeout_ms) { | 112 MethodCall* method_call, |
| 113 int timeout_ms) { |
| 111 ScopedDBusError error; | 114 ScopedDBusError error; |
| 112 return CallMethodAndBlockWithErrorDetails(method_call, timeout_ms, &error); | 115 return CallMethodAndBlockWithErrorDetails(method_call, timeout_ms, &error); |
| 113 } | 116 } |
| 114 | 117 |
| 115 void ObjectProxy::CallMethod(MethodCall* method_call, | 118 void ObjectProxy::CallMethod(MethodCall* method_call, |
| 116 int timeout_ms, | 119 int timeout_ms, |
| 117 ResponseCallback callback) { | 120 ResponseCallback callback) { |
| 118 CallMethodWithErrorCallback(method_call, timeout_ms, callback, | 121 CallMethodWithErrorCallback(method_call, timeout_ms, callback, |
| 119 base::Bind(&ObjectProxy::OnCallMethodError, | 122 base::Bind(&ObjectProxy::OnCallMethodError, |
| 120 this, | 123 this, |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 DBusMessage* response_message) { | 321 DBusMessage* response_message) { |
| 319 bus_->AssertOnOriginThread(); | 322 bus_->AssertOnOriginThread(); |
| 320 | 323 |
| 321 bool method_call_successful = false; | 324 bool method_call_successful = false; |
| 322 if (!response_message) { | 325 if (!response_message) { |
| 323 // The response is not received. | 326 // The response is not received. |
| 324 error_callback.Run(NULL); | 327 error_callback.Run(NULL); |
| 325 } else if (dbus_message_get_type(response_message) == | 328 } else if (dbus_message_get_type(response_message) == |
| 326 DBUS_MESSAGE_TYPE_ERROR) { | 329 DBUS_MESSAGE_TYPE_ERROR) { |
| 327 // This will take |response_message| and release (unref) it. | 330 // This will take |response_message| and release (unref) it. |
| 328 scoped_ptr<ErrorResponse> error_response( | 331 std::unique_ptr<ErrorResponse> error_response( |
| 329 ErrorResponse::FromRawMessage(response_message)); | 332 ErrorResponse::FromRawMessage(response_message)); |
| 330 error_callback.Run(error_response.get()); | 333 error_callback.Run(error_response.get()); |
| 331 // Delete the message on the D-Bus thread. See below for why. | 334 // Delete the message on the D-Bus thread. See below for why. |
| 332 bus_->GetDBusTaskRunner()->PostTask( | 335 bus_->GetDBusTaskRunner()->PostTask( |
| 333 FROM_HERE, | 336 FROM_HERE, |
| 334 base::Bind(&base::DeletePointer<ErrorResponse>, | 337 base::Bind(&base::DeletePointer<ErrorResponse>, |
| 335 error_response.release())); | 338 error_response.release())); |
| 336 } else { | 339 } else { |
| 337 // This will take |response_message| and release (unref) it. | 340 // This will take |response_message| and release (unref) it. |
| 338 scoped_ptr<Response> response(Response::FromRawMessage(response_message)); | 341 std::unique_ptr<Response> response( |
| 342 Response::FromRawMessage(response_message)); |
| 339 // The response is successfully received. | 343 // The response is successfully received. |
| 340 response_callback.Run(response.get()); | 344 response_callback.Run(response.get()); |
| 341 // The message should be deleted on the D-Bus thread for a complicated | 345 // The message should be deleted on the D-Bus thread for a complicated |
| 342 // reason: | 346 // reason: |
| 343 // | 347 // |
| 344 // libdbus keeps track of the number of bytes in the incoming message | 348 // libdbus keeps track of the number of bytes in the incoming message |
| 345 // queue to ensure that the data size in the queue is manageable. The | 349 // queue to ensure that the data size in the queue is manageable. The |
| 346 // bookkeeping is partly done via dbus_message_unref(), and immediately | 350 // bookkeeping is partly done via dbus_message_unref(), and immediately |
| 347 // asks the client code (Chrome) to stop monitoring the underlying | 351 // asks the client code (Chrome) to stop monitoring the underlying |
| 348 // socket, if the number of bytes exceeds a certian number, which is set | 352 // socket, if the number of bytes exceeds a certian number, which is set |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 DBusConnection* connection, | 463 DBusConnection* connection, |
| 460 DBusMessage* raw_message) { | 464 DBusMessage* raw_message) { |
| 461 bus_->AssertOnDBusThread(); | 465 bus_->AssertOnDBusThread(); |
| 462 | 466 |
| 463 if (dbus_message_get_type(raw_message) != DBUS_MESSAGE_TYPE_SIGNAL) | 467 if (dbus_message_get_type(raw_message) != DBUS_MESSAGE_TYPE_SIGNAL) |
| 464 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 468 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 465 | 469 |
| 466 // raw_message will be unrefed on exit of the function. Increment the | 470 // raw_message will be unrefed on exit of the function. Increment the |
| 467 // reference so we can use it in Signal. | 471 // reference so we can use it in Signal. |
| 468 dbus_message_ref(raw_message); | 472 dbus_message_ref(raw_message); |
| 469 scoped_ptr<Signal> signal( | 473 std::unique_ptr<Signal> signal(Signal::FromRawMessage(raw_message)); |
| 470 Signal::FromRawMessage(raw_message)); | |
| 471 | 474 |
| 472 // Verify the signal comes from the object we're proxying for, this is | 475 // Verify the signal comes from the object we're proxying for, this is |
| 473 // our last chance to return DBUS_HANDLER_RESULT_NOT_YET_HANDLED and | 476 // our last chance to return DBUS_HANDLER_RESULT_NOT_YET_HANDLED and |
| 474 // allow other object proxies to handle instead. | 477 // allow other object proxies to handle instead. |
| 475 const ObjectPath path = signal->GetPath(); | 478 const ObjectPath path = signal->GetPath(); |
| 476 if (path != object_path_) { | 479 if (path != object_path_) { |
| 477 if (path.value() == kDBusSystemObjectPath && | 480 if (path.value() == kDBusSystemObjectPath && |
| 478 signal->GetMember() == kNameOwnerChangedMember) { | 481 signal->GetMember() == kNameOwnerChangedMember) { |
| 479 // Handle NameOwnerChanged separately | 482 // Handle NameOwnerChanged separately |
| 480 return HandleNameOwnerChanged(std::move(signal)); | 483 return HandleNameOwnerChanged(std::move(signal)); |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 bus_->AssertOnDBusThread(); | 655 bus_->AssertOnDBusThread(); |
| 653 // Errors should be suppressed here, as the service may not be yet running | 656 // Errors should be suppressed here, as the service may not be yet running |
| 654 // when connecting to signals of the service, which is just fine. | 657 // when connecting to signals of the service, which is just fine. |
| 655 // The ObjectProxy will be notified when the service is launched via | 658 // The ObjectProxy will be notified when the service is launched via |
| 656 // NameOwnerChanged signal. See also comments in ConnectToSignalInternal(). | 659 // NameOwnerChanged signal. See also comments in ConnectToSignalInternal(). |
| 657 service_name_owner_ = | 660 service_name_owner_ = |
| 658 bus_->GetServiceOwnerAndBlock(service_name_, Bus::SUPPRESS_ERRORS); | 661 bus_->GetServiceOwnerAndBlock(service_name_, Bus::SUPPRESS_ERRORS); |
| 659 } | 662 } |
| 660 | 663 |
| 661 DBusHandlerResult ObjectProxy::HandleNameOwnerChanged( | 664 DBusHandlerResult ObjectProxy::HandleNameOwnerChanged( |
| 662 scoped_ptr<Signal> signal) { | 665 std::unique_ptr<Signal> signal) { |
| 663 DCHECK(signal); | 666 DCHECK(signal); |
| 664 bus_->AssertOnDBusThread(); | 667 bus_->AssertOnDBusThread(); |
| 665 | 668 |
| 666 // Confirm the validity of the NameOwnerChanged signal. | 669 // Confirm the validity of the NameOwnerChanged signal. |
| 667 if (signal->GetMember() == kNameOwnerChangedMember && | 670 if (signal->GetMember() == kNameOwnerChangedMember && |
| 668 signal->GetInterface() == kDBusSystemObjectInterface && | 671 signal->GetInterface() == kDBusSystemObjectInterface && |
| 669 signal->GetSender() == kDBusSystemObjectAddress) { | 672 signal->GetSender() == kDBusSystemObjectAddress) { |
| 670 MessageReader reader(signal.get()); | 673 MessageReader reader(signal.get()); |
| 671 std::string name, old_owner, new_owner; | 674 std::string name, old_owner, new_owner; |
| 672 if (reader.PopString(&name) && | 675 if (reader.PopString(&name) && |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 bool service_is_available) { | 708 bool service_is_available) { |
| 706 bus_->AssertOnOriginThread(); | 709 bus_->AssertOnOriginThread(); |
| 707 | 710 |
| 708 std::vector<WaitForServiceToBeAvailableCallback> callbacks; | 711 std::vector<WaitForServiceToBeAvailableCallback> callbacks; |
| 709 callbacks.swap(wait_for_service_to_be_available_callbacks_); | 712 callbacks.swap(wait_for_service_to_be_available_callbacks_); |
| 710 for (size_t i = 0; i < callbacks.size(); ++i) | 713 for (size_t i = 0; i < callbacks.size(); ++i) |
| 711 callbacks[i].Run(service_is_available); | 714 callbacks[i].Run(service_is_available); |
| 712 } | 715 } |
| 713 | 716 |
| 714 } // namespace dbus | 717 } // namespace dbus |
| OLD | NEW |