summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
authorthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-04 15:48:37 +0000
committerthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-04 15:48:37 +0000
commit1db0b3573f76703384f4d3dc6a81930f04e81a63 (patch)
tree23e7666560dbda3237648642ab1a0bb28a7e7c92 /dbus
parentb80965554a11ef9d71df551c993e67a9ebe56cf9 (diff)
downloadchromium_src-1db0b3573f76703384f4d3dc6a81930f04e81a63.zip
chromium_src-1db0b3573f76703384f4d3dc6a81930f04e81a63.tar.gz
chromium_src-1db0b3573f76703384f4d3dc6a81930f04e81a63.tar.bz2
Add a method to check if a D-Bus service has an owner. Use it for mtpd.
BUG=181064 Review URL: https://chromiumcodereview.appspot.com/14568005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198328 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'dbus')
-rw-r--r--dbus/bus.cc58
-rw-r--r--dbus/bus.h30
-rw-r--r--dbus/object_proxy.cc82
3 files changed, 118 insertions, 52 deletions
diff --git a/dbus/bus.cc b/dbus/bus.cc
index ea0497d..0d170ff 100644
--- a/dbus/bus.cc
+++ b/dbus/bus.cc
@@ -832,6 +832,64 @@ void Bus::AssertOnDBusThread() {
}
}
+std::string Bus::GetServiceOwnerAndBlock(const std::string& service_name,
+ GetServiceOwnerOption options) {
+ AssertOnDBusThread();
+
+ MethodCall get_name_owner_call("org.freedesktop.DBus", "GetNameOwner");
+ MessageWriter writer(&get_name_owner_call);
+ writer.AppendString(service_name);
+ VLOG(1) << "Method call: " << get_name_owner_call.ToString();
+
+ const ObjectPath obj_path("/org/freedesktop/DBus");
+ if (!get_name_owner_call.SetDestination("org.freedesktop.DBus") ||
+ !get_name_owner_call.SetPath(obj_path)) {
+ if (options == REPORT_ERRORS)
+ LOG(ERROR) << "Failed to get name owner.";
+ return "";
+ }
+
+ ScopedDBusError error;
+ DBusMessage* response_message =
+ SendWithReplyAndBlock(get_name_owner_call.raw_message(),
+ ObjectProxy::TIMEOUT_USE_DEFAULT,
+ error.get());
+ if (!response_message) {
+ if (options == REPORT_ERRORS) {
+ LOG(ERROR) << "Failed to get name owner. Got " << error.name() << ": "
+ << error.message();
+ }
+ return "";
+ }
+
+ scoped_ptr<Response> response(Response::FromRawMessage(response_message));
+ MessageReader reader(response.get());
+
+ std::string service_owner;
+ if (!reader.PopString(&service_owner))
+ service_owner.clear();
+ return service_owner;
+}
+
+void Bus::GetServiceOwner(const std::string& service_name,
+ const GetServiceOwnerCallback& callback) {
+ AssertOnOriginThread();
+
+ PostTaskToDBusThread(
+ FROM_HERE,
+ base::Bind(&Bus::GetServiceOwnerInternal, this, service_name, callback));
+}
+
+void Bus::GetServiceOwnerInternal(const std::string& service_name,
+ const GetServiceOwnerCallback& callback) {
+ AssertOnDBusThread();
+
+ std::string service_owner;
+ if (Connect())
+ service_owner = GetServiceOwnerAndBlock(service_name, REPORT_ERRORS);
+ PostTaskToOriginThread(FROM_HERE, base::Bind(callback, service_owner));
+}
+
dbus_bool_t Bus::OnAddWatch(DBusWatch* raw_watch) {
AssertOnDBusThread();
diff --git a/dbus/bus.h b/dbus/bus.h
index ec6bef1..5cf73ac 100644
--- a/dbus/bus.h
+++ b/dbus/bus.h
@@ -161,6 +161,13 @@ class CHROME_DBUS_EXPORT Bus : public base::RefCountedThreadSafe<Bus> {
SHARED,
};
+ // Specifies whether the GetServiceOwnerAndBlock call should report or
+ // suppress errors.
+ enum GetServiceOwnerOption {
+ REPORT_ERRORS,
+ SUPPRESS_ERRORS,
+ };
+
// Options used to create a Bus object.
struct CHROME_DBUS_EXPORT Options {
Options();
@@ -211,6 +218,12 @@ class CHROME_DBUS_EXPORT Bus : public base::RefCountedThreadSafe<Bus> {
// - the requested service name.
// - whether ownership has been obtained or not.
typedef base::Callback<void (const std::string&, bool)> OnOwnershipCallback;
+
+ // Called when GetServiceOwner() completes.
+ // |service_owner| is the return value from GetServiceOwnerAndBlock().
+ typedef base::Callback<void (const std::string& service_owner)>
+ GetServiceOwnerCallback;
+
// TODO(satorux): Remove the service name parameter as the caller of
// RequestOwnership() knows the service name.
@@ -530,6 +543,19 @@ class CHROME_DBUS_EXPORT Bus : public base::RefCountedThreadSafe<Bus> {
// AssertOnOriginThread().
virtual void AssertOnDBusThread();
+ // Gets the owner for |service_name| via org.freedesktop.DBus.GetNameOwner.
+ // Returns the owner name, if any, or an empty string on failure.
+ // |options| specifies where to printing error messages or not.
+ //
+ // BLOCKING CALL.
+ virtual std::string GetServiceOwnerAndBlock(const std::string& service_name,
+ GetServiceOwnerOption options);
+
+ // A non-blocking version of GetServiceOwnerAndBlock().
+ // Must be called in the origin thread.
+ virtual void GetServiceOwner(const std::string& service_name,
+ const GetServiceOwnerCallback& callback);
+
// Returns true if the bus is connected to D-Bus.
bool is_connected() { return connection_ != NULL; }
@@ -555,6 +581,10 @@ class CHROME_DBUS_EXPORT Bus : public base::RefCountedThreadSafe<Bus> {
void RequestOwnershipInternal(const std::string& service_name,
OnOwnershipCallback on_ownership_callback);
+ // Helper function used for GetServiceOwner().
+ void GetServiceOwnerInternal(const std::string& service_name,
+ const GetServiceOwnerCallback& callback);
+
// Processes the all incoming data to the connection, if any.
//
// BLOCKING CALL.
diff --git a/dbus/object_proxy.cc b/dbus/object_proxy.cc
index 0e56c7a..53b3539 100644
--- a/dbus/object_proxy.cc
+++ b/dbus/object_proxy.cc
@@ -18,6 +18,8 @@
#include "dbus/object_proxy.h"
#include "dbus/scoped_dbus_error.h"
+namespace dbus {
+
namespace {
const char kErrorServiceUnknown[] = "org.freedesktop.DBus.Error.ServiceUnknown";
@@ -28,6 +30,15 @@ const int kSuccessRatioHistogramMaxValue = 2;
// The path of D-Bus Object sending NameOwnerChanged signal.
const char kDBusSystemObjectPath[] = "/org/freedesktop/DBus";
+// The D-Bus Object interface.
+const char kDBusSystemObjectInterface[] = "org.freedesktop.DBus";
+
+// The D-Bus Object address.
+const char kDBusSystemObjectAddress[] = "org.freedesktop.DBus";
+
+// The NameOwnerChanged member in |kDBusSystemObjectInterface|.
+const char kNameOwnerChangedMember[] = "NameOwnerChanged";
+
// Gets the absolute signal name by concatenating the interface name and
// the signal name. Used for building keys for method_table_ in
// ObjectProxy.
@@ -38,13 +49,11 @@ std::string GetAbsoluteSignalName(
}
// An empty function used for ObjectProxy::EmptyResponseCallback().
-void EmptyResponseCallbackBody(dbus::Response* unused_response) {
+void EmptyResponseCallbackBody(Response* /*response*/) {
}
} // namespace
-namespace dbus {
-
ObjectProxy::ObjectProxy(Bus* bus,
const std::string& service_name,
const ObjectPath& object_path,
@@ -285,18 +294,17 @@ void ObjectProxy::RunResponseCallback(ResponseCallback response_callback,
} else if (dbus_message_get_type(response_message) ==
DBUS_MESSAGE_TYPE_ERROR) {
// This will take |response_message| and release (unref) it.
- scoped_ptr<dbus::ErrorResponse> error_response(
- dbus::ErrorResponse::FromRawMessage(response_message));
+ scoped_ptr<ErrorResponse> error_response(
+ ErrorResponse::FromRawMessage(response_message));
error_callback.Run(error_response.get());
// Delete the message on the D-Bus thread. See below for why.
bus_->PostTaskToDBusThread(
FROM_HERE,
- base::Bind(&base::DeletePointer<dbus::ErrorResponse>,
+ base::Bind(&base::DeletePointer<ErrorResponse>,
error_response.release()));
} else {
// This will take |response_message| and release (unref) it.
- scoped_ptr<dbus::Response> response(
- dbus::Response::FromRawMessage(response_message));
+ scoped_ptr<Response> response(Response::FromRawMessage(response_message));
// The response is successfully received.
response_callback.Run(response.get());
// The message should be deleted on the D-Bus thread for a complicated
@@ -319,8 +327,7 @@ void ObjectProxy::RunResponseCallback(ResponseCallback response_callback,
// thread, not from the current thread here, which is likely UI thread.
bus_->PostTaskToDBusThread(
FROM_HERE,
- base::Bind(&base::DeletePointer<dbus::Response>,
- response.release()));
+ base::Bind(&base::DeletePointer<Response>, response.release()));
method_call_successful = true;
// Record time spent for the method call. Don't include failures.
@@ -439,10 +446,10 @@ DBusHandlerResult ObjectProxy::HandleMessage(
// Verify the signal comes from the object we're proxying for, this is
// our last chance to return DBUS_HANDLER_RESULT_NOT_YET_HANDLED and
// allow other object proxies to handle instead.
- const dbus::ObjectPath path = signal->GetPath();
+ const ObjectPath path = signal->GetPath();
if (path != object_path_) {
if (path.value() == kDBusSystemObjectPath &&
- signal->GetMember() == "NameOwnerChanged") {
+ signal->GetMember() == kNameOwnerChangedMember) {
// Handle NameOwnerChanged separately
return HandleNameOwnerChanged(signal.Pass());
}
@@ -507,7 +514,7 @@ void ObjectProxy::RunMethod(base::TimeTicks start_time,
// RunResponseCallback().
bus_->PostTaskToDBusThread(
FROM_HERE,
- base::Bind(&base::DeletePointer<dbus::Signal>, signal));
+ base::Bind(&base::DeletePointer<Signal>, signal));
// Record time spent for handling the signal.
UMA_HISTOGRAM_TIMES("DBus.SignalHandleTime",
@@ -541,7 +548,7 @@ void ObjectProxy::OnCallMethodError(const std::string& interface_name,
ErrorResponse* error_response) {
if (error_response) {
// Error message may contain the error message as string.
- dbus::MessageReader reader(error_response);
+ MessageReader reader(error_response);
std::string error_message;
reader.PopString(&error_message);
LogMethodCallFailure(interface_name,
@@ -564,8 +571,8 @@ bool ObjectProxy::AddMatchRuleWithCallback(
ScopedDBusError error;
bus_->AddMatch(match_rule, error.get());
if (error.is_set()) {
- LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " <<
- error.name() << ": " << error.message();
+ LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got "
+ << error.name() << ": " << error.message();
return false;
} else {
// Store the match rule, so that we can remove this in Detach().
@@ -594,8 +601,8 @@ bool ObjectProxy::AddMatchRuleWithoutCallback(
ScopedDBusError error;
bus_->AddMatch(match_rule, error.get());
if (error.is_set()) {
- LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " <<
- error.name() << ": " << error.message();
+ LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got "
+ << error.name() << ": " << error.message();
return false;
}
// Store the match rule, so that we can remove this in Detach().
@@ -605,37 +612,8 @@ bool ObjectProxy::AddMatchRuleWithoutCallback(
void ObjectProxy::UpdateNameOwnerAndBlock() {
bus_->AssertOnDBusThread();
-
- MethodCall get_name_owner_call("org.freedesktop.DBus", "GetNameOwner");
- MessageWriter writer(&get_name_owner_call);
- writer.AppendString(service_name_);
- VLOG(1) << "Method call: " << get_name_owner_call.ToString();
-
- const dbus::ObjectPath obj_path("/org/freedesktop/DBus");
- ScopedDBusError error;
- if (!get_name_owner_call.SetDestination("org.freedesktop.DBus") ||
- !get_name_owner_call.SetPath(obj_path)) {
- LOG(ERROR) << "Failed to get name owner.";
- return;
- }
-
- DBusMessage* response_message = bus_->SendWithReplyAndBlock(
- get_name_owner_call.raw_message(),
- TIMEOUT_USE_DEFAULT,
- error.get());
- if (!response_message) {
- LOG(ERROR) << "Failed to get name owner. Got " << error.name() << ": " <<
- error.message();
- return;
- }
- scoped_ptr<Response> response(Response::FromRawMessage(response_message));
- MessageReader reader(response.get());
-
- std::string new_service_name_owner;
- if (reader.PopString(&new_service_name_owner))
- service_name_owner_ = new_service_name_owner;
- else
- service_name_owner_.clear();
+ service_name_owner_ =
+ bus_->GetServiceOwnerAndBlock(service_name_, Bus::SUPPRESS_ERRORS);
}
DBusHandlerResult ObjectProxy::HandleNameOwnerChanged(
@@ -644,9 +622,9 @@ DBusHandlerResult ObjectProxy::HandleNameOwnerChanged(
bus_->AssertOnDBusThread();
// Confirm the validity of the NameOwnerChanged signal.
- if (signal->GetMember() == "NameOwnerChanged" &&
- signal->GetInterface() == "org.freedesktop.DBus" &&
- signal->GetSender() == "org.freedesktop.DBus") {
+ if (signal->GetMember() == kNameOwnerChangedMember &&
+ signal->GetInterface() == kDBusSystemObjectInterface &&
+ signal->GetSender() == kDBusSystemObjectAddress) {
MessageReader reader(signal.get());
std::string name, old_owner, new_owner;
if (reader.PopString(&name) &&