Revert "Revert "Refactor app launcher tool"" 03/129903/1
authorHwankyu Jhun <h.jhun@samsung.com>
Thu, 18 May 2017 08:52:55 +0000 (17:52 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Thu, 18 May 2017 09:47:54 +0000 (18:47 +0900)
This reverts commit 034c7bf5b8958c573705262325ae7af8bdd28782.

Change-Id: Idf95e63089861810c7707366f49ca930cd580389

tool/app_launcher.c

index 45095ac..bf303c9 100644 (file)
 /*
- *  app_launcher
- *
- * Copyright (c) 2014, Intel Corporation.
- *
- * Contact: Baptiste DURAND <baptiste.durand@open.eurogiciel.org>
+ * Copyright (c) 2014 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- *
  */
 
+#define _GNU_SOURCE
 #include <stdio.h>
-#include <getopt.h>
 #include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <sys/types.h>
 #include <string.h>
-#include <linux/limits.h>
+#include <stdbool.h>
+#include <sys/types.h>
 #include <sys/inotify.h>
-
-#include <gio/gio.h>
+#include <linux/limits.h>
 #include <glib.h>
+#include <gio/gio.h>
 #include <pkgmgr-info.h>
-#include <bundle.h>
 #include <bundle_internal.h>
-#include <tzplatform_config.h>
 
 #include "aul.h"
 #include "aul_svc.h"
 #include "launch.h"
 
-#define PATH_RUN "/run"
-#define AMD_READY ".amd_ready"
 #define LAUNCHPAD_PROCESS_POOL_SOCK ".launchpad-process-pool-sock"
+#define AMD_SOCK ".amd-sock"
+#define PATH_AUL_DAEMONS "/run/aul/daemons"
+#define PATH_AMD_SOCK PATH_AUL_DAEMONS "/" AMD_SOCK
 #define APP_TYPE_UI "uiapp"
 #define APP_TYPE_SERVICE "svcapp"
-#define REGULAR_UID_MIN 5000
 #define INOTIFY_BUF (1024 * ((sizeof(struct inotify_event)) + 16))
-#define TIMEOUT_INTERVAL 1000
 
 struct launch_arg {
-       char appid[256];
-       char **argv;
-       int argc;
-       int flag_debug;
-       int flag_web;
-       int sync;
-       char op;
-       int pid;
+       char *appid;
+       bundle *b;
+       pid_t pid;
+       uid_t uid;
+       bool debug;
+       bool web_debug;
+       bool sync;
+       bool fast;
 };
 
-struct amd_watch {
+struct monitor {
        int fd;
        int wd;
        GIOChannel *io;
        guint wid;
-       char *appid;
-       int pid;
 };
 
-static GMainLoop *mainloop = NULL;
-static uid_t uid;
-static int monitoring_dead_signal;
-static int monitoring_amd_ready;
+enum command_e {
+       CMD_LIST,
+       CMD_STATUS,
+       CMD_START,
+       CMD_KILL,
+       CMD_TERMINATE,
+       CMD_IS_RUNNING,
+       CMD_FAST_START,
+       CMD_DIRECT_START,
+       CMD_MAX,
+};
+
+enum option_e {
+       OPT_DEBUG,
+       OPT_WEB_DEBUG,
+       OPT_USER,
+       OPT_MAX,
+};
+
+struct command {
+       const char *name;
+       int (*init)(struct launch_arg *arg);
+       int (*run)(struct launch_arg *arg);
+       void (*finish)(struct launch_arg *arg);
+};
+
+static GMainLoop *loop;
+static gchar *help;
+static struct monitor amd_monitor;
+static gpointer cmd_opt[CMD_MAX];
+static GOptionEntry cmd_entries[] = {
+       {
+               .long_name = "list",
+               .short_name = 'l',
+               .flags = 0,
+               .arg = G_OPTION_ARG_NONE,
+               .arg_data = &cmd_opt[CMD_LIST],
+               .description = "Show installed application list",
+               .arg_description = NULL
+       },
+       {
+               .long_name = "status",
+               .short_name = 'S',
+               .flags = 0,
+               .arg = G_OPTION_ARG_NONE,
+               .arg_data = &cmd_opt[CMD_STATUS],
+               .description = "Show the running application information",
+               .arg_description = NULL
+       },
+       {
+               .long_name = "start",
+               .short_name = 's',
+               .flags = 0,
+               .arg = G_OPTION_ARG_STRING,
+               .arg_data = &cmd_opt[CMD_START],
+               .description = "Execute the application",
+               .arg_description = "APPLICATION ID"
+       },
+       {
+               .long_name = "kill",
+               .short_name = 'k',
+               .flags = 0,
+               .arg = G_OPTION_ARG_STRING,
+               .arg_data = &cmd_opt[CMD_KILL],
+               .description = "Kill the running application",
+               .arg_description = "APPLICATION ID"
+       },
+       {
+               .long_name = "terminate",
+               .short_name = 't',
+               .flags = 0,
+               .arg = G_OPTION_ARG_STRING,
+               .arg_data = &cmd_opt[CMD_TERMINATE],
+               .description = "Terminte the running application",
+               .arg_description = "APPLICATION ID"
+       },
+       {
+               .long_name = "is-running",
+               .short_name = 'r',
+               .flags = 0,
+               .arg = G_OPTION_ARG_STRING,
+               .arg_data = &cmd_opt[CMD_IS_RUNNING],
+               .description = "Check whether the application is running or Not",
+               .arg_description = "APPLICATION ID"
+       },
+       {
+               .long_name = "fast-start",
+               .short_name = 'f',
+               .flags = 0,
+               .arg = G_OPTION_ARG_STRING,
+               .arg_data = &cmd_opt[CMD_FAST_START],
+               .description = "Execute the application quickly",
+               .arg_description = "APPLICATION ID"
+       },
+       {
+               .long_name = "direct-start",
+               .short_name = 'e',
+               .flags = 0,
+               .arg = G_OPTION_ARG_STRING,
+               .arg_data = &cmd_opt[CMD_DIRECT_START],
+               .description = "Execute the application without the loader",
+               .arg_description = "APPLICATION ID"
+       },
+};
+static gpointer opt[OPT_MAX];
+static GOptionEntry opt_entries[] = {
+       {
+               .long_name = "debug",
+               .short_name = 'd',
+               .flags = 0,
+               .arg = G_OPTION_ARG_NONE,
+               .arg_data = &opt[OPT_DEBUG],
+               .description = "Activate debug mode",
+               .arg_description = NULL
+       },
+       {
+               .long_name = "web-debug",
+               .short_name = 'w',
+               .flags = 0,
+               .arg = G_OPTION_ARG_NONE,
+               .arg_data = &opt[OPT_WEB_DEBUG],
+               .description = "Activate web debug mode, Use only for webapps",
+               .arg_description = NULL
+       },
+       {
+               .long_name = "user",
+               .short_name = 'u',
+               .flags = 0,
+               .arg = G_OPTION_ARG_INT,
+               .arg_data = &opt[OPT_USER],
+               .description = "Specify the user ID",
+               .arg_description = "USER ID"
+       },
+};
 
-static bundle *_create_internal_bundle(struct launch_arg *args)
+static GOptionGroup *__get_opt_group(void)
 {
-       bundle *b;
-       int i;
+       GOptionGroup *group;
 
-       if (!args->flag_debug && args->argc < 2)
+       group = g_option_group_new("option", "Additional Options:",
+                       "Additional options", NULL, NULL);
+       if (!group)
                return NULL;
 
-       b = bundle_create();
-       if (args->flag_debug)
-               bundle_add(b, AUL_K_DEBUG, "1");
+       g_option_group_add_entries(group, opt_entries);
+
+       return group;
+}
 
-       for (i = 0; i + 1 < args->argc; i += 2) {
-               bundle_add(b, args->argv[i], args->argv[i + 1]);
-               if (!strcmp(args->argv[i], "__LAUNCH_APP_MODE__") &&
-                               !strcmp(args->argv[i + 1], "SYNC"))
-                       args->sync = 1;
+static int __is_app_installed(const char *appid, uid_t uid)
+{
+       pkgmgrinfo_appinfo_filter_h filter;
+       int is_installed = 0;
+       int ret;
+
+       ret = pkgmgrinfo_appinfo_filter_create(&filter);
+       if (ret != PMINFO_R_OK) {
+               printf("Failed to create filter\n");
+               return -1;
        }
 
-       return b;
+       ret = pkgmgrinfo_appinfo_filter_add_string(filter,
+                       PMINFO_APPINFO_PROP_APP_ID, appid);
+       if (ret != PMINFO_R_OK) {
+               printf("Failed to add filter string\n");
+               pkgmgrinfo_appinfo_filter_destroy(filter);
+               return -1;
+       }
+
+       ret = pkgmgrinfo_appinfo_usr_filter_count(filter,
+                       &is_installed, uid);
+       if (ret != PMINFO_R_OK) {
+               printf("Failed to get filter count\n");
+               pkgmgrinfo_appinfo_filter_destroy(filter);
+               return -1;
+       }
+
+       pkgmgrinfo_appinfo_filter_destroy(filter);
+
+       return is_installed;
 }
 
-static int __launch_app_dead_handler(int pid, void *data)
+static int __cmd_common_init(struct launch_arg *arg)
 {
-       struct launch_arg *launch_arg_data = (struct launch_arg *)data;
+       if (!__is_app_installed(arg->appid, arg->uid)) {
+               printf("The app with ID: %s is not avaible for the user %d\n",
+                               arg->appid, arg->uid);
+               return -1;
+       }
 
-       if (launch_arg_data->pid == pid) {
-               if (monitoring_amd_ready)
-                       printf("... launch failed\n");
+       return 0;
+}
+
+static void __cmd_common_finish(struct launch_arg *arg)
+{
+       g_main_loop_quit(loop);
+}
+
+static int __installed_list_cb(const pkgmgrinfo_appinfo_h handle, void *data)
+{
+       char *label;
+       char *appid;
+
+       if (pkgmgrinfo_appinfo_get_label(handle, &label))
+               label = "";
 
-               g_main_loop_quit(mainloop);
+       if (pkgmgrinfo_appinfo_get_appid(handle, &appid)) {
+               printf("Failed to get appid\n");
+               return -1;
        }
 
+       printf("\t'%s'\t '%s'\n", label, appid);
+
        return 0;
 }
 
-static gboolean __check_running(gpointer data)
+static int __cmd_list_run(struct launch_arg *arg)
 {
        int ret;
-       struct launch_arg *launch_arg_data = (struct launch_arg *)data;
 
-       ret = aul_app_is_running(launch_arg_data->appid);
-       if (ret == 0) {
-               if (monitoring_amd_ready)
-                       return TRUE;
-               else
-                       printf("... launch failed\n");
+       printf("\tApplication List for user %u\n", arg->uid);
+       printf("\tUser's Application \n");
+       printf("\t Name \t AppID \n");
+       printf("\t=================================================\n");
 
-               g_main_loop_quit(mainloop);
+       ret = pkgmgrinfo_appinfo_get_usr_installed_list(__installed_list_cb,
+                       arg->uid, NULL);
+
+       printf("\t=================================================\n");
+
+       return ret;
+}
+
+static int __running_app_info_cb(const aul_app_info *info, void *data)
+{
+       printf("\t  %s (%d)\n", info->appid, info->pid);
+       return 0;
+}
+
+static int __cmd_status_run(struct launch_arg *arg)
+{
+       int ret;
+
+       printf("\t appId (PID)\n");
+       ret = aul_app_get_running_app_info_for_uid(__running_app_info_cb,
+                       NULL, arg->uid);
+       if (ret < 0) {
+               printf("Failed to show the list of running applications\n");
+               return -1;
        }
 
-       return FALSE;
+       return 0;
 }
 
-static void __reply_cb_func(bundle *b, int request_code, aul_svc_result_val result, void *data)
+static int __app_dead_signal_cb(int pid, void *data)
 {
-       char* port = NULL;
-       const char* pid_str = NULL;
-       int pid = 0;
+       struct launch_arg *arg = (struct launch_arg *)data;
+
+       if (arg->pid == pid) {
+               if (amd_monitor.wid)
+                       printf("... launch failed\n");
 
-       bundle_get_str(b, "port", &port);
-       pid_str = bundle_get_val(b, AUL_K_CALLEE_PID);
-       if (pid_str)
-               pid = atoi(pid_str);
+               g_main_loop_quit(loop);
+       }
 
-       if (port != NULL && strlen(port) > 0) {
-               printf("... successfully launched pid = %d with debug 1 port: %s\n",
-                                       pid, port);
+       return 0;
+}
+
+static void __reply_cb(bundle *b, int request_code,
+               aul_svc_result_val result, void *data)
+{
+       const char *port;
+       const char *pid;
+
+       port = bundle_get_val(b, "port");
+       pid = bundle_get_val(b, AUL_K_CALLEE_PID);
+       if (port && pid) {
+               printf("... successfully launched pid = %s with debug 1 port: %s\n",
+                               pid, port);
        } else {
                printf("... launch failed\n");
        }
 
-       g_main_loop_quit(mainloop);
+       g_main_loop_quit(loop);
 }
 
-static gboolean run_func(void *data)
+static int __cmd_start_run(struct launch_arg *arg)
 {
-       int pid;
-       bundle *kb;
-       struct launch_arg *launch_arg_data = (struct launch_arg *)data;
+       if (arg->web_debug) {
+               aul_svc_set_operation(arg->b, AUL_SVC_OPERATION_DEFAULT);
+               aul_svc_set_appid(arg->b, arg->appid);
+               arg->pid = aul_svc_run_service_for_uid(arg->b, 0, __reply_cb,
+                               NULL, arg->uid);
+       } else {
+               arg->pid = aul_launch_app_for_uid(arg->appid, arg->b, arg->uid);
+               if (arg->pid > 0) {
+                       printf("... successfully launched pid = %d with debug %d\n",
+                                       arg->pid, arg->debug);
+               }
+       }
 
-       kb = _create_internal_bundle(launch_arg_data);
+       if (arg->pid <= 0) {
+                printf("... launch failed\n");
+                return -1;
+       }
 
-       if (launch_arg_data->op == 'e') {
-               if (kb == NULL)
-                       kb = bundle_create();
-               aul_svc_set_loader_id(kb, PAD_LOADER_ID_DIRECT);
+       return 0;
+}
+
+static void __cmd_start_finish(struct launch_arg *arg)
+{
+       if (arg->pid > 0 && arg->sync) {
+               aul_listen_app_dead_signal(__app_dead_signal_cb, arg);
+               return;
        }
 
-       if (!launch_arg_data->flag_web) {
-               pid = aul_launch_app_for_uid((char *)launch_arg_data->appid, kb, uid);
+       g_main_loop_quit(loop);
+}
 
-               if (kb) {
-                       bundle_free(kb);
-                       kb = NULL;
-               }
+static int __kill_running_app_cb(const aul_app_info *info, void *data)
+{
+       if (!strcmp(info->appid, data)) {
+               aul_kill_pid(info->pid);
+               printf("\t Kill appId: %s (%d)\n", info->appid, info->pid);
+       }
 
-               if (pid > 0) {
-                       printf("... successfully launched pid = %d with debug %d\n",
-                                       pid, launch_arg_data->flag_debug);
-                       if (launch_arg_data->sync) {
-                               launch_arg_data->pid = pid;
-                               aul_listen_app_dead_signal(__launch_app_dead_handler, launch_arg_data);
-                               g_idle_add(__check_running, launch_arg_data);
-                               monitoring_dead_signal = 1;
-                               return FALSE;
-                       }
-               } else {
-                       printf("... launch failed\n");
-               }
+       return 0;
+}
 
-               g_main_loop_quit(mainloop);
-       } else {
-               aul_svc_set_operation(kb, AUL_SVC_OPERATION_DEFAULT);
-               aul_svc_set_appid(kb, (char *)launch_arg_data->appid);
-               pid = aul_svc_run_service_for_uid(kb, 0, __reply_cb_func, (void*)NULL, uid);
-               bundle_free(kb);
-               if (pid <= 0) {
-                       printf("... launch failed\n");
-                       g_main_loop_quit(mainloop);
-               }
+static int __cmd_kill_run(struct launch_arg *arg)
+{
+       int ret;
+
+       if (!aul_app_is_running_for_uid(arg->appid, arg->uid)) {
+               printf("result: App isn't running\n");
+               return -1;
        }
 
-       return FALSE;
+       ret = aul_app_get_running_app_info_for_uid(__kill_running_app_cb,
+                       arg->appid, arg->uid);
+       if (ret < 0)
+               return -1;
+
+       return 0;
+}
+
+static int __terminate_running_app_cb(const aul_app_info *info, void *data)
+{
+       if (!strcmp(info->appid, data)) {
+               aul_terminate_pid(info->pid);
+               printf("\t Terminate appId: %s (%d)\n", info->appid, info->pid);
+       }
+
+       return 0;
+}
+
+static int __cmd_terminate_run(struct launch_arg *arg)
+{
+       int ret;
+
+       if (!aul_app_is_running_for_uid(arg->appid, arg->uid)) {
+               printf("result: App isn't running\n");
+               return -1;
+       }
+
+       ret = aul_app_get_running_app_info_for_uid(__terminate_running_app_cb,
+                       arg->appid, arg->uid);
+       if (ret < 0)
+               return -1;
+
+       return 0;
+}
+
+static int __cmd_is_running_run(struct launch_arg *arg)
+{
+       if (!aul_app_is_running_for_uid(arg->appid, arg->uid)) {
+               printf("result: not running\n");
+               return -1;
+       }
+
+       printf("result: running\n");
+
+       return 0;
 }
 
 static int __get_gles(void)
 {
        FILE *fp;
-       char buf[PATH_MAX];
+       char buf[LINE_MAX];
        char *tmp;
        int gles = 1;
 
@@ -222,7 +464,7 @@ static int __get_gles(void)
        return gles;
 }
 
-static int __set_appinfo_for_launchpad(bundle *kb, const char *appid)
+static int __set_appinfo_for_launchpad(bundle *kb, const char *appid, uid_t uid)
 {
        pkgmgrinfo_appinfo_h handle;
        int ret;
@@ -264,8 +506,8 @@ static int __set_appinfo_for_launchpad(bundle *kb, const char *appid)
        if (ret != PMINFO_R_OK)
                goto end;
 
-       if (!component_type || (strcmp(component_type, APP_TYPE_SERVICE) != 0
-                       && strcmp(component_type, APP_TYPE_UI) != 0)) {
+       if (!component_type || (!strcmp(component_type, APP_TYPE_SERVICE) &&
+                               !strcmp(component_type, APP_TYPE_UI))) {
                ret = -1;
                goto end;
        }
@@ -278,14 +520,12 @@ static int __set_appinfo_for_launchpad(bundle *kb, const char *appid)
        if (ret != PMINFO_R_OK)
                goto end;
 
-       if (__get_gles()) {
-               if (hwacc == PMINFO_HWACCELERATION_OFF)
-                       hwacc_str = "NOT_USE";
-               else if (hwacc == PMINFO_HWACCELERATION_ON)
-                       hwacc_str = "USE";
-               else
-                       hwacc_str = "SYS";
-       }
+       if (__get_gles() && hwacc == PMINFO_HWACCELERATION_ON)
+               hwacc_str = "USE";
+       else if (hwacc == PMINFO_HWACCELERATION_OFF)
+               hwacc_str = "NOT_USE";
+       else
+               hwacc_str = "SYS";
 
        ret = pkgmgrinfo_appinfo_get_root_path(handle, &root_path);
        if (ret != PMINFO_R_OK)
@@ -314,7 +554,28 @@ end:
        return ret;
 }
 
-static gboolean __amd_monitor_cb(GIOChannel *io, GIOCondition cond,
+static int __cmd_fast_start_run(struct launch_arg *arg)
+{
+       if (!access(PATH_AMD_SOCK, F_OK))
+               return __cmd_start_run(arg);
+
+       if (__set_appinfo_for_launchpad(arg->b, arg->appid, arg->uid) < 0) {
+               printf("Failed to set appinfo\n");
+               return -1;
+       }
+
+       arg->pid = app_send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK,
+                       arg->uid, 0, arg->b);
+       if (arg->pid < 0) {
+               printf("... launch failed\n");
+               return -1;
+       }
+       arg->fast = true;
+
+       return 0;
+}
+
+static gboolean __monitor_amd_sock_cb(GIOChannel *io, GIOCondition cond,
                gpointer data)
 {
        char buf[INOTIFY_BUF];
@@ -323,7 +584,7 @@ static gboolean __amd_monitor_cb(GIOChannel *io, GIOCondition cond,
        struct inotify_event *event;
        char *p;
        int fd = g_io_channel_unix_get_fd(io);
-       struct amd_watch *watch = (struct amd_watch *)data;
+       struct launch_arg *arg = (struct launch_arg *)data;
 
        len = read(fd, buf, sizeof(buf));
        if (len < 0)
@@ -333,12 +594,12 @@ static gboolean __amd_monitor_cb(GIOChannel *io, GIOCondition cond,
                event = (struct inotify_event *)&buf[i];
                if (event->len) {
                        p = event->name;
-                       if (p && !strcmp(p, AMD_READY)) {
-                               aul_app_register_pid(watch->appid, watch->pid);
-                               monitoring_amd_ready = 0;
+                       if (p && !strcmp(p, AMD_SOCK)) {
+                               aul_app_register_pid(arg->appid, arg->pid);
+                               amd_monitor.wid = 0;
                                printf("... successfully launched pid = %d\n",
-                                               watch->pid);
-                               return FALSE;
+                                               arg->pid);
+                               return G_SOURCE_REMOVE;
                        }
                }
                i += offsetof(struct inotify_event, name) + event->len;
@@ -346,447 +607,301 @@ static gboolean __amd_monitor_cb(GIOChannel *io, GIOCondition cond,
                        break;
        }
 
-       return TRUE;
+       return G_SOURCE_CONTINUE;
 }
 
-static void __watch_destroy_cb(gpointer data)
+static void __monitor_amd_sock_destroy_cb(gpointer data)
 {
-       struct amd_watch *watch = (struct amd_watch *)data;
+       struct launch_arg *arg = (struct launch_arg *)data;
 
-       if (watch == NULL)
-               return;
-
-       g_io_channel_unref(watch->io);
+       if (!arg->sync)
+               g_main_loop_quit(loop);
 
-       if (watch->appid)
-               free(watch->appid);
-       if (watch->wd)
-               inotify_rm_watch(watch->fd, watch->wd);
-       close(watch->fd);
-       free(watch);
-
-       if (!monitoring_dead_signal && !monitoring_amd_ready)
-               g_main_loop_quit(mainloop);
+       g_io_channel_unref(amd_monitor.io);
+       inotify_rm_watch(amd_monitor.fd, amd_monitor.wd);
+       close(amd_monitor.fd);
 }
 
-static void __watch_amd_ready(const char *appid, int pid)
+static int __monitor_amd_sock_creation(struct launch_arg *arg)
 {
-       struct amd_watch *watch;
-
-       watch = (struct amd_watch *)calloc(1, sizeof(struct amd_watch));
-       if (watch == NULL)
-               return;
-
-       watch->appid = strdup(appid);
-       if (watch->appid == NULL) {
-               free(watch);
-               return;
-       }
-
-       watch->pid = pid;
+       amd_monitor.fd = inotify_init();
+       if (amd_monitor.fd < 0)
+               return -1;
 
-       watch->fd = inotify_init();
-       if (watch->fd < 0) {
-               free(watch->appid);
-               free(watch);
-               return;
+       amd_monitor.wd = inotify_add_watch(amd_monitor.fd, PATH_AUL_DAEMONS,
+                       IN_CREATE);
+       if (amd_monitor.wd < 0) {
+               close(amd_monitor.fd);
+               return -1;
        }
 
-       watch->wd = inotify_add_watch(watch->fd, PATH_RUN, IN_CREATE);
-       if (watch->wd < 0) {
-               close(watch->fd);
-               free(watch->appid);
-               free(watch);
-               return;
+       amd_monitor.io = g_io_channel_unix_new(amd_monitor.fd);
+       if (!amd_monitor.io) {
+               inotify_rm_watch(amd_monitor.fd, amd_monitor.wd);
+               close(amd_monitor.fd);
+               return -1;
        }
 
-       watch->io = g_io_channel_unix_new(watch->fd);
-       if (watch->io == 0) {
-               inotify_rm_watch(watch->fd, watch->wd);
-               close(watch->fd);
-               free(watch->appid);
-               free(watch);
-               return;
-       }
+       amd_monitor.wid = g_io_add_watch_full(amd_monitor.io,
+                       G_PRIORITY_DEFAULT, G_IO_IN, __monitor_amd_sock_cb,
+                       arg, __monitor_amd_sock_destroy_cb);
 
-       watch->wid = g_io_add_watch_full(watch->io, G_PRIORITY_DEFAULT,
-                       G_IO_IN, __amd_monitor_cb, watch, __watch_destroy_cb);
-       monitoring_amd_ready = 1;
+       return 1;
 }
 
-static void __register_appinfo(const char *appid, int pid)
+static int __register_appinfo(struct launch_arg *arg)
 {
-       char buf[PATH_MAX];
-
-       snprintf(buf, sizeof(buf), "/run/%s", AMD_READY);
-       if (access(buf, F_OK) == 0) {
-               aul_app_register_pid(appid, pid);
-               return;
+       if (!access(PATH_AMD_SOCK, F_OK)) {
+               aul_app_register_pid(arg->appid, arg->pid);
+               return 0;
        }
 
-       __watch_amd_ready(appid, pid);
+       return __monitor_amd_sock_creation(arg);
 }
 
 static gboolean __register_dead_signal(gpointer data)
 {
        int ret;
 
-       ret = aul_listen_app_dead_signal(__launch_app_dead_handler, data);
-       if (ret == 0) {
-               monitoring_dead_signal = 1;
-               return FALSE;
-       }
+       ret = aul_listen_app_dead_signal(__app_dead_signal_cb, data);
+       if (ret < 0)
+               return G_SOURCE_CONTINUE;
 
-       return TRUE;
+       return G_SOURCE_REMOVE;
 }
 
-static gboolean fast_run_func(void *data)
+static void __cmd_fast_start_finish(struct launch_arg *arg)
 {
-       int pid;
-       bundle *kb;
-       struct launch_arg *launch_arg_data = (struct launch_arg *)data;
-       int ret;
-
-       kb = _create_internal_bundle(launch_arg_data);
-       if (kb == NULL)
-               kb = bundle_create();
-
-       if (__set_appinfo_for_launchpad(kb, launch_arg_data->appid) < 0) {
-               printf("failed to set appinfo\n");
-               bundle_free(kb);
-               return FALSE;
-       }
-
-       pid = app_send_cmd_to_launchpad(LAUNCHPAD_PROCESS_POOL_SOCK,
-                       uid, 0, kb);
-       bundle_free(kb);
-       if (pid > 0) {
-               __register_appinfo(launch_arg_data->appid, pid);
-               if (!monitoring_amd_ready)
-                       printf("... successfully launched pid = %d\n", pid);
-
-               if (launch_arg_data->sync || monitoring_amd_ready) {
-                       launch_arg_data->pid = pid;
-                       ret = aul_listen_app_dead_signal(
-                                       __launch_app_dead_handler,
-                                       launch_arg_data);
-                       g_timeout_add(TIMEOUT_INTERVAL, __check_running,
-                                       launch_arg_data);
-                       if (ret == 0) {
-                               monitoring_dead_signal = 1;
-                       } else {
-                               g_timeout_add(TIMEOUT_INTERVAL,
-                                               __register_dead_signal,
-                                               launch_arg_data);
-                               return FALSE;
-                       }
-               }
+       if (!arg->fast) {
+               __cmd_start_finish(arg);
+               return;
+       }
 
-               if (monitoring_dead_signal || monitoring_amd_ready)
-                       return FALSE;
-       } else {
-               printf("... launch failed\n");
+       if (__register_appinfo(arg) > 0) {
+               g_timeout_add_seconds(1, __register_dead_signal, arg);
+               return;
        }
 
-       g_main_loop_quit(mainloop);
+       g_main_loop_quit(loop);
+}
 
-       return FALSE;
+static int __cmd_direct_start_run(struct launch_arg *arg)
+{
+       aul_svc_set_loader_id(arg->b, PAD_LOADER_ID_DIRECT);
+
+       return __cmd_start_run(arg);
 }
 
-static void print_usage(char *program)
+static void __cmd_direct_start_finish(struct launch_arg *arg)
 {
-       printf("Usage : %s [ OPTIONS... ] [ ARGS... ]\n", program);
-       printf(
-                       "   -h                        --help              Display this usage information.\n"
-                       "   -l                        --list              Display installed apps list\n"
-                       "   -S                        --status            Display running apps list\n"
-                       "   -s [tizen application ID] --start             Launch widget with tizen application ID\n"
-                       "   -k [tizen application ID] --kill              Kill widget with tizen application ID\n"
-                       "   -t [tizen application ID] --terminate         Terminate widget with tizen application ID\n"
-                       "   -r [tizen application ID] --is-running        Check whether application is running by tizen application ID,\n"
-                       "                                                 If widget is running, 0(zero) will be returned.\n"
-                       "   -f [tizen application ID] --fast-start        Fast launch app with tizen application ID\n"
-                       "   -e [tizen application ID] --direct-start      Direct Launch app with tizen application ID\n"
-                       "   -d                        --debug             Activate debug mode\n"
-                       "   -w                        --web-debug         Activate web debug mode. Use only for webapps\n"
-                       "   -u [uid]                  --user              Specify user. Use with other commands.\n"
-             );
+       __cmd_start_finish(arg);
 }
 
-static int __appinfo_list_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
+static bundle *__create_bundle(int argc, char **argv, bool debug)
 {
-       char *label;
-       char *appid;
+       bundle *b;
+       int i;
 
-       if (pkgmgrinfo_appinfo_get_label(handle, &label))
-               label = "";
+       b = bundle_create();
+       if (!b)
+               return NULL;
 
-       if (pkgmgrinfo_appinfo_get_appid(handle, &appid)) {
-               printf("Failed to get appid\n");
-               return -1;
-       }
+       if (debug)
+               bundle_add(b, AUL_K_DEBUG, "1");
 
-       printf("\t'%s'\t '%s'\n", label, appid);
+       for (i = 0; i + 1 < argc; i += 2)
+               bundle_add(b, argv[i], argv[i + 1]);
 
-       return 0;
+       return b;
 }
 
-static int list_app(void)
+static void __destroy_launch_arg(struct launch_arg *launch_arg)
 {
-       int ret = 0;
+       if (launch_arg == NULL)
+               return;
 
-       printf("\tApplication List for user %lu\n", (long)uid);
-       printf("\tUser's Application \n");
-       printf("\t Name \t AppID \n");
-       printf("\t=================================================\n");
-       if (pkgmgrinfo_appinfo_get_usr_installed_list(__appinfo_list_cb,
-                               uid, NULL) != PMINFO_R_OK)
-               ret = -1;
-       printf("\t=================================================\n");
-       return ret;
+       if (launch_arg->b)
+               bundle_free(launch_arg->b);
+       free(launch_arg);
 }
 
-static int __iterfunc_status(const aul_app_info *info, void *data)
+static struct launch_arg *__create_launch_arg(int argc, char **argv)
 {
-       printf("\t  %s (%d)\n", info->appid, info->pid);
-       return 0;
-}
+       struct launch_arg *launch_arg;
+       const char *val;
 
-static int __iterfunc_kill(const aul_app_info *info, void *data)
-{
-       if (!data)
-               return 0;
-       if (strcmp(info->appid, data) == 0) {
-               aul_kill_pid(info->pid);
-               printf("\t Kill appId: %s (%d)\n", info->appid, info->pid);
+       launch_arg = (struct launch_arg *)calloc(1, sizeof(struct launch_arg));
+       if (!launch_arg)
+               return NULL;
+
+       if (cmd_opt[CMD_START])
+               launch_arg->appid = cmd_opt[CMD_START];
+       else if (cmd_opt[CMD_KILL])
+               launch_arg->appid = cmd_opt[CMD_KILL];
+       else if (cmd_opt[CMD_TERMINATE])
+               launch_arg->appid = cmd_opt[CMD_TERMINATE];
+       else if (cmd_opt[CMD_IS_RUNNING])
+               launch_arg->appid = cmd_opt[CMD_IS_RUNNING];
+       else if (cmd_opt[CMD_FAST_START])
+               launch_arg->appid = cmd_opt[CMD_FAST_START];
+       else if (cmd_opt[CMD_DIRECT_START])
+               launch_arg->appid = cmd_opt[CMD_DIRECT_START];
+
+       if (opt[OPT_USER])
+               launch_arg->uid = GPOINTER_TO_INT(opt[OPT_USER]);
+       else
+               launch_arg->uid = getuid();
+
+       launch_arg->debug = GPOINTER_TO_INT(opt[OPT_DEBUG]);
+       launch_arg->web_debug = GPOINTER_TO_INT(opt[OPT_WEB_DEBUG]);
+       launch_arg->b = __create_bundle(argc, argv, launch_arg->debug);
+       if (launch_arg->b) {
+               val = bundle_get_val(launch_arg->b, "__LAUNCH_APP_MODE__");
+               if (val && !strcmp(val, "SYNC"))
+                       launch_arg->sync = true;
        }
-       return 0;
+
+       return launch_arg;
 }
 
-static int __iterfunc_term(const aul_app_info *info, void *data)
+static struct command cmd_table[] = {
+       [CMD_LIST] = {
+               .name = "list",
+               .init = NULL,
+               .run = __cmd_list_run,
+               .finish = __cmd_common_finish
+       },
+       [CMD_STATUS] = {
+               .name = "status",
+               .init = NULL,
+               .run = __cmd_status_run,
+               .finish = __cmd_common_finish
+       },
+       [CMD_START] = {
+               .name = "start",
+               .init = __cmd_common_init,
+               .run = __cmd_start_run,
+               .finish = __cmd_start_finish
+       },
+       [CMD_KILL] = {
+               .name = "kill",
+               .init = __cmd_common_init,
+               .run = __cmd_kill_run,
+               .finish = __cmd_common_finish
+       },
+       [CMD_TERMINATE] = {
+               .name = "terminate",
+               .init = __cmd_common_init,
+               .run = __cmd_terminate_run,
+               .finish = __cmd_common_finish
+       },
+       [CMD_IS_RUNNING] = {
+               .name = "is-running",
+               .init = __cmd_common_init,
+               .run = __cmd_is_running_run,
+               .finish = __cmd_common_finish
+       },
+       [CMD_FAST_START] = {
+               .name = "fast-start",
+               .init = __cmd_common_init,
+               .run = __cmd_fast_start_run,
+               .finish = __cmd_fast_start_finish
+       },
+       [CMD_DIRECT_START] = {
+               .name = "direct-start",
+               .init = __cmd_common_init,
+               .run = __cmd_direct_start_run,
+               .finish = __cmd_direct_start_finish
+       },
+};
+
+static struct command *__find_cmd(void)
 {
-       if (!data)
-               return 0;
-       if (strcmp(info->appid, data) == 0) {
-               aul_terminate_pid_for_uid(info->pid, uid);
-               printf("\t Terminate appId: %s (%d)\n", info->appid, info->pid);
+       int i;
+
+       for (i = 0; i < G_N_ELEMENTS(cmd_table); ++i) {
+               if (cmd_opt[i])
+                       return &cmd_table[i];
        }
-       return 0;
+
+       return NULL;
 }
 
-static int is_app_installed(char *appid)
+static gboolean __run_cmd(gpointer data)
 {
-       int is_installed = 0;
-       pkgmgrinfo_appinfo_filter_h filter;
-
-       if (pkgmgrinfo_appinfo_filter_create(&filter)) {
-               printf("Failed to create filter\n");
-               return -1;
+       struct launch_arg *launch_arg = (struct launch_arg *)data;
+       struct command *cmd;
+
+       cmd = __find_cmd();
+       if (cmd == NULL) {
+               printf("%s", help);
+               g_main_loop_quit(loop);
+               return G_SOURCE_REMOVE;
        }
 
-       if (pkgmgrinfo_appinfo_filter_add_string(filter,
-                               PMINFO_APPINFO_PROP_APP_ID, appid)) {
-               printf("Failed to add filter string\n");
-               pkgmgrinfo_appinfo_filter_destroy(filter);
-               return -1;
+       if (cmd->init && cmd->init(launch_arg)) {
+               g_main_loop_quit(loop);
+               return G_SOURCE_REMOVE;
        }
 
-       if (pkgmgrinfo_appinfo_usr_filter_count(filter, &is_installed,
-                               uid)) {
-               printf("Failed to get filter count\n");
-               pkgmgrinfo_appinfo_filter_destroy(filter);
-               return -1;
+       if (cmd->run && cmd->run(launch_arg)) {
+               g_main_loop_quit(loop);
+               return G_SOURCE_REMOVE;
        }
 
-       pkgmgrinfo_appinfo_filter_destroy(filter);
+       if (cmd->finish)
+               cmd->finish(launch_arg);
 
-       return is_installed;
+       return G_SOURCE_REMOVE;
 }
 
-int main(int argc, char **argv)
-{
-       char path[PATH_MAX];
-       bool disp_help = false;
-       bool disp_list = false;
-       bool disp_run_list = false;
-       bool is_running;
-       int next_opt;
-       int opt_idx = 0;
-       char op = '\0';
-       struct launch_arg args;
-       static struct option long_options[] = {
-               { "help", no_argument, 0, 'h' },
-               { "list", no_argument, 0, 'l' },
-               { "status", no_argument, 0, 'S' },
-               { "start", required_argument, 0, 's' },
-               { "args", required_argument, 0, 'a' },
-               { "kill", required_argument, 0, 'k' },
-               { "terminate", required_argument, 0, 't' },
-               { "is-running", required_argument, 0, 'r' },
-               { "fast-launch", required_argument, 0, 'f' },
-               { "direct-launch", required_argument, 0, 'e' },
-               { "debug", no_argument, 0, 'd' },
-               { "web-debug", no_argument, 0, 'w' },
-               { "user", required_argument, 0, 'u' },
-               { 0, 0, 0, 0 }
-       };
-       memset(&args, 0, sizeof(struct launch_arg));
-
-       uid = getuid();
-
-       do {
-               next_opt = getopt_long(argc,
-                               argv,
-                               "hlSs:k:t:r:f:e:dwu:",
-                               long_options,
-                               &opt_idx);
-
-               switch (next_opt) {
-               case 'h':
-                       if (!disp_help) {
-                               print_usage(argv[0]);
-                               disp_help = true;
-                       }
-                       break;
-               case 'l':
-                       if (disp_list)
-                               break;
-
-                       op = next_opt;
-                       disp_list = true;
-                       break;
-               case 'S':
-                       if (disp_run_list)
-                               break;
-                       op = next_opt;
-                       disp_run_list = true;
-                       break;
-               case 's':
-               case 'k':
-               case 't':
-               case 'r':
-               case 'f':
-               case 'e':
-                       if (strlen(optarg) > 255) {
-                               print_usage(argv[0]);
-                               return -1;
-                       } else {
-                               strncpy(args.appid, optarg, sizeof(args.appid) - 1);
-                       }
-                       op = next_opt;
-                       break;
-               case 'd':
-                       args.flag_debug = 1;
-                       break;
-               case 'w':
-                       args.flag_debug = 1;
-                       args.flag_web = 1;
-                       break;
-               case '?':
-                       break;
-               case -1:
-                       break;
-               case 'u':
-                       uid = atoi(optarg);
-                       break;
-               default:
-                       print_usage(argv[0]);
-                       break;
-               }
-       } while (next_opt != -1);
-
-       if (argc == 1)
-               print_usage(argv[0]);
-
-       if (op == 'S') {
-               printf("\t appId (PID)\n");
-               if (aul_app_get_running_app_info_for_uid(__iterfunc_status,
-                                       NULL, uid)) {
-                       printf("Fail to display the list of "
-                                       "Running applications\n");
-                       return -1;
-               }
-       } else if (op == 'l') {
-               if (list_app()) {
-                       printf("Fail to display the list of "
-                                       "installed applications\n");
-                       return -1;
-               }
+int main(int argc, char *argv[])
+{
+       GOptionContext *context;
+       GOptionGroup *opt_group;
+       GError *error = NULL;
+       struct launch_arg *launch_arg;
+
+       context = g_option_context_new(NULL);
+       g_option_context_add_main_entries(context, cmd_entries, NULL);
+
+       opt_group = __get_opt_group();
+       if (!opt_group) {
+               printf("Failed to get opt group\n");
+               g_option_context_free(context);
+               return -1;
        }
+       g_option_context_add_group(context, opt_group);
 
-       if (optind < argc) {
-               args.argc = argc - optind;
-               args.argv = &argv[optind];
-       }
-       if ((op == 's') || (op == 'k') || (op == 'r') || (op == 'f') || (op == 'e')) {
-               if (is_app_installed(args.appid) <= 0) {
-                       printf("The app with ID: %s is not avaible "
-                                       "for the user %d \n",
-                                       args.appid, uid);
-                       return -1;
-               }
+       if (!g_option_context_parse(context, &argc, &argv, &error)) {
+               printf("%s: %s\n", argv[0], error->message);
+               g_option_group_unref(opt_group);
+               g_option_context_free(context);
+               g_clear_error(&error);
+               return -1;
        }
 
-       if ((op == 's') || (op == 'e')) {
-               if (strlen(args.appid) <= 0) {
-                       printf("result: %s\n", "failed");
-                       return -1;
-               }
-               args.op = op;
-               g_idle_add(run_func, args.appid);
-               mainloop = g_main_loop_new(NULL, FALSE);
-               if (!mainloop) {
-                       printf("failed to create glib main loop\n");
-                       exit(EXIT_FAILURE);
-               }
-               g_main_loop_run(mainloop);
-               return 0;
-       } else if (op == 'k') {
-               is_running = aul_app_is_running_for_uid(args.appid, uid);
-               if (true == is_running) {
-                       aul_app_get_running_app_info_for_uid(__iterfunc_kill,
-                                       args.appid, uid);
-               } else {
-                       printf("result: %s\n", "App isn't running");
-                       return 1;
-               }
-       } else if (op == 't') {
-               is_running = aul_app_is_running_for_uid(args.appid, uid);
-               if (true == is_running) {
-                       aul_app_get_running_app_info_for_uid(__iterfunc_term,
-                                       args.appid, uid);
-               } else {
-                       printf("result: %s\n", "App isn't running");
-                       return 1;
-               }
-       } else if (op == 'r') {
-               is_running = aul_app_is_running_for_uid(args.appid, uid);
-               if (true == is_running) {
-                       printf("result: %s\n", "running");
-                       return 0;
-               } else {
-                       printf("result: %s\n", "not running");
-                       return 1;
-               }
-       } else if (op == 'f') {
-               if (strlen(args.appid) <= 0) {
-                       printf("result: failed\n");
-                       return -1;
-               }
+       help = g_option_context_get_help(context, TRUE, NULL);
+       g_option_group_unref(opt_group);
+       g_option_context_free(context);
 
-               snprintf(path, sizeof(path), "/run/%s", AMD_READY);
-               if (access(path, F_OK) == 0)
-                       g_idle_add(run_func, args.appid);
-               else
-                       g_idle_add(fast_run_func, args.appid);
+       launch_arg = __create_launch_arg(argc, argv);
+       if (!launch_arg) {
+               printf("%s", help);
+               free(help);
+               return -1;
+       }
 
-               mainloop = g_main_loop_new(NULL, FALSE);
-               if (!mainloop) {
-                       printf("failed to create glib main loop\n");
-                       exit(EXIT_FAILURE);
-               }
-               g_main_loop_run(mainloop);
+       g_idle_add(__run_cmd, launch_arg);
+       loop = g_main_loop_new(NULL, FALSE);
+       if (!loop) {
+               printf("Failed to create glib main loop\n");
+               exit(EXIT_FAILURE);
        }
+       g_main_loop_run(loop);
+       g_main_loop_unref(loop);
+       __destroy_launch_arg(launch_arg);
+       free(help);
 
        return 0;
 }