summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
authorkeybuk@chromium.org <keybuk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-07 02:24:33 +0000
committerkeybuk@chromium.org <keybuk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-07 02:24:33 +0000
commit043fb8c60d2274770d4229df4f2ba61936a16c7d (patch)
treede821ffcc2444946dc5f966f227c25823f6f5439 /dbus
parentcc0cdd692cbe2d946e0812949cbb39903622af3b (diff)
downloadchromium_src-043fb8c60d2274770d4229df4f2ba61936a16c7d.zip
chromium_src-043fb8c60d2274770d4229df4f2ba61936a16c7d.tar.gz
chromium_src-043fb8c60d2274770d4229df4f2ba61936a16c7d.tar.bz2
dbus: Handle NameOwnerChanged in ObjectManager
Since the ObjectManager class managers the set of object proxies and properties structures for remote service it needs to handle the NameOwnerChanged signal, deleting the current set of objects when a previously owned name changes to a new owner (or is released) and re-requesting the set of managed objects when a name is claimed by a new owner. BUG=346975 TEST=dbus_unittests Review URL: https://codereview.chromium.org/177703006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@255495 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'dbus')
-rw-r--r--dbus/object_manager.cc34
-rw-r--r--dbus/object_manager.h6
-rw-r--r--dbus/object_manager_unittest.cc17
-rw-r--r--dbus/test_service.cc53
-rw-r--r--dbus/test_service.h23
5 files changed, 133 insertions, 0 deletions
diff --git a/dbus/object_manager.cc b/dbus/object_manager.cc
index 0386228..d8eb569 100644
--- a/dbus/object_manager.cc
+++ b/dbus/object_manager.cc
@@ -32,6 +32,9 @@ ObjectManager::ObjectManager(Bus* bus,
DCHECK(bus_);
object_proxy_ = bus_->GetObjectProxy(service_name_, object_path_);
+ object_proxy_->SetNameOwnerChangedCallback(
+ base::Bind(&ObjectManager::NameOwnerChanged,
+ weak_ptr_factory_.GetWeakPtr()));
object_proxy_->ConnectToSignal(
kObjectManagerInterface,
@@ -292,4 +295,35 @@ void ObjectManager::RemoveInterface(const ObjectPath& object_path,
}
}
+void ObjectManager::NameOwnerChanged(const std::string& old_owner,
+ const std::string& new_owner) {
+ if (!old_owner.empty()) {
+ ObjectMap::iterator iter = object_map_.begin();
+ while (iter != object_map_.end()) {
+ ObjectMap::iterator tmp = iter;
+ ++iter;
+
+ // PropertiesMap is mutated by RemoveInterface, and also Object is
+ // destroyed; easier to collect the object path and interface names
+ // and remove them safely.
+ const dbus::ObjectPath object_path = tmp->first;
+ Object* object = tmp->second;
+ std::vector<std::string> interfaces;
+
+ for (Object::PropertiesMap::iterator piter =
+ object->properties_map.begin();
+ piter != object->properties_map.end(); ++piter)
+ interfaces.push_back(piter->first);
+
+ for (std::vector<std::string>::iterator iiter = interfaces.begin();
+ iiter != interfaces.end(); ++iiter)
+ RemoveInterface(object_path, *iiter);
+ }
+
+ }
+
+ if (!new_owner.empty())
+ GetManagedObjects();
+}
+
} // namespace dbus
diff --git a/dbus/object_manager.h b/dbus/object_manager.h
index 333f69e..0d3ae5d0 100644
--- a/dbus/object_manager.h
+++ b/dbus/object_manager.h
@@ -273,6 +273,12 @@ public:
void RemoveInterface(const ObjectPath& object_path,
const std::string& interface_name);
+ // Removes all objects and interfaces from the object manager when
+ // |old_owner| is not the empty string and/or re-requests the set of managed
+ // objects when |new_owner| is not the empty string.
+ void NameOwnerChanged(const std::string& old_owner,
+ const std::string& new_owner);
+
Bus* bus_;
std::string service_name_;
ObjectPath object_path_;
diff --git a/dbus/object_manager_unittest.cc b/dbus/object_manager_unittest.cc
index 595489f..3e53095 100644
--- a/dbus/object_manager_unittest.cc
+++ b/dbus/object_manager_unittest.cc
@@ -333,4 +333,21 @@ TEST_F(ObjectManagerTest, RemoveSecondObject) {
EXPECT_EQ(ObjectPath("/org/chromium/TestObject"), object_paths[0]);
}
+TEST_F(ObjectManagerTest, OwnershipLost) {
+ PerformAction("ReleaseOwnership", ObjectPath("/org/chromium/TestService"));
+ WaitForRemoveObject();
+
+ std::vector<ObjectPath> object_paths = object_manager_->GetObjects();
+ ASSERT_EQ(0U, object_paths.size());
+}
+
+TEST_F(ObjectManagerTest, OwnershipLostAndRegained) {
+ PerformAction("Ownership", ObjectPath("/org/chromium/TestService"));
+ WaitForRemoveObject();
+ WaitForObject();
+
+ std::vector<ObjectPath> object_paths = object_manager_->GetObjects();
+ ASSERT_EQ(1U, object_paths.size());
+}
+
} // namespace dbus
diff --git a/dbus/test_service.cc b/dbus/test_service.cc
index 21a885d..064b91e 100644
--- a/dbus/test_service.cc
+++ b/dbus/test_service.cc
@@ -142,6 +142,24 @@ void TestService::OnOwnership(base::Callback<void(bool)> callback,
on_name_obtained_.Signal();
}
+void TestService::ReleaseOwnership(base::Closure callback) {
+ bus_->GetDBusTaskRunner()->PostTask(
+ FROM_HERE,
+ base::Bind(&TestService::ReleaseOwnershipInternal,
+ base::Unretained(this),
+ callback));
+}
+
+void TestService::ReleaseOwnershipInternal(
+ base::Closure callback) {
+ bus_->ReleaseOwnership("org.chromium.TestService");
+ has_ownership_ = false;
+
+ bus_->GetOriginTaskRunner()->PostTask(
+ FROM_HERE,
+ callback);
+}
+
void TestService::OnExported(const std::string& interface_name,
const std::string& method_name,
bool success) {
@@ -443,11 +461,46 @@ void TestService::PerformAction(
AddObject(object_path);
else if (action == "RemoveObject")
RemoveObject(object_path);
+ else if (action == "ReleaseOwnership") {
+ ReleaseOwnership(base::Bind(&TestService::PerformActionResponse,
+ base::Unretained(this),
+ method_call, response_sender));
+ return;
+ } else if (action == "Ownership") {
+ ReleaseOwnership(base::Bind(&TestService::OwnershipReleased,
+ base::Unretained(this),
+ method_call, response_sender));
+ return;
+ }
scoped_ptr<Response> response = Response::FromMethodCall(method_call);
response_sender.Run(response.Pass());
}
+void TestService::PerformActionResponse(
+ MethodCall* method_call,
+ ExportedObject::ResponseSender response_sender) {
+ scoped_ptr<Response> response = Response::FromMethodCall(method_call);
+ response_sender.Run(response.Pass());
+}
+
+void TestService::OwnershipReleased(
+ MethodCall* method_call,
+ ExportedObject::ResponseSender response_sender) {
+ RequestOwnership(base::Bind(&TestService::OwnershipRegained,
+ base::Unretained(this),
+ method_call, response_sender));
+}
+
+
+void TestService::OwnershipRegained(
+ MethodCall* method_call,
+ ExportedObject::ResponseSender response_sender,
+ bool success) {
+ PerformActionResponse(method_call, response_sender);
+}
+
+
void TestService::GetManagedObjects(
MethodCall* method_call,
ExportedObject::ResponseSender response_sender) {
diff --git a/dbus/test_service.h b/dbus/test_service.h
index 197b8d2..523864c 100644
--- a/dbus/test_service.h
+++ b/dbus/test_service.h
@@ -74,6 +74,10 @@ class TestService : public base::Thread {
// completed.
void RequestOwnership(base::Callback<void(bool)> callback);
+ // Release the ownership of the well-known name "TestService".
+ // |callback| will be called when the ownership has been released.
+ void ReleaseOwnership(base::Closure callback);
+
// Returns whether this instance has the name ownership or not.
bool has_ownership() const { return has_ownership_; }
@@ -166,6 +170,25 @@ class TestService : public base::Thread {
// Helper function for RequestOwnership().
void RequestOwnershipInternal(base::Callback<void(bool)> callback);
+ // Helper function for ReleaseOwnership().
+ void ReleaseOwnershipInternal(base::Closure callback);
+
+ // Sends the response on completion of the performed action.
+ void PerformActionResponse(
+ MethodCall* method_call,
+ dbus::ExportedObject::ResponseSender response_sender);
+
+ // Re-requests ownership of the well-known name after releasing it.
+ void OwnershipReleased(
+ MethodCall* method_call,
+ dbus::ExportedObject::ResponseSender response_sender);
+
+ // Sends the action response after regaining the well-known name.
+ void OwnershipRegained(
+ MethodCall* method_call,
+ dbus::ExportedObject::ResponseSender response_sender,
+ bool success);
+
// Options to use when requesting service ownership.
Bus::ServiceOwnershipOptions request_ownership_options_;