From 9f13bf463b153a65b0e9a94a5b7984e3d1c16339 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 20 Jan 2016 14:22:45 +0900 Subject: [PATCH] Support quick launch without AMD - Add "-f" option on app_launcher tool Change-Id: I2e41e089d8f24733c64f621f4f5a747093afceac Signed-off-by: Hwankyu Jhun --- include/aul_cmd.h | 2 + include/aul_sock.h | 5 ++ include/launch.h | 2 + src/aul_sock.c | 46 ++++++++++++++ src/launch.c | 59 ++++++++++++++++++ tool/app_launcher.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 280 insertions(+), 2 deletions(-) diff --git a/include/aul_cmd.h b/include/aul_cmd.h index a789fd3..fd6185f 100644 --- a/include/aul_cmd.h +++ b/include/aul_cmd.h @@ -73,6 +73,8 @@ enum app_cmd { APP_COM_LEAVE, APP_COM_MESSAGE, + APP_REGISTER_PID, + /* for special purpose */ AMD_RELOAD_APPINFO, /* reserved for AMD Agent */ diff --git a/include/aul_sock.h b/include/aul_sock.h index 86b2ca2..9ef4153 100644 --- a/include/aul_sock.h +++ b/include/aul_sock.h @@ -80,3 +80,8 @@ app_pkt_t *aul_sock_send_raw_with_pkt_reply(int pid, uid_t uid, int cmd, unsigne * This API is only for Appfw internally. */ app_pkt_t *aul_sock_recv_pkt(int fd, int *clifd, struct ucred *cr); + +/* + * This API is only for Appfw internally. + */ +int aul_sock_create_launchpad_client(const char *pad_type, uid_t uid); diff --git a/include/launch.h b/include/launch.h index 6e809c6..ddcace4 100644 --- a/include/launch.h +++ b/include/launch.h @@ -24,11 +24,13 @@ int aul_register_init_callback( int aul_is_initialized(); int aul_sock_handler(int fd); int aul_make_bundle_from_argv(int argc, char **argv, bundle **kb); +int aul_app_register_pid(const char *appid, int pid); int app_start(bundle *kb); int app_send_cmd(int pid, int cmd, bundle *kb); int app_send_cmd_for_uid(int pid, uid_t uid, int cmd, bundle *kb); int app_send_cmd_with_noreply(int pid, int cmd, bundle *kb); +int app_send_cmd_to_launchpad(const char *pad_type, uid_t uid, int cmd, bundle *kb); int app_request_to_launchpad(int cmd, const char *pkgname, bundle *kb); int app_request_to_launchpad_for_uid(int cmd, const char *pkgname, bundle *kb, uid_t uid); diff --git a/src/aul_sock.c b/src/aul_sock.c index cda5205..7039e7f 100644 --- a/src/aul_sock.c +++ b/src/aul_sock.c @@ -662,3 +662,49 @@ retry_recv: return res; } + +int aul_sock_create_launchpad_client(const char *pad_type, uid_t uid) +{ + int fd = -1; + struct sockaddr_un saddr = { 0, }; + int retry = 1; + int ret = -1; + + fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + /* support above version 2.6.27*/ + if (fd < 0) { + if (errno == EINVAL) { + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + _E("second chance - socket create error"); + return -1; + } + } else { + _E("socket error"); + return -1; + } + } + + saddr.sun_family = AF_UNIX; + snprintf(saddr.sun_path, sizeof(saddr.sun_path), + "/run/user/%d/%s", uid, pad_type); +retry_con: + ret = __connect_client_sock(fd, (struct sockaddr *)&saddr, + sizeof(saddr), 100 * 1000); + if (ret < -1) { + _E("maybe peer not launched or peer daed\n"); + if (retry > 0) { + usleep(100 * 1000); + retry--; + goto retry_con; + } + } + if (ret < 0) { + close(fd); + return -1; + } + + __set_sock_option(fd, 1); + + return fd; +} diff --git a/src/launch.c b/src/launch.c index 8af598a..7ecf286 100644 --- a/src/launch.c +++ b/src/launch.c @@ -257,6 +257,48 @@ API int app_send_cmd_with_noreply(int pid, int cmd, bundle *kb) return res; } +API int app_send_cmd_to_launchpad(const char *pad_type, uid_t uid, int cmd, bundle *kb) +{ + int fd; + int datalen; + bundle_raw *kb_data; + int len; + int res; + + fd = aul_sock_create_launchpad_client(pad_type, uid); + if (fd < 0) + return -1; + + bundle_encode(kb, &kb_data, &datalen); + res = aul_sock_send_raw_async_with_fd(fd, cmd, + kb_data, datalen, AUL_SOCK_NONE); + if (res < 0) { + free(kb_data); + close(fd); + return res; + } + +retry_recv: + len = recv(fd, &res, sizeof(int), 0); + if (len == -1) { + if (errno == EAGAIN) { + _E("recv timeout: %s", strerror(errno)); + res = -EAGAIN; + } else if (errno == EINTR) { + _D("recv: %s", strerror(errno)); + goto retry_recv; + } else { + _E("recv error: %s", strerror(errno)); + res = -ECOMM; + } + } + + free(kb_data); + close(fd); + + return res; +} + static void __clear_internal_key(bundle *kb) { bundle_del(kb, AUL_K_CALLER_PID); @@ -949,4 +991,21 @@ API int aul_remove_loader(int loader_id) return ret; } +API int aul_app_register_pid(const char *appid, int pid) +{ + char buf[MAX_PID_STR_BUFSZ]; + int ret; + bundle *b; + + if (!appid || pid <= 0) + return AUL_R_EINVAL; + + b = bundle_create(); + bundle_add_str(b, AUL_K_APPID, appid); + snprintf(buf, sizeof(buf), "%d", pid); + bundle_add_str(b, AUL_K_PID, buf); + ret = app_send_cmd_with_noreply(AUL_UTIL_PID, APP_REGISTER_PID, b); + bundle_free(b); + return ret; +} diff --git a/tool/app_launcher.c b/tool/app_launcher.c index 4032afc..4db865f 100644 --- a/tool/app_launcher.c +++ b/tool/app_launcher.c @@ -27,12 +27,20 @@ #include #include #include +#include #include #include #include #include "aul.h" +#include "aul_svc.h" +#include "launch.h" + +#define AMD_READY ".amd_ready" +#define LAUNCHPAD_PROCESS_POOL_SOCK ".launchpad-process-pool-sock" +#define APP_TYPE_UI "uiapp" +#define APP_TYPE_SERVICE "svcapp" static GMainLoop *mainloop = NULL; @@ -106,6 +114,138 @@ static gboolean run_func(void *data) return FALSE; } +static int __get_gles(void) +{ + FILE *fp; + char buf[PATH_MAX]; + char *tmp; + int gles = 1; + + fp = fopen("/proc/cmdline", "r"); + if (fp == NULL) + return gles; + + if (fgets(buf, sizeof(buf), fp) != NULL) { + tmp = strstr(buf, "gles"); + if (tmp != NULL) + sscanf(tmp, "gles=%d", &gles); + } + + fclose(fp); + + return gles; +} + +static int __set_appinfo_for_launchpad(bundle *kb, const char *appid) +{ + pkgmgrinfo_appinfo_h handle; + int ret; + char *pkgid; + char *exec; + char *apptype; + char *component_type; + pkgmgrinfo_app_hwacceleration hwacc = PMINFO_HWACCELERATION_NOT_USE_GL; + const char *hwacc_str = "NOT_USE"; + bool process_pool = false; + + if (kb == NULL) + return -1; + + ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, getuid(), &handle); + if (ret != PMINFO_R_OK) + return -1; + + ret = pkgmgrinfo_appinfo_get_exec(handle, &exec); + if (ret != PMINFO_R_OK) + goto end; + + ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid); + if (ret != PMINFO_R_OK) + goto end; + + ret = pkgmgrinfo_appinfo_get_apptype(handle, &apptype); + if (ret != PMINFO_R_OK) + goto end; + + ret = pkgmgrinfo_appinfo_get_component_type(handle, &component_type); + if (ret != PMINFO_R_OK) + goto end; + + if (!component_type || (strcmp(component_type, APP_TYPE_SERVICE) != 0 + && strcmp(component_type, APP_TYPE_UI) != 0)) { + ret = -1; + goto end; + } + + ret = pkgmgrinfo_appinfo_get_hwacceleration(handle, &hwacc); + if (ret != PMINFO_R_OK) + goto end; + + ret = pkgmgrinfo_appinfo_is_process_pool(handle, &process_pool); + if (ret != PMINFO_R_OK) + goto end; + + if (__get_gles()) { + if (hwacc == PMINFO_HWACCELERATION_NOT_USE_GL) + hwacc_str = "NOT_USE"; + else if (hwacc == PMINFO_HWACCELERATION_USE_GL) + hwacc_str = "USE"; + else + hwacc_str = "SYS"; + } + + bundle_add(kb, AUL_K_APPID, appid); + bundle_add(kb, AUL_K_HWACC, hwacc_str); + bundle_add(kb, AUL_K_EXEC, exec); + bundle_add(kb, AUL_K_PACKAGETYPE, apptype); + bundle_add(kb, AUL_K_PKGID, pkgid); + bundle_add(kb, AUL_K_INTERNAL_POOL, process_pool ? "true" : "false"); + bundle_add(kb, AUL_K_COMP_TYPE, component_type); + + aul_svc_set_loader_id(kb, PAD_LOADER_ID_DIRECT); + +end: + pkgmgrinfo_appinfo_destroy_appinfo(handle); + + return ret; +} + +static gboolean fast_run_func(void *data) +{ + int pid; + bundle *kb; + struct launch_arg *launch_arg_data = (struct launch_arg *)data; + + 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, + getuid(), 0, kb); + bundle_free(kb); + if (pid > 0) { + printf("... successfully launched pid = %d\n", pid); + aul_app_register_pid(launch_arg_data->appid, pid); + if (launch_arg_data->sync) { + aul_listen_app_dead_signal(__launch_app_dead_handler, + (void *)(intptr_t)pid); + return FALSE; + } + } else { + printf("... launch failed\n"); + } + + g_main_loop_quit(mainloop); + + return FALSE; +} + static void print_usage(char *program) { printf("Usage : %s [ OPTIONS... ] [ ARGS... ]\n", program); @@ -118,6 +258,7 @@ static void print_usage(char *program) " -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" " -d --debug Activate debug mode\n" ); } @@ -214,6 +355,7 @@ static int is_app_installed(char *appid) int main(int argc, char **argv) { + char path[PATH_MAX]; bool disp_help = false; bool disp_list = false; bool disp_run_list = false; @@ -231,6 +373,7 @@ int main(int argc, char **argv) { "kill", required_argument, 0, 'k' }, { "terminate", required_argument, 0, 't' }, { "is-running", required_argument, 0, 'r' }, + { "fast-launch", required_argument, 0, 'f' }, { "debug", no_argument, 0, 'd' }, { 0, 0, 0, 0 } }; @@ -239,7 +382,7 @@ int main(int argc, char **argv) do { next_opt = getopt_long(argc, argv, - "hlSs:k:t:r:d", + "hlSs:k:t:r:f:d", long_options, &opt_idx); @@ -276,6 +419,7 @@ int main(int argc, char **argv) case 'k': case 't': case 'r': + case 'f': if (strlen(optarg) > 255) { print_usage(argv[0]); return -1; @@ -304,7 +448,7 @@ int main(int argc, char **argv) args.argc = argc - optind; args.argv = &argv[optind]; } - if ((op == 's') || (op == 'k') || (op == 'r')) { + if ((op == 's') || (op == 'k') || (op == 'r') || (op == 'f')) { if (is_app_installed(args.appid) <= 0) { printf("The app with ID: %s is not avaible " "for the user %d \n", @@ -354,6 +498,26 @@ int main(int argc, char **argv) printf("result: %s\n", "not running"); return 1; } + } else if (op == 'f') { + if (strlen(args.appid) <= 0) { + printf("result: failed\n"); + return -1; + } + aul_launch_init(NULL, NULL); + + snprintf(path, sizeof(path), "/run/user/%d/%s", + getuid(), AMD_READY); + if (access(path, F_OK) == 0) + g_idle_add(run_func, args.appid); + else + g_idle_add(fast_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; -- 2.7.4