Commit e463407a authored by Sonny Sasaka's avatar Sonny Sasaka Committed by Commit Bot

dbus: Support UnexportMethod from an exported object.

Currently there is no way to override a method handler that is already
registered to an ExportedObject. A support to do so is required to
correctly implement Chrome OS Bluetooth dispatcher which needs to
add/remove an interface to an exported object dynamically. Therefore
this CL adds methods to allow method handlers to be unexported so
another handler can be exported afterwards.

Bug: 883039
Change-Id: Id26dbdb8b2ee3425c21ec0797e1c08183f3e04ab
Reviewed-on: https://chromium-review.googlesource.com/c/1370573
Commit-Queue: Sonny Sasaka <sonnysasaka@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarRyo Hashimoto <hashimoto@chromium.org>
Reviewed-by: default avatarDan Erat <derat@chromium.org>
Cr-Commit-Position: refs/heads/master@{#616020}
parent a451e49e
...@@ -68,6 +68,23 @@ bool ExportedObject::ExportMethodAndBlock( ...@@ -68,6 +68,23 @@ bool ExportedObject::ExportMethodAndBlock(
return true; return true;
} }
bool ExportedObject::UnexportMethodAndBlock(const std::string& interface_name,
const std::string& method_name) {
bus_->AssertOnDBusThread();
const std::string absolute_method_name =
GetAbsoluteMemberName(interface_name, method_name);
MethodTable::const_iterator iter = method_table_.find(absolute_method_name);
if (iter == method_table_.end()) {
LOG(ERROR) << absolute_method_name << " is not exported";
return false;
}
method_table_.erase(iter);
return true;
}
void ExportedObject::ExportMethod(const std::string& interface_name, void ExportedObject::ExportMethod(const std::string& interface_name,
const std::string& method_name, const std::string& method_name,
MethodCallCallback method_call_callback, MethodCallCallback method_call_callback,
...@@ -83,6 +100,18 @@ void ExportedObject::ExportMethod(const std::string& interface_name, ...@@ -83,6 +100,18 @@ void ExportedObject::ExportMethod(const std::string& interface_name,
bus_->GetDBusTaskRunner()->PostTask(FROM_HERE, task); bus_->GetDBusTaskRunner()->PostTask(FROM_HERE, task);
} }
void ExportedObject::UnexportMethod(
const std::string& interface_name,
const std::string& method_name,
OnUnexportedCallback on_unexported_calback) {
bus_->AssertOnOriginThread();
base::Closure task =
base::Bind(&ExportedObject::UnexportMethodInternal, this, interface_name,
method_name, on_unexported_calback);
bus_->GetDBusTaskRunner()->PostTask(FROM_HERE, task);
}
void ExportedObject::SendSignal(Signal* signal) { void ExportedObject::SendSignal(Signal* signal) {
// For signals, the object path should be set to the path to the sender // For signals, the object path should be set to the path to the sender
// object, which is this exported object here. // object, which is this exported object here.
...@@ -141,6 +170,19 @@ void ExportedObject::ExportMethodInternal( ...@@ -141,6 +170,19 @@ void ExportedObject::ExportMethodInternal(
success)); success));
} }
void ExportedObject::UnexportMethodInternal(
const std::string& interface_name,
const std::string& method_name,
OnUnexportedCallback on_unexported_calback) {
bus_->AssertOnDBusThread();
const bool success = UnexportMethodAndBlock(interface_name, method_name);
bus_->GetOriginTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&ExportedObject::OnUnexported, this, on_unexported_calback,
interface_name, method_name, success));
}
void ExportedObject::OnExported(OnExportedCallback on_exported_callback, void ExportedObject::OnExported(OnExportedCallback on_exported_callback,
const std::string& interface_name, const std::string& interface_name,
const std::string& method_name, const std::string& method_name,
...@@ -150,6 +192,15 @@ void ExportedObject::OnExported(OnExportedCallback on_exported_callback, ...@@ -150,6 +192,15 @@ void ExportedObject::OnExported(OnExportedCallback on_exported_callback,
on_exported_callback.Run(interface_name, method_name, success); on_exported_callback.Run(interface_name, method_name, success);
} }
void ExportedObject::OnUnexported(OnExportedCallback on_unexported_callback,
const std::string& interface_name,
const std::string& method_name,
bool success) {
bus_->AssertOnOriginThread();
on_unexported_callback.Run(interface_name, method_name, success);
}
void ExportedObject::SendSignalInternal(base::TimeTicks start_time, void ExportedObject::SendSignalInternal(base::TimeTicks start_time,
DBusMessage* signal_message) { DBusMessage* signal_message) {
uint32_t serial = 0; uint32_t serial = 0;
......
...@@ -60,6 +60,13 @@ class CHROME_DBUS_EXPORT ExportedObject ...@@ -60,6 +60,13 @@ class CHROME_DBUS_EXPORT ExportedObject
bool success)> bool success)>
OnExportedCallback; OnExportedCallback;
// Called when method unexporting is done.
// |success| indicates whether unexporting was successful or not.
typedef base::Callback<void(const std::string& interface_name,
const std::string& method_name,
bool success)>
OnUnexportedCallback;
// Exports the method specified by |interface_name| and |method_name|, // Exports the method specified by |interface_name| and |method_name|,
// and blocks until exporting is done. Returns true on success. // and blocks until exporting is done. Returns true on success.
// //
...@@ -81,6 +88,11 @@ class CHROME_DBUS_EXPORT ExportedObject ...@@ -81,6 +88,11 @@ class CHROME_DBUS_EXPORT ExportedObject
const std::string& method_name, const std::string& method_name,
MethodCallCallback method_call_callback); MethodCallCallback method_call_callback);
// Unexports the method specified by |interface_name| and |method_name|,
// and blocks until unexporting is done. Returns true on success.
virtual bool UnexportMethodAndBlock(const std::string& interface_name,
const std::string& method_name);
// Requests to export the method specified by |interface_name| and // Requests to export the method specified by |interface_name| and
// |method_name|. See Also ExportMethodAndBlock(). // |method_name|. See Also ExportMethodAndBlock().
// //
...@@ -93,6 +105,17 @@ class CHROME_DBUS_EXPORT ExportedObject ...@@ -93,6 +105,17 @@ class CHROME_DBUS_EXPORT ExportedObject
MethodCallCallback method_call_callback, MethodCallCallback method_call_callback,
OnExportedCallback on_exported_callback); OnExportedCallback on_exported_callback);
// Requests to unexport the method specified by |interface_name| and
// |method_name|. See also UnexportMethodAndBlock().
//
// |on_unexported_callback| is called when the method is unexported or
// failed to be unexported, in the origin thread.
//
// Must be called in the origin thread.
virtual void UnexportMethod(const std::string& interface_name,
const std::string& method_name,
OnUnexportedCallback on_unexported_callback);
// Requests to send the signal from this object. The signal will be sent // Requests to send the signal from this object. The signal will be sent
// synchronously if this method is called from the message loop in the D-Bus // synchronously if this method is called from the message loop in the D-Bus
// thread and asynchronously otherwise. // thread and asynchronously otherwise.
...@@ -117,12 +140,23 @@ class CHROME_DBUS_EXPORT ExportedObject ...@@ -117,12 +140,23 @@ class CHROME_DBUS_EXPORT ExportedObject
MethodCallCallback method_call_callback, MethodCallCallback method_call_callback,
OnExportedCallback exported_callback); OnExportedCallback exported_callback);
// Helper function for UnexportMethod().
void UnexportMethodInternal(const std::string& interface_name,
const std::string& method_name,
OnUnexportedCallback unexported_callback);
// Called when the object is exported. // Called when the object is exported.
void OnExported(OnExportedCallback on_exported_callback, void OnExported(OnExportedCallback on_exported_callback,
const std::string& interface_name, const std::string& interface_name,
const std::string& method_name, const std::string& method_name,
bool success); bool success);
// Called when a method is unexported.
void OnUnexported(OnExportedCallback on_unexported_callback,
const std::string& interface_name,
const std::string& method_name,
bool success);
// Helper function for SendSignal(). // Helper function for SendSignal().
void SendSignalInternal(base::TimeTicks start_time, void SendSignalInternal(base::TimeTicks start_time,
DBusMessage* signal_message); DBusMessage* signal_message);
......
...@@ -28,6 +28,13 @@ class MockExportedObject : public ExportedObject { ...@@ -28,6 +28,13 @@ class MockExportedObject : public ExportedObject {
const std::string& method_name, const std::string& method_name,
MethodCallCallback method_call_callback, MethodCallCallback method_call_callback,
OnExportedCallback on_exported_callback)); OnExportedCallback on_exported_callback));
MOCK_METHOD2(UnexportMethodAndBlock,
bool(const std::string& interface_name,
const std::string& method_name));
MOCK_METHOD3(UnexportMethod,
void(const std::string& interface_name,
const std::string& method_name,
OnUnexportedCallback on_unexported_callback));
MOCK_METHOD1(SendSignal, void(Signal* signal)); MOCK_METHOD1(SendSignal, void(Signal* signal));
MOCK_METHOD0(Unregister, void()); MOCK_METHOD0(Unregister, void());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment