Implement Listen, SendData functions
authorIlho Kim <ilho159.kim@samsung.com>
Mon, 18 May 2020 06:48:54 +0000 (15:48 +0900)
committerSangyoon Jang <jeremy.jang@samsung.com>
Mon, 25 May 2020 04:28:15 +0000 (13:28 +0900)
These functions are for calling method in client
and receiving method call request and return result in server

Signed-off-by: Ilho Kim <ilho159.kim@samsung.com>
src/theme/dbus/request_broker.cc
src/theme/dbus/request_broker.h
src/theme/dbus/request_filter.cc
src/theme/dbus/request_filter.h

index fcb33ea..1477ea1 100644 (file)
  * limitations under the License.
  */
 
+#include <gio/gio.h>
+
 #include "theme/dbus/request_broker.h"
+#include "theme/utils/logging.h"
+
+#define THEME_MANAGER_DBUS_NAME "org.tizen.theme_manager"
+#define THEME_MANAGER_OBJECT_PATH "/org/tizen/theme_manager"
+#define THEME_MANAGER_INTERFACE_NAME "org.tizen.theme_manager"
 
 namespace ttm {
 namespace dbus {
 
+void RequestBroker::OnReceiveDbusMethod(GDBusConnection *conn,
+    const gchar *sender, const gchar *object_path,
+    const gchar *iface_name, const gchar *method_name,
+    GVariant *parameters, GDBusMethodInvocation *invocation,
+    gpointer user_data) {
+  RequestBroker* broker = static_cast<RequestBroker*>(user_data);
+  GVariant *reply_body = NULL;
+  char *serialized = NULL;
+  int command;
+  g_variant_get(parameters, "(&i&s)", &command, &serialized);
+
+  Command cmd = static_cast<Command>(command);
+  tizen_base::Bundle b(serialized);
+
+  if (cmd == Command::UnKnown || broker->filters_.count(cmd) == 0) {
+    LOG(ERROR) << "UnKnown";
+    g_dbus_method_invocation_return_value(invocation, nullptr);
+    return;
+  }
+
+  tizen_base::Bundle result =
+      broker->filters_.find(cmd)->second.GetHandler()->OnRequest(cmd, b);
+
+  GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE("(s)"));
+  g_variant_builder_add(builder, "(s)",
+      reinterpret_cast<char*>(result.ToRaw().first.get()));
+  reply_body = g_variant_new("(s)", builder);
+  g_variant_builder_unref(builder);
+
+  g_dbus_method_invocation_return_value(invocation, reply_body);
+}
+
+bool RequestBroker::Init() {
+  GError* error = nullptr;
+  connection_ = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+  if (connection_ == NULL) {
+    if (error != NULL) {
+      LOG(ERROR) << "Failed to get dbus [" << error->message << "]";
+      g_error_free(error);
+    }
+    return false;
+  }
+
+  return true;
+}
+
 RequestBroker& RequestBroker::GetInst() {
   static RequestBroker sBroker;
-
+  if (sBroker.connection_ == nullptr)
+    sBroker.Init();
   return sBroker;
 }
 
@@ -30,16 +84,90 @@ GDBusConnection* RequestBroker::GetConnection() {
 }
 
 int RequestBroker::RegisterRequestFilter(RequestFilter filter) {
-  filters_.emplace_back(std::move(filter));
+  filters_.emplace(filter.GetCmd(), filter);
   return 0;
 }
 
+bool RequestBroker::Listen() {
+  const GDBusInterfaceVTable interface_vtable = {
+    OnReceiveDbusMethod,
+    nullptr,
+    nullptr
+  };
+  gchar introspection_xml[] =
+    "  <node>"
+    "  <interface name='org.tizen.theme_manager'>"
+    "        <method name='Get'>"
+    "          <arg type='i' name='command' direction='in'/>"
+    "          <arg type='s' name='serialized' direction='in'/>"
+    "          <arg type='(s)' name='serialized' direction='out'/>"
+    "        </method>"
+    "  </interface>"
+    "  </node>";
+  GError *error = NULL;
+  GDBusNodeInfo *introspection_data =
+      g_dbus_node_info_new_for_xml(introspection_xml, &error);
+  if (!introspection_data) {
+    LOG(ERROR) << "g_dbus_node_info_new_for_xml is failed";
+    if (error != NULL) {
+      LOG(ERROR) << "g_dbus_node_info_new_for_xml err ["
+                 << error->message << "]";
+      g_error_free(error);
+    }
+    return false;
+  }
+
+  registration_id_ = g_dbus_connection_register_object(
+      connection_,
+      THEME_MANAGER_OBJECT_PATH, introspection_data->interfaces[0],
+      &interface_vtable, this, NULL, NULL);
+  g_dbus_node_info_unref(introspection_data);
+  if (registration_id_ == 0) {
+    LOGE("register object fail");
+    return false;
+  }
+
+  int owner_id = g_bus_own_name_on_connection(connection_, THEME_MANAGER_DBUS_NAME,
+                                          G_BUS_NAME_OWNER_FLAGS_NONE,
+                                          NULL, NULL, NULL, NULL);
+  if (!owner_id) {
+    g_object_unref(connection_);
+    LOG(ERROR) << "g_bus_own_name_on_connection error";
+    return false;
+  }
+
+  return true;
+}
+
 tizen_base::Bundle RequestBroker::SendData(Command cmd,
-    const tizen_base::Bundle& data) {
-  return {};
+    tizen_base::Bundle& data) {
+  GError* err = nullptr;
+  GDBusMessage* msg = g_dbus_message_new_method_call(
+      THEME_MANAGER_DBUS_NAME, THEME_MANAGER_OBJECT_PATH,
+      THEME_MANAGER_INTERFACE_NAME, "Get");
+  if (!msg) {
+    LOGE("Can't allocate new method call");
+    return {};
+  }
+
+  g_dbus_message_set_body(msg,
+      g_variant_new("(is)",
+        static_cast<int>(cmd),
+        reinterpret_cast<char*>(data.ToRaw().first.get())
+      )
+  );
+
+  GDBusMessage* reply = g_dbus_connection_send_message_with_reply_sync(
+      connection_, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
+  GVariant *reply_body = g_dbus_message_get_body(reply);
+  char *raw;
+  g_variant_get(reply_body, "(s)", &raw);
+  tizen_base::Bundle result(raw);
+
+  return result;
 }
 
-void RequestBroker::SendDataAsync(Command cmd, const tizen_base::Bundle&) {
+void RequestBroker::SendDataAsync(Command cmd, tizen_base::Bundle&) {
 }
 
 }  // namespace dbus
index be6abc3..0bd2d09 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <gio/gio.h>
 
-#include <list>
+#include <map>
 #include <memory>
 
 #include "theme/dbus/request_filter.h"
@@ -33,14 +33,24 @@ class RequestBroker {
   GDBusConnection* GetConnection();
 
   int RegisterRequestFilter(RequestFilter filter);
-  tizen_base::Bundle SendData(Command cmd, const tizen_base::Bundle&);
-  void SendDataAsync(Command cmd, const tizen_base::Bundle&);
+  bool Listen();
+  tizen_base::Bundle SendData(Command cmd, tizen_base::Bundle&);
+  void SendDataAsync(Command cmd, tizen_base::Bundle&);
 
  private:
+  static void OnReceiveDbusMethod(GDBusConnection *conn, const gchar *sender,
+                                  const gchar *object_path,
+                                  const gchar *iface_name,
+                                  const gchar *method_name,
+                                  GVariant *parameters,
+                                  GDBusMethodInvocation *invocation,
+                                  gpointer user_data);
   RequestBroker() = default;
   ~RequestBroker() = default;
+  bool Init();
   GDBusConnection* connection_ = nullptr;
-  std::list<RequestFilter> filters_;
+  std::map<Command, RequestFilter> filters_;
+  int registration_id_ = 0;
 };
 
 }  // namespace dbus
index e66ac4e..854b353 100644 (file)
@@ -27,8 +27,8 @@ Command RequestFilter::GetCmd() const {
   return cmd_;
 }
 
-const IRequestHandler& RequestFilter::GetHandler() const {
-  return *handler_;
+std::shared_ptr<IRequestHandler> RequestFilter::GetHandler() const {
+  return handler_;
 }
 
 }  // namespace dbus
index 8759005..3911711 100644 (file)
@@ -31,7 +31,7 @@ class RequestFilter {
       : cmd_(cmd), handler_(std::move(handler)) { }
   bool IsOneway() const;
   Command GetCmd() const;
-  const IRequestHandler& GetHandler() const;
+  std::shared_ptr<IRequestHandler> GetHandler() const;
 
  private:
   Command cmd_;