summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
authorkeybuk@chromium.org <keybuk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-14 20:08:06 +0000
committerkeybuk@chromium.org <keybuk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-14 20:08:06 +0000
commitbc1b18ecfc890dde4aae0a5a5db27dde2796b25e (patch)
tree8e37e62d98047d218bf8fdeff2f10361fbaab961 /dbus
parentce1402accb9a01358fc1235f1319d934cd611248 (diff)
downloadchromium_src-bc1b18ecfc890dde4aae0a5a5db27dde2796b25e.zip
chromium_src-bc1b18ecfc890dde4aae0a5a5db27dde2796b25e.tar.gz
chromium_src-bc1b18ecfc890dde4aae0a5a5db27dde2796b25e.tar.bz2
dbus: add ObjectPath type
Rather than use std::string for object paths, add a dbus::ObjectPath type that wraps one while allowing more type-safety. This solves all sorts of issues with confusing object paths for strings, and allows us to do Properties code using templates disambiguating them from strings. BUG=chromium:109194 TEST=built and run tests Change-Id: Icaf6f19daea4af23a9d2ec0ed76d2cbd379d680e Review URL: http://codereview.chromium.org/9378039 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121920 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'dbus')
-rw-r--r--dbus/bus.cc24
-rw-r--r--dbus/bus.h15
-rw-r--r--dbus/bus_unittest.cc25
-rw-r--r--dbus/dbus.gyp2
-rw-r--r--dbus/end_to_end_async_unittest.cc8
-rw-r--r--dbus/end_to_end_sync_unittest.cc8
-rw-r--r--dbus/exported_object.cc9
-rw-r--r--dbus/exported_object.h7
-rw-r--r--dbus/message.cc37
-rw-r--r--dbus/message.h17
-rw-r--r--dbus/message_unittest.cc39
-rw-r--r--dbus/mock_bus.h11
-rw-r--r--dbus/mock_exported_object.cc4
-rw-r--r--dbus/mock_exported_object.h5
-rw-r--r--dbus/mock_object_proxy.cc2
-rw-r--r--dbus/mock_object_proxy.h5
-rw-r--r--dbus/mock_unittest.cc19
-rw-r--r--dbus/object_path.cc21
-rw-r--r--dbus/object_path.h46
-rw-r--r--dbus/object_proxy.cc3
-rw-r--r--dbus/object_proxy.h5
-rw-r--r--dbus/test_service.cc5
22 files changed, 205 insertions, 112 deletions
diff --git a/dbus/bus.cc b/dbus/bus.cc
index 0c6a421..3b2f059 100644
--- a/dbus/bus.cc
+++ b/dbus/bus.cc
@@ -16,6 +16,7 @@
#include "base/threading/thread_restrictions.h"
#include "base/time.h"
#include "dbus/exported_object.h"
+#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "dbus/scoped_dbus_error.h"
@@ -207,18 +208,19 @@ Bus::~Bus() {
}
ObjectProxy* Bus::GetObjectProxy(const std::string& service_name,
- const std::string& object_path) {
+ const ObjectPath& object_path) {
return GetObjectProxyWithOptions(service_name, object_path,
ObjectProxy::DEFAULT_OPTIONS);
}
ObjectProxy* Bus::GetObjectProxyWithOptions(const std::string& service_name,
- const std::string& object_path,
+ const dbus::ObjectPath& object_path,
int options) {
AssertOnOriginThread();
// Check if we already have the requested object proxy.
- const ObjectProxyTable::key_type key(service_name + object_path, options);
+ const ObjectProxyTable::key_type key(service_name + object_path.value(),
+ options);
ObjectProxyTable::iterator iter = object_proxy_table_.find(key);
if (iter != object_proxy_table_.end()) {
return iter->second;
@@ -232,11 +234,11 @@ ObjectProxy* Bus::GetObjectProxyWithOptions(const std::string& service_name,
}
ExportedObject* Bus::GetExportedObject(const std::string& service_name,
- const std::string& object_path) {
+ const ObjectPath& object_path) {
AssertOnOriginThread();
// Check if we already have the requested exported object.
- const std::string key = service_name + object_path;
+ const std::string key = service_name + object_path.value();
ExportedObjectTable::iterator iter = exported_object_table_.find(key);
if (iter != exported_object_table_.end()) {
return iter->second;
@@ -521,7 +523,7 @@ void Bus::RemoveMatch(const std::string& match_rule, DBusError* error) {
match_rules_added_.erase(match_rule);
}
-bool Bus::TryRegisterObjectPath(const std::string& object_path,
+bool Bus::TryRegisterObjectPath(const ObjectPath& object_path,
const DBusObjectPathVTable* vtable,
void* user_data,
DBusError* error) {
@@ -530,13 +532,13 @@ bool Bus::TryRegisterObjectPath(const std::string& object_path,
if (registered_object_paths_.find(object_path) !=
registered_object_paths_.end()) {
- LOG(ERROR) << "Object path already registered: " << object_path;
+ LOG(ERROR) << "Object path already registered: " << object_path.value();
return false;
}
const bool success = dbus_connection_try_register_object_path(
connection_,
- object_path.c_str(),
+ object_path.value().c_str(),
vtable,
user_data,
error);
@@ -545,20 +547,20 @@ bool Bus::TryRegisterObjectPath(const std::string& object_path,
return success;
}
-void Bus::UnregisterObjectPath(const std::string& object_path) {
+void Bus::UnregisterObjectPath(const ObjectPath& object_path) {
DCHECK(connection_);
AssertOnDBusThread();
if (registered_object_paths_.find(object_path) ==
registered_object_paths_.end()) {
LOG(ERROR) << "Requested to unregister an unknown object path: "
- << object_path;
+ << object_path.value();
return;
}
const bool success = dbus_connection_unregister_object_path(
connection_,
- object_path.c_str());
+ object_path.value().c_str());
CHECK(success) << "Unable to allocate memory";
registered_object_paths_.erase(object_path);
}
diff --git a/dbus/bus.h b/dbus/bus.h
index 22c2218..e045386 100644
--- a/dbus/bus.h
+++ b/dbus/bus.h
@@ -17,6 +17,7 @@
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "base/tracked_objects.h"
+#include "dbus/object_path.h"
class MessageLoop;
@@ -112,7 +113,7 @@ class ObjectProxy;
// }
//
// void OnExported(const std::string& interface_name,
-// const std::string& object_path,
+// const ObjectPath& object_path,
// bool success) {
// // success is true if the method was exported successfully.
// }
@@ -194,13 +195,13 @@ class Bus : public base::RefCountedThreadSafe<Bus> {
//
// Must be called in the origin thread.
virtual ObjectProxy* GetObjectProxy(const std::string& service_name,
- const std::string& object_path);
+ const ObjectPath& object_path);
// Same as above, but also takes a bitfield of ObjectProxy::Options.
// See object_proxy.h for available options.
virtual ObjectProxy* GetObjectProxyWithOptions(
const std::string& service_name,
- const std::string& object_path,
+ const ObjectPath& object_path,
int options);
// Gets the exported object for the given service name and the object
@@ -219,7 +220,7 @@ class Bus : public base::RefCountedThreadSafe<Bus> {
//
// Must be called in the origin thread.
virtual ExportedObject* GetExportedObject(const std::string& service_name,
- const std::string& object_path);
+ const ObjectPath& object_path);
// Shuts down the bus and blocks until it's done. More specifically, this
// function does the following:
@@ -353,7 +354,7 @@ class Bus : public base::RefCountedThreadSafe<Bus> {
// http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html
//
// BLOCKING CALL.
- virtual bool TryRegisterObjectPath(const std::string& object_path,
+ virtual bool TryRegisterObjectPath(const ObjectPath& object_path,
const DBusObjectPathVTable* vtable,
void* user_data,
DBusError* error);
@@ -361,7 +362,7 @@ class Bus : public base::RefCountedThreadSafe<Bus> {
// Unregister the object path.
//
// BLOCKING CALL.
- virtual void UnregisterObjectPath(const std::string& object_path);
+ virtual void UnregisterObjectPath(const ObjectPath& object_path);
// Posts the task to the message loop of the thread that created the bus.
virtual void PostTaskToOriginThread(
@@ -461,7 +462,7 @@ class Bus : public base::RefCountedThreadSafe<Bus> {
// The following sets are used to check if rules/object_paths/filters
// are properly cleaned up before destruction of the bus object.
std::set<std::string> match_rules_added_;
- std::set<std::string> registered_object_paths_;
+ std::set<ObjectPath> registered_object_paths_;
std::set<std::pair<DBusHandleMessageFunction, void*> >
filter_functions_added_;
diff --git a/dbus/bus_unittest.cc b/dbus/bus_unittest.cc
index c21044b..c66a05b 100644
--- a/dbus/bus_unittest.cc
+++ b/dbus/bus_unittest.cc
@@ -9,6 +9,7 @@
#include "base/memory/ref_counted.h"
#include "base/threading/thread.h"
#include "dbus/exported_object.h"
+#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -30,20 +31,21 @@ TEST(BusTest, GetObjectProxy) {
dbus::ObjectProxy* object_proxy1 =
bus->GetObjectProxy("org.chromium.TestService",
- "/org/chromium/TestObject");
+ dbus::ObjectPath("/org/chromium/TestObject"));
ASSERT_TRUE(object_proxy1);
// This should return the same object.
dbus::ObjectProxy* object_proxy2 =
bus->GetObjectProxy("org.chromium.TestService",
- "/org/chromium/TestObject");
+ dbus::ObjectPath("/org/chromium/TestObject"));
ASSERT_TRUE(object_proxy2);
EXPECT_EQ(object_proxy1, object_proxy2);
// This should not.
dbus::ObjectProxy* object_proxy3 =
- bus->GetObjectProxy("org.chromium.TestService",
- "/org/chromium/DifferentTestObject");
+ bus->GetObjectProxy(
+ "org.chromium.TestService",
+ dbus::ObjectPath("/org/chromium/DifferentTestObject"));
ASSERT_TRUE(object_proxy3);
EXPECT_NE(object_proxy1, object_proxy3);
@@ -57,7 +59,7 @@ TEST(BusTest, GetObjectProxyIgnoreUnknownService) {
dbus::ObjectProxy* object_proxy1 =
bus->GetObjectProxyWithOptions(
"org.chromium.TestService",
- "/org/chromium/TestObject",
+ dbus::ObjectPath("/org/chromium/TestObject"),
dbus::ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
ASSERT_TRUE(object_proxy1);
@@ -65,7 +67,7 @@ TEST(BusTest, GetObjectProxyIgnoreUnknownService) {
dbus::ObjectProxy* object_proxy2 =
bus->GetObjectProxyWithOptions(
"org.chromium.TestService",
- "/org/chromium/TestObject",
+ dbus::ObjectPath("/org/chromium/TestObject"),
dbus::ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
ASSERT_TRUE(object_proxy2);
EXPECT_EQ(object_proxy1, object_proxy2);
@@ -74,7 +76,7 @@ TEST(BusTest, GetObjectProxyIgnoreUnknownService) {
dbus::ObjectProxy* object_proxy3 =
bus->GetObjectProxyWithOptions(
"org.chromium.TestService",
- "/org/chromium/DifferentTestObject",
+ dbus::ObjectPath("/org/chromium/DifferentTestObject"),
dbus::ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
ASSERT_TRUE(object_proxy3);
EXPECT_NE(object_proxy1, object_proxy3);
@@ -88,20 +90,21 @@ TEST(BusTest, GetExportedObject) {
dbus::ExportedObject* object_proxy1 =
bus->GetExportedObject("org.chromium.TestService",
- "/org/chromium/TestObject");
+ dbus::ObjectPath("/org/chromium/TestObject"));
ASSERT_TRUE(object_proxy1);
// This should return the same object.
dbus::ExportedObject* object_proxy2 =
bus->GetExportedObject("org.chromium.TestService",
- "/org/chromium/TestObject");
+ dbus::ObjectPath("/org/chromium/TestObject"));
ASSERT_TRUE(object_proxy2);
EXPECT_EQ(object_proxy1, object_proxy2);
// This should not.
dbus::ExportedObject* object_proxy3 =
- bus->GetExportedObject("org.chromium.TestService",
- "/org/chromium/DifferentTestObject");
+ bus->GetExportedObject(
+ "org.chromium.TestService",
+ dbus::ObjectPath("/org/chromium/DifferentTestObject"));
ASSERT_TRUE(object_proxy3);
EXPECT_NE(object_proxy1, object_proxy3);
diff --git a/dbus/dbus.gyp b/dbus/dbus.gyp
index 2dc8fee..8a3cb22 100644
--- a/dbus/dbus.gyp
+++ b/dbus/dbus.gyp
@@ -25,6 +25,8 @@
'exported_object.h',
'message.cc',
'message.h',
+ 'object_path.cc',
+ 'object_path.h',
'object_proxy.cc',
'object_proxy.h',
'scoped_dbus_error.h',
diff --git a/dbus/end_to_end_async_unittest.cc b/dbus/end_to_end_async_unittest.cc
index 150ed29..9a88b42 100644
--- a/dbus/end_to_end_async_unittest.cc
+++ b/dbus/end_to_end_async_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -15,6 +15,7 @@
#include "base/threading/thread_restrictions.h"
#include "dbus/bus.h"
#include "dbus/message.h"
+#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "dbus/test_service.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -51,8 +52,9 @@ class EndToEndAsyncTest : public testing::Test {
bus_options.dbus_thread_message_loop_proxy =
dbus_thread_->message_loop_proxy();
bus_ = new dbus::Bus(bus_options);
- object_proxy_ = bus_->GetObjectProxy("org.chromium.TestService",
- "/org/chromium/TestObject");
+ object_proxy_ = bus_->GetObjectProxy(
+ "org.chromium.TestService",
+ dbus::ObjectPath("/org/chromium/TestObject"));
ASSERT_TRUE(bus_->HasDBusThread());
// Connect to the "Test" signal of "org.chromium.TestInterface" from
diff --git a/dbus/end_to_end_sync_unittest.cc b/dbus/end_to_end_sync_unittest.cc
index c338809..26a9011 100644
--- a/dbus/end_to_end_sync_unittest.cc
+++ b/dbus/end_to_end_sync_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,6 +6,7 @@
#include "base/memory/scoped_ptr.h"
#include "dbus/bus.h"
#include "dbus/message.h"
+#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "dbus/test_service.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -31,8 +32,9 @@ class EndToEndSyncTest : public testing::Test {
client_bus_options.bus_type = dbus::Bus::SESSION;
client_bus_options.connection_type = dbus::Bus::PRIVATE;
client_bus_ = new dbus::Bus(client_bus_options);
- object_proxy_ = client_bus_->GetObjectProxy("org.chromium.TestService",
- "/org/chromium/TestObject");
+ object_proxy_ = client_bus_->GetObjectProxy(
+ "org.chromium.TestService",
+ dbus::ObjectPath("/org/chromium/TestObject"));
ASSERT_FALSE(client_bus_->HasDBusThread());
}
diff --git a/dbus/exported_object.cc b/dbus/exported_object.cc
index de25168..730c98b 100644
--- a/dbus/exported_object.cc
+++ b/dbus/exported_object.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -13,6 +13,7 @@
#include "base/time.h"
#include "dbus/bus.h"
#include "dbus/message.h"
+#include "dbus/object_path.h"
#include "dbus/scoped_dbus_error.h"
namespace dbus {
@@ -35,7 +36,7 @@ std::string GetAbsoluteMethodName(
ExportedObject::ExportedObject(Bus* bus,
const std::string& service_name,
- const std::string& object_path)
+ const ObjectPath& object_path)
: bus_(bus),
service_name_(service_name),
object_path_(object_path),
@@ -175,8 +176,8 @@ bool ExportedObject::Register() {
this,
error.get());
if (!success) {
- LOG(ERROR) << "Failed to register the object: " << object_path_ << ": "
- << (error.is_set() ? error.message() : "");
+ LOG(ERROR) << "Failed to register the object: " << object_path_.value()
+ << ": " << (error.is_set() ? error.message() : "");
return false;
}
diff --git a/dbus/exported_object.h b/dbus/exported_object.h
index 7ac2f88..24db66e 100644
--- a/dbus/exported_object.h
+++ b/dbus/exported_object.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -17,6 +17,7 @@
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "base/time.h"
+#include "dbus/object_path.h"
namespace dbus {
@@ -36,7 +37,7 @@ class ExportedObject : public base::RefCountedThreadSafe<ExportedObject> {
// constructor.
ExportedObject(Bus* bus,
const std::string& service_name,
- const std::string& object_path);
+ const ObjectPath& object_path);
// Called to send a response from an exported method. Response* is the
// response message. Callers should pass a NULL Response* in the event
@@ -157,7 +158,7 @@ class ExportedObject : public base::RefCountedThreadSafe<ExportedObject> {
scoped_refptr<Bus> bus_;
std::string service_name_;
- std::string object_path_;
+ ObjectPath object_path_;
bool object_is_registered_;
// The method table where keys are absolute method names (i.e. interface
diff --git a/dbus/message.cc b/dbus/message.cc
index 4a94b54..486538a 100644
--- a/dbus/message.cc
+++ b/dbus/message.cc
@@ -10,6 +10,7 @@
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/stringprintf.h"
+#include "dbus/object_path.h"
#include "third_party/protobuf/src/google/protobuf/message_lite.h"
namespace {
@@ -157,10 +158,10 @@ std::string Message::ToStringInternal(const std::string& indent,
break;
}
case OBJECT_PATH: {
- std::string value;
+ ObjectPath value;
if (!reader->PopObjectPath(&value))
return kBrokenMessage;
- output += indent + "object_path \"" + value + "\"\n";
+ output += indent + "object_path \"" + value.value() + "\"\n";
break;
}
case ARRAY: {
@@ -224,7 +225,7 @@ std::string Message::ToString() {
std::string headers;
AppendStringHeader("message_type", GetMessageTypeAsString(), &headers);
AppendStringHeader("destination", GetDestination(), &headers);
- AppendStringHeader("path", GetPath(), &headers);
+ AppendStringHeader("path", GetPath().value(), &headers);
AppendStringHeader("interface", GetInterface(), &headers);
AppendStringHeader("member", GetMember(), &headers);
AppendStringHeader("error_name", GetErrorName(), &headers);
@@ -244,9 +245,9 @@ void Message::SetDestination(const std::string& destination) {
CHECK(success) << "Unable to allocate memory";
}
-void Message::SetPath(const std::string& path) {
+void Message::SetPath(const ObjectPath& path) {
const bool success = dbus_message_set_path(raw_message_,
- path.c_str());
+ path.value().c_str());
CHECK(success) << "Unable to allocate memory";
}
@@ -287,9 +288,9 @@ std::string Message::GetDestination() {
return destination ? destination : "";
}
-std::string Message::GetPath() {
+ObjectPath Message::GetPath() {
const char* path = dbus_message_get_path(raw_message_);
- return path ? path : "";
+ return ObjectPath(path ? path : "");
}
std::string Message::GetInterface() {
@@ -490,8 +491,8 @@ void MessageWriter::AppendString(const std::string& value) {
// bool AppendStringWithErrorChecking().
}
-void MessageWriter::AppendObjectPath(const std::string& value) {
- const char* pointer = value.c_str();
+void MessageWriter::AppendObjectPath(const ObjectPath& value) {
+ const char* pointer = value.value().c_str();
AppendBasic(DBUS_TYPE_OBJECT_PATH, &pointer);
}
@@ -587,7 +588,7 @@ void MessageWriter::AppendArrayOfStrings(
}
void MessageWriter::AppendArrayOfObjectPaths(
- const std::vector<std::string>& object_paths) {
+ const std::vector<ObjectPath>& object_paths) {
DCHECK(!container_is_open_);
MessageWriter array_writer(message_);
OpenArray("o", &array_writer);
@@ -652,8 +653,8 @@ void MessageWriter::AppendVariantOfString(const std::string& value) {
AppendVariantOfBasic(DBUS_TYPE_STRING, &pointer);
}
-void MessageWriter::AppendVariantOfObjectPath(const std::string& value) {
- const char* pointer = value.c_str();
+void MessageWriter::AppendVariantOfObjectPath(const ObjectPath& value) {
+ const char* pointer = value.value().c_str();
AppendVariantOfBasic(DBUS_TYPE_OBJECT_PATH, &pointer);
}
@@ -746,11 +747,11 @@ bool MessageReader::PopString(std::string* value) {
return success;
}
-bool MessageReader::PopObjectPath(std::string* value) {
+bool MessageReader::PopObjectPath(ObjectPath* value) {
char* tmp_value = NULL;
const bool success = PopBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value);
if (success)
- value->assign(tmp_value);
+ *value = ObjectPath(tmp_value);
return success;
}
@@ -805,12 +806,12 @@ bool MessageReader::PopArrayOfStrings(
}
bool MessageReader::PopArrayOfObjectPaths(
- std::vector<std::string> *object_paths) {
+ std::vector<ObjectPath> *object_paths) {
MessageReader array_reader(message_);
if (!PopArray(&array_reader))
return false;
while (array_reader.HasMoreData()) {
- std::string object_path;
+ ObjectPath object_path;
if (!array_reader.PopObjectPath(&object_path))
return false;
object_paths->push_back(object_path);
@@ -882,11 +883,11 @@ bool MessageReader::PopVariantOfString(std::string* value) {
return success;
}
-bool MessageReader::PopVariantOfObjectPath(std::string* value) {
+bool MessageReader::PopVariantOfObjectPath(ObjectPath* value) {
char* tmp_value = NULL;
const bool success = PopVariantOfBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value);
if (success)
- value->assign(tmp_value);
+ *value = ObjectPath(tmp_value);
return success;
}
diff --git a/dbus/message.h b/dbus/message.h
index 54227a0..4683abe 100644
--- a/dbus/message.h
+++ b/dbus/message.h
@@ -11,6 +11,7 @@
#include <dbus/dbus.h>
#include "base/basictypes.h"
+#include "dbus/object_path.h"
namespace google {
namespace protobuf {
@@ -80,7 +81,7 @@ class Message {
// Sets the destination, the path, the interface, the member, etc.
void SetDestination(const std::string& destination);
- void SetPath(const std::string& path);
+ void SetPath(const ObjectPath& path);
void SetInterface(const std::string& interface);
void SetMember(const std::string& member);
void SetErrorName(const std::string& error_name);
@@ -92,7 +93,7 @@ class Message {
// Gets the destination, the path, the interface, the member, etc.
// If not set, an empty string is returned.
std::string GetDestination();
- std::string GetPath();
+ ObjectPath GetPath();
std::string GetInterface();
std::string GetMember();
std::string GetErrorName();
@@ -265,7 +266,7 @@ class MessageWriter {
void AppendUint64(uint64 value);
void AppendDouble(double value);
void AppendString(const std::string& value);
- void AppendObjectPath(const std::string& value);
+ void AppendObjectPath(const ObjectPath& value);
// Opens an array. The array contents can be added to the array with
// |sub_writer|. The client code must close the array with
@@ -302,7 +303,7 @@ class MessageWriter {
// Appends the array of object paths. Arrays of object paths are often
// used when exchanging object paths, hence it's worth having a
// specialized function.
- void AppendArrayOfObjectPaths(const std::vector<std::string>& object_paths);
+ void AppendArrayOfObjectPaths(const std::vector<ObjectPath>& object_paths);
// Appends the protocol buffer as an array of bytes. The buffer is serialized
// into an array of bytes before communication, since protocol buffers are not
@@ -326,7 +327,7 @@ class MessageWriter {
void AppendVariantOfUint64(uint64 value);
void AppendVariantOfDouble(double value);
void AppendVariantOfString(const std::string& value);
- void AppendVariantOfObjectPath(const std::string& value);
+ void AppendVariantOfObjectPath(const ObjectPath& value);
private:
// Helper function used to implement AppendByte etc.
@@ -374,7 +375,7 @@ class MessageReader {
bool PopUint64(uint64* value);
bool PopDouble(double* value);
bool PopString(std::string* value);
- bool PopObjectPath(std::string* value);
+ bool PopObjectPath(ObjectPath* value);
// Sets up the given message reader to read an array at the current
// iterator position.
@@ -409,7 +410,7 @@ class MessageReader {
// Arrays of object paths are often used to communicate with D-Bus
// services like NetworkManager, hence it's worth having a specialized
// function.
- bool PopArrayOfObjectPaths(std::vector<std::string>* object_paths);
+ bool PopArrayOfObjectPaths(std::vector<ObjectPath>* object_paths);
// Gets the array of bytes at the current iterator position. It then parses
// this binary blob into the protocol buffer supplied.
@@ -436,7 +437,7 @@ class MessageReader {
bool PopVariantOfUint64(uint64* value);
bool PopVariantOfDouble(double* value);
bool PopVariantOfString(std::string* value);
- bool PopVariantOfObjectPath(std::string* value);
+ bool PopVariantOfObjectPath(ObjectPath* value);
// Get the data type of the value at the current iterator
// position. INVALID_DATA will be returned if the iterator points to the
diff --git a/dbus/message_unittest.cc b/dbus/message_unittest.cc
index 1e6d668..a40ba0aa 100644
--- a/dbus/message_unittest.cc
+++ b/dbus/message_unittest.cc
@@ -7,6 +7,7 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "dbus/object_path.h"
#include "dbus/test_proto.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -50,7 +51,7 @@ TEST(MessageTest, AppendAndPopBasicDataTypes) {
writer.AppendUint64(7);
writer.AppendDouble(8.0);
writer.AppendString("string");
- writer.AppendObjectPath("/object/path");
+ writer.AppendObjectPath(dbus::ObjectPath("/object/path"));
uint8 byte_value = 0;
bool bool_value = false;
@@ -62,7 +63,7 @@ TEST(MessageTest, AppendAndPopBasicDataTypes) {
uint64 uint64_value = 0;
double double_value = 0;
std::string string_value;
- std::string object_path_value;
+ dbus::ObjectPath object_path_value;
dbus::MessageReader reader(message.get());
ASSERT_TRUE(reader.HasMoreData());
@@ -90,7 +91,7 @@ TEST(MessageTest, AppendAndPopBasicDataTypes) {
EXPECT_EQ(7U, uint64_value);
EXPECT_DOUBLE_EQ(8.0, double_value);
EXPECT_EQ("string", string_value);
- EXPECT_EQ("/object/path", object_path_value);
+ EXPECT_EQ(dbus::ObjectPath("/object/path"), object_path_value);
}
// Check all variant types can be properly written and read.
@@ -109,7 +110,7 @@ TEST(MessageTest, AppendAndPopVariantDataTypes) {
writer.AppendVariantOfUint64(7);
writer.AppendVariantOfDouble(8.0);
writer.AppendVariantOfString("string");
- writer.AppendVariantOfObjectPath("/object/path");
+ writer.AppendVariantOfObjectPath(dbus::ObjectPath("/object/path"));
uint8 byte_value = 0;
bool bool_value = false;
@@ -121,7 +122,7 @@ TEST(MessageTest, AppendAndPopVariantDataTypes) {
uint64 uint64_value = 0;
double double_value = 0;
std::string string_value;
- std::string object_path_value;
+ dbus::ObjectPath object_path_value;
dbus::MessageReader reader(message.get());
ASSERT_TRUE(reader.HasMoreData());
@@ -149,7 +150,7 @@ TEST(MessageTest, AppendAndPopVariantDataTypes) {
EXPECT_EQ(7U, uint64_value);
EXPECT_DOUBLE_EQ(8.0, double_value);
EXPECT_EQ("string", string_value);
- EXPECT_EQ("/object/path", object_path_value);
+ EXPECT_EQ(dbus::ObjectPath("/object/path"), object_path_value);
}
TEST(MessageTest, ArrayOfBytes) {
@@ -211,20 +212,20 @@ TEST(MessageTest, ArrayOfStrings) {
TEST(MessageTest, ArrayOfObjectPaths) {
scoped_ptr<dbus::Response> message(dbus::Response::CreateEmpty());
dbus::MessageWriter writer(message.get());
- std::vector<std::string> object_paths;
- object_paths.push_back("/object/path/1");
- object_paths.push_back("/object/path/2");
- object_paths.push_back("/object/path/3");
+ std::vector<dbus::ObjectPath> object_paths;
+ object_paths.push_back(dbus::ObjectPath("/object/path/1"));
+ object_paths.push_back(dbus::ObjectPath("/object/path/2"));
+ object_paths.push_back(dbus::ObjectPath("/object/path/3"));
writer.AppendArrayOfObjectPaths(object_paths);
dbus::MessageReader reader(message.get());
- std::vector<std::string> output_object_paths;
+ std::vector<dbus::ObjectPath> output_object_paths;
ASSERT_TRUE(reader.PopArrayOfObjectPaths(&output_object_paths));
ASSERT_FALSE(reader.HasMoreData());
ASSERT_EQ(3U, output_object_paths.size());
- EXPECT_EQ("/object/path/1", output_object_paths[0]);
- EXPECT_EQ("/object/path/2", output_object_paths[1]);
- EXPECT_EQ("/object/path/3", output_object_paths[2]);
+ EXPECT_EQ(dbus::ObjectPath("/object/path/1"), output_object_paths[0]);
+ EXPECT_EQ(dbus::ObjectPath("/object/path/2"), output_object_paths[1]);
+ EXPECT_EQ(dbus::ObjectPath("/object/path/3"), output_object_paths[2]);
}
TEST(MessageTest, ProtoBuf) {
@@ -408,7 +409,7 @@ TEST(MessageTest, MethodCall) {
EXPECT_EQ(dbus::Message::MESSAGE_METHOD_CALL, method_call.GetMessageType());
EXPECT_EQ("MESSAGE_METHOD_CALL", method_call.GetMessageTypeAsString());
method_call.SetDestination("com.example.Service");
- method_call.SetPath("/com/example/Object");
+ method_call.SetPath(dbus::ObjectPath("/com/example/Object"));
dbus::MessageWriter writer(&method_call);
writer.AppendString("payload");
@@ -440,7 +441,7 @@ TEST(MessageTest, Signal) {
EXPECT_TRUE(signal.raw_message() != NULL);
EXPECT_EQ(dbus::Message::MESSAGE_SIGNAL, signal.GetMessageType());
EXPECT_EQ("MESSAGE_SIGNAL", signal.GetMessageTypeAsString());
- signal.SetPath("/com/example/Object");
+ signal.SetPath(dbus::ObjectPath("/com/example/Object"));
dbus::MessageWriter writer(&signal);
writer.AppendString("payload");
@@ -513,7 +514,7 @@ TEST(MessageTest, GetAndSetHeaders) {
scoped_ptr<dbus::Response> message(dbus::Response::CreateEmpty());
EXPECT_EQ("", message->GetDestination());
- EXPECT_EQ("", message->GetPath());
+ EXPECT_EQ(dbus::ObjectPath(""), message->GetPath());
EXPECT_EQ("", message->GetInterface());
EXPECT_EQ("", message->GetMember());
EXPECT_EQ("", message->GetErrorName());
@@ -522,7 +523,7 @@ TEST(MessageTest, GetAndSetHeaders) {
EXPECT_EQ(0U, message->GetReplySerial());
message->SetDestination("org.chromium.destination");
- message->SetPath("/org/chromium/path");
+ message->SetPath(dbus::ObjectPath("/org/chromium/path"));
message->SetInterface("org.chromium.interface");
message->SetMember("member");
message->SetErrorName("org.chromium.error");
@@ -531,7 +532,7 @@ TEST(MessageTest, GetAndSetHeaders) {
message->SetReplySerial(456);
EXPECT_EQ("org.chromium.destination", message->GetDestination());
- EXPECT_EQ("/org/chromium/path", message->GetPath());
+ EXPECT_EQ(dbus::ObjectPath("/org/chromium/path"), message->GetPath());
EXPECT_EQ("org.chromium.interface", message->GetInterface());
EXPECT_EQ("member", message->GetMember());
EXPECT_EQ("org.chromium.error", message->GetErrorName());
diff --git a/dbus/mock_bus.h b/dbus/mock_bus.h
index 31c1349..463790a 100644
--- a/dbus/mock_bus.h
+++ b/dbus/mock_bus.h
@@ -7,6 +7,7 @@
#pragma once
#include "dbus/bus.h"
+#include "dbus/object_path.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace dbus {
@@ -20,14 +21,14 @@ class MockBus : public Bus {
virtual ~MockBus();
MOCK_METHOD2(GetObjectProxy, ObjectProxy*(const std::string& service_name,
- const std::string& object_path));
+ const ObjectPath& object_path));
MOCK_METHOD3(GetObjectProxyWithOptions,
ObjectProxy*(const std::string& service_name,
- const std::string& object_path,
+ const ObjectPath& object_path,
int options));
MOCK_METHOD2(GetExportedObject, ExportedObject*(
const std::string& service_name,
- const std::string& object_path));
+ const ObjectPath& object_path));
MOCK_METHOD0(ShutdownAndBlock, void());
MOCK_METHOD0(ShutdownOnDBusThreadAndBlock, void());
MOCK_METHOD0(Connect, bool());
@@ -50,11 +51,11 @@ class MockBus : public Bus {
DBusError* error));
MOCK_METHOD2(RemoveMatch, void(const std::string& match_rule,
DBusError* error));
- MOCK_METHOD4(TryRegisterObjectPath, bool(const std::string& object_path,
+ MOCK_METHOD4(TryRegisterObjectPath, bool(const ObjectPath& object_path,
const DBusObjectPathVTable* vtable,
void* user_data,
DBusError* error));
- MOCK_METHOD1(UnregisterObjectPath, void(const std::string& object_path));
+ MOCK_METHOD1(UnregisterObjectPath, void(const ObjectPath& object_path));
MOCK_METHOD2(PostTaskToOriginThread, void(
const tracked_objects::Location& from_here,
const base::Closure& task));
diff --git a/dbus/mock_exported_object.cc b/dbus/mock_exported_object.cc
index 0fd4f2e..f49cd3d 100644
--- a/dbus/mock_exported_object.cc
+++ b/dbus/mock_exported_object.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,7 +8,7 @@ namespace dbus {
MockExportedObject::MockExportedObject(Bus* bus,
const std::string& service_name,
- const std::string& object_path)
+ const ObjectPath& object_path)
: ExportedObject(bus, service_name, object_path) {
}
diff --git a/dbus/mock_exported_object.h b/dbus/mock_exported_object.h
index 17a36d0..7deb111 100644
--- a/dbus/mock_exported_object.h
+++ b/dbus/mock_exported_object.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,6 +9,7 @@
#include <string>
#include "dbus/exported_object.h"
+#include "dbus/object_path.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace dbus {
@@ -18,7 +19,7 @@ class MockExportedObject : public ExportedObject {
public:
MockExportedObject(Bus* bus,
const std::string& service_name,
- const std::string& object_path);
+ const ObjectPath& object_path);
virtual ~MockExportedObject();
MOCK_METHOD3(ExportMethodAndBlock,
diff --git a/dbus/mock_object_proxy.cc b/dbus/mock_object_proxy.cc
index a7186bb..7e26f01 100644
--- a/dbus/mock_object_proxy.cc
+++ b/dbus/mock_object_proxy.cc
@@ -8,7 +8,7 @@ namespace dbus {
MockObjectProxy::MockObjectProxy(Bus* bus,
const std::string& service_name,
- const std::string& object_path)
+ const ObjectPath& object_path)
: ObjectProxy(bus, service_name, object_path, DEFAULT_OPTIONS) {
}
diff --git a/dbus/mock_object_proxy.h b/dbus/mock_object_proxy.h
index b5d4477..a8a5791 100644
--- a/dbus/mock_object_proxy.h
+++ b/dbus/mock_object_proxy.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,6 +8,7 @@
#include <string>
+#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -18,7 +19,7 @@ class MockObjectProxy : public ObjectProxy {
public:
MockObjectProxy(Bus* bus,
const std::string& service_name,
- const std::string& object_path);
+ const ObjectPath& object_path);
virtual ~MockObjectProxy();
MOCK_METHOD2(CallMethodAndBlock, Response*(MethodCall* method_call,
diff --git a/dbus/mock_unittest.cc b/dbus/mock_unittest.cc
index 022b03d..cf644df 100644
--- a/dbus/mock_unittest.cc
+++ b/dbus/mock_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,6 +11,7 @@
#include "dbus/mock_bus.h"
#include "dbus/mock_object_proxy.h"
#include "dbus/mock_exported_object.h"
+#include "dbus/object_path.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -31,9 +32,10 @@ class MockTest : public testing::Test {
mock_bus_ = new dbus::MockBus(options);
// Create a mock proxy.
- mock_proxy_ = new dbus::MockObjectProxy(mock_bus_.get(),
- "org.chromium.TestService",
- "/org/chromium/TestObject");
+ mock_proxy_ = new dbus::MockObjectProxy(
+ mock_bus_.get(),
+ "org.chromium.TestService",
+ dbus::ObjectPath("/org/chromium/TestObject"));
// Set an expectation so mock_proxy's CallMethodAndBlock() will use
// CreateMockProxyResponse() to return responses.
@@ -49,8 +51,9 @@ class MockTest : public testing::Test {
// Set an expectation so mock_bus's GetObjectProxy() for the given
// service name and the object path will return mock_proxy_.
- EXPECT_CALL(*mock_bus_, GetObjectProxy("org.chromium.TestService",
- "/org/chromium/TestObject"))
+ EXPECT_CALL(*mock_bus_, GetObjectProxy(
+ "org.chromium.TestService",
+ dbus::ObjectPath("/org/chromium/TestObject")))
.WillOnce(Return(mock_proxy_.get()));
// ShutdownAndBlock() will be called in TearDown().
@@ -130,7 +133,7 @@ TEST_F(MockTest, CallMethodAndBlock) {
// Get an object proxy from the mock bus.
dbus::ObjectProxy* proxy = mock_bus_->GetObjectProxy(
"org.chromium.TestService",
- "/org/chromium/TestObject");
+ dbus::ObjectPath("/org/chromium/TestObject"));
// Create a method call.
dbus::MethodCall method_call("org.chromium.TestInterface", "Echo");
@@ -159,7 +162,7 @@ TEST_F(MockTest, CallMethod) {
// Get an object proxy from the mock bus.
dbus::ObjectProxy* proxy = mock_bus_->GetObjectProxy(
"org.chromium.TestService",
- "/org/chromium/TestObject");
+ dbus::ObjectPath("/org/chromium/TestObject"));
// Create a method call.
dbus::MethodCall method_call("org.chromium.TestInterface", "Echo");
diff --git a/dbus/object_path.cc b/dbus/object_path.cc
new file mode 100644
index 0000000..2dda466
--- /dev/null
+++ b/dbus/object_path.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "dbus/object_path.h"
+
+namespace dbus {
+
+bool ObjectPath::operator<(const ObjectPath& that) const {
+ return value_ < that.value_;
+}
+
+bool ObjectPath::operator==(const ObjectPath& that) const {
+ return value_ == that.value_;
+}
+
+bool ObjectPath::operator!=(const ObjectPath& that) const {
+ return value_ != that.value_;
+}
+
+} // namespace dbus
diff --git a/dbus/object_path.h b/dbus/object_path.h
new file mode 100644
index 0000000..59071da
--- /dev/null
+++ b/dbus/object_path.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DBUS_OBJECT_PATH_H_
+#define DBUS_OBJECT_PATH_H_
+#pragma once
+
+#include <string>
+
+namespace dbus {
+
+// ObjectPath is a type used to distinguish D-Bus object paths from simple
+// strings, especially since normal practice is that these should be only
+// initialized from static constants or obtained from remote objects and no
+// assumptions about their value made.
+class ObjectPath {
+ public:
+ // Permit initialization without a value for passing to
+ // dbus::MessageReader::PopObjectPath to fill in and from std::string
+ // objects.
+ //
+ // The compiler synthesised copy constructor and assignment operator are
+ // sufficient for our needs, as is implicit initialization of a std::string
+ // from a string constant.
+ ObjectPath() {}
+ explicit ObjectPath(const std::string& value) : value_(value) {}
+
+ // Retrieves value as a std::string.
+ const std::string& value() const { return value_; }
+
+ // Permit sufficient comparison to allow an ObjectPath to be used as a
+ // key in a std::map.
+ bool operator<(const ObjectPath&) const;
+
+ // Permit testing for equality, required for mocks to work and useful for
+ // observers.
+ bool operator==(const ObjectPath&) const;
+ bool operator!=(const ObjectPath&) const;
+ private:
+ std::string value_;
+};
+
+} // namespace dbus
+
+#endif // DBUS_OBJECT_PATH_H_
diff --git a/dbus/object_proxy.cc b/dbus/object_proxy.cc
index 58d679c..32f6a60 100644
--- a/dbus/object_proxy.cc
+++ b/dbus/object_proxy.cc
@@ -13,6 +13,7 @@
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "dbus/message.h"
+#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "dbus/scoped_dbus_error.h"
@@ -42,7 +43,7 @@ namespace dbus {
ObjectProxy::ObjectProxy(Bus* bus,
const std::string& service_name,
- const std::string& object_path,
+ const ObjectPath& object_path,
int options)
: bus_(bus),
service_name_(service_name),
diff --git a/dbus/object_proxy.h b/dbus/object_proxy.h
index 3da4e9b..3a9fab1 100644
--- a/dbus/object_proxy.h
+++ b/dbus/object_proxy.h
@@ -16,6 +16,7 @@
#include "base/memory/ref_counted.h"
#include "base/string_piece.h"
#include "base/time.h"
+#include "dbus/object_path.h"
namespace dbus {
@@ -35,7 +36,7 @@ class ObjectProxy : public base::RefCountedThreadSafe<ObjectProxy> {
// Bus::GetObjectProxyWithOptions() instead of this constructor.
ObjectProxy(Bus* bus,
const std::string& service_name,
- const std::string& object_path,
+ const ObjectPath& object_path,
int options);
// Options to be OR-ed together when calling Bus::GetObjectProxyWithOptions().
@@ -196,7 +197,7 @@ class ObjectProxy : public base::RefCountedThreadSafe<ObjectProxy> {
scoped_refptr<Bus> bus_;
std::string service_name_;
- std::string object_path_;
+ ObjectPath object_path_;
// True if the message filter was added.
bool filter_added_;
diff --git a/dbus/test_service.cc b/dbus/test_service.cc
index 714c09b..6454bb5 100644
--- a/dbus/test_service.cc
+++ b/dbus/test_service.cc
@@ -10,6 +10,7 @@
#include "dbus/bus.h"
#include "dbus/exported_object.h"
#include "dbus/message.h"
+#include "dbus/object_path.h"
namespace dbus {
@@ -96,7 +97,7 @@ void TestService::SendTestSignalFromRootInternal(const std::string& message) {
// Use "/" just like dbus-send does.
ExportedObject* root_object =
bus_->GetExportedObject("org.chromium.TestService",
- "/");
+ dbus::ObjectPath("/"));
root_object->SendSignal(&signal);
}
@@ -125,7 +126,7 @@ void TestService::Run(MessageLoop* message_loop) {
exported_object_ = bus_->GetExportedObject(
"org.chromium.TestService",
- "/org/chromium/TestObject");
+ dbus::ObjectPath("/org/chromium/TestObject"));
int num_methods = 0;
exported_object_->ExportMethod(