buffet: libchromeos: Move ExportedObjectManager to libchromeos We'd like to reuse this code in peerd. BUG=chromium:398626 TEST=buffet/libchromeos unittests Change-Id: I37be87dacbd5507d0f405b832cb45f65b4d70203 Reviewed-on: https://chromium-review.googlesource.com/211962 Reviewed-by: Christopher Wiley <wiley@chromium.org> Commit-Queue: Christopher Wiley <wiley@chromium.org> Tested-by: Christopher Wiley <wiley@chromium.org>
diff --git a/buffet/buffet.gyp b/buffet/buffet.gyp index 03b3c81..925afd9 100644 --- a/buffet/buffet.gyp +++ b/buffet/buffet.gyp
@@ -4,17 +4,11 @@ 'deps': [ 'dbus-1', 'libchrome-<(libbase_ver)', - 'libchrome-test-<(libbase_ver)', 'libchromeos-<(libbase_ver)', 'libcurl', 'libmetrics-<(libbase_ver)', ], }, - 'link_settings': { - 'libraries': [ - '-lbase-dbus_test_support-<(libbase_ver)', - ], - }, }, 'targets': [ { @@ -39,7 +33,6 @@ 'device_registration_info.cc', 'error.cc', 'error_codes.cc', - 'exported_object_manager.cc', 'http_request.cc', 'http_connection_curl.cc', 'http_transport_curl.cc', @@ -98,7 +91,6 @@ 'data_encoding_unittest.cc', 'device_registration_info_unittest.cc', 'error_unittest.cc', - 'exported_object_manager_unittest.cc', 'http_connection_fake.cc', 'http_transport_fake.cc', 'http_utils_unittest.cc',
diff --git a/buffet/exported_object_manager.cc b/buffet/exported_object_manager.cc deleted file mode 100644 index d76e067..0000000 --- a/buffet/exported_object_manager.cc +++ /dev/null
@@ -1,134 +0,0 @@ -// Copyright 2014 The Chromium OS 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 "buffet/exported_object_manager.h" - -#include <chromeos/async_event_sequencer.h> -#include <dbus/object_manager.h> - - -using chromeos::dbus_utils::AsyncEventSequencer; - -namespace buffet { - -namespace dbus_utils { - -ExportedObjectManager::ExportedObjectManager(scoped_refptr<dbus::Bus> bus, - const dbus::ObjectPath& path) - : bus_(bus), exported_object_(bus->GetExportedObject(path)) {} - -void ExportedObjectManager::Init(const OnInitFinish& cb) { - bus_->AssertOnOriginThread(); - scoped_refptr<AsyncEventSequencer> sequencer(new AsyncEventSequencer()); - exported_object_->ExportMethod( - dbus::kObjectManagerInterface, - dbus::kObjectManagerGetManagedObjects, - base::Bind(&ExportedObjectManager::HandleGetManagedObjects, - AsWeakPtr()), - sequencer->GetExportHandler( - dbus::kObjectManagerInterface, - dbus::kObjectManagerGetManagedObjects, - "Failed exporting GetManagedObjects method of ObjectManager", - false)); - sequencer->OnAllTasksCompletedCall({cb}); -} - -void ExportedObjectManager::ClaimInterface( - const dbus::ObjectPath& path, - const std::string& interface_name, - const PropertyWriter& property_writer) { - bus_->AssertOnOriginThread(); - // We're sending signals that look like: - // org.freedesktop.DBus.ObjectManager.InterfacesAdded ( - // OBJPATH object_path, - // DICT<STRING,DICT<STRING,VARIANT>> interfaces_and_properties); - dbus::Signal signal(dbus::kObjectManagerInterface, - dbus::kObjectManagerInterfacesAdded); - dbus::MessageWriter signal_writer(&signal); - dbus::MessageWriter all_interfaces(&signal); - dbus::MessageWriter each_interface(&signal); - signal_writer.AppendObjectPath(path); - signal_writer.OpenArray("{sa{sv}}", &all_interfaces); - all_interfaces.OpenDictEntry(&each_interface); - each_interface.AppendString(interface_name); - property_writer.Run(&each_interface); - all_interfaces.CloseContainer(&each_interface); - signal_writer.CloseContainer(&all_interfaces); - exported_object_->SendSignal(&signal); - registered_objects_[path][interface_name] = property_writer; -} - -void ExportedObjectManager::ReleaseInterface( - const dbus::ObjectPath& path, const std::string& interface_name) { - bus_->AssertOnOriginThread(); - auto interfaces_for_path_itr = registered_objects_.find(path); - CHECK(interfaces_for_path_itr != registered_objects_.end()) - << "Attempting to signal interface removal for path " << path.value() - << " which was never registered."; - auto interfaces_for_path = interfaces_for_path_itr->second; - auto property_for_interface_itr = interfaces_for_path.find(interface_name); - CHECK(property_for_interface_itr != interfaces_for_path.end()) - << "Attempted to remove interface " << interface_name << " from " - << path.value() << ", but this interface was never registered."; - interfaces_for_path.erase(interface_name); - if (interfaces_for_path.size() < 1) { - registered_objects_.erase(path); - } - // We're sending signals that look like: - // org.freedesktop.DBus.ObjectManager.InterfacesRemoved ( - // OBJPATH object_path, ARRAY<STRING> interfaces); - dbus::Signal signal(dbus::kObjectManagerInterface, - dbus::kObjectManagerInterfacesRemoved); - dbus::MessageWriter signal_writer(&signal); - signal_writer.AppendObjectPath(path); - dbus::MessageWriter interface_writer(nullptr); - signal_writer.OpenArray("s", &interface_writer); - interface_writer.AppendString(interface_name); - signal_writer.CloseContainer(&interface_writer); - exported_object_->SendSignal(&signal); -} - -void ExportedObjectManager::HandleGetManagedObjects( - dbus::MethodCall* method_call, - dbus::ExportedObject::ResponseSender response_sender) const { - // Implements the GetManagedObjects method: - // - // org.freedesktop.DBus.ObjectManager.GetManagedObjects ( - // out DICT<OBJPATH, - // DICT<STRING, - // DICT<STRING,VARIANT>>> ) - bus_->AssertOnOriginThread(); - scoped_ptr<dbus::Response> response( - dbus::Response::FromMethodCall(method_call)); - dbus::MessageWriter response_writer(response.get()); - dbus::MessageWriter all_object_paths(nullptr); - dbus::MessageWriter each_object_path(nullptr); - dbus::MessageWriter all_interfaces(nullptr); - dbus::MessageWriter each_interface(nullptr); - - response_writer.OpenArray("{oa{sa{sv}}}", &all_object_paths); - for (const auto path_pair : registered_objects_) { - const dbus::ObjectPath& path = path_pair.first; - const InterfaceProperties& interface2properties = path_pair.second; - all_object_paths.OpenDictEntry(&each_object_path); - each_object_path.AppendObjectPath(path); - each_object_path.OpenArray("{sa{sv}}", &all_interfaces); - for (const auto interface : interface2properties) { - const std::string& interface_name = interface.first; - const PropertyWriter& property_writer = interface.second; - all_interfaces.OpenDictEntry(&each_interface); - each_interface.AppendString(interface_name); - property_writer.Run(&each_interface); - all_interfaces.CloseContainer(&each_interface); - } - each_object_path.CloseContainer(&all_interfaces); - all_object_paths.CloseContainer(&each_object_path); - } - response_writer.CloseContainer(&all_object_paths); - response_sender.Run(response.Pass()); -} - -} // namespace dbus_utils - -} // namespace buffet
diff --git a/buffet/exported_object_manager.h b/buffet/exported_object_manager.h deleted file mode 100644 index 978c84e..0000000 --- a/buffet/exported_object_manager.h +++ /dev/null
@@ -1,118 +0,0 @@ -// Copyright 2014 The Chromium OS 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 BUFFET_EXPORTED_OBJECT_MANAGER_H_ -#define BUFFET_EXPORTED_OBJECT_MANAGER_H_ - -#include <map> -#include <string> - -#include <base/memory/weak_ptr.h> -#include <dbus/bus.h> -#include <dbus/exported_object.h> -#include <dbus/message.h> -#include <dbus/object_path.h> - -namespace buffet { - -namespace dbus_utils { - -// ExportedObjectManager is a delegate that implements the -// org.freedesktop.DBus.ObjectManager interface on behalf of another -// object. It handles sending signals when new interfaces are added. -// -// This class is very similar to the ExportedPropertySet class, except that -// it allows objects to expose an object manager interface rather than the -// properties interface. -// -// Example usage: -// -// class ExampleObjectManager { -// public: -// ExampleObjectManager(dbus::Bus* bus) -// : object_manager_(bus, "/my/objects/path") { } -// -// void Init(const OnInitFinish& cb) { object_manager_.Init(cb); } -// void ClaimInterface(const dbus::ObjectPath& path, -// const std::string& interface_name, -// const PropertyWriter& writer) { -// object_manager_->ClaimInterface(...); -// } -// void ReleaseInterface(const dbus::ObjectPath& path, -// const std::string& interface_name) { -// object_manager_->ReleaseInterface(...); -// } -// -// private: -// ExportedObjectManager object_manager_; -// }; -// -// class MyObjectClaimingAnInterface { -// public: -// MyObjectClaimingAnInterface(ExampleObjectManager* object_manager) -// : object_manager_(object_manager) {} -// -// void OnInitFinish(bool success) { -// if (!success) { /* handle that */ } -// object_manager_->ClaimInterface( -// my_path_, my_interface_, my_properties_.GetWriter()); -// } -// -// private: -// struct Properties : public ExportedPropertySet { -// public: -// /* Lots of interesting properties. */ -// }; -// -// Properties my_properties_; -// ExampleObjectManager* object_manager_; -// }; -class ExportedObjectManager - : public base::SupportsWeakPtr<ExportedObjectManager> { - public: - // Writes a dictionary of property name to property value variants to writer. - typedef base::Callback<void(dbus::MessageWriter* writer)> PropertyWriter; - typedef base::Callback<void(bool success)> OnInitFinish; - typedef std::map<std::string, PropertyWriter> InterfaceProperties; - - ExportedObjectManager(scoped_refptr<dbus::Bus> bus, - const dbus::ObjectPath& path); - - // Registers methods implementing the ObjectManager interface on the object - // exported on the path given in the constructor. Must be called on the - // origin thread. - void Init(const OnInitFinish& cb); - - // Trigger a signal that |path| has added an interface |interface_name| - // with properties as given by |writer|. - void ClaimInterface(const dbus::ObjectPath& path, - const std::string& interface_name, - const PropertyWriter& writer); - - // Trigger a signal that |path| has removed an interface |interface_name|. - void ReleaseInterface(const dbus::ObjectPath& path, - const std::string& interface_name); - - const scoped_refptr<dbus::Bus>& GetBus() const { return bus_; } - - private: - void HandleGetManagedObjects( - dbus::MethodCall* method_call, - dbus::ExportedObject::ResponseSender response_sender) const; - - scoped_refptr<dbus::Bus> bus_; - // |exported_object_| outlives *this. - dbus::ExportedObject* const exported_object_; - // Tracks all objects currently known to the ExportedObjectManager. - std::map<dbus::ObjectPath, InterfaceProperties> registered_objects_; - - friend class ExportedObjectManagerTest; - DISALLOW_COPY_AND_ASSIGN(ExportedObjectManager); -}; - -} // namespace dbus_utils - -} // namespace buffet - -#endif // BUFFET_EXPORTED_OBJECT_MANAGER_H_
diff --git a/buffet/exported_object_manager_unittest.cc b/buffet/exported_object_manager_unittest.cc deleted file mode 100644 index 696b76f..0000000 --- a/buffet/exported_object_manager_unittest.cc +++ /dev/null
@@ -1,205 +0,0 @@ -// Copyright 2014 The Chromium OS 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 "buffet/exported_object_manager.h" - -#include <base/bind.h> -#include <dbus/mock_bus.h> -#include <dbus/mock_exported_object.h> -#include <dbus/object_manager.h> -#include <dbus/object_path.h> -#include <gtest/gtest.h> - -using ::testing::AnyNumber; -using ::testing::InSequence; -using ::testing::Invoke; -using ::testing::Return; -using ::testing::_; - -namespace buffet { - -namespace dbus_utils { - -namespace { - -const dbus::ObjectPath kTestPath(std::string("/test/om_path")); -const dbus::ObjectPath kClaimedTestPath(std::string("/test/claimed_path")); -const std::string kClaimedInterface("claimed.interface"); -const std::string kTestPropertyName("PropertyName"); -const std::string kTestPropertyValue("PropertyValue"); - -void WriteTestPropertyDict(dbus::MessageWriter* writer) { - dbus::MessageWriter all_properties(nullptr); - dbus::MessageWriter each_property(nullptr); - writer->OpenArray("{sv}", &all_properties); - all_properties.OpenDictEntry(&each_property); - each_property.AppendString(kTestPropertyName); - each_property.AppendVariantOfString(kTestPropertyValue); - all_properties.CloseContainer(&each_property); - writer->CloseContainer(&all_properties); -} - -void ReadTestPropertyDict(dbus::MessageReader* reader) { - dbus::MessageReader all_properties(nullptr); - dbus::MessageReader each_property(nullptr); - ASSERT_TRUE(reader->PopArray(&all_properties)); - ASSERT_TRUE(all_properties.PopDictEntry(&each_property)); - std::string property_name; - std::string property_value; - ASSERT_TRUE(each_property.PopString(&property_name)); - ASSERT_TRUE(each_property.PopVariantOfString(&property_value)); - EXPECT_FALSE(each_property.HasMoreData()); - EXPECT_FALSE(all_properties.HasMoreData()); - EXPECT_EQ(property_name, kTestPropertyName); - EXPECT_EQ(property_value, kTestPropertyValue); -} - -void VerifyInterfaceClaimSignal(dbus::Signal* signal) { - EXPECT_EQ(signal->GetInterface(), - std::string(dbus::kObjectManagerInterface)); - EXPECT_EQ(signal->GetMember(), - std::string(dbus::kObjectManagerInterfacesAdded)); - // org.freedesktop.DBus.ObjectManager.InterfacesAdded ( - // OBJPATH object_path, - // DICT<STRING,DICT<STRING,VARIANT>> interfaces_and_properties); - dbus::MessageReader reader(signal); - dbus::MessageReader all_interfaces(nullptr); - dbus::MessageReader each_interface(nullptr); - dbus::ObjectPath path; - ASSERT_TRUE(reader.PopObjectPath(&path)); - ASSERT_TRUE(reader.PopArray(&all_interfaces)); - ASSERT_TRUE(all_interfaces.PopDictEntry(&each_interface)); - std::string interface_name; - ASSERT_TRUE(each_interface.PopString(&interface_name)); - ReadTestPropertyDict(&each_interface); - EXPECT_FALSE(each_interface.HasMoreData()); - EXPECT_FALSE(all_interfaces.HasMoreData()); - EXPECT_FALSE(reader.HasMoreData()); - EXPECT_EQ(interface_name, kClaimedInterface); - EXPECT_EQ(path, kClaimedTestPath); -} - -void VerifyInterfaceDropSignal(dbus::Signal* signal) { - EXPECT_EQ(signal->GetInterface(), - std::string(dbus::kObjectManagerInterface)); - EXPECT_EQ(signal->GetMember(), - std::string(dbus::kObjectManagerInterfacesRemoved)); - // org.freedesktop.DBus.ObjectManager.InterfacesRemoved ( - // OBJPATH object_path, ARRAY<STRING> interfaces); - dbus::MessageReader reader(signal); - dbus::MessageReader each_interface(nullptr); - dbus::ObjectPath path; - ASSERT_TRUE(reader.PopObjectPath(&path)); - ASSERT_TRUE(reader.PopArray(&each_interface)); - std::string interface_name; - ASSERT_TRUE(each_interface.PopString(&interface_name)); - EXPECT_FALSE(each_interface.HasMoreData()); - EXPECT_FALSE(reader.HasMoreData()); - EXPECT_EQ(interface_name, kClaimedInterface); - EXPECT_EQ(path, kClaimedTestPath); -} - -} // namespace - -class ExportedObjectManagerTest: public ::testing::Test { - public: - virtual void SetUp() { - dbus::Bus::Options options; - options.bus_type = dbus::Bus::SYSTEM; - bus_ = new dbus::MockBus(options); - // By default, don't worry about threading assertions. - EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber()); - EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber()); - // Use a mock exported object. - mock_exported_object_ = new dbus::MockExportedObject( - bus_.get(), kTestPath); - EXPECT_CALL(*bus_, GetExportedObject(kTestPath)) - .Times(1).WillOnce(Return(mock_exported_object_.get())); - om_.reset(new ExportedObjectManager(bus_.get(), kTestPath)); - property_writer_ = base::Bind(&WriteTestPropertyDict); - response_storer_ = base::Bind(&ExportedObjectManagerTest::StoreResponse, - base::Unretained(this)); - } - - void StoreResponse(scoped_ptr<dbus::Response> method_response) { - last_response_.reset(method_response.release()); - } - - void CallHandleGetManagedObjects( - dbus::MethodCall* method_call, - dbus::ExportedObject::ResponseSender sender) { - om_->HandleGetManagedObjects(method_call, response_storer_); - } - - scoped_refptr<dbus::MockBus> bus_; - scoped_refptr<dbus::MockExportedObject> mock_exported_object_; - scoped_ptr<ExportedObjectManager> om_; - ExportedObjectManager::PropertyWriter property_writer_; - dbus::ExportedObject::ResponseSender response_storer_; - scoped_ptr<dbus::Response> last_response_; -}; - -TEST_F(ExportedObjectManagerTest, ClaimInterfaceSendsSignals) { - EXPECT_CALL(*mock_exported_object_, SendSignal(_)) - .Times(1).WillOnce(Invoke(&VerifyInterfaceClaimSignal)); - om_->ClaimInterface(kClaimedTestPath, kClaimedInterface, property_writer_); -} - -TEST_F(ExportedObjectManagerTest, ReleaseInterfaceSendsSignals) { - InSequence dummy; - EXPECT_CALL(*mock_exported_object_, SendSignal(_)).Times(1); - EXPECT_CALL(*mock_exported_object_, SendSignal(_)) - .Times(1).WillOnce(Invoke(&VerifyInterfaceDropSignal)); - om_->ClaimInterface(kClaimedTestPath, kClaimedInterface, property_writer_); - om_->ReleaseInterface(kClaimedTestPath, kClaimedInterface); -} - -TEST_F(ExportedObjectManagerTest, GetManagedObjectsResponseEmptyCorrectness) { - dbus::MethodCall method_call(dbus::kObjectManagerInterface, - dbus::kObjectManagerGetManagedObjects); - method_call.SetSerial(123); - CallHandleGetManagedObjects(&method_call, response_storer_); - dbus::MessageReader reader(last_response_.get()); - dbus::MessageReader all_paths(nullptr); - ASSERT_TRUE(reader.PopArray(&all_paths)); - EXPECT_FALSE(reader.HasMoreData()); -} - -TEST_F(ExportedObjectManagerTest, GetManagedObjectsResponseCorrectness) { - // org.freedesktop.DBus.ObjectManager.GetManagedObjects ( - // out DICT<OBJPATH, - // DICT<STRING, - // DICT<STRING,VARIANT>>> ) - dbus::MethodCall method_call(dbus::kObjectManagerInterface, - dbus::kObjectManagerGetManagedObjects); - method_call.SetSerial(123); - EXPECT_CALL(*mock_exported_object_, SendSignal(_)).Times(1); - om_->ClaimInterface(kClaimedTestPath, kClaimedInterface, property_writer_); - CallHandleGetManagedObjects(&method_call, response_storer_); - dbus::MessageReader reader(last_response_.get()); - dbus::MessageReader all_paths(nullptr); - dbus::MessageReader each_path(nullptr); - dbus::MessageReader all_interfaces(nullptr); - dbus::MessageReader each_interface(nullptr); - ASSERT_TRUE(reader.PopArray(&all_paths)); - ASSERT_TRUE(all_paths.PopDictEntry(&each_path)); - dbus::ObjectPath path; - ASSERT_TRUE(each_path.PopObjectPath(&path)); - ASSERT_TRUE(each_path.PopArray(&all_interfaces)); - ASSERT_TRUE(all_interfaces.PopDictEntry(&each_interface)); - std::string interface_name; - ASSERT_TRUE(each_interface.PopString(&interface_name)); - ReadTestPropertyDict(&each_interface); - EXPECT_FALSE(each_interface.HasMoreData()); - EXPECT_FALSE(all_interfaces.HasMoreData()); - EXPECT_FALSE(each_path.HasMoreData()); - EXPECT_FALSE(all_paths.HasMoreData()); - EXPECT_FALSE(reader.HasMoreData()); - EXPECT_EQ(path, kClaimedTestPath); - EXPECT_EQ(interface_name, kClaimedInterface); -} - -} // namespace dbus_utils - -} // namespace buffet
diff --git a/buffet/main.cc b/buffet/main.cc index b70421b..66e2cbe 100644 --- a/buffet/main.cc +++ b/buffet/main.cc
@@ -13,15 +13,15 @@ #include <base/strings/string_util.h> #include <base/strings/stringprintf.h> #include <chromeos/async_event_sequencer.h> +#include <chromeos/exported_object_manager.h> #include <dbus/bus.h> #include <sysexits.h> #include "buffet/dbus_constants.h" -#include "buffet/exported_object_manager.h" #include "buffet/manager.h" using chromeos::dbus_utils::AsyncEventSequencer; -using buffet::dbus_utils::ExportedObjectManager; +using chromeos::dbus_utils::ExportedObjectManager; namespace {
diff --git a/buffet/manager.cc b/buffet/manager.cc index 1cb0da2..6f7928e 100644 --- a/buffet/manager.cc +++ b/buffet/manager.cc
@@ -12,6 +12,7 @@ #include <base/json/json_writer.h> #include <chromeos/async_event_sequencer.h> #include <chromeos/dbus_utils.h> +#include <chromeos/exported_object_manager.h> #include <dbus/bus.h> #include <dbus/object_path.h> #include <dbus/values_util.h> @@ -20,16 +21,16 @@ #include "buffet/dbus_constants.h" #include "buffet/dbus_utils.h" #include "buffet/error.h" -#include "buffet/exported_object_manager.h" using chromeos::dbus_utils::AsyncEventSequencer; using chromeos::dbus_utils::GetBadArgsError; +using chromeos::dbus_utils::ExportedObjectManager; using buffet::dbus_utils::GetDBusError; namespace buffet { Manager::Manager( - const base::WeakPtr<dbus_utils::ExportedObjectManager>& object_manager) + const base::WeakPtr<ExportedObjectManager>& object_manager) : exported_object_(object_manager->GetBus()->GetExportedObject( dbus::ObjectPath(dbus_constants::kManagerServicePath))), object_manager_(object_manager) { } @@ -121,7 +122,7 @@ properties_->Init( sequencer->GetHandler("Manager properties export failed.", true)); auto claim_interface_task = sequencer->WrapCompletionTask( - base::Bind(&dbus_utils::ExportedObjectManager::ClaimInterface, + base::Bind(&ExportedObjectManager::ClaimInterface, object_manager_->AsWeakPtr(), dbus::ObjectPath(dbus_constants::kManagerServicePath), dbus_constants::kManagerInterface,
diff --git a/buffet/manager.h b/buffet/manager.h index 6bfccd0..2bb9d5f 100644 --- a/buffet/manager.h +++ b/buffet/manager.h
@@ -20,13 +20,15 @@ #include "buffet/dbus_constants.h" #include "buffet/device_registration_info.h" -namespace buffet { - -class CommandManager; - +namespace chromeos { namespace dbus_utils { class ExportedObjectManager; } // namespace dbus_utils +} // namespace chromeos + +namespace buffet { + +class CommandManager; // The Manager is responsible for global state of Buffet. It exposes // interfaces which affect the entire device such as device registration and @@ -35,8 +37,8 @@ public: typedef base::Callback<void(bool success)> OnInitFinish; - Manager( - const base::WeakPtr<dbus_utils::ExportedObjectManager>& object_manager); + Manager(const base::WeakPtr<chromeos::dbus_utils::ExportedObjectManager>& + object_manager); ~Manager(); void Init(const OnInitFinish& cb); @@ -72,7 +74,7 @@ ::dbus::MethodCall* method_call); dbus::ExportedObject* exported_object_; // weak; owned by the Bus object. - base::WeakPtr<dbus_utils::ExportedObjectManager> object_manager_; + base::WeakPtr<chromeos::dbus_utils::ExportedObjectManager> object_manager_; scoped_ptr<Properties> properties_; std::shared_ptr<CommandManager> command_manager_;