object_proxy.cc revision 9ab5563a3196760eb381d102cbb2bc0f7abc6a50
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/bus.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/dbus_statistics.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/message.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_path.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_proxy.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/scoped_dbus_error.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace dbus { 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kErrorServiceUnknown[] = "org.freedesktop.DBus.Error.ServiceUnknown"; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used for success ratio histograms. 1 for success, 0 for failure. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kSuccessRatioHistogramMaxValue = 2; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The path of D-Bus Object sending NameOwnerChanged signal. 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDBusSystemObjectPath[] = "/org/freedesktop/DBus"; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The D-Bus Object interface. 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kDBusSystemObjectInterface[] = "org.freedesktop.DBus"; 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The D-Bus Object address. 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kDBusSystemObjectAddress[] = "org.freedesktop.DBus"; 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The NameOwnerChanged member in |kDBusSystemObjectInterface|. 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kNameOwnerChangedMember[] = "NameOwnerChanged"; 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets the absolute signal name by concatenating the interface name and 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the signal name. Used for building keys for method_table_ in 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ObjectProxy. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetAbsoluteSignalName( 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& interface_name, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& signal_name) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return interface_name + "." + signal_name; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An empty function used for ObjectProxy::EmptyResponseCallback(). 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EmptyResponseCallbackBody(Response* /*response*/) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ObjectProxy::ObjectProxy(Bus* bus, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& service_name, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ObjectPath& object_path, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int options) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : bus_(bus), 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_name_(service_name), 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object_path_(object_path), 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_added_(false), 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignore_service_unknown_errors_( 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options & IGNORE_SERVICE_UNKNOWN_ERRORS) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ObjectProxy::~ObjectProxy() { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Originally we tried to make |method_call| a const reference, but we 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// gave up as dbus_connection_send_with_reply_and_block() takes a 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// non-const pointer of DBusMessage as the second parameter. 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<Response> ObjectProxy::CallMethodAndBlock(MethodCall* method_call, 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int timeout_ms) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnDBusThread(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!bus_->Connect() || 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !method_call->SetDestination(service_name_) || 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !method_call->SetPath(object_path_)) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scoped_ptr<Response>(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusMessage* request_message = method_call->raw_message(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedDBusError error; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send the message synchronously. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks start_time = base::TimeTicks::Now(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusMessage* response_message = 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->SendWithReplyAndBlock(request_message, timeout_ms, error.get()); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record if the method call is successful, or not. 1 if successful. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("DBus.SyncMethodCallSuccess", 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_message ? 1 : 0, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kSuccessRatioHistogramMaxValue); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) statistics::AddBlockingSentMethodCall(service_name_, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) method_call->GetInterface(), 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) method_call->GetMember()); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_message) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogMethodCallFailure(method_call->GetInterface(), 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method_call->GetMember(), 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error.is_set() ? error.name() : "unknown error type", 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error.is_set() ? error.message() : ""); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scoped_ptr<Response>(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record time spent for the method call. Don't include failures. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("DBus.SyncMethodCallTime", 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks::Now() - start_time); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Response::FromRawMessage(response_message); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ObjectProxy::CallMethod(MethodCall* method_call, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int timeout_ms, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCallback callback) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallMethodWithErrorCallback(method_call, timeout_ms, callback, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ObjectProxy::OnCallMethodError, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method_call->GetInterface(), 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method_call->GetMember(), 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback)); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ObjectProxy::CallMethodWithErrorCallback(MethodCall* method_call, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int timeout_ms, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCallback callback, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorCallback error_callback) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnOriginThread(); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks start_time = base::TimeTicks::Now(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!method_call->SetDestination(service_name_) || 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !method_call->SetPath(object_path_)) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In case of a failure, run the error callback with NULL. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusMessage* response_message = NULL; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Closure task = base::Bind(&ObjectProxy::RunResponseCallback, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_callback, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_time, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_message); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->PostTaskToOriginThread(FROM_HERE, task); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Increment the reference count so we can safely reference the 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // underlying request message until the method call is complete. This 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be unref'ed in StartAsyncMethodCall(). 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusMessage* request_message = method_call->raw_message(); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_ref(request_message); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Closure task = base::Bind(&ObjectProxy::StartAsyncMethodCall, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_ms, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_message, 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_callback, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_time); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) statistics::AddSentMethodCall(service_name_, 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) method_call->GetInterface(), 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) method_call->GetMember()); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait for the response in the D-Bus thread. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->PostTaskToDBusThread(FROM_HERE, task); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ObjectProxy::ConnectToSignal(const std::string& interface_name, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& signal_name, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignalCallback signal_callback, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnConnectedCallback on_connected_callback) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnOriginThread(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->PostTaskToDBusThread(FROM_HERE, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ObjectProxy::ConnectToSignalInternal, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interface_name, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal_name, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal_callback, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) on_connected_callback)); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ObjectProxy::Detach() { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnDBusThread(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (filter_added_) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!bus_->RemoveFilterFunction(&ObjectProxy::HandleMessageThunk, this)) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to remove filter function"; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<std::string>::iterator iter = match_rules_.begin(); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != match_rules_.end(); ++iter) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedDBusError error; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->RemoveMatch(*iter, error.get()); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error.is_set()) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is nothing we can do to recover, so just print the error. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to remove match rule: " << *iter; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_rules_.clear(); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ObjectProxy::ResponseCallback ObjectProxy::EmptyResponseCallback() { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::Bind(&EmptyResponseCallbackBody); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ObjectProxy::OnPendingCallIsCompleteData::OnPendingCallIsCompleteData( 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObjectProxy* in_object_proxy, 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCallback in_response_callback, 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorCallback in_error_callback, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks in_start_time) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : object_proxy(in_object_proxy), 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_callback(in_response_callback), 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_callback(in_error_callback), 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_time(in_start_time) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ObjectProxy::OnPendingCallIsCompleteData::~OnPendingCallIsCompleteData() { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ObjectProxy::StartAsyncMethodCall(int timeout_ms, 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusMessage* request_message, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCallback response_callback, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorCallback error_callback, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks start_time) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnDBusThread(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!bus_->Connect() || !bus_->SetUpAsyncOperations()) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In case of a failure, run the error callback with NULL. 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusMessage* response_message = NULL; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Closure task = base::Bind(&ObjectProxy::RunResponseCallback, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_callback, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_callback, 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_time, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_message); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->PostTaskToOriginThread(FROM_HERE, task); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_unref(request_message); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusPendingCall* pending_call = NULL; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->SendWithReply(request_message, &pending_call, timeout_ms); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prepare the data we'll be passing to OnPendingCallIsCompleteThunk(). 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The data will be deleted in OnPendingCallIsCompleteThunk(). 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnPendingCallIsCompleteData* data = 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new OnPendingCallIsCompleteData(this, response_callback, error_callback, 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_time); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This returns false only when unable to allocate memory. 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_pending_call_set_notify( 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_call, 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ObjectProxy::OnPendingCallIsCompleteThunk, 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_pending_call_unref(pending_call); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's now safe to unref the request message. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_unref(request_message); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ObjectProxy::OnPendingCallIsComplete(DBusPendingCall* pending_call, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCallback response_callback, 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorCallback error_callback, 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks start_time) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnDBusThread(); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusMessage* response_message = dbus_pending_call_steal_reply(pending_call); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Closure task = base::Bind(&ObjectProxy::RunResponseCallback, 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_callback, 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_callback, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_time, 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_message); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->PostTaskToOriginThread(FROM_HERE, task); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ObjectProxy::RunResponseCallback(ResponseCallback response_callback, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorCallback error_callback, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks start_time, 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusMessage* response_message) { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnOriginThread(); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool method_call_successful = false; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_message) { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The response is not received. 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_callback.Run(NULL); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (dbus_message_get_type(response_message) == 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBUS_MESSAGE_TYPE_ERROR) { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will take |response_message| and release (unref) it. 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ErrorResponse> error_response( 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ErrorResponse::FromRawMessage(response_message)); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_callback.Run(error_response.get()); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete the message on the D-Bus thread. See below for why. 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->PostTaskToDBusThread( 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&base::DeletePointer<ErrorResponse>, 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_response.release())); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will take |response_message| and release (unref) it. 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<Response> response(Response::FromRawMessage(response_message)); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The response is successfully received. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_callback.Run(response.get()); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The message should be deleted on the D-Bus thread for a complicated 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reason: 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // libdbus keeps track of the number of bytes in the incoming message 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // queue to ensure that the data size in the queue is manageable. The 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bookkeeping is partly done via dbus_message_unref(), and immediately 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // asks the client code (Chrome) to stop monitoring the underlying 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // socket, if the number of bytes exceeds a certian number, which is set 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to 63MB, per dbus-transport.cc: 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // /* Try to default to something that won't totally hose the system, 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // * but doesn't impose too much of a limitation. 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // */ 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The monitoring of the socket is done on the D-Bus thread (see Watch 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // class in bus.cc), hence we should stop the monitoring from D-Bus 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread, not from the current thread here, which is likely UI thread. 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->PostTaskToDBusThread( 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&base::DeletePointer<Response>, response.release())); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method_call_successful = true; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record time spent for the method call. Don't include failures. 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("DBus.AsyncMethodCallTime", 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks::Now() - start_time); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record if the method call is successful, or not. 1 if successful. 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("DBus.AsyncMethodCallSuccess", 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method_call_successful, 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kSuccessRatioHistogramMaxValue); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ObjectProxy::OnPendingCallIsCompleteThunk(DBusPendingCall* pending_call, 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* user_data) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnPendingCallIsCompleteData* data = 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<OnPendingCallIsCompleteData*>(user_data); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObjectProxy* self = data->object_proxy; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self->OnPendingCallIsComplete(pending_call, 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->response_callback, 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->error_callback, 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->start_time); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete data; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ObjectProxy::ConnectToSignalInternal( 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& interface_name, 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& signal_name, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignalCallback signal_callback, 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnConnectedCallback on_connected_callback) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnDBusThread(); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string absolute_signal_name = 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetAbsoluteSignalName(interface_name, signal_name); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Will become true, if everything is successful. 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = false; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bus_->Connect() && bus_->SetUpAsyncOperations()) { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should add the filter only once. Otherwise, HandleMessage() will 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be called more than once. 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!filter_added_) { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bus_->AddFilterFunction(&ObjectProxy::HandleMessageThunk, this)) { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_added_ = true; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to add filter function"; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a match rule so the signal goes through HandleMessage(). 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string match_rule = 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPrintf("type='signal', interface='%s', path='%s'", 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interface_name.c_str(), 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object_path_.value().c_str()); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a match_rule listening NameOwnerChanged for the well-known name 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |service_name_|. 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string name_owner_changed_match_rule = 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPrintf( 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "type='signal',interface='org.freedesktop.DBus'," 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "member='NameOwnerChanged',path='/org/freedesktop/DBus'," 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sender='org.freedesktop.DBus',arg0='%s'", 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_name_.c_str()); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (AddMatchRuleWithCallback(match_rule, 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) absolute_signal_name, 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal_callback) && 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMatchRuleWithoutCallback(name_owner_changed_match_rule, 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "org.freedesktop.DBus.NameOwnerChanged")) { 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = true; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try getting the current name owner. It's not guaranteed that we can get 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the name owner at this moment, as the service may not yet be started. If 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that's the case, we'll get the name owner via NameOwnerChanged signal, 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as soon as the service is started. 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateNameOwnerAndBlock(); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Run on_connected_callback in the origin thread. 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->PostTaskToOriginThread( 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ObjectProxy::OnConnected, 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) on_connected_callback, 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interface_name, 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal_name, 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success)); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ObjectProxy::OnConnected(OnConnectedCallback on_connected_callback, 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& interface_name, 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& signal_name, 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success) { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnOriginThread(); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) on_connected_callback.Run(interface_name, signal_name, success); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectProxy::SetNameOwnerChangedCallback(SignalCallback callback) { 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bus_->AssertOnOriginThread(); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name_owner_changed_callback_ = callback; 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DBusHandlerResult ObjectProxy::HandleMessage( 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusConnection* connection, 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusMessage* raw_message) { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnDBusThread(); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dbus_message_get_type(raw_message) != DBUS_MESSAGE_TYPE_SIGNAL) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // raw_message will be unrefed on exit of the function. Increment the 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reference so we can use it in Signal. 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_message_ref(raw_message); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Signal> signal( 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Signal::FromRawMessage(raw_message)); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify the signal comes from the object we're proxying for, this is 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // our last chance to return DBUS_HANDLER_RESULT_NOT_YET_HANDLED and 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // allow other object proxies to handle instead. 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ObjectPath path = signal->GetPath(); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (path != object_path_) { 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (path.value() == kDBusSystemObjectPath && 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signal->GetMember() == kNameOwnerChangedMember) { 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle NameOwnerChanged separately 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return HandleNameOwnerChanged(signal.Pass()); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string interface = signal->GetInterface(); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string member = signal->GetMember(); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) statistics::AddReceivedSignal(service_name_, interface, member); 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if we know about the signal. 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string absolute_signal_name = GetAbsoluteSignalName( 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interface, member); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MethodTable::const_iterator iter = method_table_.find(absolute_signal_name); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == method_table_.end()) { 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't know about the signal. 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Signal received: " << signal->ToString(); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sender = signal->GetSender(); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (service_name_owner_ != sender) { 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Rejecting a message from a wrong sender."; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("DBus.RejectedSignalCount", 1); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks start_time = base::TimeTicks::Now(); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bus_->HasDBusThread()) { 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post a task to run the method in the origin thread. 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Transfer the ownership of |signal| to RunMethod(). 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |released_signal| will be deleted in RunMethod(). 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Signal* released_signal = signal.release(); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->PostTaskToOriginThread(FROM_HERE, 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ObjectProxy::RunMethod, 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_time, 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter->second, 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) released_signal)); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks start_time = base::TimeTicks::Now(); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the D-Bus thread is not used, just call the callback on the 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // current thread. Transfer the ownership of |signal| to RunMethod(). 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Signal* released_signal = signal.release(); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMethod(start_time, iter->second, released_signal); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DBUS_HANDLER_RESULT_HANDLED; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ObjectProxy::RunMethod(base::TimeTicks start_time, 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<SignalCallback> signal_callbacks, 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Signal* signal) { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnOriginThread(); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (std::vector<SignalCallback>::iterator iter = signal_callbacks.begin(); 510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) iter != signal_callbacks.end(); ++iter) 511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) iter->Run(signal); 512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete the message on the D-Bus thread. See comments in 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RunResponseCallback(). 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->PostTaskToDBusThread( 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&base::DeletePointer<Signal>, signal)); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record time spent for handling the signal. 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("DBus.SignalHandleTime", 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks::Now() - start_time); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DBusHandlerResult ObjectProxy::HandleMessageThunk( 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusConnection* connection, 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusMessage* raw_message, 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* user_data) { 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObjectProxy* self = reinterpret_cast<ObjectProxy*>(user_data); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self->HandleMessage(connection, raw_message); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ObjectProxy::LogMethodCallFailure( 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& interface_name, 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& method_name, 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& error_name, 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& error_message) const { 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ignore_service_unknown_errors_ && error_name == kErrorServiceUnknown) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to call method: " 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << interface_name << "." << method_name 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ": object_path= " << object_path_.value() 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ": " << error_name << ": " << error_message; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ObjectProxy::OnCallMethodError(const std::string& interface_name, 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& method_name, 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseCallback response_callback, 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorResponse* error_response) { 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_response) { 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Error message may contain the error message as string. 551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MessageReader reader(error_response); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string error_message; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader.PopString(&error_message); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogMethodCallFailure(interface_name, 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method_name, 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_response->GetErrorName(), 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_message); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_callback.Run(NULL); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ObjectProxy::AddMatchRuleWithCallback( 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& match_rule, 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& absolute_signal_name, 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignalCallback signal_callback) { 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!match_rule.empty()); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!absolute_signal_name.empty()); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnDBusThread(); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (match_rules_.find(match_rule) == match_rules_.end()) { 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedDBusError error; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AddMatch(match_rule, error.get()); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error.is_set()) { 574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " 575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error.name() << ": " << error.message(); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Store the match rule, so that we can remove this in Detach(). 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_rules_.insert(match_rule); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the signal callback to the method table. 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) method_table_[absolute_signal_name].push_back(signal_callback); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We already have the match rule. 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) method_table_[absolute_signal_name].push_back(signal_callback); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ObjectProxy::AddMatchRuleWithoutCallback( 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& match_rule, 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& absolute_signal_name) { 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!match_rule.empty()); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!absolute_signal_name.empty()); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnDBusThread(); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (match_rules_.find(match_rule) != match_rules_.end()) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedDBusError error; 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AddMatch(match_rule, error.get()); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error.is_set()) { 604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " 605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error.name() << ": " << error.message(); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Store the match rule, so that we can remove this in Detach(). 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_rules_.insert(match_rule); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ObjectProxy::UpdateNameOwnerAndBlock() { 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnDBusThread(); 615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) service_name_owner_ = 616b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bus_->GetServiceOwnerAndBlock(service_name_, Bus::REPORT_ERRORS); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DBusHandlerResult ObjectProxy::HandleNameOwnerChanged( 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Signal> signal) { 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(signal); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_->AssertOnDBusThread(); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Confirm the validity of the NameOwnerChanged signal. 625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (signal->GetMember() == kNameOwnerChangedMember && 626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signal->GetInterface() == kDBusSystemObjectInterface && 627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signal->GetSender() == kDBusSystemObjectAddress) { 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessageReader reader(signal.get()); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name, old_owner, new_owner; 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reader.PopString(&name) && 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader.PopString(&old_owner) && 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader.PopString(&new_owner) && 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name == service_name_) { 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_name_owner_ = new_owner; 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!name_owner_changed_callback_.is_null()) { 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::TimeTicks start_time = base::TimeTicks::Now(); 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Signal* released_signal = signal.release(); 638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<SignalCallback> callbacks; 639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callbacks.push_back(name_owner_changed_callback_); 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bus_->PostTaskToOriginThread(FROM_HERE, 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ObjectProxy::RunMethod, 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_time, 644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callbacks, 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) released_signal)); 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Always return unhandled to let other object proxies handle the same 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // signal. 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace dbus 656