Support script file to register static launchers 39/92039/12 accepted/tizen/common/20161027.073714 accepted/tizen/common/20161031.121708 accepted/tizen/ivi/20161031.082319 accepted/tizen/mobile/20161031.082214 accepted/tizen/tv/20161031.082239 accepted/tizen/wearable/20161031.082259 submit/tizen/20161027.062225 submit/tizen/20161031.010650
authorHwankyu Jhun <h.jhun@samsung.com>
Thu, 13 Oct 2016 04:20:29 +0000 (13:20 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Mon, 17 Oct 2016 23:57:55 +0000 (08:57 +0900)
Change-Id: I8d689122d43409502b7a13277ed63dfa86862600
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
CMakeLists.txt
inc/launcher_info.h [new file with mode: 0644]
src/launcher_info.c [new file with mode: 0644]
src/launchpad.c

index c4edd07..28ad574 100755 (executable)
@@ -98,6 +98,7 @@ SET(${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES
        src/launchpad.c
        src/launchpad_common.c
        src/loader_info.c
+       src/launcher_info.c
        )
 ADD_EXECUTABLE(${LAUNCHPAD_PROCESS_POOL} ${${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES})
 
diff --git a/inc/launcher_info.h b/inc/launcher_info.h
new file mode 100644 (file)
index 0000000..c8a470b
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LAUNCHER_INFO_H__
+#define __LAUNCHER_INFO_H__
+
+#include <glib.h>
+
+typedef struct launcher_info_s *launcher_info_h;
+
+GList *_launcher_info_load(const char *path);
+void _launcher_info_unload(GList *info);
+launcher_info_h _launcher_info_find(GList *info_list, const char *app_type);
+const char *_launcher_info_get_exe(launcher_info_h launcher_info);
+GList *_launcher_info_get_extra_args(launcher_info_h launcher_info);
+
+#endif /* __LAUNCHER_INFO_H__ */
diff --git a/src/launcher_info.c b/src/launcher_info.c
new file mode 100644 (file)
index 0000000..06b46ab
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "launcher_info.h"
+#include "launchpad_common.h"
+
+#define TAG_LAUNCHER   "[LAUNCHER]"
+#define TAG_NAME       "NAME"
+#define TAG_EXE                "EXE"
+#define TAG_APP_TYPE   "APP_TYPE"
+#define TAG_EXTRA_ARG  "EXTRA_ARG"
+
+struct launcher_info_s {
+       char *name;
+       char *exe;
+       GList *app_types;
+       GList *extra_args;
+};
+
+static struct launcher_info_s *__create_launcher_info(void)
+{
+       struct launcher_info_s *info;
+
+       info = calloc(1, sizeof(struct launcher_info_s));
+       if (info == NULL) {
+               _E("out of memory");
+               return NULL;
+       }
+
+       return info;
+}
+
+static void __destroy_launcher_info(gpointer data)
+{
+       struct launcher_info_s *info = (struct launcher_info_s *)data;
+
+       if (info == NULL)
+               return;
+
+       if (info->extra_args)
+               g_list_free_full(info->extra_args, free);
+       if (info->app_types)
+               g_list_free_full(info->app_types, free);
+       if (info->exe)
+               free(info->exe);
+       if (info->name)
+               free(info->name);
+       free(info);
+}
+
+static void __parse_app_types(struct launcher_info_s *info, char *line)
+{
+       char *token;
+       char *saveptr = NULL;
+       char tok[LINE_MAX];
+
+       token = strtok_r(line, "|", &saveptr);
+       while (token) {
+               tok[0] = '\0';
+               sscanf(token, "%s", tok);
+               if (tok[0] != '\0' && strcasecmp(tok, "null") != 0) {
+                       info->app_types = g_list_append(info->app_types,
+                                       strdup(tok));
+               }
+               token = strtok_r(NULL, "|", &saveptr);
+       }
+}
+
+static GList *__parse_file(GList *list, const char *path)
+{
+       FILE *fp;
+       char buf[LINE_MAX];
+       char tok1[LINE_MAX];
+       char tok2[LINE_MAX];
+       struct launcher_info_s *info = NULL;
+
+       fp = fopen(path, "rt");
+       if (fp == NULL)
+               return list;
+
+       while (fgets(buf, sizeof(buf), fp) != NULL) {
+               tok1[0] = '\0';
+               tok2[0] = '\0';
+               sscanf(buf, "%s %s", tok1, tok2);
+
+               if (strcasecmp(TAG_LAUNCHER, tok1) == 0) {
+                       if (info) {
+                               _D("name: %s, exe: %s", info->name, info->exe);
+                               list = g_list_append(list, info);
+                       }
+
+                       info = __create_launcher_info();
+                       if (info == NULL)
+                               break;
+
+                       continue;
+               }
+
+               if (tok1[0] == '\0' || tok2[0] == '\0' || tok1[0] == '#')
+                       continue;
+               if (info == NULL)
+                       continue;
+
+               if (strcasecmp(TAG_NAME, tok1) == 0) {
+                       info->name = strdup(tok2);
+                       if (info->name == NULL) {
+                               _E("out of memory");
+                               __destroy_launcher_info(info);
+                               info = NULL;
+                               break;
+                       }
+               } else if (strcasecmp(TAG_EXE, tok1) == 0) {
+                       info->exe = strdup(tok2);
+                       if (info->exe == NULL) {
+                               _E("out of memory");
+                               __destroy_launcher_info(info);
+                               info = NULL;
+                               break;
+                       }
+                       if (access(info->exe, F_OK | X_OK) != 0) {
+                               _E("Failed to access %s", info->exe);
+                               __destroy_launcher_info(info);
+                               info = NULL;
+                       }
+               } else if (strcasecmp(TAG_APP_TYPE, tok1) == 0) {
+                       __parse_app_types(info, &buf[strlen(tok1)]);
+                       if (info->app_types == NULL) {
+                               _E("app_types is NULL");
+                               __destroy_launcher_info(info);
+                               info = NULL;
+                               break;
+                       }
+               } else if (strcasecmp(TAG_EXTRA_ARG, tok1) == 0) {
+                       info->extra_args = g_list_append(info->extra_args,
+                                       strdup(tok2));
+               }
+       }
+       fclose(fp);
+
+       if (info) {
+               _D("name: %s, exe: %s", info->name, info->exe);
+               list = g_list_append(list, info);
+       }
+
+       return list;
+}
+
+GList *_launcher_info_load(const char *path)
+{
+       DIR *dp;
+       struct dirent dentry;
+       struct dirent *result = NULL;
+       GList *list = NULL;
+       char buf[PATH_MAX];
+       char *ext;
+
+       if (path == NULL)
+               return NULL;
+
+       dp = opendir(path);
+       if (dp == NULL)
+               return NULL;
+
+       while (readdir_r(dp, &dentry, &result) == 0 && result != NULL) {
+               if (dentry.d_name[0] == '.')
+                       continue;
+
+               ext = strrchr(dentry.d_name, '.');
+               if (ext && strcmp(ext, ".launcher") == 0) {
+                       snprintf(buf, sizeof(buf), "%s/%s",
+                                       path, dentry.d_name);
+                       list = __parse_file(list, buf);
+               }
+       }
+       closedir(dp);
+
+       return list;
+}
+
+void _launcher_info_unload(GList *info)
+{
+       if (info == NULL)
+               return;
+
+       g_list_free_full(info, __destroy_launcher_info);
+}
+
+static int __comp_str(gconstpointer a, gconstpointer b)
+{
+       if (a == NULL || b == NULL)
+               return -1;
+
+       return strcmp(a, b);
+}
+
+static int __comp_app_type(gconstpointer a, gconstpointer b)
+{
+       struct launcher_info_s *info = (struct launcher_info_s *)a;
+
+       if (info == NULL || info->app_types == NULL || b == NULL)
+               return -1;
+
+       if (g_list_find_custom(info->app_types, b, __comp_str))
+               return 0;
+
+       return -1;
+}
+
+launcher_info_h _launcher_info_find(GList *info_list, const char *app_type)
+{
+       GList *list;
+
+       if (info_list == NULL || app_type == NULL)
+               return NULL;
+
+       list = g_list_find_custom(info_list, app_type, __comp_app_type);
+       if (list == NULL)
+               return NULL;
+
+       return (launcher_info_h)list->data;
+}
+
+const char *_launcher_info_get_exe(launcher_info_h info)
+{
+       if (info == NULL)
+               return NULL;
+
+       return info->exe;
+}
+
+GList *_launcher_info_get_extra_args(launcher_info_h info)
+{
+       if (info == NULL)
+               return NULL;
+
+       return info->extra_args;
+}
index a0c8a8b..7917433 100755 (executable)
@@ -41,6 +41,7 @@
 #include "key.h"
 #include "launchpad.h"
 #include "loader_info.h"
+#include "launcher_info.h"
 
 #define AUL_PR_NAME         16
 #define EXEC_CANDIDATE_EXPIRED 5
@@ -50,6 +51,7 @@
 #define PROCESS_POOL_LAUNCHPAD_SOCK ".launchpad-process-pool-sock"
 #define LOADER_PATH_DEFAULT "/usr/bin/launchpad-loader"
 #define LOADER_INFO_PATH       "/usr/share/aul"
+#define LAUNCHER_INFO_PATH     LOADER_INFO_PATH
 #define REGULAR_UID_MIN 5000
 #define PAD_ERR_FAILED                 -1
 #define PAD_ERR_REJECTED               -2
@@ -82,11 +84,19 @@ typedef struct {
        int loader_id;
 } loader_context_t;
 
+struct app_launch_arg {
+       const char *appid;
+       const char *app_path;
+       appinfo_t *menu_info;
+       bundle *kb;
+};
+
 static int __sys_hwacc;
 static GList *loader_info_list;
 static int user_slot_offset;
 static GList *candidate_slot_list;
 static app_labels_monitor *label_monitor;
+static GList *launcher_info_list;
 
 static candidate_process_context_t *__add_slot(int type, int loader_id,
                int caller_pid, const char *loader_path, const char *extra,
@@ -504,11 +514,66 @@ static int __normal_fork_exec(int argc, char **argv)
        return 0;
 }
 
-static void __real_launch(const char *app_path, bundle *kb)
+static int __set_launcher_info(int *argc, char ***argv, const char *app_type)
+{
+       launcher_info_h launcher_info;
+       char **new_argv;
+       int new_argc;
+       const char *exe;
+       GList *extra_args;
+       int extra_argc;
+       const char *extra_arg;
+       GList *iter;
+       int i;
+
+       launcher_info = _launcher_info_find(launcher_info_list, app_type);
+       if (launcher_info == NULL)
+               return 0;
+
+       exe = _launcher_info_get_exe(launcher_info);
+       if (exe == NULL) {
+               _E("Failed to get launcher exe");
+               return -1;
+       }
+
+       extra_args = _launcher_info_get_extra_args(launcher_info);
+       extra_argc = g_list_length(extra_args) + 1;
+
+       new_argc = *argc + extra_argc;
+       new_argv = (char **)realloc(*argv, sizeof(char *) * new_argc);
+       if (new_argv == NULL) {
+               _E("Failed to reallocate memory");
+               return -1;
+       }
+
+       for (i = new_argc; i >= extra_argc; i--)
+               new_argv[i] = new_argv[i - extra_argc];
+
+       i = LOADER_ARG_PATH;
+       new_argv[i++] = strdup(exe);
+
+       iter = g_list_first(extra_args);
+       while (iter) {
+               extra_arg = (char *)iter->data;
+               if (extra_arg)
+                       new_argv[i++] = strdup(extra_arg);
+
+               iter = g_list_next(iter);
+       }
+
+       *argc = new_argc;
+       *argv = new_argv;
+
+       return 0;
+}
+
+static void __real_launch(const char *app_path, bundle *kb,
+               appinfo_t *menu_info)
 {
        int app_argc;
        char **app_argv;
        int i;
+       int ret;
 
        if (bundle_get_val(kb, AUL_K_DEBUG) != NULL)
                putenv("TIZEN_DEBUGGING_PORT=1");
@@ -516,12 +581,15 @@ static void __real_launch(const char *app_path, bundle *kb)
        app_argv = _create_argc_argv(kb, &app_argc);
        app_argv[LOADER_ARG_PATH] = strdup(app_path);
 
-       for (i = 0; i < app_argc; i++) {
-               if ((i % 2) == 1)
-                       continue;
-               SECURE_LOGD("input argument %d : %s##", i, app_argv[i]);
+       ret = __set_launcher_info(&app_argc, &app_argv, menu_info->app_type);
+       if (ret < 0) {
+               _E("Failed to set launcher info");
+               exit(-1);
        }
 
+       for (i = 0; i < app_argc; i += 2)
+               SECURE_LOGD("input argument %d : %s##", i, app_argv[i]);
+
        PERF("setup argument done");
        __normal_fork_exec(app_argc, app_argv);
 }
@@ -570,13 +638,6 @@ static int __prepare_exec(const char *appid, const char *app_path,
        return 0;
 }
 
-struct app_launch_arg {
-       const char *appid;
-       const char *app_path;
-       appinfo_t *menu_info;
-       bundle *kb;
-};
-
 static int __exec_app_process(void *arg)
 {
        struct app_launch_arg *launch_arg = arg;
@@ -597,7 +658,8 @@ static int __exec_app_process(void *arg)
                return ret;
 
        PERF("prepare exec - second done");
-       __real_launch(launch_arg->app_path, launch_arg->kb);
+       __real_launch(launch_arg->app_path, launch_arg->kb,
+                       launch_arg->menu_info);
 
        return PAD_ERR_FAILED;
 }
@@ -607,14 +669,14 @@ static int __launch_directly(const char *appid, const char *app_path, int clifd,
                candidate_process_context_t *cpc)
 {
        struct app_launch_arg arg;
+       int pid;
 
        arg.appid = appid;
        arg.app_path = app_path;
        arg.menu_info = menu_info;
        arg.kb = kb;
 
-       int pid = __fork_app_process(__exec_app_process, &arg);
-
+       pid = __fork_app_process(__exec_app_process, &arg);
        if (pid <= 0)
                _E("failed to fork app process");
 
@@ -1434,7 +1496,6 @@ static int __add_default_slots(void)
                _loader_info_dispose(loader_info_list);
 
        loader_info_list = _loader_info_load(LOADER_INFO_PATH);
-
        if (loader_info_list == NULL)
                return -1;
 
@@ -1490,9 +1551,19 @@ static int __before_loop(int argc, char **argv)
                                VCONFKEY_SETAPPL_APP_HW_ACCELERATION);
        }
 
+       launcher_info_list = _launcher_info_load(LAUNCHER_INFO_PATH);
+
        return 0;
 }
 
+static void __after_loop(void)
+{
+       _launcher_info_unload(launcher_info_list);
+
+       if (label_monitor)
+               security_manager_app_labels_monitor_finish(label_monitor);
+}
+
 #ifdef _APPFW_FEATURE_PRIORITY_CHANGE
 static void __set_priority(void)
 {
@@ -1528,8 +1599,7 @@ int main(int argc, char **argv)
 #endif
        g_main_loop_run(mainloop);
 
-       if (label_monitor)
-               security_manager_app_labels_monitor_finish(label_monitor);
+       __after_loop();
 
        return -1;
 }