Refactor App Com 11/239011/6
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 21 Jul 2020 02:08:37 +0000 (11:08 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 21 Jul 2020 06:33:47 +0000 (15:33 +0900)
To avoid making a delay, amd creates a thread to send app com messages.
The thread name is "AppComBroker". If calling aul_sock_send_bundle()
returns AUL_R_ECOMM error, amd removes client info from app com endpoints.

Change-Id: I6085485f8c475ba9c48f50fe35753fbae811cc3a
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
16 files changed:
CMakeLists.txt
inc/amd_app_com.h
inc/amd_cynara.h
inc/amd_request.h
src/core/amd_app_com.c [deleted file]
src/core/amd_app_com.cc [new file with mode: 0644]
src/core/app_com/app_com_broker.cc [new file with mode: 0644]
src/core/app_com/app_com_broker.hh [new file with mode: 0644]
src/core/app_com/app_com_client.cc [new file with mode: 0644]
src/core/app_com/app_com_client.hh [new file with mode: 0644]
src/core/app_com/app_com_endpoint.cc [new file with mode: 0644]
src/core/app_com/app_com_endpoint.hh [new file with mode: 0644]
src/core/app_com/app_com_message.hh [new file with mode: 0644]
src/core/common/key_private.hh [new file with mode: 0644]
src/core/common/log_private.hh [new file with mode: 0644]
src/core/common/shared_queue.hh [new file with mode: 0644]

index 7c96d03681ec359b920974805390b1dfadd706de..5fc80510830f82c3401b53a41aa4089cb586f4b3 100644 (file)
@@ -55,7 +55,10 @@ INSTALL(TARGETS ${AMD} DESTINATION bin)
 SET(LIB_AMD "libamd")
 AUX_SOURCE_DIRECTORY(src/core CORE_AMD_SRCS)
 AUX_SOURCE_DIRECTORY(src/lib LIB_AMD_SRCS)
+AUX_SOURCE_DIRECTORY(src/core/app_com CORE_APP_COM_AMD_SRCS)
+AUX_SOURCE_DIRECTORY(src/core/common CORE_COMMON_AMD_SRCS)
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
 SET(HEADERS_LIB_AMD
        amd.h
        amd_api_noti.h
@@ -111,12 +114,14 @@ ENDFOREACH(flag)
 
 ADD_LIBRARY(${LIB_AMD} SHARED
        ${CORE_AMD_SRCS}
-       ${LIB_AMD_SRCS})
+       ${LIB_AMD_SRCS}
+       ${CORE_APP_COM_AMD_SRCS}
+       ${CORE_COMMON_AMD_SRCS})
 SET_TARGET_PROPERTIES(${LIB_AMD} PROPERTIES COMPILE_FLAGS "${EXTRA_FLAGS_LIB_AMD}")
 SET_TARGET_PROPERTIES(${LIB_AMD} PROPERTIES SOVERSION ${MAJORVER})
 SET_TARGET_PROPERTIES(${LIB_AMD} PROPERTIES VERSION ${FULLVER})
 SET_TARGET_PROPERTIES(${LIB_AMD} PROPERTIES OUTPUT_NAME amd)
-TARGET_LINK_LIBRARIES(${LIB_AMD} ${LIB_AMD_PKGS_LDFLAGS} "-ldl")
+TARGET_LINK_LIBRARIES(${LIB_AMD} ${LIB_AMD_PKGS_LDFLAGS} "-ldl -lpthread")
 
 CONFIGURE_FILE(${LIB_AMD}.pc.in ${AMD}.pc @ONLY)
 
index 3fbc5023d0404f9ba3fdb73658def5e5f196a449..47f18c3815402d010606e90ecb3a949b17e20653 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 - 2020 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.
 #include <sys/types.h>
 #include <bundle.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 int _app_com_broker_init(void);
+
 int _app_com_broker_fini(void);
+
 int _app_com_client_remove(int cpid);
-int _app_com_join(const char *endpoint, int cpid, const char *filter,
-               uid_t uid);
+
 int _app_com_send(const char *endpoint, int cpid, bundle *envelope, uid_t uid);
+
 const char *_app_com_get_privilege(const char *endpoint);
+
 bool _app_com_endpoint_exists(const char *endpoint);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* __AMD_APP_COM_H__ */
index d2f94c3d6d7c75d988943a7283e941ab4a6d691e..281104ed5e63142daf9ad8afb15b7a1e58c1cc9d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 - 2020 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.
 #define PRIVILEGE_PACKAGEMANAGER_INFO                                          \
         "http://tizen.org/privilege/packagemanager.info"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 enum amd_cynara_res {
        AMD_CYNARA_ERROR = -2,
        AMD_CYNARA_DENIED,
@@ -86,3 +90,6 @@ int _cynara_sub_checker_add(const char *name, sub_checker_func func);
 int _cynara_sub_checker_check(const char *name, caller_info_h info, request_h req);
 int _cynara_register_ops(cynara_ops ops, cynara_caller_info_ops ci_ops);
 
+#ifdef __cplusplus
+}
+#endif
index c247c069e7511bd39d48a852c2083c1f5494fa49..e54c54e0837959a40b2a6062a4be44e6189bbab2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 - 2020 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.
 #include <sys/types.h>
 #include <time.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef struct request_s *request_h;
 typedef int (*request_cmd_dispatch_cb)(request_h req);
 typedef struct _request_cmd_dispatch {
@@ -62,3 +66,7 @@ unsigned char *_request_get_raw(request_h req);
 struct timespec *_request_get_start_time(request_h req);
 int _request_set_request_type(request_h req, const char *req_type);
 const char *_request_get_request_type(request_h req);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/core/amd_app_com.c b/src/core/amd_app_com.c
deleted file mode 100644 (file)
index f2f4eec..0000000
+++ /dev/null
@@ -1,604 +0,0 @@
-/*
- * Copyright (c) 2015 - 2017 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 <glib.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <aul.h>
-#include <aul_cmd.h>
-#include <aul_app_com.h>
-#include <aul_sock.h>
-
-#include "amd_util.h"
-#include "amd_app_com.h"
-#include "amd_request.h"
-#include "amd_cynara.h"
-
-struct endpoint_info {
-       char *endpoint;
-       unsigned int propagate;
-       char *privilege;
-       GList *clients;
-};
-
-struct client_info {
-       int pid;
-       uid_t uid;
-       char *filter;
-       struct endpoint_info *endpoint;
-};
-
-static GHashTable *cpid_tbl;
-static GHashTable *endpoint_tbl;
-
-static void __remove_client(struct endpoint_info *info, int cpid);
-
-static void __free_endpoint(struct endpoint_info *info)
-{
-       if (!info)
-               return;
-
-       if (info->endpoint)
-               g_free(info->endpoint);
-
-       if (info->privilege)
-               g_free(info->privilege);
-
-       if (info->clients)
-               g_list_free(info->clients);
-
-       g_free(info);
-}
-
-static void __remove_cpid(gpointer key, gpointer value, gpointer user_data)
-{
-       int pid = GPOINTER_TO_INT(key);
-       struct endpoint_info *info;
-       GList *client_list = (GList *)value;
-
-       while (client_list) {
-               info = (struct endpoint_info *)client_list->data;
-               __remove_client(info, pid);
-               client_list = client_list->next;
-       }
-       g_list_free((GList *)value);
-}
-
-static int __app_com_add_endpoint(const char *endpoint, unsigned int propagate,
-               const char *assoc_priv)
-{
-       struct endpoint_info *info;
-
-       info = g_hash_table_lookup(endpoint_tbl, endpoint);
-       if (info) {
-               _E("endpoint already exists.");
-               return AUL_APP_COM_R_ERROR_ENDPOINT_ALREADY_EXISTS;
-       }
-
-       _D("endpoint=%s propagate=%d assoc_priv=%s",
-                       endpoint, propagate, assoc_priv);
-
-       info = (struct endpoint_info *)g_malloc0(sizeof(struct endpoint_info));
-       if (info == NULL) {
-               _E("out of memory");
-               return AUL_APP_COM_R_ERROR_OUT_OF_MEMORY;
-       }
-
-       info->endpoint = g_strdup(endpoint);
-       if (info->endpoint == NULL) {
-               _E("Out of memory");
-               g_free(info);
-               return AUL_APP_COM_R_ERROR_OUT_OF_MEMORY;
-       }
-       info->propagate = propagate;
-       info->clients = NULL;
-
-       if (assoc_priv) {
-               info->privilege = g_strdup(assoc_priv);
-               if (info->privilege == NULL) {
-                       _E("Out of memory");
-                       g_free(info->endpoint);
-                       g_free(info);
-                       return AUL_APP_COM_R_ERROR_OUT_OF_MEMORY;
-               }
-       } else {
-               info->privilege = NULL;
-       }
-
-       g_hash_table_insert(endpoint_tbl, info->endpoint, info);
-
-       return AUL_APP_COM_R_ERROR_OK;
-}
-
-static int __app_com_remove_endpoint(const char *endpoint)
-{
-       struct endpoint_info *info;
-
-       info = g_hash_table_lookup(endpoint_tbl, endpoint);
-       if (!info) {
-               _D("endpoint not exists");
-               return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
-       }
-
-       if (info->clients != NULL) {
-               _D("client active");
-               return AUL_APP_COM_R_ERROR_CLIENT_REMAINING;
-       }
-
-       g_hash_table_remove(endpoint_tbl, endpoint);
-       __free_endpoint(info);
-
-       return AUL_APP_COM_R_ERROR_OK;
-}
-
-static struct client_info *__add_client(struct endpoint_info *info,
-               const char *filter, int pid, uid_t uid)
-{
-       GList *client_list;
-       struct client_info *c;
-
-       c = (struct client_info *)g_malloc0(sizeof(struct client_info));
-       if (c == NULL) {
-               _E("out of memory");
-               return NULL;
-       }
-
-       c->endpoint = info;
-       c->pid = pid;
-       c->uid = uid;
-       if (filter) {
-               c->filter = g_strdup(filter);
-               if (c->filter == NULL) {
-                       _E("Out of memory");
-                       g_free(c);
-                       return NULL;
-               }
-       } else {
-               c->filter = NULL;
-       }
-
-       info->clients = g_list_append(info->clients, c);
-       client_list = g_hash_table_lookup(cpid_tbl, GINT_TO_POINTER(pid));
-       if (client_list == NULL) {
-               client_list = g_list_append(client_list, info);
-               g_hash_table_insert(cpid_tbl, GINT_TO_POINTER(pid),
-                               client_list);
-       } else {
-               client_list = g_list_append(client_list, info);
-       }
-
-       return c;
-}
-
-static int __app_com_join(const char *endpoint, int cpid, const char *filter,
-               uid_t uid)
-{
-       struct endpoint_info *info;
-
-       info = g_hash_table_lookup(endpoint_tbl, endpoint);
-       if (!info) {
-               _E("endpoint not exists: %s", endpoint);
-               return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
-       }
-
-       _D("endpoint=%s cpid=%d filter=%s uid=%d", endpoint, cpid, filter, uid);
-
-       if (__add_client(info, filter, cpid, uid) == NULL)
-               return AUL_APP_COM_R_ERROR_OUT_OF_MEMORY;
-
-       return AUL_APP_COM_R_ERROR_OK;
-}
-
-const char *_app_com_get_privilege(const char *endpoint)
-{
-       struct endpoint_info *info;
-
-       info = g_hash_table_lookup(endpoint_tbl, endpoint);
-       if (!info) {
-               _E("endpoint not exists: %s", endpoint);
-               return NULL;
-       }
-
-       return info->privilege;
-}
-
-static int __check_filter(const char *filter, int cpid, int rpid, bundle *b)
-{
-       /* TODO */
-       return 0;
-}
-
-int _app_com_send(const char *endpoint, int cpid, bundle *envelope, uid_t uid)
-{
-       struct endpoint_info *info;
-       GList *client_head;
-       struct client_info *client;
-       int ret;
-       int result = AUL_APP_COM_R_OK;
-
-       info = g_hash_table_lookup(endpoint_tbl, endpoint);
-       if (!info) {
-               _E("endpoint not exists: %s", endpoint);
-               return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
-       }
-
-       /* TODO delete internal keys */
-
-       _D("endpoint=%s cpid=%d", endpoint, cpid);
-
-       bundle_add_str(envelope, AUL_K_COM_ENDPOINT, endpoint);
-       bundle_add_byte(envelope, AUL_K_COM_RESULT, &result, sizeof(result));
-
-       client_head = info->clients;
-       while (client_head) {
-               client = (struct client_info *)client_head->data;
-               client_head = client_head->next;
-               if (client == NULL)
-                       continue;
-               if (client->pid == cpid)
-                       continue;
-               if (client->uid >= REGULAR_UID_MIN && client->uid != uid)
-                       continue;
-
-               if (client->filter) {
-                       ret = __check_filter(client->filter, cpid, client->pid,
-                                       envelope);
-                       if (ret < 0)
-                               continue;
-               }
-
-               ret = aul_sock_send_bundle(client->pid, client->uid,
-                               APP_COM_MESSAGE, envelope, AUL_SOCK_NOREPLY);
-               if (ret < 0) {
-                       _E("failed to send message pid(%d), uid(%d), ret(%d)",
-                                       client->pid, client->uid, ret);
-               }
-       }
-
-       return AUL_APP_COM_R_ERROR_OK;
-}
-
-static void __remove_client(struct endpoint_info *info, int cpid)
-{
-       GList *client_head;
-       struct client_info *client;
-
-       if (info == NULL)
-               return;
-
-       client_head = info->clients;
-       while (client_head) {
-               client = (struct client_info *)client_head->data;
-               client_head = client_head->next;
-               if (client && client->pid == cpid) {
-                       info->clients = g_list_remove(info->clients, client);
-                       if (client->filter)
-                               g_free(client->filter);
-
-                       g_free(client);
-                       break;
-               }
-       }
-
-       if (info->clients == NULL) {
-               g_hash_table_remove(endpoint_tbl, info->endpoint);
-               _D("endpoint removed: %s", info->endpoint);
-               __free_endpoint(info);
-       }
-}
-
-static int __app_com_leave(const char *endpoint, int cpid)
-{
-       struct endpoint_info *info;
-       GList *endpoint_head;
-
-       info = g_hash_table_lookup(endpoint_tbl, endpoint);
-       if (!info) {
-               _E("endpoint not exists: %s", endpoint);
-               return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
-       }
-
-       endpoint_head = g_hash_table_lookup(cpid_tbl, GINT_TO_POINTER(cpid));
-       if (endpoint_head) {
-               endpoint_head = g_list_remove(endpoint_head, info);
-               if (endpoint_head == NULL) {
-                       g_hash_table_remove(cpid_tbl, GINT_TO_POINTER(cpid));
-               } else {
-                       g_hash_table_replace(cpid_tbl, GINT_TO_POINTER(cpid),
-                                       endpoint_head);
-               }
-       }
-       __remove_client(info, cpid);
-
-       return AUL_APP_COM_R_ERROR_OK;
-}
-
-int _app_com_client_remove(int cpid)
-{
-       GList *client_list;
-       struct endpoint_info *info;
-       GList *client_head;
-
-       client_list = g_hash_table_lookup(cpid_tbl, GINT_TO_POINTER(cpid));
-       if (client_list == NULL)
-               return AUL_APP_COM_R_OK;
-
-       client_head = g_list_first(client_list);
-       while (client_head) {
-               info = (struct endpoint_info *)client_head->data;
-               client_head = g_list_next(client_head);
-               if (info) {
-                       client_list = g_list_remove(client_list, info);
-                       __remove_client(info, cpid);
-               }
-       }
-
-       g_hash_table_remove(cpid_tbl, GINT_TO_POINTER(cpid));
-
-       return AUL_APP_COM_R_ERROR_OK;
-}
-
-bool _app_com_endpoint_exists(const char *endpoint)
-{
-       return g_hash_table_contains(endpoint_tbl, endpoint);
-}
-
-static int __dispatch_app_com_create(request_h req)
-{
-       bundle *kb;
-       int ret;
-       size_t propagate_size;
-       unsigned int propagate = 0;
-       const char *privilege;
-       const char *endpoint;
-       unsigned int *prop;
-
-       kb = _request_get_bundle(req);
-       if (kb == NULL)
-               return -1;
-
-       endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
-       if (endpoint == NULL) {
-               _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
-               return 0;
-       }
-
-       privilege = bundle_get_val(kb, AUL_K_COM_PRIVILEGE);
-       if (!privilege) {
-               /* privilege is not mandatory so far */
-               _D("non-privileged endpoint: %s", endpoint);
-       }
-
-       ret = bundle_get_byte(kb, AUL_K_COM_PROPAGATE, (void **)&prop,
-                       &propagate_size);
-       if (ret == 0)
-               propagate = *prop;
-
-       _D("endpoint: %s propagate: %x privilege: %s",
-                       endpoint, propagate, privilege);
-
-       ret = __app_com_add_endpoint(endpoint, propagate, privilege);
-       if (ret == AUL_APP_COM_R_ERROR_OK ||
-                       ret == AUL_APP_COM_R_ERROR_ENDPOINT_ALREADY_EXISTS) {
-               ret = __app_com_join(endpoint, getpgid(_request_get_pid(req)), NULL,
-                               _request_get_uid(req));
-               if (ret == AUL_APP_COM_R_ERROR_ILLEGAL_ACCESS) {
-                       _E("illegal access: remove endpoint");
-                       __app_com_remove_endpoint(endpoint);
-               }
-       }
-
-       _request_send_result(req, ret);
-       return 0;
-}
-
-static int __dispatch_app_com_join(request_h req)
-{
-       bundle *kb;
-       int ret;
-       const char *endpoint;
-       const char *filter;
-
-       kb = _request_get_bundle(req);
-       if (kb == NULL)
-               return -1;
-
-       endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
-       if (endpoint == NULL) {
-               bundle_free(kb);
-               _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
-               return 0;
-       }
-
-       filter = bundle_get_val(kb, AUL_K_COM_FILTER);
-
-       ret = __app_com_join(endpoint, getpgid(_request_get_pid(req)), filter,
-                       _request_get_uid(req));
-
-       _request_send_result(req, ret);
-
-       return 0;
-}
-
-static int __dispatch_app_com_send(request_h req)
-{
-       bundle *kb;
-       int ret;
-       const char *endpoint;
-       int sender_pid = _request_get_pid(req);
-       char sender_pid_str[MAX_PID_STR_BUFSZ];
-       uid_t sender_uid = _request_get_uid(req);
-
-       kb = _request_get_bundle(req);
-       if (kb == NULL)
-               return -1;
-
-       snprintf(sender_pid_str, MAX_PID_STR_BUFSZ, "%d", sender_pid);
-       bundle_del(kb, AUL_K_COM_SENDER_PID);
-       bundle_add(kb, AUL_K_COM_SENDER_PID, sender_pid_str);
-       endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
-       if (endpoint == NULL) {
-               _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
-               return 0;
-       }
-
-       ret = _app_com_send(endpoint, getpgid(sender_pid), kb, sender_uid);
-       _request_send_result(req, ret);
-
-       return 0;
-}
-
-static int __dispatch_app_com_leave(request_h req)
-{
-       bundle *kb;
-       int ret;
-       const char *endpoint;
-
-       kb = _request_get_bundle(req);
-       if (kb == NULL)
-               return -1;
-
-       endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
-       if (endpoint == NULL) {
-               _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
-               return 0;
-       }
-
-       ret = __app_com_leave(endpoint, getpgid(_request_get_pid(req)));
-       _request_send_result(req, ret);
-
-       return 0;
-}
-
-static request_cmd_dispatch __dispatch_table[] = {
-       {
-               .cmd = APP_COM_CREATE,
-               .callback = __dispatch_app_com_create
-       },
-       {
-               .cmd = APP_COM_JOIN,
-               .callback = __dispatch_app_com_join
-       },
-       {
-               .cmd = APP_COM_SEND,
-               .callback = __dispatch_app_com_send
-       },
-       {
-               .cmd = APP_COM_LEAVE,
-               .callback = __dispatch_app_com_leave
-       },
-};
-
-static int __com_create_checker(caller_info_h info, request_h req,
-               void *data)
-{
-       char *privilege = NULL;
-       bundle *kb = _request_get_bundle(req);
-
-       bundle_get_str(kb, AUL_K_COM_PRIVILEGE, &privilege);
-       if (!privilege)
-               return 0;
-
-       return _cynara_simple_checker(info, req, privilege);
-}
-
-static int __com_join_checker(caller_info_h info, request_h req,
-               void *data)
-{
-       char *endpoint = NULL;
-       const char *privilege;
-       bundle *kb = _request_get_bundle(req);
-
-       bundle_get_str(kb, AUL_K_COM_ENDPOINT, &endpoint);
-       if (!endpoint)
-               return -1;
-
-       privilege = _app_com_get_privilege(endpoint);
-       if (!privilege)
-               return 0;
-
-       return _cynara_simple_checker(info, req, (void *)privilege);
-}
-
-static cynara_checker __cynara_checkers[] = {
-       {
-               .cmd = APP_COM_JOIN,
-               .checker = __com_join_checker,
-               .data = NULL
-       },
-       {
-               .cmd = APP_COM_CREATE,
-               .checker = __com_create_checker,
-               .data = NULL
-       },
-};
-
-int _app_com_broker_init(void)
-{
-       int r;
-
-       if (!endpoint_tbl) {
-               endpoint_tbl = g_hash_table_new(g_str_hash, g_str_equal);
-               if (endpoint_tbl == NULL) {
-                       _E("out of memory");
-                       return -1;
-               }
-       }
-
-       if (!cpid_tbl) {
-               cpid_tbl = g_hash_table_new(g_direct_hash, g_direct_equal);
-               if (cpid_tbl == NULL) {
-                       _E("out of memory");
-                       return -1;
-               }
-       }
-
-       r = _request_register_cmds(__dispatch_table,
-                       ARRAY_SIZE(__dispatch_table));
-       if (r < 0) {
-               _E("Failed to register cmds");
-               return -1;
-       }
-
-       r = _cynara_register_checkers(__cynara_checkers,
-                       ARRAY_SIZE(__cynara_checkers));
-       if (r < 0) {
-               _E("Failed to register checkers");
-               return -1;
-       }
-
-       return 0;
-}
-
-int _app_com_broker_fini(void)
-{
-       if (cpid_tbl) {
-               g_hash_table_foreach(cpid_tbl, __remove_cpid, NULL);
-               g_hash_table_destroy(cpid_tbl);
-               cpid_tbl = NULL;
-       }
-
-       if (endpoint_tbl) {
-               g_hash_table_destroy(endpoint_tbl);
-               endpoint_tbl = NULL;
-       }
-
-       return 0;
-}
diff --git a/src/core/amd_app_com.cc b/src/core/amd_app_com.cc
new file mode 100644 (file)
index 0000000..66a73e1
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2020 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 <aul.h>
+#include <aul_app_com.h>
+#include <aul_cmd.h>
+#include <bundle.h>
+#include <bundle_cpp.h>
+#include <bundle_internal.h>
+
+#include "amd_app_com.h"
+#include "amd_cynara.h"
+#include "amd_request.h"
+
+#include "core/app_com/app_com_broker.hh"
+#include "core/common/key_private.hh"
+#include "core/common/log_private.hh"
+
+using namespace amd;
+
+const char* _app_com_get_privilege(const char* endpoint) {
+  auto& inst = AppComBroker::GetInst();
+  if (!inst.Exist(endpoint))
+    return nullptr;
+
+  return inst.GetPrivilege(endpoint).c_str();
+}
+
+int _app_com_send(const char* endpoint, int cpid, bundle* envelope, uid_t uid) {
+  auto& inst = AppComBroker::GetInst();
+  if (!inst.Exist(endpoint)) {
+    _E("Endpoint(%s) does not exist", endpoint);
+    return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
+  }
+
+  _D("endpoint=%s cpid=%d", endpoint, cpid);
+  bundle_add_str(envelope, AUL_K_COM_ENDPOINT, endpoint);
+  int result = AUL_APP_COM_R_OK;
+  bundle_add_byte(envelope, AUL_K_COM_RESULT, &result, sizeof(result));
+
+  std::shared_ptr<tizen_base::Bundle> envelope_ptr(
+      new (std::nothrow) tizen_base::Bundle(envelope));
+  if (envelope_ptr.get() == nullptr) {
+    _E("Out of memory");
+    return AUL_APP_COM_R_ERROR_OUT_OF_MEMORY;
+  }
+
+  return inst.Send(endpoint, envelope_ptr, cpid, uid);
+}
+
+int _app_com_client_remove(int cpid) {
+  AppComBroker::GetInst().Remove(cpid);
+  return AUL_APP_COM_R_ERROR_OK;
+}
+
+bool _app_com_endpoint_exists(const char* endpoint) {
+  return AppComBroker::GetInst().Exist(endpoint);
+}
+
+static int __dispatch_app_com_create(request_h req) {
+  bundle* kb = _request_get_bundle(req);
+  if (kb == nullptr) {
+    _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+    return -EINVAL;
+  }
+
+  const char* endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
+  if (endpoint == nullptr) {
+    _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+    return -EINVAL;
+  }
+
+  const char* privilege = bundle_get_val(kb, AUL_K_COM_PRIVILEGE);
+  if (privilege == nullptr) {
+    _D("Non-privileged endpoint: %s", endpoint);
+    privilege = "";
+  }
+
+  unsigned int propagate;
+  unsigned int* prop;
+  size_t propagate_size;
+  int ret = bundle_get_byte(kb, AUL_K_COM_PROPAGATE, (void **)&prop,
+      &propagate_size);
+  if (ret == BUNDLE_ERROR_NONE)
+    propagate = *prop;
+  else
+    propagate = 0;
+
+  _D("endpoint=%s propagate=%x privilege=%s",
+      endpoint, propagate, privilege);
+
+  ret = AppComBroker::GetInst().Create(endpoint, propagate, privilege);
+  if (ret == AUL_APP_COM_R_ERROR_OK ||
+      ret == AUL_APP_COM_R_ERROR_ENDPOINT_ALREADY_EXISTS) {
+    int pid = _request_get_pid(req);
+    uid_t uid = _request_get_uid(req);
+    ret = AppComBroker::GetInst().Join(endpoint, "", getpgid(pid), uid);
+    if (ret == AUL_APP_COM_R_ERROR_ILLEGAL_ACCESS) {
+      _E("Illegal access: remove endpoint");
+      AppComBroker::GetInst().Destroy(endpoint);
+    }
+  }
+  _request_send_result(req, ret);
+  return ret;
+}
+
+static int __dispatch_app_com_join(request_h req) {
+  bundle* kb = _request_get_bundle(req);
+  if (kb == nullptr) {
+    _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+    return -EINVAL;
+  }
+
+  const char* endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
+  if (endpoint == nullptr) {
+    _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+    return -EINVAL;
+  }
+
+  const char* filter = bundle_get_val(kb, AUL_K_COM_FILTER);
+  int pid = _request_get_pid(req);
+  uid_t uid = _request_get_uid(req);
+  int ret = AppComBroker::GetInst().Join(endpoint, filter ? filter : "",
+      getpgid(pid), uid);
+  _request_send_result(req, ret);
+  return ret;
+}
+
+static int __dispatch_app_com_send(request_h req) {
+  bundle* kb = _request_get_bundle(req);
+  if (kb == nullptr) {
+    _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+    return -EINVAL;
+  }
+
+  int sender_pid = _request_get_pid(req);
+  bundle_del(kb, AUL_K_COM_SENDER_PID);
+  bundle_add(kb, AUL_K_COM_SENDER_PID, std::to_string(sender_pid).c_str());
+
+  const char* endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
+  if (endpoint == nullptr) {
+    _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+    return -EINVAL;
+  }
+
+  uid_t sender_uid = _request_get_uid(req);
+  int ret = _app_com_send(endpoint, getpgid(sender_pid), kb, sender_uid);
+  _request_send_result(req, ret);
+  return ret;
+}
+
+static int __dispatch_app_com_leave(request_h req) {
+  bundle* kb = _request_get_bundle(req);
+  if (kb == nullptr) {
+    _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+    return -EINVAL;
+  }
+
+  const char* endpoint = bundle_get_val(kb, AUL_K_COM_ENDPOINT);
+  if (endpoint == nullptr) {
+    _request_send_result(req, AUL_APP_COM_R_ERROR_FATAL_ERROR);
+    return -EINVAL;
+  }
+
+  int pid = _request_get_pid(req);
+  int ret = AppComBroker::GetInst().Leave(endpoint, getpgid(pid));
+  _request_send_result(req, ret);
+  return ret;
+}
+
+static request_cmd_dispatch __dispatch_table[] = {
+  {
+    .cmd = APP_COM_CREATE,
+    .callback = __dispatch_app_com_create
+  },
+  {
+    .cmd = APP_COM_JOIN,
+    .callback = __dispatch_app_com_join
+  },
+  {
+    .cmd = APP_COM_SEND,
+    .callback = __dispatch_app_com_send
+  },
+  {
+    .cmd = APP_COM_LEAVE,
+    .callback = __dispatch_app_com_leave
+  },
+};
+
+static int __com_create_checker(caller_info_h info, request_h req, void* data) {
+  bundle* kb = _request_get_bundle(req);
+  if (kb == nullptr) {
+    _E("Invalid parameter");
+    return -EINVAL;
+  }
+
+  char* privilege = nullptr;
+  bundle_get_str(kb, AUL_K_COM_PRIVILEGE, &privilege);
+  if (privilege == nullptr)
+    return 0;
+
+  return _cynara_simple_checker(info, req, reinterpret_cast<void*>(privilege));
+}
+
+static int __com_join_checker(caller_info_h info, request_h req, void* data) {
+  bundle* kb = _request_get_bundle(req);
+  if (kb == nullptr) {
+    _E("Invalid parameter");
+    return -EINVAL;
+  }
+
+  char* endpoint = nullptr;
+  bundle_get_str(kb, AUL_K_COM_ENDPOINT, &endpoint);
+  if (endpoint == nullptr)
+    return -EINVAL;
+
+  const char* privilege = _app_com_get_privilege(endpoint);
+  if (privilege == nullptr)
+    return 0;
+
+  return _cynara_simple_checker(info, req,
+      static_cast<void*>(const_cast<char*>(privilege)));
+}
+
+static cynara_checker __cynara_checkers[] = {
+  {
+    .cmd = APP_COM_JOIN,
+    .checker = __com_join_checker,
+    .data = NULL
+  },
+  {
+    .cmd = APP_COM_CREATE,
+    .checker = __com_create_checker,
+    .data = NULL
+  },
+};
+
+int _app_com_broker_init(void) {
+  _W("APP_COM_BROKER_INIT");
+  AppComBroker::GetInst();
+  int ret = _request_register_cmds(__dispatch_table,
+      ARRAY_SIZE(__dispatch_table));
+  if (ret < 0) {
+    _E("Failed to register cmds");
+    return -1;
+  }
+
+  ret = _cynara_register_checkers(__cynara_checkers,
+      ARRAY_SIZE(__cynara_checkers));
+  if (ret < 0) {
+    _E("Failed to register checkers");
+    return -1;
+  }
+
+  return 0;
+}
+
+int _app_com_broker_fini(void) {
+  _W("APP_COM_BROKER_FINI");
+  AppComBroker::GetInst().Dispose();
+  return 0;
+}
diff --git a/src/core/app_com/app_com_broker.cc b/src/core/app_com/app_com_broker.cc
new file mode 100644 (file)
index 0000000..cda4ba3
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2020 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 <aul.h>
+#include <aul_app_com.h>
+#include <aul_sock.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "core/app_com/app_com_broker.hh"
+#include "core/common/log_private.hh"
+#include "core/common/key_private.hh"
+
+namespace amd {
+
+AppComBroker::~AppComBroker() {
+  if (!disposed_)
+    Dispose();
+}
+
+AppComBroker& AppComBroker::GetInst() {
+  static AppComBroker inst;
+  std::lock_guard<std::recursive_mutex> lock(inst.GetMutex());
+  if (inst.disposed_)
+    inst.Init();
+  return inst;
+}
+
+void AppComBroker::Dispose() {
+  queue_.Push(AppComMessage(true));
+  if (thread_.joinable()) {
+    _W("Join thread");
+    thread_.join();
+  }
+  disposed_ = true;
+}
+
+int AppComBroker::Create(const std::string& endpoint, unsigned int propagate,
+    const std::string& privilege) {
+  std::lock_guard<std::recursive_mutex> lock(GetMutex());
+  if (Exist(endpoint)) {
+    _W("Already exists");
+    return AUL_APP_COM_R_ERROR_ENDPOINT_ALREADY_EXISTS;
+  }
+
+  auto* new_endpoint = new (std::nothrow) AppComEndpoint(endpoint,
+      propagate, privilege);
+  if (new_endpoint == nullptr) {
+    _E("Out of memory");
+    return AUL_APP_COM_R_ERROR_OUT_OF_MEMORY;
+  }
+
+  endpoints_[endpoint] = std::unique_ptr<AppComEndpoint>(new_endpoint);
+  return AUL_APP_COM_R_ERROR_OK;
+}
+
+int AppComBroker::Destroy(const std::string& endpoint) {
+  std::lock_guard<std::recursive_mutex> lock(GetMutex());
+  if (!Exist(endpoint))
+    return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
+
+  endpoints_.erase(endpoint);
+  return AUL_APP_COM_R_ERROR_OK;
+}
+
+int AppComBroker::Join(const std::string& endpoint, const std::string& filter,
+    int pid, uid_t uid) {
+  std::lock_guard<std::recursive_mutex> lock(GetMutex());
+  if (!Exist(endpoint)) {
+    _W("Endpoint(%s) does not exist", endpoint.c_str());
+    return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
+  }
+
+  auto* client = new (std::nothrow) AppComClient(filter, pid, uid);
+  if (client == nullptr) {
+    _E("Out of memory");
+    return AUL_APP_COM_R_ERROR_OUT_OF_MEMORY;
+  }
+
+  endpoints_[endpoint]->AddClient(pid, std::shared_ptr<AppComClient>(client));
+  return AUL_APP_COM_R_ERROR_OK;
+}
+
+int AppComBroker::Send(const std::string& endpoint,
+    std::shared_ptr<tizen_base::Bundle> envelope,
+    int sender_pid, uid_t sender_uid) {
+  std::lock_guard<std::recursive_mutex> lock(GetMutex());
+  if (!Exist(endpoint)) {
+    _W("Endpoint(%s) does not exist", endpoint.c_str());
+    return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
+  }
+
+  for (auto iter : endpoints_[endpoint]->GetClients()) {
+    auto& client = iter.second;
+    int pid = client->GetPid();
+    if (pid == sender_pid)
+      continue;
+
+    uid_t uid = client->GetUid();
+    if (uid >= REGULAR_UID_MIN && uid != sender_uid)
+      continue;
+
+    queue_.Push(AppComMessage(pid, uid, envelope));
+  }
+  return AUL_APP_COM_R_ERROR_OK;
+}
+
+int AppComBroker::Leave(const std::string& endpoint, int pid) {
+  std::lock_guard<std::recursive_mutex> lock(GetMutex());
+  if (!Exist(endpoint)) {
+    _W("Endpoint(%s) does not exist", endpoint.c_str());
+    return AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT;
+  }
+
+  endpoints_[endpoint]->RemoveClient(pid);
+  if (endpoints_[endpoint]->GetClientCount() == 0) {
+    _W("Remove endpoint(%s)", endpoint.c_str());
+    endpoints_.erase(endpoint);
+  }
+  return AUL_APP_COM_R_ERROR_OK;
+}
+
+int AppComBroker::Remove(int pid) {
+  std::lock_guard<std::recursive_mutex> lock(GetMutex());
+  auto iter = endpoints_.begin();
+  while (iter != endpoints_.end()) {
+    auto& key = iter->first;
+    auto& endpoint = iter->second;
+    endpoint->RemoveClient(pid);
+    if (endpoint->GetClientCount() == 0) {
+      _W("Remove endpoint(%s)", key.c_str());
+      iter = endpoints_.erase(iter);
+    } else {
+      iter++;
+    }
+  }
+  return 0;
+}
+
+bool AppComBroker::Exist(const std::string& endpoint) {
+  std::lock_guard<std::recursive_mutex> lock(GetMutex());
+  auto iter = endpoints_.find(endpoint);
+  if (iter != endpoints_.end())
+    return true;
+  return false;
+}
+
+const std::string& AppComBroker::GetPrivilege(const std::string& endpoint) {
+  std::lock_guard<std::recursive_mutex> lock(GetMutex());
+  return endpoints_[endpoint]->GetPrivilege();
+}
+
+void AppComBroker::Init() {
+  thread_ = std::thread([&]() {
+        _W("START");
+        SetComm();
+        do {
+          auto msg = queue_.WaitAndPop();
+          if (msg.Done()) {
+            _W("Done");
+            break;
+          }
+
+          int pid = msg.GetPid();
+          uid_t uid = msg.GetUid();
+          int ret = aul_sock_send_bundle(pid, uid, APP_COM_MESSAGE,
+              msg.GetEnvelope()->GetHandle(), AUL_SOCK_NOREPLY);
+          if (ret < 0) {
+            if (ret == AUL_R_ECOMM) {
+              _E("Remove client. pid(%d), uid(%u)", pid, uid);
+              Remove(pid);
+            } else {
+              _E("Failed to send message. pid(%d), uid(%u), error(%d)",
+                  pid, uid, ret);
+            }
+          }
+        } while (true);
+        _W("END");
+      });
+  disposed_ = false;
+}
+
+void AppComBroker::SetComm() {
+  pid_t tid = syscall(__NR_gettid);
+  std::string path = "/proc/" + std::to_string(tid) + "/comm";
+  int fd = open(path.c_str(), O_WRONLY);
+  if (fd < 0) {
+    _E("open(%s) is failed. errno(%d)", path.c_str(), errno);
+    return;
+  }
+
+  std::string name = "AppComBroker";
+  ssize_t bytes_written = write(fd, name.c_str(), name.length() + 1);
+  if (bytes_written < 0)
+    _E("write(%d) is failed. errno(%d)", fd, errno);
+
+  close(fd);
+}
+
+std::recursive_mutex& AppComBroker::GetMutex() const {
+  return mutex_;
+}
+
+}  // namespace amd
diff --git a/src/core/app_com/app_com_broker.hh b/src/core/app_com/app_com_broker.hh
new file mode 100644 (file)
index 0000000..d67618f
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2020 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 CORE_APP_COM_APP_COM_BROKER_HH_
+#define CORE_APP_COM_APP_COM_BROKER_HH_
+
+#include <bundle_cpp.h>
+
+#include <list>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <thread>
+
+#include "core/app_com/app_com_client.hh"
+#include "core/app_com/app_com_endpoint.hh"
+#include "core/app_com/app_com_message.hh"
+#include "core/common/shared_queue.hh"
+
+namespace amd {
+
+class AppComBroker {
+ private:
+  AppComBroker() = default;
+  ~AppComBroker();
+
+ public:
+  static AppComBroker& GetInst();
+  void Dispose();
+
+  int Create(const std::string& endpoint, unsigned int propagate,
+      const std::string& privilege);
+  int Destroy(const std::string& endpoint);
+  int Join(const std::string& endpoint, const std::string& filter,
+      int pid, uid_t uid);
+  int Send(const std::string& endpoint,
+      std::shared_ptr<tizen_base::Bundle> envelope,
+      int sender_pid, uid_t sender_uid);
+  int Leave(const std::string& endpoint, int pid);
+  int Remove(int pid);
+  bool Exist(const std::string& endpoint);
+  const std::string& GetPrivilege(const std::string& endpoint);
+
+ private:
+  void Init();
+  void SetComm();
+  std::recursive_mutex& GetMutex() const;
+
+ private:
+  bool disposed_ = true;
+  std::thread thread_;
+  SharedQueue<AppComMessage> queue_;
+  std::map<std::string, std::unique_ptr<AppComEndpoint>> endpoints_;
+  mutable std::recursive_mutex mutex_;
+};
+
+}  // namespace amd
+
+#endif  // CORE_APP_COM_APP_COM_BROKER_HH_
diff --git a/src/core/app_com/app_com_client.cc b/src/core/app_com/app_com_client.cc
new file mode 100644 (file)
index 0000000..d49c79b
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2020 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 "core/app_com/app_com_client.hh"
+
+namespace amd {
+
+AppComClient::AppComClient(std::string filter, int pid, uid_t uid)
+  : filter_(std::move(filter)), pid_(pid), uid_(uid) {
+}
+
+AppComClient::~AppComClient() = default;
+
+const std::string& AppComClient::GetFilter() {
+  return filter_;
+}
+
+int AppComClient::GetPid() const {
+  return pid_;
+}
+
+uid_t AppComClient::GetUid() const {
+  return uid_;
+}
+
+}  // namespace amd
diff --git a/src/core/app_com/app_com_client.hh b/src/core/app_com/app_com_client.hh
new file mode 100644 (file)
index 0000000..258c699
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020 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 CORE_APP_COM_APP_COM_CLIENT_HH_
+#define CORE_APP_COM_APP_COM_CLIENT_HH_
+
+#include <map>
+#include <memory>
+#include <string>
+
+namespace amd {
+
+class AppComClient {
+ public:
+  AppComClient(std::string filter, int pid, uid_t uid);
+  virtual ~AppComClient();
+
+  const std::string& GetFilter();
+  int GetPid() const;
+  uid_t GetUid() const;
+
+ private:
+  std::string filter_;
+  int pid_;
+  uid_t uid_;
+};
+
+}  // namespace amd
+
+#endif  // CORE_APP_COM_APP_COM_CLIENT_HH_
diff --git a/src/core/app_com/app_com_endpoint.cc b/src/core/app_com/app_com_endpoint.cc
new file mode 100644 (file)
index 0000000..d449536
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2020 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 "core/app_com/app_com_endpoint.hh"
+
+namespace amd {
+
+AppComEndpoint::AppComEndpoint(std::string endpoint, unsigned int propagate,
+    std::string privilege)
+  : endpoint_(std::move(endpoint)),
+    propagate_(propagate),
+    privilege_(std::move(privilege)) {
+}
+
+AppComEndpoint::~AppComEndpoint() = default;
+
+void AppComEndpoint::AddClient(int pid, std::shared_ptr<AppComClient> client) {
+  auto iter = clients_.find(pid);
+  if (iter != clients_.end())
+    return;
+
+  clients_[pid] = client;
+}
+
+void AppComEndpoint::RemoveClient(int pid) {
+  auto iter = clients_.find(pid);
+  if (iter == clients_.end())
+    return;
+
+  clients_.erase(iter);
+}
+
+const std::string& AppComEndpoint::GetEndpoint() {
+  return endpoint_;
+}
+
+unsigned int AppComEndpoint::GetPropagate() const {
+  return propagate_;
+}
+
+const std::string& AppComEndpoint::GetPrivilege() {
+  return privilege_;
+}
+
+const std::map<int, std::shared_ptr<AppComClient>>&
+AppComEndpoint::GetClients() {
+  return clients_;
+}
+
+int AppComEndpoint::GetClientCount() {
+  return clients_.size();
+}
+
+}  // namespace amd
diff --git a/src/core/app_com/app_com_endpoint.hh b/src/core/app_com/app_com_endpoint.hh
new file mode 100644 (file)
index 0000000..b1cb17c
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2020 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 CORE_APP_COM_APP_COM_ENDPOINT_HH_
+#define CORE_APP_COM_APP_COM_ENDPOINT_HH_
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "core/app_com/app_com_client.hh"
+
+namespace amd {
+
+class AppComEndpoint {
+ public:
+  AppComEndpoint(std::string endpoint, unsigned int propagate,
+      std::string privilege);
+  virtual ~AppComEndpoint();
+
+  void AddClient(int pid, std::shared_ptr<AppComClient> client);
+  void RemoveClient(int pid);
+
+  const std::string& GetEndpoint();
+  unsigned int GetPropagate() const;
+  const std::string& GetPrivilege();
+  const std::map<int, std::shared_ptr<AppComClient>>& GetClients();
+  int GetClientCount();
+
+ private:
+  std::string endpoint_;
+  unsigned int propagate_;
+  std::string privilege_;
+  std::map<int, std::shared_ptr<AppComClient>> clients_;
+};
+
+}  // namespace amd
+
+#endif  // CORE_APP_COM_APP_COM_ENDPOINT_HH_
diff --git a/src/core/app_com/app_com_message.hh b/src/core/app_com/app_com_message.hh
new file mode 100644 (file)
index 0000000..3faab5c
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2020 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 CORE_APP_COM_APP_COM_MESSAGE_H_
+#define CORE_APP_COM_APP_COM_MESSAGE_H_
+
+#include <bundle_cpp.h>
+
+#include <memory>
+#include <string>
+
+namespace amd {
+
+class AppComMessage {
+ public:
+  AppComMessage(int pid, uid_t uid,
+      std::shared_ptr<tizen_base::Bundle> envelope)
+    : pid_(pid), uid_(uid), envelope_(std::move(envelope)) {
+  }
+
+  AppComMessage(bool done = false) : done_(done) {
+  }
+
+  virtual ~AppComMessage() = default;
+
+  int GetPid() const {
+    return pid_;
+  }
+
+  uid_t GetUid() const {
+    return uid_;
+  }
+
+  const std::shared_ptr<tizen_base::Bundle>& GetEnvelope() {
+    return envelope_;
+  }
+
+  bool Done() {
+    return done_;
+  }
+
+ private:
+  bool done_ = false;
+  int pid_;
+  uid_t uid_;
+  std::shared_ptr<tizen_base::Bundle> envelope_;
+};
+
+}  // namespace amd
+
+#endif  // CORE_APP_COM_APP_COM_MESSAGE_HH_
diff --git a/src/core/common/key_private.hh b/src/core/common/key_private.hh
new file mode 100644 (file)
index 0000000..d3580a8
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020 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 CORE_COMMON_KEY_PRIVATE_HH_
+#define CORE_COMMON_KEY_PRIVATE_HH_
+
+#undef REGULAR_UID_MIN
+#define REGULAR_UID_MIN 5000
+
+#undef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+#endif  // CORE_COMMON_KEY_PRIVATE_HH_
diff --git a/src/core/common/log_private.hh b/src/core/common/log_private.hh
new file mode 100644 (file)
index 0000000..81e8c1a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020 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 CORE_COMMON_LOG_PRIVATE_HH_
+#define CORE_COMMON_LOG_PRIVATE_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "AMD"
+
+#undef _E
+#define _E(fmt, arg...) LOGE(fmt, ##arg)
+
+#undef _D
+#define _D(fmt, arg...) LOGD(fmt, ##arg)
+
+#undef _W
+#define _W(fmt, arg...) LOGW(fmt, ##arg)
+
+#undef _I
+#define _I(fmt, arg...) LOGI(fmt, ##arg)
+
+#endif  // CORE_COMMON_LOG_PRIVATE_HH_
diff --git a/src/core/common/shared_queue.hh b/src/core/common/shared_queue.hh
new file mode 100644 (file)
index 0000000..772881b
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2020 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 CORE_COMMON_SHARED_QUEUE_HH_
+#define CORE_COMMON_SHARED_QUEUE_HH_
+
+#include <condition_variable>
+#include <thread>
+#include <mutex>
+#include <memory>
+#include <queue>
+
+namespace amd {
+
+template <class T>
+class SharedQueue {
+ public:
+  SharedQueue() = default;
+  virtual ~SharedQueue() = default;
+
+  void Push(T item) {
+    std::lock_guard<std::mutex> lock(mutex_);
+    queue_.push(item);
+    cond_var_.notify_one();
+  }
+
+  T WaitAndPop() {
+    std::unique_lock<std::mutex> lock(mutex_);
+    while (queue_.empty())
+      cond_var_.wait(lock);
+
+    auto item = std::move(queue_.front());
+    queue_.pop();
+    return item;
+  }
+
+  bool IsEmpty() const {
+    std::lock_guard<std::mutex> lock(mutex_);
+    return queue_.empty();
+  }
+
+  unsigned int Size() const {
+    std::lock_guard<std::mutex> lock(mutex_);
+    return queue_.size();
+  }
+
+ private:
+  std::queue<T> queue_;
+  mutable std::mutex mutex_;
+  std::condition_variable cond_var_;
+};
+
+}  // namespace amd
+
+#endif  // CORE_COMMON_SHARED_QUEUE_HH_