2 * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include <sys/prctl.h>
23 #include <sys/types.h>
25 #include <linux/limits.h>
26 #include <Elementary.h>
27 #include <bundle_internal.h>
30 #include "launchpad_common.h"
31 #include "launchpad.h"
34 #define KEY_LOADER_TYPE "loader_type"
35 #define LOADER_TYPE_COMMON "common-loader"
36 #define LOADER_TYPE_HW "hw-loader"
37 #define LOADER_TYPE_SW "sw-loader"
39 #define PATH_LIB_VC_ELM "/usr/lib/libvc-elm.so.0"
41 extern bundle *launchpad_loader_get_bundle(void);
43 static Ecore_Fd_Handler *__fd_handler;
44 static loader_receiver_cb __receiver;
48 static int __sys_hwacc;
49 static Evas_Object *__win;
50 static Evas_Object *__bg;
51 static Evas_Object *__conform;
67 typedef void (*loader_convertible)(void);
69 static void __vconf_cb(keynode_t *key, void *data)
73 name = vconf_keynode_get_name(key);
74 if (name && strcmp(name, VCONFKEY_SETAPPL_APP_HW_ACCELERATION) == 0) {
75 __sys_hwacc = vconf_keynode_get_int(key);
76 _D("sys hwacc: %d", __sys_hwacc);
80 static void __init_theme(void)
82 char *theme = elm_theme_list_item_path_get(eina_list_data_get(
83 elm_theme_list_get(NULL)), NULL);
84 Eina_Bool is_exist = edje_file_group_exists(theme, "*");
87 _D("theme path: %s", theme);
93 static void __init_window(void)
95 __win = elm_win_add(NULL, "package_name", ELM_WIN_BASIC);
97 _E("[candidate] elm_win_add() failed");
101 elm_win_precreated_object_set(__win);
103 __bg = elm_bg_add(__win);
105 evas_object_size_hint_weight_set(__bg, EVAS_HINT_EXPAND,
107 elm_win_resize_object_add(__win, __bg);
108 elm_bg_precreated_object_set(__bg);
110 _E("[candidate] elm_bg_add() failed");
113 __conform = elm_conformant_add(__win);
115 evas_object_size_hint_weight_set(__conform, EVAS_HINT_EXPAND,
117 elm_conformant_precreated_object_set(__conform);
119 _E("elm_conformant_add() failed");
123 static void __fini_window(void)
128 evas_object_del(__conform);
129 elm_conformant_precreated_object_set(NULL);
134 evas_object_del(__bg);
135 elm_bg_precreated_object_set(NULL);
140 evas_object_del(__win);
141 elm_win_precreated_object_set(NULL);
146 static void __preload_lib(bundle *b)
151 const char **so_array;
156 so_array = bundle_get_str_array(b, "preload", &len);
161 for (i = 0; i < len; i++) {
163 _E("so_array[%d] is nullptr", i);
166 if (so_array[i][0] == '\0') {
167 _E("so_array[%d] is empty string", i);
171 _D("preload %s# - handle : %p", so_array[i], handle);
172 handle = dlopen(so_array[i], RTLD_NOW | RTLD_NODELETE);
174 _E("failed to load: %s, err: %s",
175 so_array[i], dlerror());
180 static void __loader_create_cb(bundle *extra, int type, void *user_data)
182 int elm_init_cnt = 0;
191 bundle_get_str(extra, KEY_LOADER_TYPE, <ype);
194 _E("No loader type");
198 #ifdef TIZEN_FEATURE_LOADER_PRIORITY
199 launchpad_loader_set_priority(19);
202 if (!strcmp(LOADER_TYPE_COMMON, ltype))
203 __type = TYPE_COMMON;
204 else if (!strcmp(LOADER_TYPE_SW, ltype))
206 else if (!strcmp(LOADER_TYPE_HW, ltype))
209 _D("Loader type:%d", __type);
211 __preload_lib(extra);
213 elm_init_cnt = elm_init(__argc, __argv);
214 _D("[candidate] elm init, returned: %d", elm_init_cnt);
215 setenv("AUL_LOADER_INIT", "1", 1);
219 elm_config_accel_preference_set("none");
224 elm_config_accel_preference_set("hw");
233 ret = vconf_get_int(VCONFKEY_SETAPPL_APP_HW_ACCELERATION, &__sys_hwacc);
234 if (ret != VCONF_OK) {
235 _E("Failed to get vconf int: %s",
236 VCONFKEY_SETAPPL_APP_HW_ACCELERATION);
239 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_APP_HW_ACCELERATION,
242 _E("Failed to register callback for %s",
243 VCONFKEY_SETAPPL_APP_HW_ACCELERATION);
245 #ifdef TIZEN_FEATURE_LOADER_PRIORITY
246 launchpad_loader_set_priority(0);
250 static loader_convertible __converter_table[MAX_LOADER_TYPE][MAX_ACC_TYPE] = {
251 [TYPE_COMMON][SW_ACC] = NULL,
252 [TYPE_COMMON][HW_ACC] = NULL,
253 [TYPE_SW][SW_ACC] = NULL,
254 [TYPE_SW][HW_ACC] = __fini_window,
255 [TYPE_HW][SW_ACC] = __fini_window,
256 [TYPE_HW][HW_ACC] = NULL,
259 static int __loader_launch_cb(int argc, char **argv, const char *app_path,
260 const char *appid, const char *pkgid, const char *pkg_type,
264 bundle *kb = launchpad_loader_get_bundle();
266 loader_convertible convert;
267 #ifdef TIZEN_FEATURE_PRIORITY_CHANGE
268 const char *high_priority;
271 vconf_ignore_key_changed(VCONFKEY_SETAPPL_APP_HW_ACCELERATION,
276 #ifdef TIZEN_FEATURE_PRIORITY_CHANGE
277 high_priority = bundle_get_val(kb, AUL_K_HIGHPRIORITY);
279 if (!strcmp(high_priority, "true"))
280 launchpad_loader_set_priority(-12);
281 bundle_del(kb, AUL_K_HIGHPRIORITY);
285 hwacc = bundle_get_val(kb, AUL_K_HWACC);
290 if (strcmp(hwacc, "USE") == 0 ||
291 (strcmp(hwacc, "SYS") == 0 &&
292 __sys_hwacc == SETTING_HW_ACCELERATION_ON)) {
296 convert = __converter_table[__type][acc];
303 static int __loader_terminate_cb(int argc, char **argv, void *user_data)
306 int (*dl_main)(int, char **);
307 char err_str[MAX_LOCAL_BUFSZ];
308 char old_cwd[PATH_MAX];
309 bool restore = false;
312 SECURE_LOGD("[candidate] Launch real application (%s)",
313 argv[LOADER_ARG_PATH]);
315 if (getcwd(old_cwd, sizeof(old_cwd)) == NULL)
318 libdir = _get_libdir(argv[LOADER_ARG_PATH]);
322 /* To support 2.x applications which use their own shared libraries.
323 * We set '-rpath' to make the dynamic linker looks in the CWD forcely,
324 * so here we change working directory to find shared libraries well.
327 _E("failed to chdir: %d", errno);
332 handle = dlopen(argv[LOADER_ARG_PATH],
333 RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE);
334 if (handle == NULL) {
335 _E("dlopen failed(%s). Please complile with -fPIE and " \
336 "link with -pie flag", dlerror());
342 if (restore && chdir(old_cwd))
343 _E("failed to chdir: %d", errno);
345 dl_main = dlsym(handle, "main");
346 if (dl_main == NULL) {
347 _E("dlsym not founded(%s). Please export 'main' function",
354 return dl_main(argc, argv);
357 if (access(argv[LOADER_ARG_PATH], F_OK | R_OK)) {
358 SECURE_LOGE("access() failed for file: \"%s\", error: %d (%s)",
359 argv[LOADER_ARG_PATH], errno,
360 strerror_r(errno, err_str, sizeof(err_str)));
362 SECURE_LOGD("[candidate] Exec application (%s)",
363 __argv[LOADER_ARG_PATH]);
366 setenv("LD_LIBRARY_PATH", libdir, 1);
368 unsetenv("AUL_LOADER_INIT");
369 unsetenv("VC_ELM_INIT");
370 if (execv(argv[LOADER_ARG_PATH], argv) < 0) {
371 _send_message_to_logger(argv[LOADER_ARG_PATH],
372 "Failed to execute a file. error(%d:%s)",
374 strerror_r(errno, err_str, sizeof(err_str)));
381 static Eina_Bool __process_fd_handler(void *data, Ecore_Fd_Handler *handler)
385 fd = ecore_main_fd_handler_fd_get(handler);
387 _D("[candidate] ECORE_FD_GET");
391 if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ)) {
394 } else if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR)) {
395 _D("[candidate] ECORE_FD_ERROR");
400 return ECORE_CALLBACK_CANCEL;
403 static void __adapter_loop_begin(void *user_data)
405 ecore_main_loop_begin();
408 static void __adapter_loop_quit(void *user_data)
410 ecore_main_loop_quit();
413 static void __adapter_add_fd(void *user_data, int fd,
414 loader_receiver_cb receiver)
416 __fd_handler = ecore_main_fd_handler_add(fd,
417 ECORE_FD_READ | ECORE_FD_ERROR, __process_fd_handler,
419 if (__fd_handler == NULL) {
420 _D("fd_handler is NULL");
425 __receiver = receiver;
428 static void __adapter_remove_fd(void *user_data, int fd)
431 ecore_main_fd_handler_del(__fd_handler);
437 int main(int argc, char **argv)
439 loader_lifecycle_callback_s callbacks = {
440 .create = __loader_create_cb,
441 .launch = __loader_launch_cb,
442 .terminate = __loader_terminate_cb
445 loader_adapter_s adapter = {
446 .loop_begin = __adapter_loop_begin,
447 .loop_quit = __adapter_loop_quit,
448 .add_fd = __adapter_add_fd,
449 .remove_fd = __adapter_remove_fd
455 return launchpad_loader_main(argc, argv, &callbacks, &adapter, NULL);