diff options
author | keybuk@google.com <keybuk@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-14 21:29:06 +0000 |
---|---|---|
committer | keybuk@google.com <keybuk@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-14 21:29:06 +0000 |
commit | 216ed0bef820f496f853510c6fb274a817257ea6 (patch) | |
tree | 04f3091bce4100749e7d167d033a69a61b9a6a90 /dbus | |
parent | d8f0b2d5f854cde9556fb4a9bc1a61e636aeba8e (diff) | |
download | chromium_src-216ed0bef820f496f853510c6fb274a817257ea6.zip chromium_src-216ed0bef820f496f853510c6fb274a817257ea6.tar.gz chromium_src-216ed0bef820f496f853510c6fb274a817257ea6.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
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=121920
Review URL: https://chromiumcodereview.appspot.com/9378039
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121941 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'dbus')
-rw-r--r-- | dbus/bus.cc | 24 | ||||
-rw-r--r-- | dbus/bus.h | 15 | ||||
-rw-r--r-- | dbus/bus_unittest.cc | 25 | ||||
-rw-r--r-- | dbus/dbus.gyp | 2 | ||||
-rw-r--r-- | dbus/end_to_end_async_unittest.cc | 8 | ||||
-rw-r--r-- | dbus/end_to_end_sync_unittest.cc | 8 | ||||
-rw-r--r-- | dbus/exported_object.cc | 9 | ||||
-rw-r--r-- | dbus/exported_object.h | 7 | ||||
-rw-r--r-- | dbus/message.cc | 37 | ||||
-rw-r--r-- | dbus/message.h | 17 | ||||
-rw-r--r-- | dbus/message_unittest.cc | 39 | ||||
-rw-r--r-- | dbus/mock_bus.h | 11 | ||||
-rw-r--r-- | dbus/mock_exported_object.cc | 4 | ||||
-rw-r--r-- | dbus/mock_exported_object.h | 5 | ||||
-rw-r--r-- | dbus/mock_object_proxy.cc | 2 | ||||
-rw-r--r-- | dbus/mock_object_proxy.h | 5 | ||||
-rw-r--r-- | dbus/mock_unittest.cc | 19 | ||||
-rw-r--r-- | dbus/object_path.cc | 21 | ||||
-rw-r--r-- | dbus/object_path.h | 46 | ||||
-rw-r--r-- | dbus/object_proxy.cc | 3 | ||||
-rw-r--r-- | dbus/object_proxy.h | 5 | ||||
-rw-r--r-- | dbus/test_service.cc | 5 |
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); } @@ -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( |