Refactor AMD RPC Port Module 05/259905/6
authorHwankyu Jhun <h.jhun@samsung.com>
Wed, 16 Jun 2021 08:51:55 +0000 (17:51 +0900)
committerHwanKyu Jhun <h.jhun@samsung.com>
Fri, 18 Jun 2021 10:55:20 +0000 (10:55 +0000)
The implementation is changed to c++.

Change-Id: I92cbd3288c77c5e6465b49f2187087bf97353fa0
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/modules/rpc-port/CMakeLists.txt
src/modules/rpc-port/amd_rpc_port.cc [new file with mode: 0644]
src/modules/rpc-port/log_private.hh [new file with mode: 0644]
src/modules/rpc-port/src/amd_rpc_port.c [deleted file]

index c872d0080d5c9abac9255780952ba714145d2271..d89069b0125dc5cbf57e4cc5aa79522318e5794a 100644 (file)
@@ -1,4 +1,4 @@
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src AMD_MOD_RPC_PORT_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} AMD_MOD_RPC_PORT_SRCS)
 
 ADD_LIBRARY(${TARGET_AMD_MOD_RPC_PORT} ${AMD_MOD_RPC_PORT_SRCS})
 
diff --git a/src/modules/rpc-port/amd_rpc_port.cc b/src/modules/rpc-port/amd_rpc_port.cc
new file mode 100644 (file)
index 0000000..ffa7f2e
--- /dev/null
@@ -0,0 +1,489 @@
+/*
+ * Copyright (c) 2018 - 2021 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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <amd.h>
+#include <amd_mod_common.h>
+#include <aul.h>
+#include <aul_cmd.h>
+#include <aul_rpc_port.h>
+#include <aul_sock.h>
+#include <aul_svc.h>
+#include <bundle_cpp.h>
+#include <bundle_internal.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <vconf.h>
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "log_private.hh"
+
+namespace {
+
+class MetadataInfo {
+ public:
+  MetadataInfo(std::string value) : value_(std::move(value)) {
+  }
+
+  ~MetadataInfo() = default;
+
+  bool Match(const std::string& value) {
+    if (value == value_) {
+      exist_ = true;
+      return true;
+    }
+
+    return false;
+  }
+
+  bool Exist() {
+    return exist_;
+  }
+
+ private:
+  std::string value_;
+  bool exist_ = false;
+};
+
+constexpr const char kPrivilegeDataSharing[] =
+    "http://tizen.org/privilege/datasharing";
+constexpr const char kPrivilegeCheckBypass[] =
+    "http://tizen.org/rpc-port/privilege-check-bypass";
+
+std::unordered_map<int, int> pid_map;
+std::string tts_engine_default;
+std::string tts_engine_noti_default;
+std::string tts_engine_sr_default;
+std::string tts_engine_interrupt_default;
+
+void SetTTSEngineDefault(std::string tts_engine) {
+  tts_engine_default = std::move(tts_engine);
+  tts_engine_noti_default = tts_engine_default + "-noti";
+  tts_engine_sr_default = tts_engine_default + "-sr";
+  tts_engine_interrupt_default = tts_engine_default + "-interrupt";
+}
+
+bool IsDefaultTTSEngine(const std::string& app_id) {
+  if (tts_engine_default.empty())
+    return false;
+
+  if (tts_engine_default == app_id)
+    return true;
+
+  if (tts_engine_noti_default == app_id)
+    return true;
+
+  if (tts_engine_sr_default == app_id)
+    return true;
+
+  if (tts_engine_interrupt_default == app_id)
+    return true;
+
+  return false;
+}
+
+void RpcRef(int pid) {
+  auto found = pid_map.find(pid);
+  if (found == pid_map.end()) {
+    pid_map[pid] = 1;
+    amd_suspend_remove_timer(pid);
+    amd_suspend_update_status(pid, AMD_SUSPEND_STATUS_EXCLUDE);
+  } else {
+    found->second++;
+  }
+}
+
+void RpcUnref(int pid) {
+  auto found = pid_map.find(pid);
+  if (found == pid_map.end())
+    return;
+
+  found->second--;
+  if (found->second == 0) {
+    pid_map.erase(found);
+    amd_suspend_update_status(pid, AMD_SUSPEND_STATUS_INCLUDE);
+    amd_app_status_h app_status = amd_app_status_find_by_pid(pid);
+    if (app_status) {
+      int status = amd_app_status_get_status(app_status);
+      if (status != STATUS_VISIBLE && status != STATUS_DYING)
+        amd_suspend_add_timer(pid);
+    }
+  }
+}
+
+void RpcRemove(int pid) {
+  auto found = pid_map.find(pid);
+  if (found == pid_map.end())
+    return;
+
+  pid_map.erase(found);
+}
+
+void SetRealAppId(uid_t uid, tizen_base::Bundle& b) {
+  std::string alias_appid = b.GetString(AUL_K_APPID);
+  if (alias_appid.empty())
+    return;
+
+  std::string alias_info = b.GetString(AUL_SVC_K_ALIAS_INFO);
+  if (alias_info == "disable")
+    return;
+
+  amd_app_property_h app_property = amd_app_property_find(uid);
+  if (app_property == nullptr)
+    return;
+
+  const char* appid = amd_app_property_get_real_appid(app_property,
+      alias_appid.c_str());
+  if (appid == nullptr)
+    return;
+
+  _D("alias_appid(%s), appid(%s)", alias_appid.c_str(), appid);
+  b.Delete(AUL_K_ORG_APPID);
+  b.Add(AUL_K_ORG_APPID, alias_appid);
+  b.Delete(AUL_K_APPID);
+  b.Add(AUL_K_APPID, appid);
+}
+
+int PassFds(int fd, const int (*fds)[2]) {
+#define MAX_NR_OF_DESCRIPTORS 2
+  union {
+    /*
+     * ancillary data buffer, wrapped in a union in order to ensure
+     * it is suitably aligned
+     */
+    char buf[CMSG_SPACE(sizeof(int) * MAX_NR_OF_DESCRIPTORS)];
+    struct cmsghdr align;
+  } u;
+  char iobuf[1];
+  struct iovec io = { .iov_base = iobuf, .iov_len = sizeof(iobuf) };
+  struct msghdr msg = { 0, };
+  msg.msg_iov = &io;
+  msg.msg_iovlen = 1;
+  msg.msg_control = u.buf;
+  msg.msg_controllen = sizeof(u.buf);
+  struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
+  if (cmsg == nullptr) {
+    _E("Failed to get the first cmsghdr");
+    return -EINVAL;
+  }
+
+  cmsg->cmsg_level = SOL_SOCKET;
+  cmsg->cmsg_type = SCM_RIGHTS;
+  cmsg->cmsg_len = CMSG_LEN(sizeof(int) * MAX_NR_OF_DESCRIPTORS);
+
+  /* Initialize the payload: */
+  int* fdptr = reinterpret_cast<int*>(CMSG_DATA(cmsg));
+  memcpy(fdptr, *fds, sizeof(int) * MAX_NR_OF_DESCRIPTORS);
+
+  int ret = sendmsg(fd, &msg, 0);
+  if (ret < 0) {
+    _E("Failed to send message. errno(%d)", errno);
+    return ret;
+  }
+
+  _D("[__RPC_PORT__] sendmsg result(%d)", ret);
+  return ret;
+}
+
+}  // namespace
+
+static int DispatchRpcPortPrepareStub(amd_request_h req) {
+  bundle* kb = amd_request_get_bundle(req);
+  if (kb == nullptr) {
+    _E("Failed to get bundle");
+    amd_request_send_result(req, -EINVAL);
+    return -1;
+  }
+
+  tizen_base::Bundle b(kb, false, false);
+  uid_t target_uid = amd_request_get_target_uid(req);
+  SetRealAppId(target_uid, b);
+  std::string app_id = b.GetString(AUL_K_APPID);
+  if (app_id.empty()) {
+    _E("Failed to get appid");
+    amd_request_send_result(req, -EINVAL);
+    return -1;
+  }
+
+  std::string port_name = b.GetString(AUL_K_RPC_PORT);
+  if (port_name.empty()) {
+    _E("Failed to get port name");
+    amd_request_send_result(req, -EINVAL);
+    return -1;
+  }
+
+  amd_appinfo_h ai = amd_appinfo_find(target_uid, app_id.c_str());
+  if (ai == nullptr) {
+    _E("Failed to find appinfo. %s:%u", app_id.c_str(), target_uid);
+    amd_request_send_result(req, -ENOENT);
+    return -1;
+  }
+
+  amd_noti_send(AMD_NOTI_MSG_LAUNCH_APP_START_START, 0, 0, req,
+      b.GetHandle());
+
+  amd_request_set_request_type(req, "rpc-port");
+  amd_request_set_cmd(req, APP_START_ASYNC);
+
+  bool dummy_pending = false;
+  bool dummy_bg_launch = false;
+  int pid = amd_launch_start_app(app_id.c_str(), req,
+      &dummy_pending, &dummy_bg_launch, false);
+  if (pid < 0) {
+    _E("Failed to send launch request. %s:%s, error(%d)",
+        app_id.c_str(), port_name.c_str(), pid);
+    amd_noti_send(AMD_NOTI_MSG_LAUNCH_FAIL, pid, 0, nullptr, nullptr);
+    return -1;
+  }
+
+  amd_noti_send(AMD_NOTI_MSG_LAUNCH_APP_START_END, pid,
+      dummy_bg_launch, req, b.GetHandle());
+  RpcRef(pid);
+
+  int caller_pid = amd_request_get_pid(req);
+  _I("[__RPC_PORT__] app_id(%s), pid(%d), port_name(%s), caller_pid(%d)",
+      app_id.c_str(), pid, port_name.c_str(), caller_pid);
+  return 0;
+}
+
+static int DispatchRpcPortCreateSocketPair(amd_request_h req) {
+  int fds[2] = { 0, };
+  int ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, fds);
+  if (ret != 0) {
+    _E("socketpair() is failed. error(%d)", ret);
+    amd_request_send_result(req, -1);
+    return -1;
+  }
+
+  if (fds[0] == -1) {
+    _E("Failed to open socket");
+    amd_request_send_result(req, -1);
+    return -1;
+  }
+
+  _I("[__RPC_PORT__] A Pair of sockets: %d:%d", fds[0], fds[1]);
+  ret = PassFds(amd_request_get_fd(req), &fds);
+  if (ret < 0) {
+    _E("Failed to pass file descriptors");
+    amd_request_send_result(req, ret);
+  }
+
+  close(fds[0]);
+  close(fds[1]);
+  return 0;
+}
+
+static int DispatchRpcPortNotifyRpcFinished(amd_request_h req) {
+  pid_t pid = amd_request_get_pid(req);
+  if (pid <= 0) {
+    _E("Invalid parameter");
+    return -1;
+  }
+
+  RpcUnref(pid);
+  _I("[__RPC_PORT__] pid(%d)", pid);
+  return 0;
+}
+
+static int ForeachMetadataCb(const char* value, void* user_data) {
+  char* str = strdup(value);
+  if (str == nullptr) {
+    _E("Out of memory");
+    return -1;
+  }
+
+  std::unique_ptr<char, decltype(std::free)*> str_auto(str, std::free);
+
+  auto* info = static_cast<MetadataInfo*>(user_data);
+  char* saveptr = nullptr;
+  char* token = strtok_r(str, "|", &saveptr);
+  while (token) {
+    if (info->Match(token))
+      return -1; // To break metadata iteration
+
+    token = strtok_r(nullptr, "|", &saveptr);
+  }
+
+  return 0;
+}
+
+static int VerifyPrivilegeCheckBypass(amd_request_h req) {
+  bundle* kb = amd_request_get_bundle(req);
+  if (kb == nullptr) {
+    _E("Invalid request");
+    return AMD_CYNARA_RET_ERROR;
+  }
+
+  tizen_base::Bundle b(kb, false, false);
+  std::string app_id = b.GetString(AUL_K_APPID);
+  if (app_id.empty()) {
+    _E("Failed to get appid");
+    return AMD_CYNARA_RET_ERROR;
+  }
+
+  if (IsDefaultTTSEngine(app_id)) {
+    SECURE_LOGD("Bypass privilege check");
+    return AMD_CYNARA_RET_ALLOWED;
+  }
+
+  std::string port_name = b.GetString(AUL_K_RPC_PORT);
+  if (port_name.empty()) {
+    _E("Failed to get port name");
+    return AMD_CYNARA_RET_ERROR;
+  }
+
+  uid_t target_uid = amd_request_get_target_uid(req);
+  if (amd_appinfo_is_platform_app(app_id.c_str(), target_uid)) {
+    amd_app_property_h app_property = amd_app_property_find(target_uid);
+    if (app_property) {
+      MetadataInfo info(port_name);
+      int ret = amd_app_property_metadata_foreach(app_property,
+          app_id.c_str(), kPrivilegeCheckBypass, ForeachMetadataCb, &info);
+      if (ret != 0) {
+        _E("Failed to retrieve metadata");
+        return AMD_CYNARA_RET_ERROR;
+      }
+
+      if (info.Exist()) {
+        SECURE_LOGD("Bypass privilege check");
+        return AMD_CYNARA_RET_ALLOWED;
+      }
+    }
+  }
+
+  return AMD_CYNARA_RET_UNKNOWN;
+}
+
+static int CynaraCheckerPrepareStub(amd_cynara_caller_info_h info,
+    amd_request_h req, void* data) {
+  int ret = VerifyPrivilegeCheckBypass(req);
+  if (ret != AMD_CYNARA_RET_UNKNOWN)
+    return ret;
+
+  ret = amd_cynara_simple_checker(info, req,
+      const_cast<char*>(PRIVILEGE_APPMANAGER_LAUNCH));
+  if (ret <= AMD_CYNARA_RET_DENIED)
+    return ret;
+
+  return amd_cynara_simple_checker(info, req,
+      const_cast<char*>(kPrivilegeDataSharing));
+}
+
+static int CynaraCheckerCreateSocketPair(amd_cynara_caller_info_h info,
+    amd_request_h req, void* data) {
+  int ret = VerifyPrivilegeCheckBypass(req);
+  if (ret != AMD_CYNARA_RET_UNKNOWN)
+    return ret;
+
+  return amd_cynara_simple_checker(info, req,
+      const_cast<char*>(kPrivilegeDataSharing));
+}
+
+static int OnAppStatusCleanup(const char* msg, int arg1, int arg2, void* arg3,
+    bundle* data) {
+  RpcRemove(arg1);
+  return AMD_NOTI_CONTINUE;
+}
+
+static amd_request_cmd_dispatch dispatch_table[] = {
+  {
+    .cmd = RPC_PORT_PREPARE_STUB,
+    .callback = DispatchRpcPortPrepareStub
+  },
+  {
+    .cmd = RPC_PORT_CREATE_SOCKET_PAIR,
+    .callback = DispatchRpcPortCreateSocketPair
+  },
+  {
+    .cmd = RPC_PORT_NOTIFY_RPC_FINISHED,
+    .callback = DispatchRpcPortNotifyRpcFinished
+  },
+};
+
+static amd_cynara_checker cynara_checkers[] = {
+  {
+    .cmd = RPC_PORT_PREPARE_STUB,
+    .checker = CynaraCheckerPrepareStub,
+    .data = nullptr,
+    .priority = 10
+  },
+  {
+    .cmd = RPC_PORT_CREATE_SOCKET_PAIR,
+    .checker = CynaraCheckerCreateSocketPair,
+    .data = nullptr,
+    .priority = 10
+  },
+};
+
+static void TTSEngineDefaultVconfCb(keynode_t* key, void* data) {
+  char* str = vconf_keynode_get_str(key);
+  if (str == nullptr)
+    return;
+
+  _W("TTS Engine Default %s => %s", tts_engine_default.c_str(), str);
+  SetTTSEngineDefault(str);
+}
+
+extern "C" EXPORT int AMD_MOD_INIT() {
+  _D("RPC_PORT_INIT");
+  int ret = amd_app_property_metadata_add_filter(kPrivilegeCheckBypass,
+      nullptr);
+  if (ret < 0) {
+    _E("Failed to add metadata filter");
+    return -1;
+  }
+
+  ret = amd_request_register_cmds(dispatch_table, ARRAY_SIZE(dispatch_table));
+  if (ret < 0) {
+    _E("Failed to register cmds");
+    return -1;
+  }
+
+  ret = amd_cynara_register_checkers(cynara_checkers,
+      ARRAY_SIZE(cynara_checkers));
+  if (ret < 0) {
+    _E("Failed to register cynara checkers");
+    return -1;
+  }
+
+  char* str = vconf_get_str(VCONFKEY_TTS_ENGINE_DEFAULT);
+  if (str != nullptr) {
+    SetTTSEngineDefault(str);
+    std::free(str);
+  }
+
+  ret = vconf_notify_key_changed(VCONFKEY_TTS_ENGINE_DEFAULT,
+      TTSEngineDefaultVconfCb, nullptr);
+  if (ret != 0)
+    _E("vconf_notify_key_changed() is failed. error(%d)", ret);
+
+  amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
+      OnAppStatusCleanup);
+  return 0;
+}
+
+extern "C" EXPORT void AMD_MOD_FINI() {
+  _D("RPC_PORT_FINI");
+  vconf_ignore_key_changed(VCONFKEY_TTS_ENGINE_DEFAULT,
+      TTSEngineDefaultVconfCb);
+  amd_app_property_metadata_remove_filter(kPrivilegeCheckBypass, nullptr);
+}
diff --git a/src/modules/rpc-port/log_private.hh b/src/modules/rpc-port/log_private.hh
new file mode 100644 (file)
index 0000000..c6c40cd
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RPC_PORT_LOG_PRIVATE_HH_
+#define RPC_PORT_LOG_PRIVATE_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "AMD_RPC_PORT"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#endif  // RPC_PORT_LOG_PRIVATE_HH_
diff --git a/src/modules/rpc-port/src/amd_rpc_port.c b/src/modules/rpc-port/src/amd_rpc_port.c
deleted file mode 100644 (file)
index 1bca366..0000000
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * Copyright (c) 2018 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.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <ctype.h>
-#include <sys/socket.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <aul_rpc_port.h>
-#include <aul_svc.h>
-#include <aul_sock.h>
-#include <bundle_internal.h>
-#include <cert-svc/ccert.h>
-#include <cert-svc/cinstance.h>
-#include <amd.h>
-#include <amd_mod_common.h>
-#include <vconf.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "AMD_RPC_PORT"
-
-#define MAX_NR_OF_DESCRIPTORS 2
-#define PRIVILEGE_DATASHARING "http://tizen.org/privilege/datasharing"
-#define KEY_PRIVILEGE_CHECK_BYPASS \
-       "http://tizen.org/rpc-port/privilege-check-bypass"
-
-struct metadata_info_s {
-       const char *port_name;
-       bool exist;
-};
-
-static GHashTable *__pid_table;
-static char *__tts_engine_default;
-
-static void __rpc_unref(int pid)
-{
-       gpointer value;
-       int count;
-       amd_app_status_h app_status;
-       int status;
-
-       value = g_hash_table_lookup(__pid_table, GINT_TO_POINTER(pid));
-       if (!value) {
-               _E("Critical error");
-               return;
-       }
-
-       count = GPOINTER_TO_INT(value);
-       count--;
-       if (count == 0) {
-               g_hash_table_remove(__pid_table, GINT_TO_POINTER(pid));
-               amd_suspend_update_status(pid, AMD_SUSPEND_STATUS_INCLUDE);
-               app_status = amd_app_status_find_by_pid(pid);
-               if (app_status) {
-                       status = amd_app_status_get_status(app_status);
-                       if (status != STATUS_DYING)
-                               amd_suspend_add_timer(pid);
-               }
-       } else {
-               g_hash_table_replace(__pid_table, GINT_TO_POINTER(pid),
-                               GINT_TO_POINTER(count));
-       }
-}
-
-static void __rpc_ref(int pid)
-{
-       gpointer value;
-       int count;
-
-       value = g_hash_table_lookup(__pid_table, GINT_TO_POINTER(pid));
-       if (value) {
-               count = GPOINTER_TO_INT(value);
-               count++;
-               g_hash_table_replace(__pid_table, GINT_TO_POINTER(pid),
-                               GINT_TO_POINTER(count));
-       } else {
-               count = 1;
-               g_hash_table_insert(__pid_table, GINT_TO_POINTER(pid),
-                               GINT_TO_POINTER(count));
-               amd_suspend_remove_timer(pid);
-               amd_suspend_update_status(pid, AMD_SUSPEND_STATUS_EXCLUDE);
-       }
-}
-
-static void __set_real_appid(uid_t uid, bundle *kb)
-{
-       const char *alias_appid;
-       const char *appid;
-       const char *alias_info;
-       amd_app_property_h app_property;
-
-       alias_appid = bundle_get_val(kb, AUL_K_APPID);
-       if (alias_appid == NULL)
-               return;
-
-       alias_info = bundle_get_val(kb, AUL_SVC_K_ALIAS_INFO);
-       if (alias_info && strcmp(alias_info, "disable") == 0)
-               return;
-
-       app_property = amd_app_property_find(uid);
-       if (app_property == NULL)
-               return;
-
-       appid = amd_app_property_get_real_appid(app_property, alias_appid);
-       if (appid == NULL)
-               return;
-
-       _D("alias_appid(%s), appid(%s)", alias_appid, appid);
-       bundle_del(kb, AUL_K_ORG_APPID);
-       bundle_add(kb, AUL_K_ORG_APPID, alias_appid);
-       bundle_del(kb, AUL_K_APPID);
-       bundle_add(kb, AUL_K_APPID, appid);
-}
-
-static int __dispatch_rpc_port_prepare_stub(amd_request_h req)
-{
-       bundle *b = amd_request_get_bundle(req);
-       pid_t caller_pid = amd_request_get_pid(req);
-       uid_t target_uid = amd_request_get_target_uid(req);
-       amd_appinfo_h ai;
-       const char *appid;
-       const char *port_name;
-       int pid;
-       bool dummy_pending = false;
-       bool dummy_bg_launch = false;
-
-       if (!b) {
-               _E("Invalid parameter");
-               amd_request_send_result(req, -EINVAL);
-               return -1;
-       }
-
-       __set_real_appid(target_uid, b);
-
-       appid = bundle_get_val(b, AUL_K_APPID);
-       if (!appid) {
-               _E("Failed to get appid");
-               amd_request_send_result(req, -EINVAL);
-               return -1;
-       }
-
-       port_name = bundle_get_val(b, AUL_K_RPC_PORT);
-       if (!port_name) {
-               _E("Failed to get port name");
-               amd_request_send_result(req, -EINVAL);
-               return -1;
-       }
-
-       ai = amd_appinfo_find(target_uid, appid);
-       if (!ai) {
-               _E("Failed to find %s:%u", appid, target_uid);
-               amd_request_send_result(req, -ENOENT);
-               return -1;
-       }
-
-       amd_noti_send(AMD_NOTI_MSG_LAUNCH_APP_START_START, 0, 0, req, b);
-
-       amd_request_set_request_type(req, "rpc-port");
-       amd_request_set_cmd(req, APP_START_ASYNC);
-       pid = amd_launch_start_app(appid, req,
-                       &dummy_pending, &dummy_bg_launch,
-                       false);
-       if (pid < 0) {
-               _E("Failed to send launch request(%s:%s)",
-                               appid, port_name);
-               amd_noti_send(AMD_NOTI_MSG_LAUNCH_FAIL, pid, 0, NULL, NULL);
-               return -1;
-       }
-       amd_noti_send(AMD_NOTI_MSG_LAUNCH_APP_START_END,
-                       pid, dummy_bg_launch, req, b);
-
-       __rpc_ref(pid);
-
-       _I("[__RPC_PORT__] appid(%s), pid(%d), port_name(%s), caller_pid(%d)",
-                       appid, pid, port_name, caller_pid);
-
-       return 0;
-}
-
-static int __pass_fds(int fd, const int (*fds)[2])
-{
-       struct msghdr msg = { 0, };
-       struct cmsghdr *cmsg;
-       union {
-               /*
-                * ancillary data buffer, wrapped in a union in order to ensure
-                * it is suitably aligned
-                */
-               char buf[CMSG_SPACE(sizeof(int) * MAX_NR_OF_DESCRIPTORS)];
-               struct cmsghdr align;
-       } u;
-       int *fdptr;
-       char iobuf[1];
-       struct iovec io = {
-               .iov_base = iobuf,
-               .iov_len = sizeof(iobuf)
-       };
-       int r;
-
-       msg.msg_iov = &io;
-       msg.msg_iovlen = 1;
-       msg.msg_control = u.buf;
-       msg.msg_controllen = sizeof(u.buf);
-       cmsg = CMSG_FIRSTHDR(&msg);
-       if (!cmsg) {
-               _E("Failed to get the first cmsghdr");
-               return -EINVAL;
-       }
-
-       cmsg->cmsg_level = SOL_SOCKET;
-       cmsg->cmsg_type = SCM_RIGHTS;
-       cmsg->cmsg_len = CMSG_LEN(sizeof(int) * MAX_NR_OF_DESCRIPTORS);
-
-       /* Initialize the payload: */
-       fdptr = (int *)CMSG_DATA(cmsg);
-       memcpy(fdptr, *fds, sizeof(int) * MAX_NR_OF_DESCRIPTORS);
-
-       r = sendmsg(fd, &msg, 0);
-       if (r < 0) {
-               _E("Failed to send message. errno(%d)", errno);
-               return r;
-       }
-
-       _D("[__RPC_PORT__] sendmsg result(%d)", r);
-
-       return r;
-}
-
-static int __dispatch_rpc_port_create_socket_pair(amd_request_h req)
-{
-       int fds[2] = { 0, };
-       int r;
-
-       r = socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, fds);
-       if (r != 0) {
-               _E("Failed to create socket pair. err = %d", r);
-               amd_request_send_result(req, -1);
-               return -1;
-       }
-
-       if (fds[0] == -1) {
-               _E("Failed to open socket");
-               amd_request_send_result(req, -1);
-               return -1;
-       }
-
-       _I("[__RPC_PORT__] A Pair of sockets: %d:%d", fds[0], fds[1]);
-
-       r = __pass_fds(amd_request_get_fd(req), &fds);
-       if (r < 0) {
-               _E("Failed to pass file descriptors");
-               amd_request_send_result(req, r);
-       }
-
-       close(fds[0]);
-       close(fds[1]);
-
-       return 0;
-}
-
-static int __dispatch_rpc_port_notify_rpc_finished(amd_request_h req)
-{
-       pid_t pid = amd_request_get_pid(req);
-
-       if (pid <= 0) {
-               _E("Invalid parameter");
-               return -1;
-       }
-
-       __rpc_unref(pid);
-       _I("[__RPC_PORT__] pid(%d)", pid);
-
-       return 0;
-}
-
-static int __foreach_metadata_cb(const char *value, void *user_data)
-{
-       struct metadata_info_s *info = (struct metadata_info_s *)user_data;
-       char *str;
-       char *token;
-       char *saveptr = NULL;
-
-       str = strdup(value);
-       if (!str) {
-               _E("Out of memory");
-               return -1;
-       }
-
-       token = strtok_r(str, "|", &saveptr);
-       while (token) {
-               if (!strcmp(token, info->port_name)) {
-                       info->exist = true;
-                       free(str);
-                       return -1; /* To break metadata iteration */
-               }
-               token = strtok_r(NULL, "|", &saveptr);
-       }
-
-       free(str);
-
-       return 0;
-}
-
-static bool __is_default_tts_engine(const char* appid)
-{
-       char buf[256];
-
-       if (!__tts_engine_default)
-               return false;
-
-       if (!strcmp(__tts_engine_default, appid))
-               return true;
-
-       snprintf(buf, sizeof(buf), "%s-noti", __tts_engine_default);
-       if (!strcmp(buf, appid))
-               return true;
-
-       snprintf(buf, sizeof(buf), "%s-sr", __tts_engine_default);
-       if (!strcmp(buf, appid))
-               return true;
-
-       snprintf(buf, sizeof(buf), "%s-interrupt", __tts_engine_default);
-       if (!strcmp(buf, appid))
-               return true;
-
-       return false;
-}
-
-static int __verify_privilege_check_bypass(amd_request_h req)
-{
-       int r;
-       bundle *b;
-       const char *appid;
-       struct metadata_info_s info = { 0, };
-       amd_app_property_h app_property;
-       uid_t uid = amd_request_get_target_uid(req);
-
-       b = amd_request_get_bundle(req);
-       if (!b) {
-               _E("Invalid request");
-               return AMD_CYNARA_RET_ERROR;
-       }
-
-       appid = bundle_get_val(b, AUL_K_APPID);
-       if (!appid) {
-               _E("Failed to get appid");
-               return AMD_CYNARA_RET_ERROR;
-       }
-
-       if (__is_default_tts_engine(appid)) {
-               SECURE_LOGD("Bypass privilege check");
-               return AMD_CYNARA_RET_ALLOWED;
-       }
-
-       info.port_name = bundle_get_val(b, AUL_K_RPC_PORT);
-       if (!info.port_name) {
-               _E("Failed to get port name");
-               return AMD_CYNARA_RET_ERROR;
-       }
-
-       app_property = amd_app_property_find(uid);
-       if (app_property) {
-               r = amd_app_property_metadata_foreach(app_property,
-                               appid, KEY_PRIVILEGE_CHECK_BYPASS,
-                               __foreach_metadata_cb, &info);
-               if (r != 0) {
-                       _E("Failed to retrieve metadata");
-                       return AMD_CYNARA_RET_ERROR;
-               }
-
-               if (info.exist && amd_appinfo_is_platform_app(appid, uid)) {
-                       SECURE_LOGD("Bypass privilege check");
-                       return AMD_CYNARA_RET_ALLOWED;
-               }
-       }
-
-       return AMD_CYNARA_RET_UNKNOWN;
-}
-
-static int __prepare_stub_cynara_checker(amd_cynara_caller_info_h info,
-               amd_request_h req, void *data)
-{
-       int r;
-
-       r = __verify_privilege_check_bypass(req);
-       if (r != AMD_CYNARA_RET_UNKNOWN)
-               return r;
-
-       r = amd_cynara_simple_checker(info, req, PRIVILEGE_APPMANAGER_LAUNCH);
-       if (r <= AMD_CYNARA_RET_DENIED)
-               return r;
-
-       return amd_cynara_simple_checker(info, req, PRIVILEGE_DATASHARING);
-}
-
-static int __create_socket_pair_cynara_checker(amd_cynara_caller_info_h info,
-               amd_request_h req, void *data)
-{
-       int r;
-
-       r = __verify_privilege_check_bypass(req);
-       if (r != AMD_CYNARA_RET_UNKNOWN)
-               return r;
-
-       return amd_cynara_simple_checker(info, req, PRIVILEGE_DATASHARING);
-}
-
-static int __on_app_status_cleanup(const char *msg, int arg1, int arg2,
-               void *arg3, bundle *b)
-{
-       int pid = arg1;
-
-       if (g_hash_table_contains(__pid_table, GINT_TO_POINTER(pid)))
-               g_hash_table_remove(__pid_table, GINT_TO_POINTER(pid));
-
-       return 0;
-}
-
-static amd_request_cmd_dispatch __dispatch_table[] = {
-       {
-               .cmd = RPC_PORT_PREPARE_STUB,
-               .callback = __dispatch_rpc_port_prepare_stub
-       },
-       {
-               .cmd = RPC_PORT_CREATE_SOCKET_PAIR,
-               .callback = __dispatch_rpc_port_create_socket_pair
-       },
-       {
-               .cmd = RPC_PORT_NOTIFY_RPC_FINISHED,
-               .callback = __dispatch_rpc_port_notify_rpc_finished
-       },
-};
-
-static amd_cynara_checker __cynara_checkers[] = {
-       {
-               .cmd = RPC_PORT_PREPARE_STUB,
-               .checker = __prepare_stub_cynara_checker,
-               .data = NULL,
-               .priority = 10
-       },
-       {
-               .cmd = RPC_PORT_CREATE_SOCKET_PAIR,
-               .checker = __create_socket_pair_cynara_checker,
-               .data = NULL,
-               .priority = 10
-       },
-};
-
-static void __tts_engine_default_vconf_cb(keynode_t *key, void *data)
-{
-       char *str;
-
-       str = vconf_keynode_get_str(key);
-       if (!str)
-               return;
-
-       if (__tts_engine_default)
-               free(__tts_engine_default);
-
-       _W("TTS Engine Default %s => %s", __tts_engine_default, str);
-       __tts_engine_default = strdup(str);
-}
-
-EXPORT int AMD_MOD_INIT(void)
-{
-       int r;
-
-       _D("rpc port init");
-
-       r = amd_app_property_metadata_add_filter(KEY_PRIVILEGE_CHECK_BYPASS,
-                       NULL);
-       if (r < 0) {
-               _E("Failed to add metadata filter");
-               return -1;
-       }
-
-       r = amd_request_register_cmds(__dispatch_table,
-                       ARRAY_SIZE(__dispatch_table));
-       if (r < 0) {
-               _E("Failed to register cmds");
-               return -1;
-       }
-
-       r = amd_cynara_register_checkers(__cynara_checkers,
-                       ARRAY_SIZE(__cynara_checkers));
-       if (r < 0) {
-               _E("Failed to register cynara checkers");
-               return -1;
-       }
-
-       __pid_table = g_hash_table_new(g_direct_hash, g_direct_equal);
-       if (!__pid_table) {
-               _E("Failed to create pid table");
-               return -1;
-       }
-
-       __tts_engine_default = vconf_get_str(VCONFKEY_TTS_ENGINE_DEFAULT);
-       r = vconf_notify_key_changed(VCONFKEY_TTS_ENGINE_DEFAULT,
-                       __tts_engine_default_vconf_cb, NULL);
-       if (r != 0)
-               _E("vconf_notify_key_changed() is failed");
-
-       amd_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP,
-                       __on_app_status_cleanup);
-
-       return 0;
-}
-
-EXPORT void AMD_MOD_FINI(void)
-{
-       _D("rpc port finish");
-
-       if (__tts_engine_default)
-               free(__tts_engine_default);
-
-       if (__pid_table)
-               g_hash_table_destroy(__pid_table);
-
-       amd_app_property_metadata_remove_filter(KEY_PRIVILEGE_CHECK_BYPASS,
-                       NULL);
-}