add aul_app_com_* apis for widget_service 16/54616/11
authorDaehyeon Jung <darrenh.jung@samsung.com>
Thu, 24 Dec 2015 04:29:37 +0000 (13:29 +0900)
committerDaehyeon Jung <darrenh.jung@samsung.com>
Tue, 5 Jan 2016 02:15:13 +0000 (11:15 +0900)
Change-Id: If6cb5b573d788d605bbbc186815e73792184c4a5
Signed-off-by: Daehyeon Jung <darrenh.jung@samsung.com>
CMakeLists.txt
include/aul.h
include/aul_app_com.h [new file with mode: 0644]
include/aul_cmd.h
include/launch.h
packaging/aul.spec
src/app_com.c [new file with mode: 0644]
src/launch.c
tool/app_com_tool.c [new file with mode: 0644]

index 71cd4ba..03942b1 100644 (file)
@@ -62,6 +62,7 @@ add_library(aul SHARED
                src/aul_rsc_mgr.c
                src/aul_sock.c
                src/aul_proc.c
+               src/app_com.c
                )
 TARGET_LINK_LIBRARIES(aul ${libpkgs_LDFLAGS})
 SET_TARGET_PROPERTIES(aul PROPERTIES SOVERSION ${MAJORVER})
@@ -82,6 +83,12 @@ SET_TARGET_PROPERTIES(${APPGROUP_INFO} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}
 TARGET_LINK_LIBRARIES(${APPGROUP_INFO} aul ${APPGROUP_INFO_DEPS_LDFLAGS} "-pie")
 INSTALL(TARGETS appgroup_info DESTINATION bin)
 
+SET(APP_COM_TOOL "app_com_tool")
+ADD_EXECUTABLE(${APP_COM_TOOL} tool/app_com_tool.c)
+SET_TARGET_PROPERTIES(${APP_COM_TOOL} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS} -fPIE")
+TARGET_LINK_LIBRARIES(${APP_COM_TOOL} aul ${APP_COM_TOOL_DEPS_LDFLAGS} "-pie")
+INSTALL(TARGETS app_com_tool DESTINATION bin)
+
 # pkgconfig file
 CONFIGURE_FILE(aul.pc.in aul.pc @ONLY)
 CONFIGURE_FILE(legacy/preload_list.txt.in legacy/preload_list.txt @ONLY)
