1. apply systemd unit files
authorJaeho Lee <jaeho81.lee@samsung.com>
Thu, 25 Oct 2012 10:34:11 +0000 (19:34 +0900)
committerJaeho Lee <jaeho81.lee@samsung.com>
Thu, 25 Oct 2012 10:34:11 +0000 (19:34 +0900)
2. apply application process management

42 files changed:
CMakeLists.txt
agent/CMakeLists.txt [new file with mode: 0644]
agent/daemon-manager-launch-agent.c [new file with mode: 0644]
agent/daemon-manager-release-agent.c [new file with mode: 0755]
am_daemon/ac_daemon.c [new file with mode: 0755]
am_daemon/ac_status.c [new file with mode: 0755]
am_daemon/amd_appinfo.c [new file with mode: 0755]
am_daemon/amd_appinfo.h [new file with mode: 0755]
am_daemon/amd_cgutil.c [new file with mode: 0755]
am_daemon/amd_cgutil.h [new file with mode: 0755]
am_daemon/amd_config.h [new file with mode: 0755]
am_daemon/amd_key.c [new file with mode: 0755]
am_daemon/amd_key.h [new file with mode: 0755]
am_daemon/amd_launch.c [new file with mode: 0755]
am_daemon/amd_launch.h [new file with mode: 0755]
am_daemon/amd_main.c [new file with mode: 0755]
am_daemon/amd_request.c [new file with mode: 0755]
am_daemon/amd_request.h [new file with mode: 0755]
am_daemon/amd_status.c [new file with mode: 0755]
am_daemon/amd_status.h [new file with mode: 0755]
aul.manifest [new file with mode: 0644]
include/app_sock.h
include/aul.h
include/aul_util.h
include/menu_db_util.h
include/simple_util.h
launchpad_run
launchpad_src/launchpad.c
packaging/ac.service [new file with mode: 0644]
packaging/aul.spec
packaging/launchpad-preload@.service [new file with mode: 0644]
src/app_sock.c
src/launch.c
src/launch_with_result.c
src/mime.c
src/pkginfo.c
src/service.c
src/status.c [new file with mode: 0755]
test/CMakeLists.txt
test/aul_dbus.c
test/aul_dbus.h
test/dbusapp_test.c

index 1a37d91..c8978ca 100755 (executable)
@@ -22,8 +22,9 @@ MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
 # Set required packages
 INCLUDE(FindPkgConfig)
 
-pkg_check_modules(pkgs REQUIRED dlog ecore x11 libprivilege-control app-checker rua glib-2.0 ecore-x ecore-input evas)
+pkg_check_modules(pkgs REQUIRED dlog ecore x11 libprivilege-control app-checker rua glib-2.0 ecore-x ecore-input evas vconf pkgmgr-info)
 pkg_check_modules(libpkgs REQUIRED dlog bundle dbus-glib-1 ail xdgmime app-checker)
+PKG_CHECK_MODULES(PKGS REQUIRED glib-2.0 gio-2.0 dlog bundle)
 
 FIND_LIBRARY(LIB_DL dl)
 
@@ -43,6 +44,7 @@ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic")
 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_CFLAGS}")
 SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
 SET(CMAKE_C_FLAGS_RELEASE "-O2")
 
@@ -84,6 +86,7 @@ add_library(aul SHARED
                src/miregex.c
                src/app_signal.c
                src/key.c
+               src/status.c
                )
 target_link_libraries(aul aul_mods ${libpkgs_LDFLAGS})
 SET_TARGET_PROPERTIES(aul PROPERTIES SOVERSION ${VERSION_MAJOR})
@@ -102,6 +105,31 @@ set_target_properties(${AVATAR_NAME}
                PROPERTIES SKIP_BUILD_RPATH true
                ) # remove rpath option that is automatically generated by cmake.
 
+add_executable(amd
+                am_daemon/amd_main.c
+               am_daemon/amd_key.c
+               am_daemon/amd_request.c
+               am_daemon/amd_appinfo.c
+               am_daemon/amd_cgutil.c
+               am_daemon/amd_launch.c
+               am_daemon/amd_status.c
+                )
+target_link_libraries(amd aul_mods app-checker-server rua glib-2.0 bundle ail aul utilX ${pkgs_LDFLAGS})
+
+SET(REL_AGENT daemon-manager-release-agent)
+ADD_EXECUTABLE(${REL_AGENT} agent/${REL_AGENT}.c)
+TARGET_LINK_LIBRARIES(${REL_AGENT} ${PKGS_LDFLAGS} aul aul_mods)
+SET_TARGET_PROPERTIES(${REL_AGENT} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
+
+INSTALL(TARGETS ${REL_AGENT} DESTINATION bin)
+
+SET(LAUNCH_AGENT daemon-manager-launch-agent)
+ADD_EXECUTABLE(${LAUNCH_AGENT} agent/${LAUNCH_AGENT}.c)
+TARGET_LINK_LIBRARIES(${LAUNCH_AGENT} ${PKGS_LDFLAGS})
+SET_TARGET_PROPERTIES(${LAUNCH_AGENT} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
+
+INSTALL(TARGETS ${LAUNCH_AGENT} DESTINATION bin)
+
 
 
 # pkgconfig file
@@ -111,6 +139,7 @@ CONFIGURE_FILE(aul.pc.in aul.pc @ONLY)
 ### Install ###
 INSTALL(TARGETS aul DESTINATION lib COMPONENT RuntimeLibraries)
 INSTALL(TARGETS ${AVATAR_NAME} DESTINATION bin)
+INSTALL(TARGETS amd DESTINATION bin)
 
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/aul.h DESTINATION include/aul)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/aul_service.h DESTINATION include/aul)
diff --git a/agent/CMakeLists.txt b/agent/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4f9a22d
--- /dev/null
@@ -0,0 +1,16 @@
+
+STRING(REPLACE ";" " " EXTRA_CFLAGS "${PKGS_CFLAGS}")
+
+SET(REL_AGENT daemon-manager-release-agent)
+ADD_EXECUTABLE(${REL_AGENT} ${REL_AGENT}.c)
+TARGET_LINK_LIBRARIES(${REL_AGENT} ${PKGS_LDFLAGS})
+SET_TARGET_PROPERTIES(${REL_AGENT} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
+
+INSTALL(TARGETS ${REL_AGENT} DESTINATION bin)
+
+SET(LAUNCH_AGENT daemon-manager-launch-agent)
+ADD_EXECUTABLE(${LAUNCH_AGENT} ${LAUNCH_AGENT}.c)
+TARGET_LINK_LIBRARIES(${LAUNCH_AGENT} ${PKGS_LDFLAGS})
+SET_TARGET_PROPERTIES(${LAUNCH_AGENT} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
+
+INSTALL(TARGETS ${LAUNCH_AGENT} DESTINATION bin)
diff --git a/agent/daemon-manager-launch-agent.c b/agent/daemon-manager-launch-agent.c
new file mode 100644 (file)
index 0000000..8f93c32
--- /dev/null
@@ -0,0 +1,98 @@
+#include <glib.h>
+#include <gio/gio.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#define DAEMON_MANAGER_NAME "org.tizen.DaemonManager"
+#define DAEMON_MANAGER_PATH "/org/tizen/DaemonManager"
+#define DAEMON_MANAGER_INTERFACE "org.tizen.DaemonManager"
+
+#define METHOD_RELEASED "Start"
+
+#define BUS_TYPE G_BUS_TYPE_SYSTEM
+
+#define LOG_PATH "/tmp/dmlaunch.err"
+
+static void elog(const char *fmt, ...)
+{
+       FILE *fp;
+       va_list ap;
+
+       fp = fopen(LOG_PATH, "w+");
+       if (!fp)
+               return;
+
+       va_start(ap, fmt);
+       vfprintf(fp, fmt, ap);
+       va_end(ap);
+
+       fclose(fp);
+}
+
+int main(int argc, char *argv[])
+{
+       GError *err;
+       GDBusProxy *proxy = NULL;
+       GDBusConnection *conn = NULL;
+       GVariant *res = NULL;
+
+       if (argc < 2) {
+               elog("usage) %s path\n", argv[0]);
+               return 1;
+       }
+
+       g_type_init();
+
+       /* TODO: use private bus? */
+       err = NULL;
+       conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+       if (!conn) {
+               elog("Connection failed: %s\n", err ? err->message : "");
+               goto err;
+       }
+
+       err = NULL;
+       proxy = g_dbus_proxy_new_sync(conn,
+                       G_DBUS_PROXY_FLAGS_NONE,
+                       NULL,
+                       DAEMON_MANAGER_NAME,
+                       DAEMON_MANAGER_PATH,
+                       DAEMON_MANAGER_INTERFACE,
+                       NULL,
+                       &err);
+       if (!proxy) {
+               elog("Proxy new: %s\n", err ? err->message : "");
+               goto err;
+       }
+
+       err = NULL;
+       res = g_dbus_proxy_call_sync(proxy,
+                       METHOD_RELEASED,
+                       g_variant_new("(s)", argv[1]),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       &err);
+       if (!res) {
+               elog("Call error: %s\n", err ? err->message : "");
+               goto err;
+       }
+
+err:
+       if (res)
+               g_variant_unref(res);
+
+       if (proxy)
+               g_object_unref(proxy);
+
+       if (conn)
+               g_object_unref(conn);
+
+       if (err) {
+               g_clear_error(&err);
+               return 1;
+       }
+
+       return 0;
+}
+
diff --git a/agent/daemon-manager-release-agent.c b/agent/daemon-manager-release-agent.c
new file mode 100755 (executable)
index 0000000..203529f
--- /dev/null
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include "app_sock.h"
+#include "aul_util.h"
+
+#define LOG_PATH "/tmp/dmlaunch.err"
+
+static void elog(const char *fmt, ...)
+{
+       FILE *fp;
+       va_list ap;
+
+       fp = fopen(LOG_PATH, "w+");
+       if (!fp)
+               return;
+
+       va_start(ap, fmt);
+       vfprintf(fp, fmt, ap);
+       va_end(ap);
+
+       fclose(fp);
+}
+
+
+int main(int argc, char *argv[])
+{
+       int ret = 0;
+
+       elog("release agent : [%d:%s]\n", argc, argv[1]);
+
+       if (argc < 2) {
+               elog("usage) %s path\n", argv[0]);
+               return 1;
+       }
+
+       ret = __app_send_raw(AUL_UTIL_PID, APP_RELEASED, (unsigned char*)argv[1], strlen(argv[1]));
+
+       elog("release agent : %d\n", ret);
+
+       return 0;
+}
+
diff --git a/am_daemon/ac_daemon.c b/am_daemon/ac_daemon.c
new file mode 100755 (executable)
index 0000000..c745b79
--- /dev/null
@@ -0,0 +1,659 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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 <stdio.h>
+#include <glib.h>
+#include <stdbool.h>
+#include <app-checker-server.h>
+#include <rua.h>
+#include <bundle.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <poll.h>
+#include <ail.h>
+#include <aul.h>
+#include <vconf.h>
+
+#include "simple_util.h"
+#include "app_sock.h"
+#include "aul_util.h"
+#include "menu_db_util.h"
+
+#include <Ecore_X.h>
+#include <Ecore_Input.h>
+#include <utilX.h>
+#include <Ecore.h>
+#include <Evas.h>
+
+static struct {
+       Evas_Object *win;
+       Ecore_Event_Handler *key_up;
+       Ecore_Event_Handler *key_down;
+} key_info = {
+       .win = NULL,
+       .key_up = NULL,
+       .key_down = NULL,
+};
+
+typedef struct _r_app_info_t{
+       char pkg_name[MAX_PACKAGE_STR_SIZE];
+       int pid;
+} r_app_info_t;
+
+GSList *key_pid_list = NULL;
+GSList *r_app_info_list = NULL;
+
+extern int app_send_cmd(int pid, int cmd, bundle *kb);\r
+
+static int __send_to_sigkill(int pid)
+{
+       int pgid;
+
+       pgid = getpgid(pid);
+       if (pgid <= 1)
+               return -1;
+
+       if (killpg(pgid, SIGKILL) < 0)
+               return -1;
+
+       return 0;
+}
+
+static int __kill_bg_apps(int limit)
+{
+       int len;
+       int i;
+       int n;
+       r_app_info_t *info_t = NULL;
+       GSList *iter = NULL;
+
+       len = g_slist_length(r_app_info_list);
+
+       n = len - limit;
+
+       if (n<=0) return 0;
+
+       for ( i=0, iter = r_app_info_list; i<n ; i++) {
+               info_t = (r_app_info_t *)iter->data;
+               __send_to_sigkill(info_t->pid);
+               iter = g_slist_next(iter);
+               r_app_info_list = g_slist_remove(r_app_info_list, info_t);
+               free(info_t);
+       }
+
+}
+
+static int __remove_item_running_list(int pid)
+{
+       r_app_info_t *info_t = NULL;
+       GSList *iter = NULL;
+
+       for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (r_app_info_t *)iter->data;
+               if(pid == info_t->pid) {
+                       r_app_info_list = g_slist_remove(r_app_info_list, info_t);
+                       free(info_t);
+                       break;
+               }
+       }
+       return 0;
+}
+
+static int __add_item_running_list(char *pkgname, int pid)
+{
+       bool taskmanage;
+       ail_appinfo_h handle;
+       ail_error_e ail_ret;
+       r_app_info_t *info_t = NULL;
+       GSList *iter = NULL;
+       int found = 0;
+       int limit;
+       int ret;
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS, &limit);
+
+       if (pkgname == NULL) {
+               return -1;
+       } else if (strncmp(pkgname, "org.tizen.cluster-home", 24) == 0) {
+               if(limit>0) __kill_bg_apps(limit-1);
+               return 0;
+       }
+
+       ail_ret = ail_package_get_appinfo(pkgname, &handle);
+       if (ail_ret != AIL_ERROR_OK) {
+               _E("ail_get_appinfo with %s failed", pkgname);
+               return -1;
+       }
+
+       ail_ret = ail_appinfo_get_bool(handle, AIL_PROP_X_SLP_TASKMANAGE_BOOL, &taskmanage);
+       if (ail_ret != AIL_ERROR_OK) {
+               _E("ail_appinfo_get_bool failed");
+               return -1;
+       }
+
+       if (taskmanage == false)
+               return -1;
+
+       for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (r_app_info_t *)iter->data;
+               _D("inter pkgname : %s, pid : %d, input : %d", info_t->pkg_name, info_t->pid, pid);
+               if(pid == info_t->pid) {
+                       found = 1;
+                       r_app_info_list = g_slist_remove(r_app_info_list, info_t);
+                       r_app_info_list = g_slist_append(r_app_info_list, info_t);
+                       break;
+               }
+       }
+       if(found == 0) {
+               info_t = malloc(sizeof(r_app_info_t));
+               strncpy(info_t->pkg_name, pkgname, MAX_PACKAGE_STR_SIZE-1);
+               info_t->pid = pid;
+               r_app_info_list = g_slist_append(r_app_info_list, info_t);
+       }
+
+       for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (r_app_info_t *)iter->data;
+               _D("running list(before kill) : %s", info_t->pkg_name);
+       }
+
+       if(limit>0) __kill_bg_apps(limit);
+
+       for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (r_app_info_t *)iter->data;
+               _D("running list(after kill) : %s", info_t->pkg_name);
+       }
+
+       if (ail_destroy_appinfo(handle) != AIL_ERROR_OK)
+               _E("ail_destroy_rs failed");
+
+       return 0;
+}
+
+static gboolean __add_history_handler(gpointer user_data)
+{
+       struct rua_rec rec;
+       int ret;
+       app_pkt_t *pkt = (app_pkt_t *)user_data;
+       struct history_data *hd = (struct history_data *)pkt->data;
+
+       ret = rua_init();
+
+       memset(&rec, 0, sizeof(rec));
+
+       rec.pkg_name = hd->pkg_name;
+       rec.app_path = hd->app_path;
+
+       if(hd->len > 0) {
+               rec.arg = (char *)hd->data;
+       }
+
+       _D("add rua history %s %s", rec.pkg_name, rec.app_path);
+
+       ret = rua_add_history(&rec);
+       if (ret == -1)
+               _D("rua add history error");
+
+       __add_item_running_list(hd->pkg_name, hd->pid);
+
+       free(pkt);
+
+       ret = rua_fini();
+
+       return false;
+}
+
+int __send_result_to_client(int fd, int res)
+{
+       if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
+               if (errno == EPIPE)
+                       _E("send failed due to EPIPE.\n");
+               _E("send fail to client");
+       }
+       close(fd);
+       return 0;
+}
+
+static int __get_pkginfo(const char *dname, const char *cmdline, void *priv)
+{
+       app_info_from_db *menu_info;
+       char *r_info;
+
+       r_info = (char *)priv;
+
+       if ((menu_info = _get_app_info_from_db_by_apppath(cmdline)) == NULL)
+               goto out;
+       else {
+               strncat(r_info, dname, 8);
+               strncat(r_info, ":", 1);
+               strncat(r_info, _get_pkgname(menu_info), MAX_PACKAGE_STR_SIZE);
+               strncat(r_info, ":", 1);
+               strncat(r_info, _get_app_path(menu_info), MAX_PACKAGE_APP_PATH_SIZE);
+               strncat(r_info, ";", 1);
+       }
+
+ out:
+       if (menu_info != NULL)
+               _free_app_info_from_db(menu_info);
+       return 0;
+}
+
+int __send_running_appinfo(int fd)
+{
+       app_pkt_t *pkt = NULL;
+       int len;
+
+       pkt = (app_pkt_t *) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
+       if(!pkt) {
+               _E("malloc fail");
+               return 0;
+       }
+
+       memset(pkt, 0, AUL_SOCK_MAXBUFF);
+
+       __proc_iter_cmdline(__get_pkginfo, pkt->data);
+
+       pkt->cmd = APP_RUNNING_INFO_RESULT;
+       pkt->len = strlen((char *)pkt->data) + 1;
+
+       if ((len = send(fd, pkt, pkt->len + 8, 0)) != pkt->len + 8) {
+               if (errno == EPIPE)
+                       _E("send failed due to EPIPE.\n");
+               _E("send fail to client");
+       }
+
+       if(pkt)
+               free(pkt);
+
+       close(fd);
+       return 0;
+}
+
+int __app_is_running(const char *pkgname)
+{
+       char *apppath = NULL;
+       ail_appinfo_h handle;
+       ail_error_e ail_ret;
+
+       int ret = 0;
+       int i = 0;
+
+       if (pkgname == NULL)
+               return 0;
+
+       ail_ret = ail_package_get_appinfo(pkgname, &handle);
+       if (ail_ret != AIL_ERROR_OK) {
+               _E("ail_get_appinfo with %s failed", pkgname);
+               return ret;
+       }
+
+       ail_ret = ail_appinfo_get_str(handle, AIL_PROP_EXEC_STR, &apppath);
+       if (ail_ret != AIL_ERROR_OK) {
+               _E("ail_appinfo_get_str failed");
+               goto out;
+       }
+
+       if (apppath == NULL)
+               goto out;
+
+       /*truncate apppath if it includes default bundles */
+       while (apppath[i] != 0) {
+               if (apppath[i] == ' ' || apppath[i] == '\t') {
+                       apppath[i]='\0';
+                       break;
+               }
+               i++;
+       }
+
+       if (__proc_iter_cmdline(NULL, apppath) > 0)
+               ret = 1;
+       else
+               ret = 0;
+
+ out:
+       if (ail_destroy_appinfo(handle) != AIL_ERROR_OK)
+               _E("ail_destroy_rs failed");
+       return ret;
+}
+
+static int __register_key_event(int pid)
+{
+       int *pid_data;
+       GSList *entry;
+
+       pid_data = malloc(sizeof(int));
+       *pid_data = pid;
+
+       key_pid_list = g_slist_prepend(key_pid_list, pid_data);
+
+       _D("===key stack===");
+
+       for (entry = key_pid_list; entry; entry = entry->next) {
+               if (entry->data) {
+                       pid_data = (int *) entry->data;
+                       _D("pid : %d",*pid_data);
+               }
+       }
+
+       return 0;
+}
+
+static int __unregister_key_event(int pid)
+{
+       GSList *entry;
+       int *pid_data;
+
+       for (entry = key_pid_list; entry; entry = entry->next) {
+               if (entry->data) {
+                       pid_data = (int *) entry->data;
+                       if(pid == *pid_data) {
+                               key_pid_list = g_slist_remove(key_pid_list, entry->data);
+                               free(pid_data);
+                       }
+               }
+       }
+
+       _D("===key stack===");
+
+       for (entry = key_pid_list; entry; entry = entry->next) {
+               if (entry->data) {
+                       pid_data = (int *) entry->data;
+                       _D("pid : %d",*pid_data);
+               }
+       }
+
+       return 0;
+}
+
+static gboolean __util_handler(gpointer data)
+{
+       GPollFD *gpollfd = (GPollFD *) data;
+       int fd = gpollfd->fd;
+       app_pkt_t *pkt;
+       int clifd;
+       struct ucred cr;
+       struct history_data *hd;
+       int *status;
+       int ret = -1;
+       char pkgname[MAX_PACKAGE_STR_SIZE];
+
+       if ((pkt = __app_recv_raw(fd, &clifd, &cr)) == NULL) {
+               _E("recv error");
+               return FALSE;
+       }
+
+       switch (pkt->cmd) {
+       case APP_ADD_HISTORY:
+               hd = (struct history_data *)pkt->data;
+               _D("cmd : %d, pkgname : %s, app_path : %s", pkt->cmd, hd->pkg_name, hd->app_path);
+               __send_result_to_client(clifd, 0);
+               _add_app_status_info_list(hd->pkg_name, hd->pid);
+               g_timeout_add(1000, __add_history_handler, pkt);
+               break;
+       case APP_RUNNING_INFO:
+               __send_running_appinfo(clifd);
+               free(pkt);
+               break;
+       case APP_IS_RUNNING:
+               strncpy(pkgname, (const char*)pkt->data, MAX_PACKAGE_STR_SIZE-1);
+               ret = __app_is_running(pkgname);
+               __send_result_to_client(clifd, ret);
+               free(pkt);
+               break;
+       case APP_KEY_RESERVE:
+               ret = __register_key_event(cr.pid);
+               __send_result_to_client(clifd, ret);
+               free(pkt);
+               break;
+       case APP_KEY_RELEASE:
+               ret = __unregister_key_event(cr.pid);
+               __send_result_to_client(clifd, ret);
+               free(pkt);
+               break;
+       case APP_STATUS_UPDATE:
+               status = (int *)pkt->data;
+               ret = _update_app_status_info_list(cr.pid, *status);
+               __send_result_to_client(clifd, ret);
+               free(pkt);
+       default:
+               _E("no support packet");
+       }
+
+       return TRUE;
+}
+
+static gboolean __au_glib_check(GSource *src)
+{
+       GSList *fd_list;
+       GPollFD *tmp;
+
+       fd_list = src->poll_fds;
+       do {
+               tmp = (GPollFD *) fd_list->data;
+               if ((tmp->revents & (POLLIN | POLLPRI)))
+                       return TRUE;
+               fd_list = fd_list->next;
+       } while (fd_list);
+
+       return FALSE;
+}
+
+static gboolean __au_glib_dispatch(GSource *src, GSourceFunc callback,
+                                 gpointer data)
+{
+       callback(data);
+       return TRUE;
+}
+
+static gboolean __au_glib_prepare(GSource *src, gint *timeout)
+{
+       return FALSE;
+}
+
+static GSourceFuncs funcs = {
+       .prepare = __au_glib_prepare,
+       .check = __au_glib_check,
+       .dispatch = __au_glib_dispatch,
+       .finalize = NULL
+};
+
+static Eina_Bool _key_release_cb(void *data, int type, void *event)
+{
+       Evas_Event_Key_Up *ev = event;
+       int ret;
+       GSList *entry;
+       int *pid_data;
+       bundle *kb;
+
+       _D("Released");
+
+       if (!ev) {
+               _D("Invalid event object");
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       entry = key_pid_list;
+       if (entry && entry->data) {
+               pid_data = (int *) entry->data;
+
+               kb = bundle_create();
+               bundle_add(kb, AUL_K_MULTI_KEY, ev->keyname);
+               bundle_add(kb, AUL_K_MULTI_KEY_EVENT, AUL_V_KEY_RELEASED);
+
+               ret = app_send_cmd(*pid_data, APP_KEY_EVENT, kb);
+
+               bundle_free(kb);
+       }
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+
+static Eina_Bool _key_press_cb(void *data, int type, void *event)
+{
+       Evas_Event_Key_Down *ev = event;
+       int ret;
+       GSList *entry;
+       int *pid_data;
+       bundle *kb;
+
+       _D("Pressed");
+
+       if (!ev) {
+               _D("Invalid event object");
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       entry = key_pid_list;
+       if (entry && entry->data) {
+               pid_data = (int *) entry->data;
+
+               kb = bundle_create();
+               bundle_add(kb, AUL_K_MULTI_KEY, ev->keyname);
+               bundle_add(kb, AUL_K_MULTI_KEY_EVENT, AUL_V_KEY_PRESSED);
+
+               ret = app_send_cmd(*pid_data, APP_KEY_EVENT, kb);
+
+               bundle_free(kb);
+       }
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+static int __app_dead_handler(int pid, void *data)
+{
+       int ret;
+
+       ret = __unregister_key_event(pid);
+       ret = __remove_item_running_list(pid);
+       ret = _remove_app_status_info_list(pid);
+
+       return 0;
+}
+
+static void __ac_key_initailize()
+{
+       key_info.win = ecore_x_window_input_new(0, 0, 0, 1, 1);
+       if (!key_info.win) {
+               _D("Failed to create hidden window");
+       }
+
+       ecore_x_icccm_title_set(key_info.win, "acdaemon,key,receiver");
+       ecore_x_netwm_name_set(key_info.win, "acdaemon,key,receiver");
+       ecore_x_netwm_pid_set(key_info.win, getpid());
+
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_PLAYCD, EXCLUSIVE_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_STOPCD, EXCLUSIVE_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_PAUSECD, EXCLUSIVE_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_NEXTSONG, EXCLUSIVE_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_PREVIOUSSONG, EXCLUSIVE_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_REWIND, EXCLUSIVE_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_FASTFORWARD, EXCLUSIVE_GRAB);
+
+       key_info.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, NULL);
+       if (!key_info.key_up) {
+               _D("Failed to register a key up event handler");
+       }
+
+       key_info.key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, NULL);
+       if (!key_info.key_down) {
+               _D("Failed to register a key down event handler");
+       }
+
+       aul_listen_app_dead_signal(__app_dead_handler, NULL);
+}
+
+static void __vconf_cb(keynode_t *key, void *data)
+{
+       int limit;
+       const char *name;
+
+       name = vconf_keynode_get_name(key);
+       if( name == NULL ) {
+               return;
+       } else if ( strcmp(name, VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS) != 0)
+       {
+               return;
+       }
+
+       limit = vconf_keynode_get_int(key);
+       if(limit>0) __kill_bg_apps(limit);
+}
+
+static int __initialize()
+{
+       int fd;
+       int r;
+       GPollFD *gpollfd;
+       GSource *src;
+
+       fd = __create_server_sock(AUL_UTIL_PID);
+
+       src = g_source_new(&funcs, sizeof(GSource));
+
+       gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
+       gpollfd->events = POLLIN;
+       gpollfd->fd = fd;
+
+       g_source_add_poll(src, gpollfd);
+       g_source_set_callback(src, (GSourceFunc) __util_handler,
+                             (gpointer) gpollfd, NULL);
+       g_source_set_priority(src, G_PRIORITY_DEFAULT);
+
+       r = g_source_attach(src, NULL);
+       if (r  == 0)
+       {
+               /* TODO: error handle*/
+               return AC_R_ERROR;
+       }
+
+       __ac_key_initailize();
+
+       r = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS, __vconf_cb, NULL);
+
+       return AC_R_OK;
+}
+
+int main(int argc, char *argv[])
+{
+       int ret;
+
+       ecore_init();
+       evas_init();
+       ecore_event_init();
+       ecore_x_init(NULL);
+
+       ret = ac_server_initailize();
+
+       ret = __initialize();
+
+       ecore_main_loop_begin();
+
+       return 0;
+}
diff --git a/am_daemon/ac_status.c b/am_daemon/ac_status.c
new file mode 100755 (executable)
index 0000000..6507b24
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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 <stdlib.h>
+#include <glib.h>
+#include <aul.h>
+#include "aul_util.h"
+#include "simple_util.h"
+
+GSList *app_status_info_list = NULL;
+
+int _add_app_status_info_list(char *appid, int pid)
+{
+       GSList *iter = NULL;
+       app_status_info_t *info_t = NULL;
+
+       for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (app_status_info_t *)iter->data;
+               if(pid == info_t->pid) {
+                       return 0;
+               }
+       }
+
+       info_t = malloc(sizeof(app_status_info_t));
+       strncpy(info_t->appid, appid, MAX_PACKAGE_STR_SIZE-1);
+       info_t->status = STATUS_LAUNCHING;
+       info_t->pid = pid;
+       app_status_info_list = g_slist_append(app_status_info_list, info_t);
+
+       for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (app_status_info_t *)iter->data;
+
+               _D("%s, %d, %d", info_t->appid, info_t->pid, info_t->status);
+       }
+
+       return 0;
+}
+
+int _update_app_status_info_list(int pid, int status)
+{
+       GSList *iter = NULL;
+       app_status_info_t *info_t = NULL;
+
+       for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (app_status_info_t *)iter->data;
+               if(pid == info_t->pid) {
+                       info_t->status = status;
+                       break;
+               }
+       }
+
+       for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (app_status_info_t *)iter->data;
+
+               _D("%s, %d, %d", info_t->appid, info_t->pid, info_t->status);
+       }
+
+       return 0;
+}
+
+int _remove_app_status_info_list(int pid)
+{
+       GSList *iter = NULL;
+       app_status_info_t *info_t = NULL;
+
+       for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (app_status_info_t *)iter->data;
+               if(pid == info_t->pid) {
+                       app_status_info_list = g_slist_remove(app_status_info_list, info_t);
+                       free(info_t);
+                       break;
+               }
+       }
+
+       for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (app_status_info_t *)iter->data;
+
+               _D("%s, %d, %d", info_t->appid, info_t->pid, info_t->status);
+       }
+
+       return 0;
+}
+
diff --git a/am_daemon/amd_appinfo.c b/am_daemon/amd_appinfo.c
new file mode 100755 (executable)
index 0000000..77b90da
--- /dev/null
@@ -0,0 +1,425 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <glib.h>
+#include <dirent.h>
+
+#include <pkgmgr-info.h>
+#include <vconf.h>
+#include "amd_config.h"
+#include "simple_util.h"
+#include "amd_appinfo.h"
+
+
+#define SERVICE_GROUP "Service"
+
+struct appinfomgr {
+       GHashTable *tbl; /* key is filename, value is struct appinfo */
+};
+
+enum _appinfo_idx {
+       _AI_FILE = 0, /* service filename */
+       _AI_NAME,
+       _AI_COMP,
+       _AI_EXEC,
+       _AI_TYPE,
+       _AI_ONBOOT,
+       _AI_RESTART,
+       _AI_MULTI,
+       _AI_MAX,
+};
+#define _AI_START _AI_NAME /* start index */
+
+struct appinfo_t {
+       char *name;
+       enum appinfo_type type;
+};
+
+static struct appinfo_t _appinfos[] = {
+       [_AI_NAME] = { "Name", AIT_NAME, },
+       [_AI_COMP] = { "Component", AIT_COMP, },
+       [_AI_EXEC] = { "Exec", AIT_EXEC, },
+       [_AI_TYPE] = { "PkgType", AIT_TYPE, },
+       [_AI_ONBOOT] = { "StartOnBoot", AIT_ONBOOT, },
+       [_AI_RESTART] = { "AutoRestart", AIT_RESTART, },
+       [_AI_MULTI] = { "Multiple", AIT_MULTI, },
+};
+
+struct appinfo {
+       char *val[_AI_MAX];
+};
+
+static void _free_appinfo(gpointer data)
+{
+       struct appinfo *c = data;
+       int i;
+
+       if (!c)
+               return;
+
+       for (i = 0; i < sizeof(c->val)/sizeof(c->val[0]); i++)
+               free(c->val[i]);
+
+       free(c);
+}
+
+static void _fini(struct appinfomgr *cf)
+{
+       assert(cf);
+
+       g_hash_table_destroy(cf->tbl);
+       free(cf);
+}
+
+pkgmgrinfo_pkginfo_h p_handle;
+
+static int __svc_app_info_insert_handler (const pkgmgrinfo_appinfo_h handle, void *data)
+{
+       struct appinfo *c;
+       struct appinfomgr *cf = (struct appinfomgr *)data;
+       gboolean r;
+       char *exec;
+       char *type;
+       bool onboot;
+       bool restart;
+       char *appid;
+
+       pkgmgrinfo_appinfo_get_appid(handle, &appid);
+
+       g_hash_table_remove(cf->tbl, appid);
+
+       c = calloc(1, sizeof(*c));
+       if (!c) {
+               _E("create appinfo: %s", strerror(errno));
+               return -1;
+       }
+
+       memset(c, 0, sizeof(struct appinfo));
+
+       c->val[_AI_FILE] = strdup(appid);
+       if (!c->val[_AI_FILE]) {
+               _E("create appinfo: %s", strerror(errno));
+               _free_appinfo(c);
+               return -1;
+       }
+
+       c->val[_AI_NAME] = strdup(appid); //TODO :
+
+       c->val[_AI_COMP] = strdup("svc"); //TODO :
+
+       r = pkgmgrinfo_appinfo_get_exec(handle, &exec);
+       c->val[_AI_EXEC] = strdup(exec);
+
+       r = pkgmgrinfo_pkginfo_get_type(p_handle, &type);
+       c->val[_AI_TYPE] = strdup(type);
+
+       r = pkgmgrinfo_appinfo_is_onboot(handle, &onboot);
+       if(onboot == true)
+               c->val[_AI_ONBOOT] = strdup("true");
+       else c->val[_AI_ONBOOT] = strdup("false");
+
+       r = pkgmgrinfo_appinfo_is_autorestart(handle, &restart);
+       if(restart == true)
+               c->val[_AI_RESTART] = strdup("true");
+       else c->val[_AI_RESTART] = strdup("false");
+
+       _D("%s : %s : %s : %s : %s", c->val[_AI_FILE], c->val[_AI_COMP], c->val[_AI_TYPE], c->val[_AI_ONBOOT], c->val[_AI_RESTART]);
+
+       g_hash_table_insert(cf->tbl, c->val[_AI_FILE], c);
+
+       return 0;
+}
+
+static int __ui_app_info_insert_handler (const pkgmgrinfo_appinfo_h handle, void *data)
+{
+       struct appinfo *c;
+       struct appinfomgr *cf = (struct appinfomgr *)data;
+       gboolean r;
+       char *exec;
+       char *type;
+       bool multiple;
+       char *appid;
+
+       pkgmgrinfo_appinfo_get_appid(handle, &appid);
+
+       g_hash_table_remove(cf->tbl, appid);
+
+       c = calloc(1, sizeof(*c));
+       if (!c) {
+               _E("create appinfo: %s", strerror(errno));
+               return -1;
+       }
+
+       memset(c, 0, sizeof(struct appinfo));
+
+       c->val[_AI_FILE] = strdup(appid);
+       if (!c->val[_AI_FILE]) {
+               _E("create appinfo: %s", strerror(errno));
+               _free_appinfo(c);
+               return -1;
+       }
+
+       c->val[_AI_NAME] = strdup(appid); //TODO :
+
+       c->val[_AI_COMP] = strdup("ui"); //TODO :
+
+       r = pkgmgrinfo_appinfo_get_exec(handle, &exec);
+       c->val[_AI_EXEC] = strdup(exec);
+
+       r = pkgmgrinfo_pkginfo_get_type(p_handle, &type);
+       c->val[_AI_TYPE] = strdup(type);
+
+       r = pkgmgrinfo_appinfo_is_multiple(handle, &multiple);
+       if(multiple == true)
+               c->val[_AI_MULTI] = strdup("true");
+       else c->val[_AI_MULTI] = strdup("false");
+
+       _D("%s : %s : %s : %s", c->val[_AI_FILE], c->val[_AI_COMP], c->val[_AI_TYPE], c->val[_AI_MULTI]);
+
+       g_hash_table_insert(cf->tbl, c->val[_AI_FILE], c);
+
+       return 0;
+}
+
+static int __app_info_delete_handler (const pkgmgrinfo_appinfo_h handle, void *data)
+{
+       struct appinfomgr *cf = (struct appinfomgr *)data;
+       char *appid;
+
+       pkgmgrinfo_appinfo_get_appid(handle, &appid);
+
+       g_hash_table_remove(cf->tbl, appid);
+
+       return 0;
+}
+
+static int __pkg_info_handler(const pkgmgrinfo_pkginfo_h handle, void *data)
+{
+       int r;
+
+       p_handle = handle;
+       r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_SVC_APP, __svc_app_info_insert_handler, data);
+       r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_UI_APP, __ui_app_info_insert_handler, data);
+
+       return 0;
+}
+
+static int _read_pkg_info(struct appinfomgr *cf)
+{
+       int r;
+
+       r = pkgmgrinfo_pkginfo_get_list(__pkg_info_handler, cf);
+
+       return 0;
+}
+
+static struct appinfomgr *_init()
+{
+       struct appinfomgr *cf;
+
+       cf = calloc(1, sizeof(*cf));
+       if (!cf) {
+               _E("appinfo init: %s", strerror(errno));
+               return NULL;
+       }
+
+       cf->tbl = g_hash_table_new_full(g_str_hash, g_str_equal,
+                       NULL, _free_appinfo);
+
+       return cf;
+}
+
+static void __vconf_cb(keynode_t *key, void *data)
+{
+       char *noti_string;
+       char *type_string;
+       char *appid;
+       char *saveptr;
+       pkgmgrinfo_appinfo_h handle;
+       pkgmgrinfo_app_component component;
+       struct appinfomgr *cf = (struct appinfomgr *)data;
+
+       noti_string = vconf_keynode_get_str(key);
+       if( noti_string == NULL ) {
+               return;
+       }
+
+       _D("noti_string : %s",noti_string);
+
+       type_string = strtok_r(noti_string, ":", &saveptr);
+       appid = strtok_r(NULL, ":", &saveptr);
+
+       if ( strncmp(type_string, "create", 6) == 0) {
+               pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
+
+               _D("appid : %s /handle : %x", appid, handle);
+               pkgmgrinfo_appinfo_get_component(handle, &component);
+
+               if(component == PMINFO_UI_APP) {
+                       __ui_app_info_insert_handler(handle, data);
+               } else if (component == PMINFO_SVC_APP) {
+                       __svc_app_info_insert_handler(handle, data);
+               }
+
+               pkgmgrinfo_appinfo_destroy_appinfo(handle);
+       } else if ( strncmp(type_string, "delete", 6) == 0) {
+               g_hash_table_remove(cf->tbl, appid);
+       }
+}
+
+int appinfo_init(struct appinfomgr **cf)
+{
+       struct appinfomgr *_cf;
+       int r;
+
+       if (!cf) {
+               errno = EINVAL;
+               _E("appinfo init: %s", strerror(errno));
+               return -1;
+       }
+
+       _cf = _init();
+       if (!_cf)
+               return -1;
+
+       r = _read_pkg_info(_cf);
+       if (r == -1) {
+               _fini(_cf);
+               return -1;
+       }
+
+       r = vconf_notify_key_changed("memory/menuscreen/desktop", __vconf_cb, _cf);
+
+       *cf = _cf;
+
+       return 0;
+}
+
+void appinfo_fini(struct appinfomgr **cf)
+{
+       if (!cf || !*cf)
+               return;
+
+       _fini(*cf);
+       *cf = NULL;
+}
+
+const struct appinfo *appinfo_insert(struct appinfomgr *cf, const char *pkg_name)
+{
+       int r;
+       pkgmgrinfo_pkginfo_h handle;
+
+       r = pkgmgrinfo_pkginfo_get_pkginfo(pkg_name, &handle);
+       p_handle = handle;
+       r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_SVC_APP, __svc_app_info_insert_handler, cf);
+       r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_UI_APP, __ui_app_info_insert_handler, cf);
+       pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+
+       return cf;
+}
+
+void appinfo_delete(struct appinfomgr *cf, const char *pkg_name)
+{
+       int r;
+       pkgmgrinfo_pkginfo_h handle;
+
+       r = pkgmgrinfo_pkginfo_get_pkginfo(pkg_name, &handle);
+       r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_SVC_APP, __app_info_delete_handler, cf);
+       r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_UI_APP, __app_info_delete_handler, cf);
+       pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+}
+
+const struct appinfo *appinfo_find(struct appinfomgr *cf, const char *filename)
+{
+       if (!cf || !filename || !*filename) {
+               errno = EINVAL;
+               _E("appinfo find: %s", strerror(errno));
+               return NULL;
+       }
+
+       return g_hash_table_lookup(cf->tbl, FILENAME(filename));
+}
+
+const char *appinfo_get_value(const struct appinfo *c, enum appinfo_type type)
+{
+       enum _appinfo_idx i;
+
+       if (!c) {
+               errno = EINVAL;
+               _E("appinfo get value: %s", strerror(errno));
+               return NULL;
+       }
+
+       for (i = _AI_START; i < sizeof(_appinfos)/sizeof(_appinfos[0]); i++) {
+               if (type == _appinfos[i].type)
+                       return c->val[i];
+       }
+
+       errno = ENOENT;
+       _E("appinfo get value: %s", strerror(errno));
+
+       return NULL;
+}
+
+const char *appinfo_get_filename(const struct appinfo *c)
+{
+       if (!c) {
+               errno = EINVAL;
+               _E("appinfo get filename: %s", strerror(errno));
+               return NULL;
+       }
+
+       return c->val[_AI_FILE];
+}
+
+struct _cbinfo {
+       appinfo_iter_callback cb;
+       void *cb_data;
+};
+
+static void _iter_cb(gpointer key, gpointer value, gpointer user_data)
+{
+       struct _cbinfo *cbi = user_data;
+
+       assert(cbi);
+
+       cbi->cb(cbi->cb_data, key, value);
+}
+
+void appinfo_foreach(struct appinfomgr *cf, appinfo_iter_callback cb, void *user_data)
+{
+       struct _cbinfo cbi;
+
+       if (!cf || !cb) {
+               errno = EINVAL;
+               _E("appinfo foreach: %s", strerror(errno));
+               return;
+       }
+
+       cbi.cb = cb;
+       cbi.cb_data = user_data;
+
+       g_hash_table_foreach(cf->tbl, _iter_cb, &cbi);
+}
+
+int appinfo_get_boolean(const struct appinfo *c, enum appinfo_type type)
+{
+       const char *v;
+
+       v = appinfo_get_value(c, type);
+       if (!v)
+               return -1;
+
+       if (!strcmp(v, "1") || !strcasecmp(v, "true"))
+               return 1;
+
+       if (!strcmp(v, "0") || !strcasecmp(v, "false"))
+               return 0;
+
+       errno = EFAULT;
+
+       return -1;
+}
+
diff --git a/am_daemon/amd_appinfo.h b/am_daemon/amd_appinfo.h
new file mode 100755 (executable)
index 0000000..401b284
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef __AUL_AMD_APPINFO_H_
+#define __AUL_AMD_APPINFO_H_
+
+struct appinfomgr;
+struct appinfo;
+
+enum appinfo_type {
+       AIT_NAME,
+       AIT_COMP,
+       AIT_EXEC,
+       AIT_TYPE,
+       AIT_ONBOOT, /* start on boot: boolean */
+       AIT_RESTART, /* auto restart: boolean */
+       AIT_MULTI,
+};
+
+int appinfo_init(struct appinfomgr **cf);
+void appinfo_fini(struct appinfomgr **cf);
+
+const struct appinfo *appinfo_insert(struct appinfomgr *cf, const char *filename);
+void appinfo_delete(struct appinfomgr *cf, const char *filename);
+
+const struct appinfo *appinfo_find(struct appinfomgr *cf, const char *filename);
+const char *appinfo_get_value(const struct appinfo *c, enum appinfo_type type);
+const char *appinfo_get_filename(const struct appinfo *c);
+int appinfo_get_boolean(const struct appinfo *c, enum appinfo_type type);
+
+typedef void (*appinfo_iter_callback)(void *user_data,
+               const char *filename, const struct appinfo *c);
+void appinfo_foreach(struct appinfomgr *cf, appinfo_iter_callback cb, void *user_data);
+
+#endif /* __AUL_AMD_APPINFO_H_ */
diff --git a/am_daemon/amd_cgutil.c b/am_daemon/amd_cgutil.c
new file mode 100755 (executable)
index 0000000..0a11276
--- /dev/null
@@ -0,0 +1,607 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <dirent.h>
+
+#include "amd_config.h"
+#include "simple_util.h"
+#include "amd_cgutil.h"
+
+#define CFILE_RELEASE_AGENT "release_agent"
+#define CFILE_NOTIFY_ON_RELEASE "notify_on_release"
+#define CFILE_TASKS "tasks"
+
+#define DEFAULT_MODE 0755
+
+struct ctrl {
+       enum ctrl_type ctrl;
+       char *root; /* cginfo's mount_point + subsystem name */
+};
+
+struct cginfo {
+       int refcnt;
+       char *mount_point;
+       struct ctrl ctrls[CTRL_MAX];
+};
+
+enum {
+       _MNT_ROOT,
+       _MNT_MGR,
+       _MNT_CPU,
+       _MNT_MEM,
+       /* add type after adding mount information to mntinfos[] */
+};
+
+struct mntinfo {
+       char *source;
+       char *ftype; /* filesystem type */
+       unsigned long flags;
+       char *option;
+};
+
+static struct mntinfo mntinfos[] = {
+       [_MNT_ROOT] = {
+               "cgroup_root",
+               "tmpfs",
+               MS_NODEV | MS_NOSUID | MS_NOEXEC,
+               NULL,
+       },
+       [_MNT_MGR] = {
+               "daemon_mgr",
+               "cgroup",
+               MS_NODEV | MS_NOSUID | MS_NOEXEC,
+               "none,name=daemon_mgr",
+       },
+       [_MNT_CPU] = {
+               "cpuset",
+               "cgroup",
+               MS_NODEV | MS_NOSUID | MS_NOEXEC,
+               "cpuset",
+       },
+       [_MNT_MEM] = {
+               "memory",
+               "cgroup",
+               MS_NODEV | MS_NOSUID | MS_NOEXEC,
+               "memory",
+       },
+       /* TODO: add more */
+};
+
+struct ctrlinfo {
+       int mnt_type;
+       char *name;
+};
+
+static struct ctrlinfo ctrlinfos[] = {
+       [CTRL_MGR] = { _MNT_MGR, "mgr", },
+#if defined(USE_CGROUP_CPU)
+       [CTRL_CPU] = { _MNT_CPU, "cpuset", },
+#endif
+#if defined(USE_CGROUP_MEM)
+       [CTRL_MEM] = { _MNT_MEM, "memory", },
+#endif
+};
+
+static inline int _mount(const char *mount_point, struct mntinfo *mti)
+{
+       assert(mti);
+       return mount(mti->source, mount_point, mti->ftype, mti->flags,
+                       mti->option);
+}
+
+static inline int _umount(const char *mount_point)
+{
+       return umount2(mount_point, MNT_DETACH);
+}
+
+static int _write_single(struct ctrl *ctr,
+               const char *group, const char *file, const char *str)
+{
+       FILE *fp;
+       char path[FILENAME_MAX];
+       int r;
+
+       assert(ctr);
+       assert(file);
+
+       if (!str)
+               str = "";
+
+       snprintf(path, sizeof(path), "%s/%s%s%s", ctr->root,
+                       group ? : "", group ? "/" : "", file);
+       fp = fopen(path, "w");
+       if (!fp) {
+               _E("open: %s: %s", path, strerror(errno));
+               return -1;
+       }
+
+       r = fputs(str, fp);
+       if (r == EOF) {
+               _E("write: %s,%s: %s", path, str, strerror(errno));
+               r = -1;
+       } else {
+               r = 0;
+       }
+
+       fclose(fp);
+
+       return r;
+}
+
+/*
+static void _trunc_newline(char *buf, int sz)
+{
+       char *s;
+
+       assert(buf);
+       assert(sz > 0);
+
+       s = buf;
+       while (*s) {
+               if (*s == '\r' || *s == '\n') {
+                       *s = '\0';
+                       break;
+               }
+               s++;
+       }
+}
+
+static int _read_single(struct ctrl *ctr, const char *file, char *buf, int sz)
+{
+       FILE *fp;
+       char path[FILENAME_MAX];
+       char _buf[LINE_MAX];
+       char *r;
+
+       assert(ctr);
+       assert(file);
+       assert(buf);
+       assert(sz > 0);
+
+       snprintf(path, sizeof(path), "%s/%s", ctr->root, file);
+       fp = fopen(path, "r");
+       if (!fp) {
+               _E("open: %s: %s", path, strerror(errno));
+               return -1;
+       }
+
+       r = fgets(_buf, sizeof(_buf), fp);
+       if (r == NULL) {
+               _E("read: %s: %s", path, strerror(errno));
+       } else {
+               _trunc_newline(_buf, sizeof(_buf));
+               snprintf(buf, sz, "%s", _buf);
+       }
+
+       fclose(fp);
+
+       return r == NULL ? -1 : 0;
+}
+*/
+
+static int _destroy(struct cginfo *cg)
+{
+       int i;
+       int r;
+
+       for (i = 0; i < sizeof(cg->ctrls)/sizeof(cg->ctrls[0]); i++) {
+               struct ctrl *ctr = &cg->ctrls[i];
+
+               if (ctr->root) {
+                       r = _umount(ctr->root);
+                       if (r == -1) {
+                               _E("unmount: %s: %s",
+                                               ctr->root, strerror(errno));
+                               return -1;
+                       }
+                       free(ctr->root);
+                       ctr->root = NULL;
+               }
+       }
+
+       if (cg->mount_point) {
+               r = _umount(cg->mount_point);
+               if (r == -1) {
+                       _E("unmount: %s: %s",
+                                       cg->mount_point, strerror(errno));
+                       return -1;
+               }
+               free(cg->mount_point);
+       }
+
+       free(cg);
+
+       return 0;
+}
+
+void cgutil_destroy(struct cginfo **cg)
+{
+       int r;
+
+       if (!cg || !*cg)
+               return;
+
+       (*cg)->refcnt--;
+
+       if ((*cg)->refcnt > 0)
+               return;
+
+       r = _destroy(*cg);
+       if (r == -1)
+               return;
+
+       *cg = NULL;
+}
+
+static int _mount_root(struct cginfo *cg, const char *mount_point)
+{
+       int r;
+
+       r = _mount(mount_point, &mntinfos[_MNT_ROOT]);
+       if (r == -1) {
+               if (errno != EBUSY) {
+                       _E("mount: %s: %s", mount_point, strerror(errno));
+                       return -1;
+               }
+               _D("'%s' already mounted", mount_point);
+       }
+
+       cg->mount_point = strdup(mount_point);
+
+       return 0;
+}
+
+static int _init_ctrl(struct ctrl *ctr, struct cginfo *cg, enum ctrl_type ctrl)
+{
+       int r;
+       int mt;
+       char path[FILENAME_MAX];
+
+       assert(ctr);
+       assert(ctrl >= 0);
+       assert(ctrl < sizeof(ctrlinfos)/sizeof(ctrlinfos[0]));
+
+       mt = ctrlinfos[ctrl].mnt_type;
+       snprintf(path, sizeof(path), "%s/%s",
+                       cg->mount_point, ctrlinfos[ctrl].name);
+
+       /* TODO: read /proc/cgroup and check the current type is enabled */
+
+       r = mkdir(path, DEFAULT_MODE);
+       if (r == -1) {
+               if (errno != EEXIST) {
+                       _E("mkdir: %s: %s", path, strerror(errno));
+                       return -1;
+               }
+               _D("'%s' exist", path);
+       }
+
+       r = _mount(path, &mntinfos[mt]);
+       if (r == -1) {
+               if (errno != EBUSY) {
+                       _E("mount: %s: %s", path, strerror(errno));
+                       rmdir(path);
+                       return -1;
+               }
+               _D("'%s' already mounted", path);
+       }
+
+       ctr->ctrl = ctrl;
+       ctr->root = strdup(path);
+
+       return 0;
+}
+
+static int _set_release_agent(struct ctrl *ctr, const char *agent_path)
+{
+       int r;
+
+       r = access(agent_path, X_OK);
+       if (r == -1) {
+               _E("'%s' is not executable: %s",
+                               agent_path, strerror(errno));
+               return -1;
+       }
+
+       r = _write_single(ctr, NULL, CFILE_RELEASE_AGENT, agent_path);
+       if (r == -1)
+               return -1;
+
+       r = _write_single(ctr, NULL, CFILE_NOTIFY_ON_RELEASE, "1");
+       if (r == -1)
+               return -1;
+
+       return 0;
+}
+
+struct cginfo *cgutil_ref(struct cginfo *cg)
+{
+       if (cg)
+               cg->refcnt++;
+
+       return cg;
+}
+
+static int _create(struct cginfo *cg,
+               const char *mount_point, const char *agent_path)
+{
+       int i;
+       int r;
+
+       r = _mount_root(cg, mount_point);
+       if (r == -1)
+               return -1;
+
+       for (i = 0; i < sizeof(cg->ctrls)/sizeof(cg->ctrls[0]); i++) {
+               r = _init_ctrl(&cg->ctrls[i], cg, i);
+               if (r == -1)
+                       return -1;
+       }
+
+       r = _set_release_agent(&cg->ctrls[CTRL_MGR], agent_path);
+       if (r == -1)
+               return -1;
+
+       return 0;
+}
+
+int cgutil_create(const char *mount_point, const char *agent_path,
+               struct cginfo **cg)
+{
+       struct cginfo *_cg;
+       int r;
+
+       if (!mount_point || !*mount_point ||
+                       !agent_path || !*agent_path || !cg) {
+               errno = EINVAL;
+               _E("cgutil create: %s", strerror(errno));
+               return -1;
+       }
+
+       _cg = calloc(1, sizeof(*_cg));
+       if (!_cg) {
+               _E("cgutil alloc: %s", strerror(errno));
+               return -1;
+       }
+
+       r = _create(_cg, mount_point, agent_path);
+       if (r == -1) {
+               _destroy(_cg);
+               return -1;
+       }
+
+       *cg = cgutil_ref(_cg);
+
+       return 0;
+}
+
+int cgutil_create_group(struct cginfo *cg,
+               enum ctrl_type ctrl, const char *group)
+{
+       int r;
+       struct ctrl *ctr;
+       char path[FILENAME_MAX];
+
+       assert(ctrl >= 0 && ctrl < CTRL_MAX);
+
+       if (!cg || !group || !*group) {
+               errno = EINVAL;
+               _E("cgutil create group: %s", strerror(errno));
+               return -1;
+       }
+
+       ctr = &cg->ctrls[ctrl];
+       assert(ctr);
+
+       snprintf(path, sizeof(path), "%s/%s", ctr->root, FILENAME(group));
+
+       r = mkdir(path, DEFAULT_MODE);
+       if (r == -1) {
+               _E("cgutil create group: mkdir: %s", strerror(errno));
+               return -1;
+       }
+
+       return 0;
+}
+
+int cgutil_remove_group(struct cginfo *cg,
+               enum ctrl_type ctrl, const char *group)
+{
+       int r;
+       struct ctrl *ctr;
+       char path[FILENAME_MAX];
+
+       assert(ctrl >= 0 && ctrl < CTRL_MAX);
+
+       if (!cg || !group || !*group) {
+               errno = EINVAL;
+               _E("cgutil remove group: %s", strerror(errno));
+               return -1;
+       }
+
+       ctr = &cg->ctrls[ctrl];
+       assert(ctr);
+
+       snprintf(path, sizeof(path), "%s/%s", ctr->root, FILENAME(group));
+
+       r = rmdir(path);
+       if (r == -1) {
+               _E("cgutil remove group: rmdir: %s", strerror(errno));
+               return -1;
+       }
+
+       return 0;
+}
+
+int cgutil_exist_group(struct cginfo *cg,
+               enum ctrl_type ctrl, const char *group)
+{
+       int r;
+       struct ctrl *ctr;
+       char path[FILENAME_MAX];
+       struct stat st;
+
+       assert(ctrl >= 0 && ctrl < CTRL_MAX);
+
+       if (!cg || !group || !*group) {
+               errno = EINVAL;
+               _E("cgutil exist group: %s", strerror(errno));
+               return -1;
+       }
+
+       ctr = &cg->ctrls[ctrl];
+       assert(ctr);
+
+       snprintf(path, sizeof(path), "%s/%s", ctr->root, FILENAME(group));
+
+       r = stat(path, &st);
+       if (r == -1) {
+               if (errno == ENOENT)
+                       return 0;
+
+               _E("cgutil exist group: %s", strerror(errno));
+               return -1;
+       }
+
+       /* stat() returns no error, then group exists */
+       return 1;
+}
+
+int cgutil_group_add_pid(struct cginfo *cg,
+               enum ctrl_type ctrl, const char *group, pid_t pid)
+{
+       int r;
+       struct ctrl *ctr;
+       char buf[32]; /* 32 is enough for ineger number */
+
+       assert(ctrl >= 0 && ctrl < CTRL_MAX);
+
+       /* PID 1 is init's PID */
+       if (!cg || !group || !*group || pid <= 1) {
+               errno = EINVAL;
+               _E("cgutil add pid: %s", strerror(errno));
+               return -1;
+       }
+
+       ctr = &cg->ctrls[ctrl];
+       assert(ctr);
+
+       snprintf(buf, sizeof(buf), "%d", pid);
+
+       r = _write_single(ctr, FILENAME(group), CFILE_TASKS, buf);
+       if (r == -1)
+               return -1;
+
+       return 0;
+}
+
+static int _foreach_pid(struct ctrl *ctr, const char *group,
+               cgutil_iter_pid_callback cb, void *user_data)
+{
+       int r;
+       FILE *fp;
+       char path[FILENAME_MAX];
+
+       assert(ctr);
+       assert(cb);
+
+       snprintf(path, sizeof(path), "%s/%s/%s",
+                       ctr->root, FILENAME(group), CFILE_TASKS);
+       fp = fopen(path, "r");
+       if (!fp) {
+               _E("open: %s: %s", path, strerror(errno));
+               return -1;
+       }
+
+       while (!feof(fp)) {
+               unsigned long l;
+
+               r = fscanf(fp, "%lu", &l);
+               if (r != 1)
+                       break;
+
+               r = cb(user_data, group, l);
+               if (r == -1)
+                       break;
+       }
+
+       fclose(fp);
+
+       return 0;
+}
+
+int cgutil_group_foreach_pid(struct cginfo *cg,
+               enum ctrl_type ctrl, const char *group,
+               cgutil_iter_pid_callback cb, void *user_data)
+{
+       struct ctrl *ctr;
+
+       assert(ctrl >= 0 && ctrl < CTRL_MAX);
+
+       if (!cg || !group || !*group || !cb) {
+               errno = EINVAL;
+               _E("cgutil foreach pid: %s", strerror(errno));
+               return -1;
+       }
+
+       ctr = &cg->ctrls[ctrl];
+       assert(ctr);
+
+       return _foreach_pid(ctr, group, cb, user_data);
+}
+
+static int _foreach_group(struct ctrl *ctr,
+               cgutil_iter_group_callback cb, void *user_data)
+{
+       int r;
+       DIR *d;
+       struct dirent *de;
+
+       assert(ctr);
+       assert(cb);
+
+       d = opendir(ctr->root);
+       if (!d) {
+               _E("open: %s: %s", ctr->root, strerror(errno));
+               return -1;
+       }
+
+       for (de = readdir(d); de; de = readdir(d)) {
+               if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
+                       continue;
+
+               r = cb(user_data, de->d_name);
+               if (r == -1)
+                       break;
+       }
+
+       closedir(d);
+
+       return 0;
+}
+
+int cgutil_foreach_group(struct cginfo *cg, enum ctrl_type ctrl,
+               cgutil_iter_group_callback cb, void *user_data)
+{
+       struct ctrl *ctr;
+
+       assert(ctrl >= 0 && ctrl < CTRL_MAX);
+
+       if (!cg || !cb) {
+               errno = EINVAL;
+               _E("cgutil foreach group: %s", strerror(errno));
+               return -1;
+       }
+
+       ctr = &cg->ctrls[ctrl];
+       assert(ctr);
+
+       return _foreach_group(ctr, cb, user_data);
+}
diff --git a/am_daemon/amd_cgutil.h b/am_daemon/amd_cgutil.h
new file mode 100755 (executable)
index 0000000..360bef2
--- /dev/null
@@ -0,0 +1,48 @@
+
+#ifndef __AUL_AMD_CGROUP_UTIL_H__
+#define __AUL_AMD_CGROUP_UTIL_H__
+
+enum ctrl_type {
+       CTRL_MGR, /* for manager */
+#if defined(USE_CGROUP_CPU) /* not implemented */
+       CTRL_CPU, /* cpuset */
+#endif
+#if defined(USE_CGROUP_MEM) /* not implemented */
+       CTRL_MEM, /* memory */
+#endif
+       /* TODO: add more */
+       CTRL_MAX,
+};
+
+struct cginfo;
+
+int cgutil_create(const char *mount_point, const char *agent_path,
+               struct cginfo **cg);
+void cgutil_destroy(struct cginfo **cg);
+
+struct cginfo *cgutil_ref(struct cginfo *cg);
+#define cgutil_unref(cg) cgutil_destroy(cg)
+
+
+int cgutil_create_group(struct cginfo *cg,
+               enum ctrl_type ctrl, const char *group);
+int cgutil_remove_group(struct cginfo *cg,
+               enum ctrl_type ctrl, const char *group);
+int cgutil_exist_group(struct cginfo *cg,
+               enum ctrl_type ctrl, const char *group);
+
+typedef int (*cgutil_iter_group_callback)(void *user_data, const char *group);
+int cgutil_foreach_group(struct cginfo *cg, enum ctrl_type ctrl,
+               cgutil_iter_group_callback cb, void *user_data);
+
+
+int cgutil_group_add_pid(struct cginfo *cg,
+               enum ctrl_type ctrl, const char *group, pid_t pid);
+
+typedef int (*cgutil_iter_pid_callback)(void *user_data, const char *group,
+               pid_t pid);
+int cgutil_group_foreach_pid(struct cginfo *cg,
+               enum ctrl_type ctrl, const char *group,
+               cgutil_iter_pid_callback cb, void *user_data);
+
+#endif /* __AUL_AMD_CGROUP_UTIL_H__ */
diff --git a/am_daemon/amd_config.h b/am_daemon/amd_config.h
new file mode 100755 (executable)
index 0000000..d8671b0
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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 AMD_LOG
+
diff --git a/am_daemon/amd_key.c b/am_daemon/amd_key.c
new file mode 100755 (executable)
index 0000000..d8d8523
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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 <Ecore_X.h>
+#include <Ecore_Input.h>
+#include <utilX.h>
+#include <Ecore.h>
+#include <Evas.h>
+#include <aul.h>
+#include <glib.h>
+
+#include "amd_config.h"
+#include "simple_util.h"
+#include "app_sock.h"
+
+static struct {
+       Evas_Object *win;
+       Ecore_Event_Handler *key_up;
+       Ecore_Event_Handler *key_down;
+} key_info = {
+       .win = NULL,
+       .key_up = NULL,
+       .key_down = NULL,
+};
+
+GSList *key_pid_list = NULL;
+
+static Eina_Bool __key_release_cb(void *data, int type, void *event);
+static Eina_Bool __key_press_cb(void *data, int type, void *event);
+
+static Eina_Bool __key_release_cb(void *data, int type, void *event)
+{
+       Evas_Event_Key_Up *ev = event;
+       int ret;
+       GSList *entry;
+       int *pid_data;
+       bundle *kb;
+
+       _D("Released");
+
+       if (!ev) {
+               _D("Invalid event object");
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       entry = key_pid_list;
+       if (entry && entry->data) {
+               pid_data = (int *) entry->data;
+
+               kb = bundle_create();
+               bundle_add(kb, AUL_K_MULTI_KEY, ev->keyname);
+               bundle_add(kb, AUL_K_MULTI_KEY_EVENT, AUL_V_KEY_RELEASED);
+
+               ret = app_send_cmd(*pid_data, APP_KEY_EVENT, kb);
+
+               bundle_free(kb);
+       }
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+
+static Eina_Bool __key_press_cb(void *data, int type, void *event)
+{
+       Evas_Event_Key_Down *ev = event;
+       int ret;
+       GSList *entry;
+       int *pid_data;
+       bundle *kb;
+
+       _D("Pressed");
+
+       if (!ev) {
+               _D("Invalid event object");
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       entry = key_pid_list;
+       if (entry && entry->data) {
+               pid_data = (int *) entry->data;
+
+               kb = bundle_create();
+               bundle_add(kb, AUL_K_MULTI_KEY, ev->keyname);
+               bundle_add(kb, AUL_K_MULTI_KEY_EVENT, AUL_V_KEY_PRESSED);
+
+               ret = app_send_cmd(*pid_data, APP_KEY_EVENT, kb);
+
+               bundle_free(kb);
+       }
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+int _register_key_event(int pid)
+{
+       int *pid_data;
+       GSList *entry;
+
+       pid_data = malloc(sizeof(int));
+       *pid_data = pid;
+
+       key_pid_list = g_slist_prepend(key_pid_list, pid_data);
+
+       _D("===key stack===");
+
+       for (entry = key_pid_list; entry; entry = entry->next) {
+               if (entry->data) {
+                       pid_data = (int *) entry->data;
+                       _D("pid : %d",*pid_data);
+               }
+       }
+
+       return 0;
+}
+
+int _unregister_key_event(int pid)
+{
+       GSList *entry;
+       int *pid_data;
+
+       for (entry = key_pid_list; entry; entry = entry->next) {
+               if (entry->data) {
+                       pid_data = (int *) entry->data;
+                       if(pid == *pid_data) {
+                               key_pid_list = g_slist_remove(key_pid_list, entry->data);
+                               free(pid_data);
+                       }
+               }
+       }
+
+       _D("===key stack===");
+
+       for (entry = key_pid_list; entry; entry = entry->next) {
+               if (entry->data) {
+                       pid_data = (int *) entry->data;
+                       _D("pid : %d",*pid_data);
+               }
+       }
+
+       return 0;
+}
+
+int _key_init()
+{
+       key_info.win = ecore_x_window_input_new(0, 0, 0, 1, 1);
+       if (!key_info.win) {
+               _D("Failed to create hidden window");
+       }
+
+       ecore_x_icccm_title_set(key_info.win, "acdaemon,key,receiver");
+       ecore_x_netwm_name_set(key_info.win, "acdaemon,key,receiver");
+       ecore_x_netwm_pid_set(key_info.win, getpid());
+
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_PLAYCD, EXCLUSIVE_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_STOPCD, EXCLUSIVE_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_PAUSECD, EXCLUSIVE_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_NEXTSONG, EXCLUSIVE_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_PREVIOUSSONG, EXCLUSIVE_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_REWIND, EXCLUSIVE_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_FASTFORWARD, EXCLUSIVE_GRAB);
+
+       key_info.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, __key_release_cb, NULL);
+       if (!key_info.key_up) {
+               _D("Failed to register a key up event handler");
+       }
+
+       key_info.key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, __key_press_cb, NULL);
+       if (!key_info.key_down) {
+               _D("Failed to register a key down event handler");
+       }
+
+       return 0;
+}
+
diff --git a/am_daemon/amd_key.h b/am_daemon/amd_key.h
new file mode 100755 (executable)
index 0000000..bcf8d2e
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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 __AUL_AMD_KEY_H_
+#define __AUL_AMD_KEY_H_
+
+int _key_init(void);
+int _register_key_event(int pid);
+int _unregister_key_event(int pid);
+
+#endif
+
diff --git a/am_daemon/amd_launch.c b/am_daemon/amd_launch.c
new file mode 100755 (executable)
index 0000000..e6c1c09
--- /dev/null
@@ -0,0 +1,542 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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 <signal.h>
+#include <bundle.h>
+#include <aul.h>
+#include <glib.h>
+#include <app-checker-server.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "amd_config.h"
+#include "amd_launch.h"
+#include "amd_appinfo.h"
+#include "amd_status.h"
+#include "app_sock.h"
+#include "simple_util.h"
+#include "amd_cgutil.h"
+
+
+#define TERM_WAIT_SEC 3
+#define INIT_PID 1
+
+struct appinfomgr *_laf;
+struct cginfo *_lcg;
+
+typedef struct {
+       char *pkg_name;         /* package */
+       char *app_path;         /* exec */
+       char *original_app_path;        /* exec */
+       int multiple;           /* x_slp_multiple */
+       char *pkg_type;
+} app_info_from_pkgmgr;
+
+static GList *_kill_list;
+
+struct ktimer {
+       pid_t pid;
+       char *group;
+       guint tid; /* timer ID */
+       struct cginfo *cg;
+};
+
+static void _prepare_exec(void)
+{
+       setsid();
+
+       signal(SIGINT, SIG_DFL);
+       signal(SIGTERM, SIG_DFL);
+       signal(SIGCHLD, SIG_DFL);
+
+       /* TODO: do security job */
+       /* TODO: setuid */
+}
+
+static int _add_cgroup(struct cginfo *cg, const char *group, int pid)
+{
+       int r;
+
+       r = cgutil_exist_group(cg, CTRL_MGR, group);
+       if (r == -1) {
+               _E("exist check error: %s", strerror(errno));
+               return -1;
+       }
+
+       if (r == 0) { /* not exist */
+               r = cgutil_create_group(cg, CTRL_MGR, group);
+               if (r == -1) {
+                       _E("create group error");
+                       return -1;
+               }
+       }
+
+       r = cgutil_group_add_pid(cg, CTRL_MGR, group, pid);
+       if (r == -1) {
+               _E("add pid to group error");
+               cgutil_remove_group(cg, CTRL_MGR, group);
+               return -1;
+       }
+
+       return 0;
+}
+
+static char **__create_argc_argv(bundle * kb, int *margc)
+{
+       char **argv;
+       int argc;
+
+       argc = bundle_export_to_argv(kb, &argv);
+
+       *margc = argc;
+       return argv;
+}
+static void _do_exec(struct cginfo *cg, const char *cmd, const char *group, bundle *kb)
+{
+       gchar **argv;
+       gint argc;
+       char **b_argv;
+       int b_argc;
+       gboolean b;
+       int r;
+
+       r = _add_cgroup(cg, group, getpid());
+       if (r == -1)
+               return;
+
+       b = g_shell_parse_argv(cmd, &argc, &argv, NULL);
+
+       if (kb) {
+               b_argv = __create_argc_argv(kb, &b_argc);
+               b_argv[0] = strdup(argv[0]);
+               _prepare_exec();
+               execv(b_argv[0], b_argv);
+       }
+
+       if (b) {
+               _prepare_exec();
+               execv(argv[0], argv);
+       }
+
+       _E("exec error: %s", strerror(errno));
+       g_strfreev(argv);
+}
+
+int service_start(struct cginfo *cg, const char *group, const char *cmd, bundle *kb)
+{
+       int r;
+       pid_t p;
+
+       if (!cg || !group || !*group || !cmd || !*cmd) {
+               errno = EINVAL;
+               _E("service start: %s", strerror(errno));
+               return -1;
+       }
+
+       p = fork();
+       switch (p) {
+       case 0: /* child process */
+               _do_exec(cg, cmd, group, kb);
+               /* exec error */
+               exit(0);
+               break;
+       case -1:
+               _E("service start: fork: %s", strerror(errno));
+               r = -1;
+               break;
+       default: /* parent process */
+               _D("child process: %d", p);
+               r = p;
+               break;
+       }
+
+       return r;
+}
+
+int _start_srv(struct appinfo *ai, bundle *kb)
+{
+       int r;
+       const char *group;
+       const char *cmd;
+
+       group = appinfo_get_filename(ai);
+
+       cmd = appinfo_get_value(ai, AIT_EXEC);
+       if (!cmd) {
+               _E("start service: '%s' has no exec", group);
+               return -1;
+       }
+
+       r = service_start(_lcg, group, cmd, kb);
+       if (r == -1) {
+               _E("start service: '%s': failed", group);
+               return -1;
+       }
+
+       return 0;
+}
+
+static void _free_kt(struct ktimer *kt)
+{
+       if (!kt)
+               return;
+
+       cgutil_unref(&kt->cg);
+       free(kt->group);
+       free(kt);
+}
+
+static void _kill_pid(struct cginfo *cg, const char *group, pid_t pid)
+{
+       int r;
+
+       if (pid <= INIT_PID) /* block sending to all process or init */
+               return;
+
+       r = cgutil_exist_group(cg, CTRL_MGR, group);
+       if (r == -1) {
+               _E("send SIGKILL: exist: %s", strerror(errno));
+               return;
+       }
+       if (r == 0) {
+               _D("send SIGKILL: '%s' not exist", group);
+               return;
+       }
+
+       /* TODO: check pid exist in group */
+
+       r = kill(pid, 0);
+       if (r == -1) {
+               _D("send SIGKILL: pid %d not exist", pid);
+               return;
+       }
+
+       r = kill(pid, SIGKILL);
+       if (r == -1)
+               _E("send SIGKILL: %s", strerror(errno));
+}
+
+static gboolean _ktimer_cb(gpointer data)
+{
+       struct ktimer *kt = data;
+
+       _kill_pid(kt->cg, kt->group, kt->pid);
+       _kill_list = g_list_remove(_kill_list, kt);
+       _free_kt(kt);
+
+       return FALSE;
+}
+
+static void _add_list(struct cginfo *cg, const char *group, pid_t pid)
+{
+       struct ktimer *kt;
+
+       kt = calloc(1, sizeof(*kt));
+       if (!kt)
+               return;
+
+       kt->pid = pid;
+       kt->group = strdup(group);
+       if (!kt->group) {
+               free(kt);
+               return;
+       }
+
+       kt->cg = cgutil_ref(cg);
+       kt->tid = g_timeout_add_seconds(TERM_WAIT_SEC, _ktimer_cb, kt);
+
+       _kill_list = g_list_append(_kill_list, kt);
+}
+
+static inline void _del_list(GList *l)
+{
+       struct ktimer *kt;
+
+       if (!l)
+               return;
+
+       kt = l->data;
+
+       g_source_remove(kt->tid);
+       _free_kt(kt);
+       _kill_list = g_list_delete_link(_kill_list, l);
+}
+
+static int _kill_pid_cb(void *user_data, const char *group, pid_t pid)
+{
+       int r;
+
+       if (pid <= INIT_PID) /* block sending to all process or init */
+               return 0;
+
+       r = kill(pid, SIGTERM);
+       if (r == -1)
+               _E("send SIGTERM: %s", strerror(errno));
+
+       _add_list(user_data, group, pid);
+
+       return 0;
+}
+
+int service_stop(struct cginfo *cg, const char *group)
+{
+       if (!cg || !group || !*group) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       return cgutil_group_foreach_pid(cg, CTRL_MGR, FILENAME(group),
+                       _kill_pid_cb, cg);
+}
+
+void service_release(const char *group)
+{
+       GList *l;
+       GList *d;
+
+       if (!group || !*group)
+               return;
+
+       group = FILENAME(group);
+
+       d = NULL;
+       for (l = _kill_list; l; l = g_list_next(l)) {
+               struct ktimer *k = l->data;
+
+               _del_list(d);
+
+               if (k->group && !strcmp(k->group, group))
+                       d = l;
+       }
+
+       _del_list(d);
+}
+
+int _send_to_sigkill(int pid)
+{
+       int pgid;
+
+       pgid = getpgid(pid);
+       if (pgid <= 1)
+               return -1;
+
+       if (killpg(pgid, SIGKILL) < 0)
+               return -1;
+
+       return 0;
+}
+int _resume_app(int pid)
+{
+       int dummy;
+       int ret;
+       if ((ret =
+            __app_send_raw(pid, APP_RESUME_BY_PID, (unsigned char *)&dummy,
+                           sizeof(int))) < 0) {
+               if (ret == -EAGAIN)
+                       _E("resume packet timeout error");
+               else {
+                       _E("raise failed - %d resume fail\n", pid);
+                       _E("we will term the app - %d\n", pid);
+                       _send_to_sigkill(pid);
+                       ret = -1;
+               }
+       }
+       _D("resume done\n");
+       return ret;
+}
+
+int _term_app(int pid)
+{
+       int dummy;
+       if (__app_send_raw
+           (pid, APP_TERM_BY_PID, (unsigned char *)&dummy, sizeof(int)) < 0) {
+               _D("terminate packet send error - use SIGKILL");
+               if (_send_to_sigkill(pid) < 0) {
+                       _E("fail to killing - %d\n", pid);
+                       return -1;
+               }
+       }
+       _D("term done\n");
+       return 0;
+}
+
+int _fake_launch_app(int cmd, int pid, bundle * kb)
+{
+       int datalen;
+       int ret;
+       bundle_raw *kb_data;
+
+       bundle_encode(kb, &kb_data, &datalen);
+       if ((ret = __app_send_raw(pid, cmd, kb_data, datalen)) < 0)
+               _E("error request fake launch - error code = %d", ret);
+       free(kb_data);
+       return ret;
+}
+
+static int __nofork_processing(int cmd, int pid, bundle * kb)
+{
+       int ret = -1;
+       switch (cmd) {
+       case APP_OPEN:
+       case APP_RESUME:
+               _D("resume app's pid : %d\n", pid);
+               if ((ret = _resume_app(pid)) < 0)
+                       _E("__resume_app failed. error code = %d", ret);
+               _D("resume app done");
+               break;
+
+       case APP_START:
+       case APP_START_RES:
+               _D("fake launch pid : %d\n", pid);
+               if ((ret = _fake_launch_app(cmd, pid, kb)) < 0)
+                       _E("fake_launch failed. error code = %d", ret);
+               _D("fake launch done");
+               break;
+       }
+       return ret;
+}
+
+static void __real_send(int clifd, int ret)
+{
+       if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
+               if (errno == EPIPE) {
+                       _E("send failed due to EPIPE.\n");
+               }
+               _E("send fail to client");
+       }
+
+       close(clifd);
+}
+
+int __sat_ui_launch(char* appid, bundle* kb, int cmd, int caller_pid, int fd)
+{
+       int ret = -1;
+       char *app_path = "/usr/apps/org.tizen.sat-ui/bin/sat-ui KEY_EXEC_TYPE 0";
+       int pid = -1;
+       char tmp_pid[MAX_PID_STR_BUFSZ];
+
+       snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", caller_pid);
+       bundle_add(kb, AUL_K_CALLER_PID, tmp_pid);
+
+       pid = _status_app_is_running(appid);
+
+       if (pid > 0) {
+               if (caller_pid == pid) {
+                       _D("caller process & callee process is same.[%s:%d]", appid, pid);
+                       pid = -ELOCALLAUNCH_ID;
+               } else if ((ret = __nofork_processing(cmd, pid, kb)) < 0) {
+                       pid = ret;
+               }
+       } else if (cmd != APP_RESUME) {
+               bundle_add(kb, AUL_K_EXEC, app_path);
+               bundle_add(kb, AUL_K_PACKAGETYPE, "rpm");
+               pid = app_send_cmd(LAUNCHPAD_PID, cmd, kb);
+       }
+
+       __real_send(fd, pid);
+
+       if(pid > 0) {
+               _status_add_app_info_list(appid, app_path, pid);
+               ac_server_check_launch_privilege(appid, "rpm", pid);
+       }
+
+       return pid;
+}
+
+int _start_app(char* appid, bundle* kb, int cmd, int caller_pid, int fd)
+{
+       struct appinfo *ai;
+       int ret = -1;
+       char *componet = NULL;
+       char *multiple = NULL;
+       char *app_path = NULL;
+       int pid = -1;
+       char tmp_pid[MAX_PID_STR_BUFSZ];
+
+       if(strncmp(appid, "org.tizen.sat-ui", 18) == 0) {
+               pid = __sat_ui_launch(appid, kb, cmd, caller_pid, fd);
+               return pid;
+       }
+
+       snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", caller_pid);
+       bundle_add(kb, AUL_K_CALLER_PID, tmp_pid);
+
+       if (cmd == APP_START_RES)
+               bundle_add(kb, AUL_K_WAIT_RESULT, "1");
+
+       ai = appinfo_find(_laf, appid);
+
+       componet = appinfo_get_value(ai, AIT_COMP);
+       app_path = appinfo_get_value(ai, AIT_EXEC);
+       if (componet && strncmp(componet, "ui", 2) == 0) {
+               multiple = appinfo_get_value(ai, AIT_MULTI);
+               if (!multiple || strncmp(multiple, "false", 5) == 0) {
+                       pid = _status_app_is_running(appid);
+               }
+
+               if (pid > 0) {
+                       if (caller_pid == pid) {
+                               _D("caller process & callee process is same.[%s:%d]", appid, pid);
+                               pid = -ELOCALLAUNCH_ID;
+                       } else if ((ret = __nofork_processing(cmd, pid, kb)) < 0) {
+                               pid = ret;
+                       }
+               } else if (cmd != APP_RESUME) {
+                       bundle_add(kb, AUL_K_EXEC, app_path);
+                       bundle_add(kb, AUL_K_PACKAGETYPE, appinfo_get_value(ai, AIT_TYPE));
+                       pid = app_send_cmd(LAUNCHPAD_PID, cmd, kb);
+                       //_add_cgroup(_lcg, appid, pid);
+               }
+       } else if (componet && strncmp(componet, "svc", 3) == 0) {
+               pid = _status_app_is_running(appid);
+               if (pid > 0) {
+                       if ((ret = __nofork_processing(cmd, pid, kb)) < 0) {
+                               pid = ret;
+                       }
+               } else if (cmd != APP_RESUME) {
+                       pid = service_start(_lcg, appid, app_path, kb);
+               }
+       } else {
+               _E("unkown application");
+       }
+
+       __real_send(fd, pid);
+
+       if(pid > 0) {
+               _status_add_app_info_list(appid, app_path, pid);
+               ac_server_check_launch_privilege(appid, appinfo_get_value(ai, AIT_TYPE), pid);
+       }
+
+       return pid;
+}
+
+
+int _launch_init(struct amdmgr* amd)
+{
+       _laf = amd->af;
+       _lcg = amd->cg;
+
+       return 0;
+}
+
+
+
diff --git a/am_daemon/amd_launch.h b/am_daemon/amd_launch.h
new file mode 100755 (executable)
index 0000000..8691f4c
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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 __AUL_AMD_LAUNCH_H_
+#define __AUL_AMD_LAUNCH_H_
+
+#include <bundle.h>
+#include "aul_util.h"
+#include "amd_appinfo.h"
+
+int _send_to_sigkill(int pid);
+int _resume_app(int pid);
+int _term_app(int pid);
+int _fake_launch_app(int cmd, int pid, bundle * kb);
+int _start_app(char* appid, bundle* kb, int cmd, int caller_pid, int fd);
+void service_release(const char *group);
+int _start_srv(struct appinfo *ai, bundle *kb);
+
+int _launch_init(struct amdmgr* amd);
+
+#endif /* __AUL_AMD_LAUNCH_H_ */
diff --git a/am_daemon/amd_main.c b/am_daemon/amd_main.c
new file mode 100755 (executable)
index 0000000..3769afa
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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 <Ecore_X.h>
+#include <Ecore_Input.h>
+#include <utilX.h>
+#include <Ecore.h>
+#include <Evas.h>
+#include <aul.h>
+#include <vconf.h>
+#include <app-checker-server.h>
+#include <ail.h>
+#include <glib.h>
+
+#include "amd_config.h"
+#include "simple_util.h"
+#include "aul_util.h"
+#include "amd_appinfo.h"
+#include "amd_cgutil.h"
+#include "amd_key.h"
+#include "amd_status.h"
+#include "amd_launch.h"
+
+#ifndef MOUNT_PATH
+#  define MOUNT_PATH "/sys/fs/cgroup"
+#endif
+
+#ifndef AGENT_PATH
+#  define AGENT_PATH "/usr/bin/daemon-manager-release-agent"
+#endif
+
+typedef struct _r_app_info_t{
+       char pkg_name[MAX_PACKAGE_STR_SIZE];
+       int pid;
+} r_app_info_t;
+
+GSList *r_app_info_list = NULL;
+
+static void __vconf_cb(keynode_t *key, void *data);
+static int __app_dead_handler(int pid, void *data);
+static int __init();
+
+static int __send_to_sigkill(int pid)
+{
+       int pgid;
+
+       pgid = getpgid(pid);
+       if (pgid <= 1)
+               return -1;
+
+       if (killpg(pgid, SIGKILL) < 0)
+               return -1;
+
+       return 0;
+}
+
+static int __kill_bg_apps(int limit)
+{
+       int len;
+       int i;
+       int n;
+       r_app_info_t *info_t = NULL;
+       GSList *iter = NULL;
+
+       len = g_slist_length(r_app_info_list);
+
+       n = len - limit;
+
+       if (n<=0) return 0;
+
+       for ( i=0, iter = r_app_info_list; i<n ; i++) {
+               info_t = (r_app_info_t *)iter->data;
+               __send_to_sigkill(info_t->pid);
+               iter = g_slist_next(iter);
+               r_app_info_list = g_slist_remove(r_app_info_list, info_t);
+               free(info_t);
+       }
+
+}
+
+static int __remove_item_running_list(int pid)
+{
+       r_app_info_t *info_t = NULL;
+       GSList *iter = NULL;
+
+       for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (r_app_info_t *)iter->data;
+               if(pid == info_t->pid) {
+                       r_app_info_list = g_slist_remove(r_app_info_list, info_t);
+                       free(info_t);
+                       break;
+               }
+       }
+       return 0;
+}
+
+gboolean __add_item_running_list(gpointer user_data)
+{
+       bool taskmanage;
+       ail_appinfo_h handle;
+       ail_error_e ail_ret;
+       r_app_info_t *info_t = NULL;
+       GSList *iter = NULL;
+       int found = 0;
+       int limit;
+       int ret;
+       char *pkgname;
+       int pid;
+
+       item_pkt_t *item;
+
+       item = (item_pkt_t *)user_data;
+
+       pkgname = item->appid;
+       pid = item->pid;
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS, &limit);
+
+       if (pkgname == NULL) {
+               return false;
+       } else if (strncmp(pkgname, "org.tizen.cluster-home", 24) == 0) {
+               if(limit>0) __kill_bg_apps(limit-1);
+               return false;
+       }
+
+       ail_ret = ail_package_get_appinfo(pkgname, &handle);
+       if (ail_ret != AIL_ERROR_OK) {
+               _E("ail_get_appinfo with %s failed", pkgname);
+               return false;
+       }
+
+       ail_ret = ail_appinfo_get_bool(handle, AIL_PROP_X_SLP_TASKMANAGE_BOOL, &taskmanage);
+       if (ail_ret != AIL_ERROR_OK) {
+               _E("ail_appinfo_get_bool failed");
+               return false;
+       }
+
+       if (taskmanage == false)
+               return false;
+
+       for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (r_app_info_t *)iter->data;
+               if(pid == info_t->pid) {
+                       found = 1;
+                       r_app_info_list = g_slist_remove(r_app_info_list, info_t);
+                       r_app_info_list = g_slist_append(r_app_info_list, info_t);
+                       break;
+               }
+       }
+       if(found == 0) {
+               info_t = malloc(sizeof(r_app_info_t));
+               strncpy(info_t->pkg_name, pkgname, MAX_PACKAGE_STR_SIZE-1);
+               info_t->pid = pid;
+               r_app_info_list = g_slist_append(r_app_info_list, info_t);
+       }
+
+       for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (r_app_info_t *)iter->data;
+       }
+
+       if(limit>0) __kill_bg_apps(limit);
+
+       for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (r_app_info_t *)iter->data;
+       }
+
+       if (ail_destroy_appinfo(handle) != AIL_ERROR_OK)
+               _E("ail_destroy_rs failed");
+
+       free(item);
+       return false;
+}
+
+static void __vconf_cb(keynode_t *key, void *data)
+{
+       int limit;
+       const char *name;
+
+       name = vconf_keynode_get_name(key);
+       if( name == NULL ) {
+               return;
+       } else if ( strcmp(name, VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS) != 0)
+       {
+               return;
+       }
+
+       limit = vconf_keynode_get_int(key);
+       if(limit>0) __kill_bg_apps(limit);
+}
+
+static int __app_dead_handler(int pid, void *data)
+{
+       int ret;
+
+       ret = _unregister_key_event(pid);
+       ret = __remove_item_running_list(pid);
+       ret = _status_remove_app_info_list(pid);
+
+       return 0;
+}
+
+static void __start_cb(void *user_data,
+               const char *filename, const struct appinfo *ai)
+{
+       struct amdmgr *amd = user_data;
+       char *componet = NULL;
+       int r;
+
+       componet = appinfo_get_value(ai, AIT_COMP);
+
+       r = appinfo_get_boolean(ai, AIT_ONBOOT);
+       if (r == 1 && strncmp(componet, "svc", 3) == 0)
+               _start_srv(ai, NULL);
+}
+
+static void _start_services(struct amdmgr *amd)
+{
+       appinfo_foreach(amd->af, __start_cb, amd);
+}
+
+static int __init()
+{
+       int r;
+       struct amdmgr amd;
+
+       ecore_init();
+       evas_init();
+       ecore_event_init();
+       ecore_x_init(NULL);
+
+       appinfo_init(&amd.af);
+       cgutil_create(MOUNT_PATH, AGENT_PATH, &amd.cg);
+       _requset_init(&amd);
+       _launch_init(&amd);
+
+#ifndef __i386__
+       _key_init();
+#endif
+
+       r = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS, __vconf_cb, NULL);
+       aul_listen_app_dead_signal(__app_dead_handler, NULL);
+
+       _start_services(&amd);
+
+       return 0;
+}
+
+int main(int argc, char *argv[])
+{
+       int ret;
+
+       ret = ac_server_initailize();
+       ret = __init();
+
+       ecore_main_loop_begin();
+
+       return 0;
+}
diff --git a/am_daemon/amd_request.c b/am_daemon/amd_request.c
new file mode 100755 (executable)
index 0000000..6d7c72e
--- /dev/null
@@ -0,0 +1,450 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <poll.h>
+#include <aul.h>
+#include <glib.h>
+#include <bundle.h>
+#include <rua.h>
+
+#include "amd_config.h"
+#include "simple_util.h"
+#include "app_sock.h"
+#include "aul_util.h"
+#include "amd_request.h"
+#include "amd_key.h"
+#include "amd_launch.h"
+#include "amd_appinfo.h"
+#include "amd_cgutil.h"
+#include "amd_status.h"
+
+
+#define INHOUSE_UID     5000
+
+struct appinfomgr *_raf;
+struct cginfo *_rcg;
+
+static int __send_result_to_client(int fd, int res);
+static gboolean __request_handler(gpointer data);
+
+static int __send_result_to_client(int fd, int res)
+{
+       if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
+               if (errno == EPIPE)
+                       _E("send failed due to EPIPE.\n");
+               _E("send fail to client");
+       }
+       close(fd);
+       return 0;
+}
+
+static void __real_send(int clifd, int ret)
+{
+       if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
+               if (errno == EPIPE) {
+                       _E("send failed due to EPIPE.\n");
+               }
+               _E("send fail to client");
+       }
+
+       close(clifd);
+}
+
+static int __get_caller_pid(bundle *kb)
+{
+       const char *pid_str;
+       int pid;
+
+       pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
+       if(pid_str)
+               goto end;
+
+       pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
+       if (pid_str == NULL)
+               return -1;
+
+end:
+       pid = atoi(pid_str);
+       if (pid <= 1)
+               return -1;
+
+       return pid;
+}
+
+static int __foward_cmd(int cmd, bundle *kb, int cr_pid)
+{
+       int pid;
+       char tmp_pid[MAX_PID_STR_BUFSZ];
+       int datalen;
+       bundle_raw *kb_data;
+       int res;
+
+       if ((pid = __get_caller_pid(kb)) < 0)
+                       return AUL_R_ERROR;
+
+       snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", cr_pid);
+
+       bundle_add(kb, AUL_K_CALLEE_PID, tmp_pid);
+
+       bundle_encode(kb, &kb_data, &datalen);
+       if ((res = __app_send_raw(pid, cmd, kb_data, datalen)) < 0)
+               res = AUL_R_ERROR;
+
+       free(kb_data);
+
+       return res;
+}
+
+static int __app_process_by_pid(int cmd,
+       const char *pkg_name, struct ucred *cr)
+{
+       int pid;
+       int ret = -1;
+
+       if (pkg_name == NULL)
+               return -1;
+
+       if ((cr->uid != 0) && (cr->uid != INHOUSE_UID)) {
+               _E("reject by security rule, your uid is %u\n", cr->uid);
+               return -1;
+       }
+
+       pid = atoi(pkg_name);
+       if (pid <= 1) {
+               _E("invalid pid");
+               return -1;
+       }
+
+       switch (cmd) {
+       case APP_RESUME_BY_PID:
+               ret = _resume_app(pid);
+               break;
+       case APP_TERM_BY_PID:
+               ret = _term_app(pid);
+               break;
+       case APP_KILL_BY_PID:
+               if ((ret = _send_to_sigkill(pid)) < 0)
+                       _E("fail to killing - %d\n", pid);
+       }
+
+       return ret;
+}
+
+static gboolean __add_history_handler(gpointer user_data)
+{
+       struct rua_rec rec;
+       int ret;
+       bundle *kb = NULL;
+       char *appid = NULL;
+       char *app_path = NULL;
+       struct appinfo *ai;
+       app_pkt_t *pkt = (app_pkt_t *)user_data;
+
+       kb = bundle_decode(pkt->data, pkt->len);
+       appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
+
+       if(strncmp(appid, "org.tizen.sat-ui", 18) == 0) {
+               app_path = "/usr/apps/org.tizen.sat-ui/bin/sat-ui KEY_EXEC_TYPE 0";
+       } else {
+               ai = (struct appinfo *)appinfo_find(_raf, appid);
+               app_path = (char *)appinfo_get_value(ai, AIT_EXEC);
+       }
+
+       ret = rua_init();
+
+       memset((void *)&rec, 0, sizeof(rec));
+
+       rec.pkg_name = appid;
+       rec.app_path = app_path;
+
+       if(pkt->len > 0) {
+               rec.arg = (char *)pkt->data;
+       }
+
+       _D("add rua history %s %s", rec.pkg_name, rec.app_path);
+
+       ret = rua_add_history(&rec);
+       if (ret == -1)
+               _D("rua add history error");
+
+       if (kb != NULL)
+               bundle_free(kb);
+       if (pkt != NULL)
+               free(pkt);
+
+       ret = rua_fini();
+
+       return FALSE;
+}
+
+static int __get_pid_cb(void *user_data, const char *group, pid_t pid)
+{
+       int *sz = user_data;
+
+       _D("%s: %d : %d", *sz, pid);
+       *sz = 1; /* 1 is enough */
+
+       return -1; /* stop the iteration */
+}
+
+static int __releasable(const char *filename)
+{
+       int sz;
+       int r;
+
+       if (!filename || !*filename) {
+               _E("release service: name is empty");
+               return -1;
+       }
+
+       r = cgutil_exist_group(_rcg, CTRL_MGR, filename);
+       if (r == -1) {
+               _E("release service: exist: %s", strerror(errno));
+               return -1;
+       }
+       if (r == 0) {
+               _E("release service: '%s' already not exist", filename);
+               return -1;
+       }
+
+       sz = 0;
+       r = cgutil_group_foreach_pid(_rcg, CTRL_MGR, filename,
+                       __get_pid_cb, &sz);
+       if (r == -1) {
+               _E("release service: '%s' read pid error", filename);
+               return -1;
+       }
+       if (sz > 0) {
+               _E("release service: '%s' group has process", filename);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int __release_srv(const char *filename)
+{
+       int r;
+       struct appinfo *ai;
+
+       r = __releasable(filename);
+       if (r == -1)
+               return -1;
+
+       ai = (struct appinfo *)appinfo_find(_raf, filename);
+       if (!ai) {
+               _E("release service: '%s' not found", filename);
+               return -1;
+       }
+
+       r = appinfo_get_boolean(ai, AIT_RESTART);
+       if (r == 1) {
+               /* Auto restart */
+               _D("Auto restart set: '%s'", filename);
+               return _start_srv(ai, NULL);
+       }
+
+       service_release(filename);
+
+       r = cgutil_remove_group(_rcg, CTRL_MGR, filename);
+       if (r == -1) {
+               _E("'%s' group remove error: %s", filename, strerror(errno));
+               return -1;
+       }
+
+       return 0;
+}
+
+static gboolean __request_handler(gpointer data)
+{
+       GPollFD *gpollfd = (GPollFD *) data;
+       int fd = gpollfd->fd;
+       app_pkt_t *pkt;
+       int clifd;
+       struct ucred cr;
+       int *status;
+       int ret = -1;
+       char *appid;
+       bundle *kb = NULL;
+       item_pkt_t *item;
+
+       if ((pkt = __app_recv_raw(fd, &clifd, &cr)) == NULL) {
+               _E("recv error");
+               return FALSE;
+       }
+
+       switch (pkt->cmd) {
+       case APP_OPEN:
+       case APP_RESUME:
+       case APP_START:
+       case APP_START_RES:
+               kb = bundle_decode(pkt->data, pkt->len);
+               appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
+               ret = _start_app(appid, kb, pkt->cmd, cr.pid, clifd);
+
+               item = malloc(sizeof(item_pkt_t));
+               item->pid = ret;
+               strncpy(item->appid, appid, 512);
+
+               if (kb != NULL)
+                       bundle_free(kb);
+
+               if(ret > 0) {
+                       g_timeout_add(1000, __add_history_handler, pkt);
+                       g_timeout_add(1200, __add_item_running_list, item);
+               } else {
+                       free(pkt);
+                       free(item);
+               }
+               break;
+       case APP_RESULT:
+       case APP_CANCEL:
+               kb = bundle_decode(pkt->data, pkt->len);
+               ret = __foward_cmd(pkt->cmd, kb, cr.pid);
+               __real_send(clifd, ret);
+               free(pkt);
+               break;
+       case APP_TERM_BY_PID:
+       case APP_RESUME_BY_PID:
+       case APP_KILL_BY_PID:
+               kb = bundle_decode(pkt->data, pkt->len);
+               appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
+               ret = __app_process_by_pid(pkt->cmd, appid, &cr);
+               __real_send(clifd, ret);
+               free(pkt);
+               break;
+       case APP_RUNNING_INFO:
+               _status_send_running_appinfo(clifd);
+               free(pkt);
+               break;
+       case APP_IS_RUNNING:
+               appid = malloc(MAX_PACKAGE_STR_SIZE);
+               strncpy(appid, (const char*)pkt->data, MAX_PACKAGE_STR_SIZE-1);
+               ret = _status_app_is_running(appid);
+               _D("APP_IS_RUNNING : %s : %d",appid, ret);
+               __send_result_to_client(clifd, ret);
+               free(pkt);
+               break;
+       case APP_KEY_RESERVE:
+               ret = _register_key_event(cr.pid);
+               __send_result_to_client(clifd, ret);
+               free(pkt);
+               break;
+       case APP_KEY_RELEASE:
+               ret = _unregister_key_event(cr.pid);
+               __send_result_to_client(clifd, ret);
+               free(pkt);
+               break;
+       case APP_STATUS_UPDATE:
+               status = (int *)pkt->data;
+               ret = _status_update_app_info_list(cr.pid, *status);
+               __send_result_to_client(clifd, ret);
+               free(pkt);
+               break;
+       case APP_RELEASED:
+               appid = malloc(MAX_PACKAGE_STR_SIZE);
+               strncpy(appid, (const char*)pkt->data, MAX_PACKAGE_STR_SIZE-1);
+               ret = __release_srv(appid);
+               __send_result_to_client(clifd, ret);
+               free(pkt);
+               break;
+       default:
+               _E("no support packet");
+       }
+
+       return TRUE;
+}
+
+static gboolean __au_glib_check(GSource *src)
+{
+       GSList *fd_list;
+       GPollFD *tmp;
+
+       fd_list = src->poll_fds;
+       do {
+               tmp = (GPollFD *) fd_list->data;
+               if ((tmp->revents & (POLLIN | POLLPRI)))
+                       return TRUE;
+               fd_list = fd_list->next;
+       } while (fd_list);
+
+       return FALSE;
+}
+
+static gboolean __au_glib_dispatch(GSource *src, GSourceFunc callback,
+                                 gpointer data)
+{
+       callback(data);
+       return TRUE;
+}
+
+static gboolean __au_glib_prepare(GSource *src, gint *timeout)
+{
+       return FALSE;
+}
+
+static GSourceFuncs funcs = {
+       .prepare = __au_glib_prepare,
+       .check = __au_glib_check,
+       .dispatch = __au_glib_dispatch,
+       .finalize = NULL
+};
+
+int _requset_init(struct amdmgr *amd)
+{
+       int fd;
+       int r;
+       GPollFD *gpollfd;
+       GSource *src;
+
+       fd = __create_server_sock(AUL_UTIL_PID);
+       src = g_source_new(&funcs, sizeof(GSource));
+
+       gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
+       gpollfd->events = POLLIN;
+       gpollfd->fd = fd;
+
+       g_source_add_poll(src, gpollfd);
+       g_source_set_callback(src, (GSourceFunc) __request_handler,
+                                     (gpointer) gpollfd, NULL);
+       g_source_set_priority(src, G_PRIORITY_DEFAULT);
+
+       r = g_source_attach(src, NULL);
+       if (r  == 0)
+       {
+               /* TODO: error handle*/
+               return -1;
+       }
+
+       _raf = amd->af;
+       _rcg = amd->cg;
+
+       return 0;
+}
+
+
diff --git a/am_daemon/amd_request.h b/am_daemon/amd_request.h
new file mode 100755 (executable)
index 0000000..3353c7e
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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 __AUL_AMD_REQUEST_H_
+#define __AUL_AMD_REQUEST_H_
+
+int _requset_init(struct amdmgr *amd);
+
+
+
+#endif
+
diff --git a/am_daemon/amd_status.c b/am_daemon/amd_status.c
new file mode 100755 (executable)
index 0000000..35fc38a
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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 <stdlib.h>
+#include <glib.h>
+#include <aul.h>
+#include <string.h>
+
+#include "amd_config.h"
+#include "amd_status.h"
+#include "aul_util.h"
+#include "simple_util.h"
+#include "app_sock.h"
+
+GSList *app_status_info_list = NULL;
+
+int _status_add_app_info_list(char *appid, char *app_path, int pid)
+{
+       GSList *iter = NULL;
+       app_status_info_t *info_t = NULL;
+
+       for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (app_status_info_t *)iter->data;
+               if(pid == info_t->pid) {
+                       return 0;
+               }
+       }
+
+       info_t = malloc(sizeof(app_status_info_t));
+       strncpy(info_t->appid, appid, MAX_PACKAGE_STR_SIZE-1);
+       strncpy(info_t->app_path, app_path, MAX_PACKAGE_APP_PATH_SIZE-1);
+       info_t->status = STATUS_LAUNCHING;
+       info_t->pid = pid;
+       app_status_info_list = g_slist_append(app_status_info_list, info_t);
+
+       for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (app_status_info_t *)iter->data;
+
+               _D("%s, %d, %d", info_t->appid, info_t->pid, info_t->status);
+       }
+
+       return 0;
+}
+
+int _status_update_app_info_list(int pid, int status)
+{
+       GSList *iter = NULL;
+       app_status_info_t *info_t = NULL;
+
+       for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (app_status_info_t *)iter->data;
+               if(pid == info_t->pid) {
+                       info_t->status = status;
+                       break;
+               }
+       }
+
+       for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (app_status_info_t *)iter->data;
+
+               _D("%s, %d, %d", info_t->appid, info_t->pid, info_t->status);
+       }
+
+       return 0;
+}
+
+int _status_remove_app_info_list(int pid)
+{
+       GSList *iter = NULL;
+       app_status_info_t *info_t = NULL;
+
+       for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (app_status_info_t *)iter->data;
+               if(pid == info_t->pid) {
+                       app_status_info_list = g_slist_remove(app_status_info_list, info_t);
+                       free(info_t);
+                       break;
+               }
+       }
+
+       for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (app_status_info_t *)iter->data;
+
+               _D("%s, %d, %d", info_t->appid, info_t->pid, info_t->status);
+       }
+
+       return 0;
+}
+
+int _status_app_is_running(char *appid)
+{
+       GSList *iter = NULL;
+       app_status_info_t *info_t = NULL;
+
+       for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (app_status_info_t *)iter->data;
+               if( strncmp(appid, info_t->appid, MAX_PACKAGE_STR_SIZE) == 0 ) {
+                       return info_t->pid;
+               }
+       }
+       return -1;
+}
+
+int _status_send_running_appinfo(int fd)
+{
+       GSList *iter = NULL;
+       app_status_info_t *info_t = NULL;
+       app_pkt_t *pkt = NULL;
+       int len;
+       char tmp_pid[MAX_PID_STR_BUFSZ];
+
+       pkt = (app_pkt_t *) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
+       if(!pkt) {
+               _E("malloc fail");
+               return 0;
+       }
+
+       memset(pkt, 0, AUL_SOCK_MAXBUFF);
+
+       for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
+       {
+               info_t = (app_status_info_t *)iter->data;
+               snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", info_t->pid);
+               strncat(pkt->data, tmp_pid, MAX_PID_STR_BUFSZ);
+               strncat(pkt->data, ":", 1);
+               strncat(pkt->data, info_t->appid, MAX_PACKAGE_STR_SIZE);
+               strncat(pkt->data, ":", 1);
+               strncat(pkt->data, info_t->app_path, MAX_PACKAGE_APP_PATH_SIZE);
+               strncat(pkt->data, ";", 1);
+       }
+
+       pkt->cmd = APP_RUNNING_INFO_RESULT;
+       pkt->len = strlen((char *)pkt->data) + 1;
+
+       if ((len = send(fd, pkt, pkt->len + 8, 0)) != pkt->len + 8) {
+               if (errno == EPIPE)
+                       _E("send failed due to EPIPE.\n");
+               _E("send fail to client");
+       }
+
+       if(pkt)
+               free(pkt);
+
+       close(fd);
+
+       return 0;
+}
+
diff --git a/am_daemon/amd_status.h b/am_daemon/amd_status.h
new file mode 100755 (executable)
index 0000000..4f532c2
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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.
+ *
+ */
+
+
+
+int _status_add_app_info_list(char *appid, char *app_path, int pid);
+int _status_update_app_info_list(int pid, int status);
+int _status_remove_app_info_list(int pid);
+int _status_app_is_running(char *appid);
+int _status_send_running_appinfo(int fd);
+
+
+//TODO : remove
+
+typedef struct _item_pkt_t {
+       int pid;
+       char appid[512];
+} item_pkt_t;
+
+gboolean __add_item_running_list(gpointer user_data);
+
+
+
diff --git a/aul.manifest b/aul.manifest
new file mode 100644 (file)
index 0000000..c48d84b
--- /dev/null
@@ -0,0 +1,15 @@
+<manifest>
+       <define>
+               <domain name="aul"/>
+               <provide>
+                       <label name="aul::db"/>
+               </provide>
+       </define>
+       <assign>
+               <filesystem path="/usr/lib/libaul.so.0" label="_"/>
+               <filesystem path="/usr/lib/libaul.so.0.1.0" label="_"/>
+       </assign>
+       <request>
+               <domain name="aul"/>
+       </request>
+</manifest>
index 74c8307..8917f67 100755 (executable)
@@ -44,7 +44,9 @@ enum app_cmd {
        APP_IS_RUNNING,
        APP_KEY_EVENT,
        APP_KEY_RESERVE,
-       APP_KEY_RELEASE
+       APP_KEY_RELEASE,
+       APP_STATUS_UPDATE,
+       APP_RELEASED
 };
 
 #define AUL_SOCK_PREFIX "/tmp/alaunch"
index 0a2ddef..ed0ba86 100755 (executable)
@@ -80,6 +80,16 @@ typedef enum _aul_return_val {
        AUL_R_OK = 0                    /**< General success */
 }aul_return_val;
 
+enum app_status {
+       STATUS_LAUNCHING,
+       STATUS_CREATED,
+       STATUS_FOCUS,
+       STATUS_VISIBLE,
+       STATUS_BG,
+       STATUS_DYING,
+       STATUS_HOME
+};
+
 /** @} */ 
 
 /**
@@ -162,7 +172,12 @@ typedef enum _aul_type{
 /** AUL public bundle value - To support Media key*/
 #define AUL_V_KEY_RELEASED     "__AUL_KEY_RELEASED__"
 
-
+/** AUL internal private key */
+#define AUL_K_EXEC             "__AUL_EXEC__"
+/** AUL internal private key */
+#define AUL_K_MULTIPLE         "__AUL_MULTIPLE__"
+/** AUL internal private key */
+#define AUL_K_PACKAGETYPE      "__AUL_PACKAGETYPE__"
 
 /** 
  * @brief      This is callback function for aul_launch_init
@@ -926,7 +941,7 @@ int aul_open_content(const char* content);
 
 /**
  * @par Description:
- *      This API get the default application(package name) associated with MIME type
+ *      This API get the default application(appid) associated with MIME type
  * @par Purpose:
  *     This API use to get default application associteted with mimetype 
  *     In general, Setting Application need this API. 
@@ -934,7 +949,7 @@ int aul_open_content(const char* content);
  *     Setting Application show mapping of default application / mimetype
  *
  * @param[in]  mimetype        a mime type
- * @param[out] defapp          a application package name of the app
+ * @param[out] defapp          a application appid of the app
  * @param[in]  len             length of defapp
  * @return     0 if success, negative value if fail
  * @retval     AUL_R_OK        - success
@@ -965,7 +980,7 @@ int aul_get_defapp_from_mime(const char *mimetype, char *defapp, int len);
 
 /**
  * @par Description:
- *      This API set the default application(package name) associated with MIME type
+ *      This API set the default application(appid) associated with MIME type
  * @par Purpose:
  *     This API use to change default application associteted with mimetype 
  *     In general, Setting Application or Installer need this API. 
@@ -974,7 +989,7 @@ int aul_get_defapp_from_mime(const char *mimetype, char *defapp, int len);
  *     So, application to process specific mimetype can be substituted. 
  *
  * @param[in]  mimetype        a mime type
- * @param[in]  defapp          a application package name of the app to be set
+ * @param[in]  defapp          a application appid of the app to be set
  * @return     0 if success, negative value if fail
  * @retval     AUL_R_OK        - success
  * @retval     AUL_R_EINVAL    - invalid argument(mimetype)
@@ -1399,7 +1414,7 @@ int aul_send_service_result(bundle *b);
 
 /**
  * @par Description:
- *     This API set the default application(package name) associated with service name 
+ *     This API set the default application(appid) associated with service name
  * @par Purpose:
  *     This API use to change default application associteted with service name
  *     In general, Setting Application needs this API. 
@@ -1438,7 +1453,7 @@ int aul_set_defapp_for_service(const char *svcname, const char *defapp);
 
 /**
  * @par Description:
- *     This API get the application package name associated with given service name
+ *     This API get the application appid associated with given service name
  * @par Purpose:
  *     This API use to get default application associteted with service name
  *     In general, Setting Application need this API. 
index 91e2416..d86a3f9 100755 (executable)
 struct history_data {
        char pkg_name[MAX_PACKAGE_STR_SIZE];
        char app_path[MAX_PACKAGE_APP_PATH_SIZE];
+       int pid;
        int len;
        unsigned char data[1];
 };
 
+typedef struct _app_status_info_t{
+       char appid[MAX_PACKAGE_STR_SIZE];
+       char app_path[MAX_PACKAGE_APP_PATH_SIZE];
+       int status;
+       int pid;
+} app_status_info_t;
+
+struct amdmgr {
+       struct appinfomgr *af;  /* appinfo manager */
+       struct cginfo *cg;  /* cgroup infomation */
+};
+
+int _add_app_status_info_list(char *appid, int pid);
+int _update_app_status_info_list(int pid, int status);
+int _remove_app_status_info_list(int pid);
+
 #endif
 
 
index d76815c..b0a952f 100755 (executable)
@@ -46,10 +46,7 @@ typedef struct {
        char *pkg_name;         /* package */
        char *app_path;         /* exec */
        char *original_app_path;        /* exec */
-       char *app_type;         /* x_slp_packagetype */
-       int multiple;           /* x_slp_multiple */
-       int task_manage;        /* x_slp_taskmanage */
-       char *pkg_type;
+       char *pkg_type;         /* x_slp_packagetype */
 } app_info_from_db;
 
 static inline char *_get_pkgname(app_info_from_db *menu_info)
@@ -98,24 +95,6 @@ static inline char *_get_original_app_path(app_info_from_db *menu_info)
        return menu_info->original_app_path;
 }
 
-static inline char *_get_app_app_type(app_info_from_db *menu_info)
-{
-       return menu_info->app_type;
-}
-
-static inline int _is_app_multi_inst(app_info_from_db *menu_info)
-{
-       if (menu_info->multiple)
-               return 1;
-       else
-               return 0;
-}
-
-static inline int _get_app_task_manage(app_info_from_db *menu_info)
-{
-       return menu_info->task_manage;
-}
-
 static inline void _free_app_info_from_db(app_info_from_db *menu_info)
 {
        if (menu_info != NULL) {
@@ -125,8 +104,6 @@ static inline void _free_app_info_from_db(app_info_from_db *menu_info)
                        free(menu_info->app_path);
                if (menu_info->original_app_path != NULL)
                        free(menu_info->original_app_path);
-               if (menu_info->app_type != NULL)
-                       free(menu_info->app_type);
                free(menu_info);
        }
 }
