Move function definition to aul header
[platform/core/appfw/aul-1.git] / src / app_com.cc
index ac1d988..57c304d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 - 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2015 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include "include/aul_app_com.h"
+
 #include <bundle_cpp.h>
 #include <bundle_internal.h>
 
 #include <mutex>
 #include <string>
 
+#include "app_request.h"
 #include "aul_api.h"
 #include "aul_util.h"
 #include "include/aul.h"
-#include "include/aul_app_com.h"
 #include "include/aul_cmd.h"
 #include "launch.h"
 
+using namespace aul::internal;
+
 namespace {
 
 class AppComConnection {
@@ -44,12 +48,21 @@ class AppComConnection {
     return endpoint_;
   }
 
+  void Disable() {
+    disabled_ = true;
+  }
+
+  bool IsDisabled() const {
+    return disabled_;
+  }
+
   void Invoke(aul_app_com_result_e result, bundle* envelope) {
-    if (cb_)
+    if (!disabled_ && cb_)
       cb_(endpoint_.c_str(), result, envelope, user_data_);
   }
 
  private:
+  bool disabled_ = false;
   std::string endpoint_;
   app_com_cb cb_;
   void* user_data_;
@@ -57,7 +70,7 @@ class AppComConnection {
 
 class AppComPermission {
  public:
-  AppComPermission() {}
+  AppComPermission() : option_(AUL_APP_COM_PUBLIC) {}
   ~AppComPermission() {}
 
   void SetPrivilege(std::string privilege) {
@@ -101,7 +114,10 @@ class Context {
     std::string endpoint(val);
 
     std::lock_guard<std::recursive_mutex> lock(mutex_);
-    for (auto& conn : conns_) {
+    auto iter = conns_.begin();
+    while (iter != conns_.end()) {
+      auto& conn = *iter;
+      iter++;
       if (conn->GetEndpoint() == endpoint)
         conn->Invoke(*result, b);
     }
@@ -136,7 +152,7 @@ class Context {
   bool ExistConnection(const std::string& endpoint) {
     std::lock_guard<std::recursive_mutex> lock(mutex_);
     for (auto& conn : conns_) {
-      if (conn->GetEndpoint() == endpoint)
+      if (conn->GetEndpoint() == endpoint && !conn->IsDisabled())
         return true;
     }
 
@@ -145,6 +161,9 @@ class Context {
 
   bool ExistConnection(AppComConnection* conn) {
     std::lock_guard<std::recursive_mutex> lock(mutex_);
+    if (conn->IsDisabled())
+      return false;
+
     for (auto& i : conns_) {
       if (i.get() == conn)
         return true;
@@ -153,6 +172,10 @@ class Context {
     return false;
   }
 
+  std::recursive_mutex& GetMutex() const {
+    return mutex_;
+  }
+
  private:
   std::list<std::unique_ptr<AppComConnection>> conns_;
   mutable std::recursive_mutex mutex_;
@@ -160,6 +183,45 @@ class Context {
 
 Context context;
 
+int AppComCreate(const char* endpoint,
+    aul_app_com_permission_h permission, app_com_cb callback, void* user_data,
+    bool sync, aul_app_com_connection_h* connection) {
+  if (endpoint == nullptr || callback == nullptr || connection == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  if (!aul_is_initialized()) {
+    if (aul_launch_init(nullptr, nullptr) < 0)
+      return AUL_R_ENOINIT;
+  }
+
+  tizen_base::Bundle b { { AUL_K_COM_ENDPOINT, endpoint } };
+  if (permission) {
+    auto* handle = static_cast<AppComPermission*>(permission);
+    auto option = handle->GetPropagationOption();
+    if (option) {
+      auto* p = reinterpret_cast<unsigned char*>(&option);
+      std::vector<unsigned char> bytes;
+      std::copy(p, p + sizeof(option), std::back_inserter(bytes));
+      b.Add(AUL_K_COM_PROPAGATE, bytes);
+    }
+
+    if (!handle->GetPrivilege().empty())
+      b.Add(AUL_K_COM_PRIVILEGE, handle->GetPrivilege());
+  }
+
+  int ret = AppRequest(APP_COM_CREATE, getuid())
+      .With(std::move(b))
+      .SendSimply(sync ? AUL_SOCK_NONE : AUL_SOCK_NOREPLY);
+  if (ret == 0) {
+    *connection = static_cast<aul_app_com_connection_h>(
+        context.AddConnection(endpoint, callback, user_data));
+  }
+
+  return ret;
+}
+
 }  // namespace
 
 int app_com_recv(bundle* b) {
@@ -204,52 +266,6 @@ extern "C" API int aul_app_com_permission_set_privilege(
   return AUL_R_OK;
 }
 
-static int AppComCreate(const char* endpoint,
-    aul_app_com_permission_h permission, app_com_cb callback, void* user_data,
-    bool sync, aul_app_com_connection_h* connection) {
-  if (endpoint == nullptr || callback == nullptr || connection == nullptr) {
-    _E("Invalid parameter");
-    return AUL_R_EINVAL;
-  }
-
-  if (!aul_is_initialized()) {
-    if (aul_launch_init(nullptr, nullptr) < 0)
-      return AUL_R_ENOINIT;
-  }
-
-  tizen_base::Bundle b;
-  b.Add(AUL_K_COM_ENDPOINT, endpoint);
-
-  if (permission) {
-    auto* handle = static_cast<AppComPermission*>(permission);
-    auto option = handle->GetPropagationOption();
-    if (option) {
-      auto* p = reinterpret_cast<unsigned char*>(&option);
-      std::vector<unsigned char> bytes;
-      std::copy(p, p + sizeof(option), std::back_inserter(bytes));
-      b.Add(AUL_K_COM_PROPAGATE, bytes);
-    }
-
-    if (!handle->GetPrivilege().empty())
-      b.Add(AUL_K_COM_PRIVILEGE, handle->GetPrivilege());
-  }
-
-  int ret;
-  if (sync) {
-    ret = app_send_cmd(AUL_UTIL_PID, APP_COM_CREATE, b.GetHandle());
-  } else {
-    ret = app_send_cmd_with_noreply(AUL_UTIL_PID, APP_COM_CREATE,
-        b.GetHandle());
-  }
-
-  if (ret == 0) {
-    *connection = static_cast<aul_app_com_connection_h>(
-        context.AddConnection(endpoint, callback, user_data));
-  }
-
-  return ret;
-}
-
 extern "C" API int aul_app_com_create(const char* endpoint,
     aul_app_com_permission_h permission, app_com_cb callback,
     void* user_data, aul_app_com_connection_h* connection) {
@@ -277,12 +293,13 @@ extern "C" API int aul_app_com_join(const char* endpoint, const char* filter,
       return AUL_R_ENOINIT;
   }
 
-  tizen_base::Bundle b;
-  b.Add(AUL_K_COM_ENDPOINT, endpoint);
+  tizen_base::Bundle b { { AUL_K_COM_ENDPOINT, endpoint } };
   if (filter)
     b.Add(AUL_K_COM_FILTER, filter);
 
-  int ret = app_send_cmd(AUL_UTIL_PID, APP_COM_JOIN, b.GetHandle());
+  int ret = AppRequest(APP_COM_JOIN, getuid())
+      .With(std::move(b))
+      .SendSimply();
   if (ret == 0) {
     *connection = static_cast<aul_app_com_connection_h>(
         context.AddConnection(endpoint, callback, user_data));
@@ -295,9 +312,25 @@ extern "C" API int aul_app_com_send(const char* endpoint, bundle* envelope) {
   if (endpoint == nullptr || envelope == nullptr)
     return AUL_R_EINVAL;
 
-  bundle_del(envelope, AUL_K_COM_ENDPOINT);
-  bundle_add(envelope, AUL_K_COM_ENDPOINT, endpoint);
-  return app_send_cmd(AUL_UTIL_PID, APP_COM_SEND, envelope);
+  std::string com_endpoint;
+  tizen_base::Bundle b(envelope, false, false);
+  bundle_type type = b.GetType(AUL_K_COM_ENDPOINT);
+  if (type != BUNDLE_TYPE_NONE) {
+    com_endpoint = b.GetString(AUL_K_COM_ENDPOINT);
+    b.Delete(AUL_K_COM_ENDPOINT);
+  }
+
+  b.Add(AUL_K_COM_ENDPOINT, endpoint);
+
+  int ret = AppRequest(APP_COM_SEND, getuid())
+      .With(std::move(b))
+      .SendSimply();
+  if (type != BUNDLE_TYPE_NONE) {
+    bundle_del(envelope, AUL_K_COM_ENDPOINT);
+    bundle_add_str(envelope, AUL_K_COM_ENDPOINT, com_endpoint.c_str());
+  }
+
+  return ret;
 }
 
 extern "C" API int aul_app_com_leave(aul_app_com_connection_h connection) {
@@ -310,13 +343,25 @@ extern "C" API int aul_app_com_leave(aul_app_com_connection_h connection) {
     return AUL_R_EINVAL;
   }
 
+  std::lock_guard<std::recursive_mutex> lock(context.GetMutex());
+  conn->Disable();
+
   std::string endpoint = conn->GetEndpoint();
-  context.RemoveConnection(conn);
+  if (!context.ExistConnection(endpoint)) {
+    tizen_base::Bundle b { { AUL_K_COM_ENDPOINT, endpoint } };
+    int ret = AppRequest(APP_COM_LEAVE, getuid())
+      .With(std::move(b))
+      .SendSimply(AUL_SOCK_NOREPLY);
+    if (ret != 0)
+      _E("Failed to send leave request. error(%d)", ret);
+  }
 
-  if (context.ExistConnection(endpoint))
-    return AUL_R_OK;
+  g_idle_add_full(G_PRIORITY_HIGH, [](gpointer user_data) -> gboolean {
+        auto* conn = static_cast<AppComConnection*>(user_data);
+        std::lock_guard<std::recursive_mutex> lock(context.GetMutex());
+        context.RemoveConnection(conn);
+        return G_SOURCE_REMOVE;
+      }, connection, nullptr);
 
-  tizen_base::Bundle b;
-  b.Add(AUL_K_COM_ENDPOINT, endpoint);
-  return app_send_cmd(AUL_UTIL_PID, APP_COM_LEAVE, b.GetHandle());
+  return AUL_R_OK;
 }