@@ -94,6 +101,7 @@ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/aul_proc.h DESTINATION include
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/aul_rsc_mgr.h DESTINATION include/aul)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/aul_svc.h DESTINATION include/aul)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/aul_cmd.h DESTINATION include/aul)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/aul_app_com.h DESTINATION include/aul)
 INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/aul.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/legacy/preload_list.txt DESTINATION ${SHARE_INSTALL_PREFIX}/aul )
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/feature/preexec_list.txt DESTINATION ${SHARE_INSTALL_PREFIX}/aul )
index b4a8d0e..e02326f 100644 (file)
@@ -169,6 +169,16 @@ typedef enum _aul_type{
 #define AUL_K_WAYLAND_DISPLAY  "__AUL_WAYLAND_DISPLAY__"
 /** AUL internal private key */
 #define AUL_K_WAYLAND_WORKING_DIR "__AUL_WAYLAND_WORKING_DIR__"
+/** AUL internal private key */
+#define AUL_K_COM_ENDPOINT     "__AUL_COM_ENDPOINT__"
+/** AUL internal private key */
+#define AUL_K_COM_PRIVILEGE    "__AUL_COM_PRIVILEGE__"
+/** AUL internal private key */
+#define AUL_K_COM_PROPAGATE    "__AUL_COM_PROPAGATE__"
+/** AUL internal private key */
+#define AUL_K_COM_FILTER       "__AUL_COM_FILTER__"
+/** AUL internal private key */
+#define AUL_K_COM_RESULT       "__AUL_COM_RESULT__"
 
 /**
  * @brief      This is callback function for aul_launch_init
diff --git a/include/aul_app_com.h b/include/aul_app_com.h
new file mode 100644 (file)
index 0000000..fe69371
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2015 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 __APP_COM_H__
+#define __APP_COM_H__
+
+#include <bundle.h>
+
+typedef enum {
+       AUL_APP_COM_PUBLIC = 0x0, /* allowed for all */
+       AUL_APP_COM_PRIVILEGED = 0x1, /* allowed for given privileged app */
+} aul_app_com_propagate_option_e;
+
+typedef enum {
+       AUL_APP_COM_R_ERROR_OK = 0,
+       AUL_APP_COM_R_ERROR_UNKNOWN_ENDPOINT = -1,
+       AUL_APP_COM_R_ERROR_ENDPOINT_ALREADY_EXISTS = -2,
+       AUL_APP_COM_R_ERROR_ILLEGAL_ACCESS = -3,
+       AUL_APP_COM_R_ERROR_CLIENT_REMAINING = -4,
+       AUL_APP_COM_R_ERROR_OUT_OF_MEMORY = -5,
+       AUL_APP_COM_R_ERROR_FATAL_ERROR = -6,
+} aul_app_com_error_e;
+
+typedef enum {
+       AUL_APP_COM_R_OK = 0,
+       AUL_APP_COM_R_ILLEGAL_ACCESS = -1,
+} aul_app_com_result_e;
+
+typedef struct _aul_app_com_permission_s aul_app_com_permission_s;
+typedef aul_app_com_permission_s *aul_app_com_permission_h;
+typedef struct _aul_app_com_connection_s aul_app_com_connection_s;
+typedef aul_app_com_connection_s *aul_app_com_connection_h;
+
+typedef int (*app_com_cb)(const char *endpoint, aul_app_com_result_e result, bundle *envelope, void *user_data);
+
+/**
+ * aul_app_com provides publish-subscribe style message for internal AUL use.
+ * e.g) widget status propagation, sharing callee app status to caller app
+ * @code
+
+static int __handler(const char *endpoint, aul_app_com_result_e result, bundle *envelope, void *user_data)
+{
+       _D("endpoint: %s", endpoint);
+       _D("result: %d", result);
+
+       return 0;
+}
+
+// viewer-side
+aul_app_com_permission_h permission = aul_app_com_permission_create();
+aul_app_com_permission_set_propagation(permission, AUL_APP_COM_PRIVILEGED);
+aul_app_com_permission_set_privilege(permission, "http://tizen.org/privilege/widget.viewer");
+aul_app_com_connection_h connection = NULL;
+aul_app_com_create("widget.status", permission, __handler, NULL, &connection);
+
+
+// widget-side
+bundle *b = bundle_create();
+bundle_add_str(b, "WIDGET_ID", "org.example.widget");
+bundle_add_str(b, "STATUS", "RUNNING");
+aul_app_com_send("widget.status", b);
+bundle_free(b);
+
+
+// monitor-side
+static int __handler(const char *endpoint, aul_app_com_result_e result, bundle *envelope, void *user_data)
+{
+       const char *widget_id = bundle_get_val(envelope, "WIDGET_ID");
+       const char *status = bundle_get_val(envelope, "STATUS");
+
+       _D("%s is %s", widget_id, status);
+
+       return 0;
+}
+
+aul_app_com_connection_h connection = NULL;
+aul_app_com_join("widget.status", NULL, __handler, NULL, &connection);
+
+ */
+
+aul_app_com_permission_h aul_app_com_permission_create();
+void aul_app_com_permission_destroy(aul_app_com_permission_h permission);
+int aul_app_com_permission_set_propagation(aul_app_com_permission_h permission, aul_app_com_propagate_option_e option);
+int aul_app_com_permission_set_privilege(aul_app_com_permission_h permission, const char *privilege);
+
+
+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);
+int aul_app_com_join(const char *endpoint, const char *filter, app_com_cb callback, void *user_data, aul_app_com_connection_h *connection);
+int aul_app_com_leave(aul_app_com_connection_h connection);
+int aul_app_com_send(const char *endpoint, bundle *envelope);
+
+#endif
index 504aa5b..a789fd3 100644 (file)
@@ -67,6 +67,12 @@ enum app_cmd {
        /* for message-port */
        APP_GET_MP_SOCKET_PAIR,
 
+       APP_COM_CREATE,
+       APP_COM_JOIN,
+       APP_COM_SEND,
+       APP_COM_LEAVE,
+       APP_COM_MESSAGE,
+
        /* for special purpose */
        AMD_RELOAD_APPINFO,
        /* reserved for AMD Agent */
index 28ff249..6e809c6 100644 (file)
@@ -42,4 +42,5 @@ int app_subapp_terminate_request(void);
 int __call_aul_handler(aul_type type, bundle *kb);
 gboolean __aul_glib_handler(gpointer data);
 
+int app_com_recv(bundle *b);
 
index 1d6ac84..d151df5 100644 (file)
@@ -107,6 +107,7 @@ chsmack -a 'User::Home' %{_sysconfdir}/skel/.applications/dbspace/.appsvc.db
 %{_bindir}/aul_test
 %{_bindir}/app_launcher
 %{_bindir}/appgroup_info
+%{_bindir}/app_com_tool
 %{_bindir}/launch_app
 %{_bindir}/appid2pid
 %{_bindir}/launch_debug
diff --git a/src/app_com.c b/src/app_com.c
new file mode 100644 (file)
index 0000000..69062e0
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2015 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 <glib.h>
+#include "aul.h"
+#include "launch.h"
+#include "aul_cmd.h"
+#include "aul_util.h"
+#include "aul_api.h"
+#include "aul_app_com.h"
+
+static GList *handlers = NULL;
+
+struct _aul_app_com_connection_s {
+       char *endpoint;
+       app_com_cb callback;
+       void *user_data;
+};
+
+struct _aul_app_com_permission_s {
+       char *privilege;
+       unsigned int propagation;
+};
+
+int app_com_recv(bundle *b)
+{
+       int ret = 0;
+       char *endpoint = NULL;
+       size_t result_sz;
+       int result;
+       GList *head = handlers;
+       aul_app_com_connection_s *handler = NULL;
+
+       if (b == NULL)
+               return -1;
+
+       ret = bundle_get_str(b, AUL_K_COM_ENDPOINT, &endpoint);
+       if (ret != BUNDLE_ERROR_NONE)
+               return -1;
+
+       ret = bundle_get_byte(b, AUL_K_COM_RESULT, (void **)&result, &result_sz);
+       if (ret != BUNDLE_ERROR_NONE)
+               return -1;
+
+       while (head) {
+               handler = (aul_app_com_connection_s *)head->data;
+               if (handler && handler->endpoint && g_strcmp0(handler->endpoint, endpoint) == 0)
+                       handler->callback(endpoint, result, b, handler->user_data);
+
+               head = head->next;
+       }
+
+       return 0;
+}
+
+API aul_app_com_permission_h aul_app_com_permission_create()
+{
+       aul_app_com_permission_s *p = NULL;
+       p = (aul_app_com_permission_s *)g_malloc0(sizeof(aul_app_com_permission_s));
+
+       return p;
+}
+
+API void aul_app_com_permission_destroy(aul_app_com_permission_h permission)
+{
+       if (permission)
+               g_free(permission);
+}
+
+API int aul_app_com_permission_set_propagation(aul_app_com_permission_h permission, aul_app_com_propagate_option_e option)
+{
+       if (permission)
+               permission->propagation = option;
+
+       return 0;
+}
+
+API int aul_app_com_permission_set_privilege(aul_app_com_permission_h permission, const char *privilege)
+{
+       if (permission) {
+               if (permission->privilege)
+                       g_free(permission->privilege);
+
+               permission->privilege = g_strdup(privilege);
+       }
+
+       return 0;
+}
+
+static aul_app_com_connection_h __add_handler(const char *endpoint, app_com_cb callback, void *user_data)
+{
+       aul_app_com_connection_s *h = NULL;
+       h = (aul_app_com_connection_s *)g_malloc0(sizeof(aul_app_com_connection_s));
+       if (h == NULL) {
+               _E("out of memory");
+               return NULL;
+       }
+
+       h->callback = callback;
+       h->user_data = user_data;
+       h->endpoint = g_strdup(endpoint);
+
+       handlers = g_list_append(handlers, h);
+
+       return h;
+}
+
+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)
+{
+       bundle *b = NULL;
+       int ret = 0;
+
+       if (endpoint == NULL || callback == NULL || connection == NULL)
+               return -1;
+
+       b = bundle_create();
+
+       if (!b) {
+               _E("out of memory");
+               return -1;
+       }
+
+       bundle_add_str(b, AUL_K_COM_ENDPOINT, endpoint);
+
+       if (permission) {
+               if (permission->propagation)
+                       bundle_add_byte(b, AUL_K_COM_PROPAGATE,
+                               (void *)(GUINT_TO_POINTER(permission->propagation)), sizeof(unsigned int));
+
+               if (permission->privilege)
+                       bundle_add_str(b, AUL_K_COM_PRIVILEGE, permission->privilege);
+       }
+
+       ret = app_send_cmd(AUL_UTIL_PID, APP_COM_CREATE, b);
+       bundle_free(b);
+
+       if (ret == 0)
+               *connection = __add_handler(endpoint, callback, user_data);
+
+       return ret;
+}
+
+API int aul_app_com_join(const char *endpoint, const char *filter, app_com_cb callback, void *user_data, aul_app_com_connection_h *connection)
+{
+       bundle *b = NULL;
+       int ret = 0;
+
+       if (endpoint == NULL || callback == NULL || connection == NULL)
+               return -1;
+
+       b = bundle_create();
+
+       if (!b) {
+               _E("out of memory");
+               return -1;
+       }
+
+       bundle_add_str(b, AUL_K_COM_ENDPOINT, endpoint);
+       if (filter)
+               bundle_add_str(b, AUL_K_COM_FILTER, filter);
+
+       ret = app_send_cmd(AUL_UTIL_PID, APP_COM_JOIN, b);
+       bundle_free(b);
+
+       if (ret == 0)
+               *connection = __add_handler(endpoint, callback, user_data);
+
+       return ret;
+}
+
+API int aul_app_com_send(const char *endpoint, bundle *envelope)
+{
+       int ret = 0;
+
+       if (endpoint == NULL || envelope == NULL)
+               return -1;
+
+       bundle_add_str(envelope, AUL_K_COM_ENDPOINT, endpoint);
+
+       ret = app_send_cmd(AUL_UTIL_PID, APP_COM_SEND, envelope);
+
+       return ret;
+}
+
+API int aul_app_com_leave(aul_app_com_connection_h connection)
+{
+       bundle *b = NULL;
+       int ret = 0;
+       GList *head = handlers;
+       aul_app_com_connection_s *h = NULL;
+       int endpoint_cnt = 0;
+
+       if (connection == NULL)
+               return -1;
+
+       while (head) {
+               h = (aul_app_com_connection_s *)head->data;
+               if (h && h->endpoint && g_strcmp0(h->endpoint, connection->endpoint) == 0) {
+                       if (h == connection)
+                               handlers = g_list_remove_link(handlers, head);
+                       else
+                               endpoint_cnt++;
+               }
+
+               head = head->next;
+       }
+
+       if (endpoint_cnt > 0) {
+               g_free(connection->endpoint);
+               g_free(connection);
+               return 0;
+       }
+
+       b = bundle_create();
+       if (!b) {
+               _E("out of memory");
+               return -1;
+       }
+
+       bundle_add_str(b, AUL_K_COM_ENDPOINT, connection->endpoint);
+
+       ret = app_send_cmd(AUL_UTIL_PID, APP_COM_LEAVE, b);
+
+       bundle_free(b);
+       g_free(connection->endpoint);
+       g_free(connection);
+
+       return ret;
+}
index f1e01e6..36f8220 100644 (file)
@@ -36,6 +36,7 @@
 #include "launch.h"
 #include "key.h"
 #include "app_signal.h"