@@ -144,7 +121,7 @@ static inline app_info_from_db *_get_app_info_from_db_by_pkgname(
                return NULL;
        }
 
-       ret = ail_package_get_appinfo(pkgname, &handle);
+       ret = ail_get_appinfo(pkgname, &handle);
        if (ret != AIL_ERROR_OK) {
                _free_app_info_from_db(menu_info);
                return NULL;
@@ -165,18 +142,6 @@ static inline app_info_from_db *_get_app_info_from_db_by_pkgname(
        if (menu_info->app_path != NULL)
                menu_info->original_app_path = strdup(menu_info->app_path);
 
-       ret = ail_appinfo_get_bool(handle, AIL_PROP_X_SLP_MULTIPLE_BOOL,
-               (bool *)&menu_info->multiple);
-
-       ret = ail_appinfo_get_bool(handle, AIL_PROP_X_SLP_TASKMANAGE_BOOL,
-               (bool *)&menu_info->task_manage);
-       
-       ret = ail_appinfo_get_str(handle, AIL_PROP_TYPE_STR, &str);
-       if (str) {
-               menu_info->app_type = strdup(str);
-               str = NULL;
-       }
-
        ret = ail_appinfo_get_str(handle, AIL_PROP_X_SLP_PACKAGETYPE_STR, &str);
        if (str) {
                menu_info->pkg_type = strdup(str);
index eed476d..2079b20 100755 (executable)
 #undef LOG_TAG
 #define LOG_TAG "AUL"
 #endif
+#ifdef AMD_LOG
+#undef LOG_TAG
+#define LOG_TAG "AMD"
+#endif
+
 
 #define MAX_LOCAL_BUFSZ 128
 #define MAX_PID_STR_BUFSZ 20
@@ -63,4 +68,22 @@ int __proc_iter_pgid(int pgid, int (*iterfunc) (int pid, void *priv),
                     void *priv);
 char *__proc_get_cmdline_bypid(int pid);
 
+static inline const char *FILENAME(const char *filename)
+{
+       const char *p;
+       const char *r;
+
+       if (!filename)
+               return NULL;
+
+       r = p = filename;
+       while (*p) {
+               if (*p == '/')
+                       r = p + 1;
+               p++;
+       }
+
+       return r;
+}
+
 #endif
index 40c8172..0a15a02 100755 (executable)
@@ -2,5 +2,7 @@
 mkdir /tmp/alaunch
 chmod 1777 /tmp/alaunch
 
+
+/usr/bin/amd &
 /usr/bin/launchpad_preloading_preinitializing_daemon "                                                                                                                                                                                                         " &
-/usr/bin/ac_daemon &
+sleep 2
index 0e893d4..b7d1873 100755 (executable)
@@ -96,9 +96,6 @@ _static_ int __raise_win_by_x(int pid);
 _static_ int __send_to_sigkill(int pid);
 _static_ int __term_app(int pid);
 _static_ int __resume_app(int pid);
-_static_ int __app_process_by_pid(int cmd, 
-       const char *pkg_name, struct ucred *cr);
-_static_ int __nofork_processing(int cmd, int pid, bundle * kb);
 _static_ void __real_send(int clifd, int ret);
 _static_ void __send_result_to_caller(int clifd, int ret);
 _static_ void __launchpad_main_loop(int main_fd);
@@ -301,26 +298,28 @@ _static_ void __add_history(int caller, int callee, const char *pkgname,
 
        if (b) {
                bundle_encode(b, (bundle_raw **)&kb_data, &len);
-               hd = (struct history_data *)malloc(sizeof(char) * (len+1029));
+               hd = (struct history_data *)malloc(sizeof(char) * (len+1033));
 
                strncpy(hd->pkg_name, pkgname, MAX_PACKAGE_STR_SIZE-1);
                strncpy(hd->app_path, app_path, MAX_PACKAGE_APP_PATH_SIZE-1);
+               hd->pid = callee;
                hd->len = len;
                memcpy(hd->data, kb_data, len);
 
                __app_send_raw(AUL_UTIL_PID, APP_ADD_HISTORY, (unsigned char *)hd,
-                       hd->len+1029);
+                       hd->len+1033);
                free(kb_data);
                free(hd);
        } else {
-               hd = (struct history_data *)malloc(sizeof(char) * 1029);
+               hd = (struct history_data *)malloc(sizeof(char) * 1033);
 
                strncpy(hd->pkg_name, pkgname, MAX_PACKAGE_STR_SIZE-1);
                strncpy(hd->app_path, app_path, MAX_PACKAGE_APP_PATH_SIZE-1);
+               hd->pid = callee;
                hd->len = 0;
 
                __app_send_raw(AUL_UTIL_PID, APP_ADD_HISTORY, (unsigned char *)hd,
-                       1029);
+                       1033);
                free(hd);
        }
 
@@ -426,13 +425,9 @@ static inline int __parser(const char *arg, char *out, int out_size)
 _static_ void __modify_bundle(bundle * kb, int caller_pid,
                            app_info_from_db * menu_info, int cmd)
 {
-       char tmp_pid[MAX_PID_STR_BUFSZ];
-
-       snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", caller_pid);
-       bundle_add(kb, AUL_K_CALLER_PID, tmp_pid);
        bundle_del(kb, AUL_K_PKG_NAME);
-       if (cmd == APP_START_RES)
-               bundle_add(kb, AUL_K_WAIT_RESULT, "1");
+       bundle_del(kb, AUL_K_EXEC);
+       bundle_del(kb, AUL_K_PACKAGETYPE);
 
        /* Parse app_path to retrieve default bundle*/
        if (cmd == APP_START || cmd == APP_START_RES || cmd == APP_OPEN || cmd == APP_RESUME) {
@@ -594,64 +589,6 @@ _static_ int __foward_cmd(int cmd, bundle *kb, int cr_pid)
        return res;
 }
 
-_static_ int __app_process_by_pid(int cmd, 
-       const char *pkg_name, struct ucred *cr)
-{
-       int pid;
-       int ret = -1;
-
-       if (pkg_name == NULL)
-               return -1;
-
-       if ((cr->uid != 0) && (cr->uid != INHOUSE_UID)) {
-               _E("reject by security rule, your uid is %u\n", cr->uid);
-               return -1;
-       }
-
-       pid = atoi(pkg_name);
-       if (pid <= 1) {
-               _E("invalid pid");
-               return -1;
-       }
-
-       switch (cmd) {
-       case APP_RESUME_BY_PID:
-               ret = __resume_app(pid);
-               break;
-       case APP_TERM_BY_PID:
-               ret = __term_app(pid);
-               break;
-       case APP_KILL_BY_PID:
-               if ((ret = __send_to_sigkill(pid)) < 0)
-                       _E("fail to killing - %d\n", pid);
-       }
-
-       return ret;
-}
-
-_static_ int __nofork_processing(int cmd, int pid, bundle * kb)
-{
-       int ret = -1;
-       switch (cmd) {
-       case APP_OPEN:
-       case APP_RESUME:
-               _D("resume app's pid : %d\n", pid);
-               if ((ret = __resume_app(pid)) < 0)
-                       _E("__resume_app failed. error code = %d", ret);
-               PERF("resume app done");
-               break;
-
-       case APP_START:
-       case APP_START_RES:
-               _D("fake launch pid : %d\n", pid);
-               if ((ret = __fake_launch_app(cmd, pid, kb)) < 0)
-                       _E("fake_launch failed. error code = %d", ret);
-               PERF("fake launch done");
-               break;
-       }
-       return ret;
-}
-
 _static_ void __real_send(int clifd, int ret)
 {
        if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
@@ -711,6 +648,30 @@ _static_ void __send_result_to_caller(int clifd, int ret)
        return;
 }
 
+static app_info_from_db *_get_app_info_from_bundle_by_pkgname(
+                                                       const char *pkgname, bundle *kb)
+{
+       app_info_from_db *menu_info;
+
+       menu_info = calloc(1, sizeof(app_info_from_db));
+       if (menu_info == NULL) {
+               return NULL;
+       }
+
+       menu_info->pkg_name = strdup(pkgname);
+       menu_info->app_path = strdup(bundle_get_val(kb, AUL_K_EXEC));
+       if (menu_info->app_path != NULL)
+               menu_info->original_app_path = strdup(menu_info->app_path);
+       menu_info->pkg_type = strdup(bundle_get_val(kb, AUL_K_PACKAGETYPE));
+
+       if (!_get_app_path(menu_info)) {
+               _free_app_info_from_db(menu_info);
+               return NULL;
+       }
+
+       return menu_info;
+}
+
 _static_ void __launchpad_main_loop(int main_fd)
 {
        bundle *kb = NULL;
@@ -741,21 +702,10 @@ _static_ void __launchpad_main_loop(int main_fd)
        INIT_PERF(kb);
        PERF("packet processing start");
 
-       if (pkt->cmd == APP_RESULT || pkt->cmd == APP_CANCEL) {
-               pid = __foward_cmd(pkt->cmd, kb, cr.pid);
-               goto end;
-       }
-
        pkg_name = bundle_get_val(kb, AUL_K_PKG_NAME);
        _D("pkg name : %s\n", pkg_name);
 
-       if (pkt->cmd == APP_TERM_BY_PID || pkt->cmd == APP_RESUME_BY_PID ||
-           pkt->cmd == APP_KILL_BY_PID) {
-               pid = __app_process_by_pid(pkt->cmd, pkg_name, &cr);
-               goto end;
-       }
-
-       menu_info = _get_app_info_from_db_by_pkgname(pkg_name);
+       menu_info = _get_app_info_from_bundle_by_pkgname(pkg_name, kb);
        if (menu_info == NULL) {
                _D("such pkg no found");
                goto end;
@@ -776,21 +726,7 @@ _static_ void __launchpad_main_loop(int main_fd)
 
        PERF("get package information & modify bundle done");
 
-       if (_is_app_multi_inst(menu_info) == 0)
-               pid = __proc_iter_cmdline(NULL, (void *)app_path);
-
-       PERF("find pid by searching proc file system done");
-
-       if (pid > 0) {
-               int ret;
-
-               if (cr.pid == pid) {
-                       _D("caller process & callee process is same.[%s:%d]",
-                          pkg_name, pid);
-                       pid = -ELOCALLAUNCH_ID;
-               } else if ((ret = __nofork_processing(pkt->cmd, pid, kb)) < 0)
-                       pid = ret;
-       } else if (pkt->cmd != APP_RESUME) {
+       {
                pid = fork();
                if (pid == 0) {
                        PERF("fork done");
@@ -798,7 +734,6 @@ _static_ void __launchpad_main_loop(int main_fd)
 
                        close(clifd);
                        close(main_fd);
-                       ail_db_close();
                        __signal_unset_sigchld();
                        __signal_fini();
 
@@ -830,21 +765,6 @@ _static_ void __launchpad_main_loop(int main_fd)
        __send_result_to_caller(clifd, pid);
 
        if (pid > 0) {
-               int ret;
-               ret = ac_check_launch_privilege(pkg_name, menu_info->pkg_type, pid);
-               _D("ac_check_launch_privilege : %d", ret);
-               switch (pkt->cmd) {
-               case APP_OPEN:
-               case APP_RESUME:
-                       __add_history(cr.pid, pid, pkg_name, NULL, app_path);
-                       break;
-               case APP_START:
-               case APP_START_RES:
-                       __add_history(cr.pid, pid, pkg_name, kb, app_path);
-                       break;
-               default:
-                       _D("no launch case");
-               }
                if (is_real_launch) {
                        /*TODO: retry*/
                        __signal_block_sigchld();
diff --git a/packaging/ac.service b/packaging/ac.service
new file mode 100644 (file)
index 0000000..6ff0443
--- /dev/null
@@ -0,0 +1,15 @@
+#
+# classical example of a socket activated service?
+#
+
+[Unit]
+Description=Start the Access Control server
+
+[Service]
+ExecStartPre=-/bin/mkdir -m 1777 /tmp/alaunch
+ExecStart=/usr/bin/amd
+
+OOMScoreAdjust=-100
+
+[Install]
+WantedBy=multi-user.target
index a332a9b..afed333 100644 (file)
@@ -1,13 +1,19 @@
 Name:       aul
 Summary:    App utility library
-Version:    0.0.186
+Version:    0.0.201
 Release:    1
 Group:      System/Libraries
 License:    Apache License, Version 2.0
 Source0:    %{name}-%{version}.tar.gz
+#Source101:  launchpad-preload@.service
+#Source102:  ac.service
 
 Requires(post): /sbin/ldconfig
+Requires(post): /usr/bin/systemctl
 Requires(postun): /sbin/ldconfig
+Requires(postun): /usr/bin/systemctl
+Requires(preun): /usr/bin/systemctl
+
 BuildRequires:  cmake
 BuildRequires:  pkgconfig(dbus-glib-1)
 BuildRequires:  pkgconfig(sqlite3)
@@ -24,6 +30,8 @@ BuildRequires:  pkgconfig(rua)
 BuildRequires:  pkgconfig(ecore-x)
 BuildRequires:  pkgconfig(ecore-input)
 BuildRequires:  pkgconfig(utilX)
+BuildRequires:  pkgconfig(vconf)
+BuildRequires:  pkgconfig(pkgmgr-info)
 
 
 %description
@@ -52,51 +60,69 @@ rm -rf %{buildroot}
 
 mkdir -p %{buildroot}/etc/init.d
 install -m 755 launchpad_run %{buildroot}/etc/init.d
-chmod +x %{buildroot}/usr/bin/aul_service.sh
-chmod +x %{buildroot}/usr/bin/aul_service_test.sh
 
+mkdir -p %{buildroot}/etc/rc.d/rc3.d
+mkdir -p %{buildroot}/etc/rc.d/rc4.d
+ln -sf ../../init.d/launchpad_run %{buildroot}/%{_sysconfdir}/rc.d/rc3.d/S35launchpad_run
+ln -sf ../../init.d/launchpad_run %{buildroot}/%{_sysconfdir}/rc.d/rc4.d/S80launchpad_run
+
+mkdir -p %{buildroot}/opt/dbspace
+sqlite3 %{buildroot}/opt/dbspace/.mida.db < %{buildroot}/usr/share/aul/mida_db.sql
+rm -rf %{buildroot}/usr/share/aul/mida_db.sql
 
-%post
+#mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants
+#install -m 0644 %SOURCE101 %{buildroot}%{_libdir}/systemd/system/launchpad-preload@.service
+#ln -s ../launchpad-preload@.service %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/launchpad-preload@app.service
 
-/sbin/ldconfig
-mkdir -p /etc/rc.d/rc3.d
-mkdir -p /etc/rc.d/rc4.d
-ln -sf /etc/init.d/launchpad_run /etc/rc.d/rc3.d/S35launchpad_run
-ln -sf /etc/init.d/launchpad_run /etc/rc.d/rc4.d/S80launchpad_run
+#mkdir -p %{buildroot}%{_libdir}/systemd/user/tizen-middleware.target.wants
+#install -m 0644 %SOURCE102 %{buildroot}%{_libdir}/systemd/user/ac.service
+#ln -s ../ac.service %{buildroot}%{_libdir}/systemd/user/tizen-middleware.target.wants/ac.service
 
-mkdir -p /opt/dbspace
-sqlite3 /opt/dbspace/.mida.db < /usr/share/aul/mida_db.sql
-rm -rf /usr/share/aul/mida_db.sql
 
-chown 0:0 /usr/lib/libaul.so.0.1.0
-chown 0:5000 /opt/dbspace/.mida.db
-chown 0:5000 /opt/dbspace/.mida.db-journal
+#%preun
+#if [ $1 == 0 ]; then
+#    systemctl stop launchpad-preload@app.service
+#fi
 
-chmod 644 /usr/lib/libaul.so.0.1.0
-chmod 664 /opt/dbspace/.mida.db
-chmod 664 /opt/dbspace/.mida.db-journal
+#%post
+#/sbin/ldconfig
+#systemctl daemon-reload
+#if [ $1 == 1 ]; then
+#    systemctl restart launchpad-preload@app.service
+#fi
 
-%postun -p /sbin/ldconfig
+#%postun -p /sbin/ldconfig
+#systemctl daemon-reload
 
 %files
-/usr/lib/*.so.*
-/etc/init.d/launchpad_run
-/usr/bin/aul_service.sh
-/usr/bin/aul_service_test.sh
-/usr/share/aul/mida_db.sql
-/usr/bin/aul_mime.sh
-/usr/bin/aul_test
-/usr/bin/launch_app
+%attr(0644,root,root) %{_libdir}/libaul.so.0
+%attr(0644,root,root) %{_libdir}/libaul.so.0.1.0
+%{_sysconfdir}/init.d/launchpad_run
+%attr(0755,root,root) %{_bindir}/aul_service.sh
+%attr(0755,root,root) %{_bindir}/aul_service_test.sh
+%attr(0755,root,root) %{_sysconfdir}/rc.d/rc3.d/S35launchpad_run
+%attr(0755,root,root) %{_sysconfdir}/rc.d/rc4.d/S80launchpad_run
+%config(noreplace) %attr(0644,root,app) /opt/dbspace/.mida.db
+%config(noreplace) %attr(0644,root,app) /opt/dbspace/.mida.db-journal
+%attr(0755,root,root) %{_bindir}/aul_mime.sh
+%{_bindir}/aul_test
+%{_bindir}/launch_app
 /usr/share/aul/miregex/*
 /usr/share/aul/service/*
 /usr/share/aul/preload_list.txt
 /usr/share/aul/preexec_list.txt
-/usr/bin/launchpad_preloading_preinitializing_daemon
-/usr/bin/ac_daemon
+%{_bindir}/launchpad_preloading_preinitializing_daemon
+%{_bindir}/amd
+%{_bindir}/daemon-manager-release-agent
+%{_bindir}/daemon-manager-launch-agent
+#%{_libdir}/systemd/system/multi-user.target.wants/launchpad-preload@app.service
+#%{_libdir}/systemd/system/launchpad-preload@.service
+#%{_libdir}/systemd/user/tizen-middleware.target.wants/ac.service
+#%{_libdir}/systemd/user/ac.service
 
 %files devel
 /usr/include/aul/*.h
-/usr/lib/*.so
-/usr/lib/pkgconfig/*.pc
+%{_libdir}/*.so
+%{_libdir}/pkgconfig/*.pc
 
 
diff --git a/packaging/launchpad-preload@.service b/packaging/launchpad-preload@.service
new file mode 100644 (file)
index 0000000..6a924d4
--- /dev/null
@@ -0,0 +1,14 @@
+[Unit]
+Description=Start the preload/preinit daemon
+
+[Service]
+EnvironmentFile=/etc/sysconfig/tizen-mobile-ui
+Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/dbus/user_bus_socket
+Environment=DISPLAY=:0
+Environment=XDG_RUNTIME_DIR=/run/user/%I
+ExecStart=/usr/bin/launchpad_preloading_preinitializing_daemon
+KillSignal=SIGKILL
+KillMode=process
+
+[Install]
+WantedBy=multi-user.target
index 732da1b..4050c7d 100755 (executable)
@@ -294,8 +294,7 @@ int __app_send_raw(int pid, int cmd, unsigned char *kb_data, int datalen)
                        _E("recv error\n");
                        res = -ECOMM;
                }
-       } else
-               _D("recv result  = %d (%d)", res, len);
+       }
        close(fd);
 
        return res;
index 5aff5d4..1811101 100755 (executable)
@@ -36,6 +36,7 @@
 #include "simple_util.h"
 #include "launch.h"
 #include "key.h"
+#include "aul_util.h"
 
 static int aul_initialized = 0;
 static int aul_fd;
@@ -186,6 +187,7 @@ int app_request_to_launchpad(int cmd, const char *pkgname, bundle *kb)
        int must_free = 0;
        int ret = 0;
 
+       _D("launch request : %s", pkgname);
        if (kb == NULL) {
                kb = bundle_create();
                must_free = 1;
@@ -194,8 +196,9 @@ int app_request_to_launchpad(int cmd, const char *pkgname, bundle *kb)
 
        bundle_add(kb, AUL_K_PKG_NAME, pkgname);
        __set_stime(kb);
-       ret = app_send_cmd(LAUNCHPAD_PID, cmd, kb);
+       ret = app_send_cmd(AUL_UTIL_PID, cmd, kb);
 
+       _D("launch request result : %d", ret);
        if (ret == AUL_R_LOCAL) {
                _E("app_request_to_launchpad : Same Process Send Local");
                bundle *b;
index db9b83a..d7dace8 100755 (executable)
@@ -29,6 +29,7 @@
 #include "app_sock.h"
 #include "simple_util.h"
 #include "launch.h"
+#include "aul_util.h"
 
 /*#define ACTIVATE_PREEMPT_FEATURE*/
 
@@ -387,7 +388,7 @@ int aul_send_result(bundle *kb, int is_cancel)
                return AUL_R_OK;
        }
 
-       ret = app_send_cmd(LAUNCHPAD_PID, (is_cancel==1)? APP_CANCEL : APP_RESULT, kb);
+       ret = app_send_cmd(AUL_UTIL_PID, (is_cancel==1)? APP_CANCEL : APP_RESULT, kb);
        
        if(latest_caller_pid == pid)
                latest_caller_pid = -1;
index d12a6e9..a6d48ee 100755 (executable)
@@ -361,7 +361,7 @@ static int __launch_with_defapp(const char *mime_type, const char *mime_content)
                if (ret > 0)
                        ret = 0;
        } else {
-               ail_ret = ail_package_get_appinfo(defapp, &handle);
+               ail_ret = ail_get_appinfo(defapp, &handle);
 
                if (ail_ret == AIL_ERROR_OK) {
                        ail_destroy_appinfo(handle);
index 514a1dc..603c031 100755 (executable)
@@ -47,7 +47,10 @@ SLPAPI int aul_app_is_running(const char *appid)
 
        ret = __app_send_raw(AUL_UTIL_PID, APP_IS_RUNNING, (unsigned char*)appid, strlen(appid));
 
-       return ret;
+       if(ret > 0)
+               return true;
+
+       return 0;
 }
 
 SLPAPI int aul_app_get_running_app_info(aul_app_info_iter_fn enum_fn,
index 495c382..6634d23 100755 (executable)
@@ -172,7 +172,7 @@ SLPAPI int aul_open_service(const char *svcname, bundle *kb,
                }
                return ret;
        } else {
-               ail_ret = ail_package_get_appinfo(defapp, &handle);
+               ail_ret = ail_get_appinfo(defapp, &handle);
 
                if (ail_ret == AIL_ERROR_OK) {
                        ail_destroy_appinfo(handle);
diff --git a/src/status.c b/src/status.c
new file mode 100755 (executable)
index 0000000..95cea3c
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *  aul
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+ *
+ * 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_util.h"
+#include "app_sock.h"
+#include "aul_api.h"
+
+SLPAPI int aul_status_update(int status)
+{
+       int ret;
+
+       ret = __app_send_raw(AUL_UTIL_PID, APP_STATUS_UPDATE, (unsigned char *)&status, sizeof(status));
+
+       return ret;
+}
+
index 53ba673..547d3d9 100644 (file)
@@ -25,13 +25,6 @@ add_executable(test_app
 set_target_properties(test_app PROPERTIES COMPILE_FLAGS "-fpie")
 target_link_libraries(test_app "-pie" aul ${pkgs_LDFLAGS} )
 
-add_executable(ac_daemon
-                ac_daemon.c
-               ../src/app_sock.c
-               ../src/simple_util.c)
-target_link_libraries(ac_daemon app-checker-server rua glib-2.0 bundle ail aul utilX ${pkgs_LDFLAGS})
-INSTALL(TARGETS ac_daemon DESTINATION bin)
-
 
 
 ### Unit tests ###
index 0d417b6..a6000a5 100755 (executable)
@@ -1,23 +1,19 @@
 /*
- *  aul
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
- *
- * 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.
- *
- */
+Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+PROPRIETARY/CONFIDENTIAL
+This software is the confidential and proprietary information of 
+SAMSUNG ELECTRONICS ("Confidential Information"). You agree and acknowledge that 
+this software is owned by Samsung and you 
+shall not disclose such Confidential Information and shall 
+use it only in accordance with the terms of the license agreement 
+you entered into with SAMSUNG ELECTRONICS.  SAMSUNG make no 
+representations or warranties about the suitability 
+of the software, either express or implied, including but not 
+limited to the implied warranties of merchantability, fitness for 
+a particular purpose, or non-infringement. 
+SAMSUNG shall not be liable for any damages suffered by licensee arising out of or 
+related to this software.
+*/
 
 #include <glib.h>
 #include "aul_dbus.h"
index 82facae..730cbf7 100755 (executable)
@@ -1,23 +1,19 @@
 /*
- *  aul
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
- *
- * 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.
- *
- */
+Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+PROPRIETARY/CONFIDENTIAL
+This software is the confidential and proprietary information of 
+SAMSUNG ELECTRONICS ("Confidential Information"). You agree and acknowledge that 
+this software is owned by Samsung and you 
+shall not disclose such Confidential Information and shall 
+use it only in accordance with the terms of the license agreement 
+you entered into with SAMSUNG ELECTRONICS.  SAMSUNG make no 
+representations or warranties about the suitability 
+of the software, either express or implied, including but not 
+limited to the implied warranties of merchantability, fitness for 
+a particular purpose, or non-infringement. 
+SAMSUNG shall not be liable for any damages suffered by licensee arising out of or 
+related to this software.
+*/
 
 #include <stdio.h>
 #include <dbus/dbus.h>
index f6643ae..c5d7b7a 100755 (executable)
@@ -1,23 +1,19 @@
 /*
- *  aul
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
- *
- * 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.
- *
- */
+Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+PROPRIETARY/CONFIDENTIAL
+This software is the confidential and proprietary information of 
+SAMSUNG ELECTRONICS ("Confidential Information"). You agree and acknowledge that 
+this software is owned by Samsung and you 
+shall not disclose such Confidential Information and shall 
+use it only in accordance with the terms of the license agreement 
+you entered into with SAMSUNG ELECTRONICS.  SAMSUNG make no 
+representations or warranties about the suitability 
+of the software, either express or implied, including but not 
+limited to the implied warranties of merchantability, fitness for 
+a particular purpose, or non-infringement. 
+SAMSUNG shall not be liable for any damages suffered by licensee arising out of or 
+related to this software.
+*/
 
 #include <stdio.h>
 #include <glib.h>