+#include "aul_app_com.h"
 
 #define TEP_ISMOUNT_MAX_RETRY_CNT 20
 
@@ -433,7 +434,8 @@ int aul_sock_handler(int fd)
                return -1;
        }
 
-       if (pkt->cmd != APP_RESULT && pkt->cmd != APP_CANCEL && pkt->cmd != APP_TERM_BY_PID_ASYNC) {
+       if (pkt->cmd != APP_RESULT && pkt->cmd != APP_CANCEL && pkt->cmd != APP_TERM_BY_PID_ASYNC &&
+               pkt->cmd != APP_COM_MESSAGE) {
                ret = __send_result_to_launchpad(clifd, 0);
                if (ret < 0) {
                        free(pkt);
@@ -496,7 +498,13 @@ int aul_sock_handler(int fd)
        case APP_PAUSE_BY_PID:
                app_pause();
                break;
-
+       case APP_COM_MESSAGE:
+               kbundle = bundle_decode(pkt->data, pkt->len);
+               if (kbundle == NULL)
+                       goto err;
+               app_com_recv(kbundle);
+               bundle_free(kbundle);
+               break;
        default:
                _E("no support packet");
        }
diff --git a/tool/app_com_tool.c b/tool/app_com_tool.c
new file mode 100644 (file)
index 0000000..6803073
--- /dev/null
@@ -0,0 +1,109 @@
+#include <glib.h>
+#include <stdio.h>
+#include <aul.h>
+#include <aul_app_com.h>
+
+static GMainLoop *mainloop = NULL;
+static int gargc;
+static char **gargv;
+static aul_app_com_connection_h conn = NULL;
+
+static void __bundle_itr(const char *key, const int type, const bundle_keyval_t *kv, void *data)
+{
+       printf("key: %s ", key);
+       printf("type: %d", type);
+       printf("\n");
+}
+
+static int __handler(const char *endpoint, aul_app_com_result_e  result, bundle *envelope, void *user_data)
+{
+       printf("endpoint: %s (%d) received\n", endpoint, result);
+       printf("---begin---\n");
+       bundle_foreach(envelope, __bundle_itr, NULL);
+       printf("---end---\n\n");
+
+       return 0;
+}
+
+static void create(const char *endpoint, const char *privilege)
+{
+       aul_app_com_permission_h permission = NULL;
+
+       if (privilege) {
+               permission = aul_app_com_permission_create();
+               aul_app_com_permission_set_privilege(permission, privilege);
+               aul_app_com_permission_set_propagation(permission, AUL_APP_COM_PRIVILEGED);
+       }
+
+       aul_app_com_create(endpoint, permission, __handler, NULL, &conn);
+
+       if (permission)
+               aul_app_com_permission_destroy(permission);
+}
+
+static void join(const char *endpoint, const char *filter)
+{
+       int ret = aul_app_com_join(endpoint, filter, __handler, NULL, &conn);
+       printf("ret: %d\n", ret);
+}
+
+static void send(const char *endpoint)
+{
+       int idx = 2;
+       bundle *b = bundle_create();
+       for (idx = 2; idx < gargc; idx += 2) {
+               bundle_add_str(b, gargv[idx], gargv[idx + 1]);
+       }
+       int ret = aul_app_com_send(endpoint, b);
+       printf("ret: %d\n", ret);
+
+       g_main_loop_quit(mainloop);
+}
+
+static gboolean run_func(void *data)
+{
+       if (gargc < 2 || (gargc > 1 && gargv[1] && (g_strcmp0(gargv[1], "help") == 0 && gargc == 2))) {
+               printf("%s help create|join|send", gargv[0]);
+               g_main_loop_quit(mainloop);
+               return FALSE;
+       }
+
+       if (g_strcmp0(gargv[1], "create") == 0) {
+               if (gargc == 3) {
+                       create(gargv[2], NULL);
+               } else if (gargc == 4) {
+                       create(gargv[2], gargv[3]);
+               }
+       }
+
+       if (g_strcmp0(gargv[1], "join") == 0) {
+               if (gargc == 3) {
+                       join(gargv[2], NULL);
+               } else if (gargc == 4) {
+                       join(gargv[2], gargv[3]);
+               }
+       }
+
+       if (g_strcmp0(gargv[1], "send") == 0) {
+               if (gargc > 4) {
+                       send(gargv[2]);
+               }
+       }
+
+       return FALSE;
+}
+
+int main(int argc, char **argv)
+{
+       aul_launch_init(NULL, NULL);
+
+       gargc = argc;
+       gargv = argv;
+
+       g_idle_add(run_func, NULL);
+
+       mainloop = g_main_loop_new(NULL, FALSE);
+       g_main_loop_run(mainloop);
+
+       return 0;
+}