2 * Copyright (c) 2000 - 2015 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.
18 #include <sys/types.h>
30 #include <bundle_internal.h>
32 #include "app_signal.h"
40 #include "aul_app_com.h"
41 #include "aul_error.h"
43 #define TEP_ISMOUNT_MAX_RETRY_CNT 20
45 static int aul_initialized = 0;
47 static void *__window_object = NULL;
48 static void *__bg_object = NULL;
49 static void *__conformant_object = NULL;
51 static int (*_aul_handler) (aul_type type, bundle *kb, void *data) = NULL;
52 static void *_aul_data;
54 static int app_resume();
55 static int app_terminate();
56 static void __clear_internal_key(bundle *kb);
57 static inline void __set_stime(bundle *kb);
58 static int __app_start_internal(gpointer data);
59 static int __app_launch_local(bundle *b);
60 static int __send_result_to_launchpad(int fd, int res);
62 static data_control_provider_handler_fn __dc_handler = NULL;
63 extern int aul_launch_fini();
65 int aul_is_initialized()
67 return aul_initialized;
70 int __call_aul_handler(aul_type type, bundle *kb)
73 _aul_handler(type, kb, _aul_data);
77 int app_start(bundle *kb)
79 const char *str = NULL;
81 _app_start_res_prepare(kb);
82 __call_aul_handler(AUL_START, kb);
83 /* Handle the DataControl callback */
84 str = bundle_get_val(kb, AUL_K_DATA_CONTROL_TYPE);
85 if (str != NULL && strcmp(str, "CORE") == 0) {
86 if (__dc_handler != NULL)
87 __dc_handler(kb, 0, NULL); /* bundle, request_id, data */
93 static int app_resume()
95 __call_aul_handler(AUL_RESUME, NULL);
99 static int app_terminate()
101 __call_aul_handler(AUL_TERMINATE, NULL);
105 static int bgapp_terminate(void)
107 __call_aul_handler(AUL_TERMINATE_BGAPP, NULL);
111 static int app_pause(void)
113 __call_aul_handler(AUL_PAUSE, NULL);
117 static int app_prepare_to_suspend(bundle *kb)
120 __call_aul_handler(AUL_SUSPEND, kb);
124 static int app_prepare_to_wake(bundle *kb)
127 __call_aul_handler(AUL_WAKE, kb);
131 static void app_update_requested(void)
133 _D("[UPDATE REQUESTED]");
134 __call_aul_handler(AUL_UPDATE_REQUESTED, NULL);
137 static int __send_cmd_for_uid_opt(int pid, uid_t uid, int cmd, bundle *kb, int opt)
141 res = aul_sock_send_bundle(pid, uid, cmd, kb, opt);
143 res = aul_error_convert(res);
148 static int __send_cmd_async_for_uid_opt(int pid, uid_t uid,
149 int cmd, bundle *kb, int opt)
153 res = aul_sock_send_bundle(pid, uid, cmd, kb, AUL_SOCK_NOREPLY);
155 res = aul_error_convert(res);
161 * @brief encode kb and send it to 'pid'
162 * @param[in] pid receiver's pid
163 * @param[in] cmd message's status (APP_START | APP_RESULT)
166 API int app_send_cmd(int pid, int cmd, bundle *kb)
168 return __send_cmd_for_uid_opt(pid, getuid(), cmd, kb, AUL_SOCK_NONE);
171 API int app_send_cmd_for_uid(int pid, uid_t uid, int cmd, bundle *kb)
173 return __send_cmd_for_uid_opt(pid, uid, cmd, kb, AUL_SOCK_NONE);
176 API int app_send_cmd_with_queue_for_uid(int pid, uid_t uid, int cmd, bundle *kb)
178 return __send_cmd_for_uid_opt(pid, uid, cmd, kb, AUL_SOCK_QUEUE);
181 API int app_send_cmd_with_queue_noreply_for_uid(int pid, uid_t uid,
184 return __send_cmd_async_for_uid_opt(pid, uid, cmd, kb, AUL_SOCK_QUEUE);
187 API int app_send_cmd_with_noreply(int pid, int cmd, bundle *kb)
189 return __send_cmd_for_uid_opt(pid, getuid(), cmd, kb, AUL_SOCK_NOREPLY);
192 API int app_send_cmd_to_launchpad(const char *pad_type, uid_t uid, int cmd, bundle *kb)
198 fd = aul_sock_create_launchpad_client(pad_type, uid);
202 res = aul_sock_send_bundle_with_fd(fd, cmd,
210 len = recv(fd, &res, sizeof(int), 0);
212 if (errno == EAGAIN) {
213 _E("recv timeout: %s", strerror(errno));
215 } else if (errno == EINTR) {
216 _D("recv: %s", strerror(errno));
219 _E("recv error: %s", strerror(errno));
229 static void __clear_internal_key(bundle *kb)
231 bundle_del(kb, AUL_K_CALLER_PID);
232 bundle_del(kb, AUL_K_APPID);
233 bundle_del(kb, AUL_K_WAIT_RESULT);
234 bundle_del(kb, AUL_K_SEND_RESULT);
235 bundle_del(kb, AUL_K_ARGV0);
238 static inline void __set_stime(bundle *kb)
241 char tmp[MAX_LOCAL_BUFSZ];
243 gettimeofday(&tv, NULL);
244 snprintf(tmp, MAX_LOCAL_BUFSZ, "%ld/%ld", tv.tv_sec, tv.tv_usec);
245 bundle_add(kb, AUL_K_STARTTIME, tmp);
248 static int __app_start_internal(gpointer data)
252 kb = (bundle *) data;
259 static int __app_launch_local(bundle *b)
261 if (!aul_is_initialized())
262 return AUL_R_ENOINIT;
265 _E("bundle for APP_START is NULL");
267 if (g_idle_add(__app_start_internal, b) > 0)
273 static int __app_resume_local()
275 if (!aul_is_initialized())
276 return AUL_R_ENOINIT;
284 * @brief start caller with kb
285 * @return callee's pid
287 int app_request_to_launchpad(int cmd, const char *appid, bundle *kb)
289 return app_request_to_launchpad_for_uid(cmd, appid, kb, getuid());
292 int app_request_to_launchpad_for_uid(int cmd, const char *appid, bundle *kb, uid_t uid)
297 char buf[MAX_PID_STR_BUFSZ];
299 traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "AUL:REQ_TO_PAD");
300 _W("request cmd(%d) : appid(%s), target_uid(%d)", cmd, appid, uid);
302 kb = bundle_create();
305 __clear_internal_key(kb);
308 bundle_del(kb, AUL_K_APPID);
309 bundle_add(kb, AUL_K_APPID, appid);
311 snprintf(buf, sizeof(buf), "%d", uid);
312 bundle_del(kb, AUL_K_TARGET_UID);
313 bundle_add(kb, AUL_K_TARGET_UID, buf);
317 case APP_PAUSE_BY_PID:
318 ret = app_send_cmd_with_queue_noreply_for_uid(AUL_UTIL_PID,
322 ret = app_send_cmd_with_queue_for_uid(AUL_UTIL_PID, uid, cmd,
327 _W("request cmd(%d) result : %d", cmd, ret);
328 if (ret == AUL_R_LOCAL) {
329 _E("app_request_to_launchpad : Same Process Send Local");
334 case APP_START_ASYNC:
337 ret = __app_launch_local(b);
341 case APP_RESUME_BY_PID:
342 case APP_RESUME_BY_PID_ASYNC:
343 ret = __app_resume_local();
346 _E("no support packet");
355 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
360 static int __send_result_to_launchpad(int fd, int res)
362 if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
363 if (errno == EPIPE) {
364 _E("send failed due to EPIPE.\n");
368 _E("send fail to client");
374 static int widget_get_content(int clifd, bundle *kb)
378 char *widget_id = NULL;
379 char *instance_id = NULL;
380 char *content_info = NULL;
382 bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
383 bundle_get_str(kb, AUL_K_WIDGET_INSTANCE_ID, &instance_id);
385 ret = aul_sock_recv_reply_sock_fd(clifd, &fd, 1);
387 _E("failed to recv sock fd");
391 if (!widget_id || !instance_id) {
392 aul_sock_send_raw_with_fd(fd, -EINVAL, 0, 0, AUL_SOCK_NOREPLY);
396 __call_aul_handler(AUL_WIDGET_CONTENT, kb);
398 bundle_get_str(kb, AUL_K_WIDGET_CONTENT_INFO, &content_info);
400 ret = aul_sock_send_raw_with_fd(fd, 0,
401 (unsigned char *)content_info,
402 strlen(content_info) + 1, AUL_SOCK_NOREPLY);
404 ret = aul_sock_send_raw_with_fd(fd, -ENOENT,
405 NULL, 0, AUL_SOCK_NOREPLY);
409 _E("failed to send content %d (%d)", fd, ret);
415 * @brief caller & callee's sock handler
417 int aul_sock_handler(int fd)
420 bundle *kbundle = NULL;
428 if ((pkt = aul_sock_recv_pkt(fd, &clifd, &cr)) == NULL) {
433 if (pkt->opt & AUL_SOCK_NOREPLY) {
435 } else if (pkt->cmd != WIDGET_GET_CONTENT) {
436 ret = __send_result_to_launchpad(clifd, 0);
443 if (pkt->opt & AUL_SOCK_BUNDLE) {
444 kbundle = bundle_decode(pkt->data, pkt->len);
450 case APP_START: /* run in callee */
452 case APP_START_ASYNC:
456 case APP_OPEN: /* run in callee */
458 case APP_RESUME_BY_PID:
462 case APP_TERM_BY_PID: /* run in callee */
463 case APP_TERM_BY_PID_ASYNC:
464 case APP_TERM_BY_PID_SYNC:
468 case APP_TERM_BGAPP_BY_PID:
472 case APP_TERM_REQ_BY_PID: /* run in callee */
473 app_subapp_terminate_request();
476 case APP_RESULT: /* run in caller */
478 pid_str = bundle_get_val(kbundle, AUL_K_CALLEE_PID);
482 app_result(pkt->cmd, kbundle, pid);
485 case APP_KEY_EVENT: /* run in caller */
486 app_key_event(kbundle);
489 case APP_PAUSE_BY_PID:
492 case APP_COM_MESSAGE:
493 app_com_recv(kbundle);
496 app_prepare_to_wake(kbundle);
499 app_prepare_to_suspend(kbundle);
501 case APP_STATUS_NOTIFICATION:
502 app_status_event(kbundle);
504 case WIDGET_GET_CONTENT:
505 widget_get_content(clifd, kbundle);
507 case UPDATE_APP_SCREEN:
508 app_update_requested();
511 _E("no support packet");
515 bundle_free(kbundle);
525 int aul_make_bundle_from_argv(int argc, char **argv, bundle **kb)
531 *kb = bundle_create();
538 if ((argv != NULL) && (argv[0] != NULL)) {
539 buf = strdup(argv[0]);
545 bundle_add(*kb, AUL_K_ARGV0, buf);
547 if (buf) { /*Prevent FIX: ID 38717 */
553 if (ac + 1 == argc) {
554 if (bundle_add(*kb, argv[ac], "") < 0) {
555 _E("bundle add error pos - %d", ac);
556 return AUL_R_ECANCELED;
559 if (bundle_add(*kb, argv[ac], argv[ac + 1]) < 0) {
560 _E("bundle add error pos - %d", ac);
561 return AUL_R_ECANCELED;
570 int aul_register_init_callback(
571 int (*aul_handler) (aul_type type, bundle *, void *), void *data)
573 /* Save start handler function in static var */
574 _aul_handler = aul_handler;
582 return AUL_R_ECANCELED;
585 aul_fd = aul_sock_create_server(getpid(), getuid());
587 _E("aul_init create sock failed");
596 API void aul_finalize()
606 API int aul_request_data_control_socket_pair(bundle *kb, int *fd)
616 __clear_internal_key(b);
623 ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(), APP_GET_DC_SOCKET_PAIR, b, AUL_SOCK_ASYNC);
625 ret = aul_sock_recv_reply_sock_fd(ret, fds, 1);
636 API int aul_request_message_port_socket_pair(int *fd)
644 ret = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
645 APP_GET_MP_SOCKET_PAIR, NULL, 0, AUL_SOCK_ASYNC);
647 ret = aul_sock_recv_reply_sock_fd(ret, fds, 2);
657 API int aul_launch_app(const char *appid, bundle *kb)
659 return aul_launch_app_for_uid(appid, kb, getuid());
662 API int aul_launch_app_for_uid(const char *appid, bundle *kb, uid_t uid)
669 ret = app_request_to_launchpad_for_uid(APP_START, appid, kb, uid);
673 API int aul_open_app(const char *appid)
675 return aul_open_app_for_uid(appid, getuid());
678 API int aul_open_app_for_uid(const char *appid, uid_t uid)
685 ret = app_request_to_launchpad_for_uid(APP_OPEN, appid, NULL, uid);
689 API int aul_resume_app(const char *appid)
691 return aul_resume_app_for_uid(appid, getuid());
694 API int aul_resume_app_for_uid(const char *appid, uid_t uid)
701 ret = app_request_to_launchpad_for_uid(APP_RESUME, appid, NULL, uid);
705 API int aul_resume_pid(int pid)
707 return aul_resume_pid_for_uid(pid, getuid());
710 API int aul_resume_pid_for_uid(int pid, uid_t uid)
712 char pid_str[MAX_PID_STR_BUFSZ];
718 snprintf(pid_str, sizeof(pid_str), "%d", pid);
719 ret = app_request_to_launchpad_for_uid(APP_RESUME_BY_PID,
724 API int aul_terminate_pid(int pid)
726 return aul_terminate_pid_for_uid(pid, getuid());
729 API int aul_terminate_pid_for_uid(int pid, uid_t uid)
731 char pid_str[MAX_PID_STR_BUFSZ];
737 snprintf(pid_str, sizeof(pid_str), "%d", pid);
738 ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID,
746 API int aul_terminate_bgapp_pid(int pid)
748 char pid_str[MAX_PID_STR_BUFSZ];
754 snprintf(pid_str, sizeof(pid_str), "%d", pid);
755 ret = app_request_to_launchpad(APP_TERM_BGAPP_BY_PID, pid_str, NULL);
762 API int aul_terminate_pid_without_restart(int pid)
764 char pid_str[MAX_PID_STR_BUFSZ];
770 snprintf(pid_str, sizeof(pid_str), "%d", pid);
771 ret = app_request_to_launchpad(APP_TERM_BY_PID_WITHOUT_RESTART,
776 API int aul_terminate_pid_sync_without_restart(int pid)
778 return aul_terminate_pid_sync_without_restart_for_uid(pid, getuid());
781 API int aul_terminate_pid_sync_without_restart_for_uid(int pid, uid_t uid)
783 char pid_str[MAX_PID_STR_BUFSZ];
789 snprintf(pid_str, sizeof(pid_str), "%d", pid);
790 ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_SYNC_WITHOUT_RESTART,
795 API int aul_terminate_pid_async(int pid)
797 return aul_terminate_pid_async_for_uid(pid, getuid());
800 API int aul_terminate_pid_async_for_uid(int pid, uid_t uid)
802 char pid_str[MAX_PID_STR_BUFSZ];
808 snprintf(pid_str, sizeof(pid_str), "%d", pid);
809 ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_ASYNC, pid_str,
814 API int aul_kill_pid(int pid)
816 char pid_str[MAX_PID_STR_BUFSZ];
822 snprintf(pid_str, sizeof(pid_str), "%d", pid);
823 ret = app_request_to_launchpad(APP_KILL_BY_PID, pid_str, NULL);
827 API int aul_set_data_control_provider_cb(data_control_provider_handler_fn handler)
829 __dc_handler = handler;
833 API int aul_unset_data_control_provider_cb(void)
839 API void aul_set_preinit_window(void *evas_object)
841 __window_object = evas_object;
844 API void* aul_get_preinit_window(const char *win_name)
846 return __window_object;
849 API void aul_set_preinit_background(void *evas_object)
851 __bg_object = evas_object;
854 API void* aul_get_preinit_background(void)
859 API void aul_set_preinit_conformant(void *evas_object)
861 __conformant_object = evas_object;
864 API void* aul_get_preinit_conformant(void)
866 return __conformant_object;
869 API int aul_pause_app(const char *appid)
871 return aul_pause_app_for_uid(appid, getuid());
874 API int aul_pause_app_for_uid(const char *appid, uid_t uid)
881 ret = app_request_to_launchpad_for_uid(APP_PAUSE, appid, NULL, uid);
885 API int aul_pause_pid(int pid)
887 return aul_pause_pid_for_uid(pid, getuid());
890 API int aul_pause_pid_for_uid(int pid, uid_t uid)
892 char pid_str[MAX_PID_STR_BUFSZ];
898 snprintf(pid_str, sizeof(pid_str), "%d", pid);
899 ret = app_request_to_launchpad_for_uid(APP_PAUSE_BY_PID,
904 API int aul_reload_appinfo(void)
906 char pid_str[MAX_PID_STR_BUFSZ];
908 snprintf(pid_str, sizeof(pid_str), "%d", getpid());
910 return app_request_to_launchpad(AMD_RELOAD_APPINFO, pid_str, NULL);
913 API int aul_is_tep_mount_dbus_done(const char *tep_string)
916 GDBusConnection *conn;
917 GDBusMessage *msg = NULL;
918 GDBusMessage *reply = NULL;
920 int ret = AUL_R_ERROR;
922 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
924 _E("g_bus_get_sync() is failed. %s", err->message);
929 msg = g_dbus_message_new_method_call(TEP_BUS_NAME,
932 TEP_IS_MOUNTED_METHOD);
934 _E("g_dbus_message_new_method_call() is failed. %s",
938 g_dbus_message_set_body(msg, g_variant_new("(s)", tep_string));
940 reply = g_dbus_connection_send_message_with_reply_sync(conn,
942 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
948 _E("g_dbus_connection_send_message_with_reply_sync() "
949 "is failed. %s", err->message);
953 body = g_dbus_message_get_body(reply);
955 _E("g_dbus_message_get_body() is failed.");
959 g_variant_get(body, "(i)", &ret);
965 g_object_unref(reply);
967 g_object_unref(conn);
974 API int aul_check_tep_mount(const char *tep_path)
979 while (cnt < TEP_ISMOUNT_MAX_RETRY_CNT) {
980 rv = aul_is_tep_mount_dbus_done(tep_path);
986 /* incase after trying 1 sec, not getting mounted then quit */
988 _E("Not able to mount within 1 sec");
995 API int aul_add_loader(const char *loader_path, bundle *kb)
997 return aul_add_loader_for_uid(loader_path, kb, getuid());
1000 API int aul_add_loader_for_uid(const char *loader_path, bundle *kb, uid_t uid)
1004 bundle_raw *kb_raw = NULL;
1006 char buf[MAX_PID_STR_BUFSZ];
1008 if (loader_path == NULL)
1009 return AUL_R_EINVAL;
1011 b = bundle_create();
1015 snprintf(buf, sizeof(buf), "%d", uid);
1016 bundle_add_str(b, AUL_K_TARGET_UID, buf);
1017 bundle_add_str(b, AUL_K_LOADER_PATH, loader_path);
1020 ret = bundle_encode(kb, &kb_raw, &len);
1021 if (ret != BUNDLE_ERROR_NONE) {
1023 return AUL_R_EINVAL;
1026 bundle_add_str(b, AUL_K_LOADER_EXTRA, (const char *)kb_raw);
1029 ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid, APP_ADD_LOADER, b);
1037 API int aul_remove_loader(int loader_id)
1039 return aul_remove_loader_for_uid(loader_id, getuid());
1042 API int aul_remove_loader_for_uid(int loader_id, uid_t uid)
1044 char buf[MAX_PID_STR_BUFSZ];
1049 return AUL_R_EINVAL;
1051 b = bundle_create();
1053 _E("out of memory");
1057 snprintf(buf, sizeof(buf), "%d", loader_id);
1058 bundle_add_str(b, AUL_K_LOADER_ID, buf);
1059 snprintf(buf, sizeof(buf), "%d", uid);
1060 bundle_add_str(b, AUL_K_TARGET_UID, buf);
1062 ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid, APP_REMOVE_LOADER, b);
1068 API int aul_app_register_pid(const char *appid, int pid)
1070 char pid_str[MAX_PID_STR_BUFSZ];
1074 if (!appid || pid <= 0)
1075 return AUL_R_EINVAL;
1077 b = bundle_create();
1079 _E("out of memory");
1083 bundle_add_str(b, AUL_K_APPID, appid);
1084 snprintf(pid_str, sizeof(pid_str), "%d", pid);
1085 bundle_add_str(b, AUL_K_PID, pid_str);
1087 ret = app_send_cmd_with_noreply(AUL_UTIL_PID, APP_REGISTER_PID, b);
1093 API int aul_launch_app_async(const char *appid, bundle *kb)
1095 return aul_launch_app_async_for_uid(appid, kb, getuid());
1098 API int aul_launch_app_async_for_uid(const char *appid, bundle *kb, uid_t uid)
1103 return AUL_R_EINVAL;
1105 ret = app_request_to_launchpad_for_uid(APP_START_ASYNC, appid, kb, uid);
1109 API int aul_prepare_candidate_process(void)
1111 unsigned char dummy[1] = { 0 };
1113 return aul_sock_send_raw(AUL_UTIL_PID, getuid(),
1114 APP_PREPARE_CANDIDATE_PROCESS, dummy, 0, AUL_SOCK_NONE);
1117 API int aul_terminate_pid_sync(int pid)
1119 return aul_terminate_pid_sync_for_uid(pid, getuid());
1122 API int aul_terminate_pid_sync_for_uid(int pid, uid_t uid)
1124 char pid_str[MAX_PID_STR_BUFSZ];
1128 return AUL_R_EINVAL;
1130 snprintf(pid_str, sizeof(pid_str), "%d", pid);
1131 ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_SYNC, pid_str,
1136 API int aul_resume_pid_async(int pid)
1138 return aul_resume_pid_async_for_uid(pid, getuid());
1141 API int aul_resume_pid_async_for_uid(int pid, uid_t uid)
1143 char pid_str[MAX_PID_STR_BUFSZ];
1147 return AUL_R_EINVAL;
1149 snprintf(pid_str, sizeof(pid_str), "%d", pid);
1150 ret = app_request_to_launchpad_for_uid(APP_RESUME_BY_PID_ASYNC,
1151 pid_str, NULL, uid);
1155 API int aul_resume_app_by_instance_id(const char *appid,
1156 const char *instance_id)
1158 return aul_resume_app_by_instance_id_for_uid(appid,
1159 instance_id, getuid());
1162 API int aul_resume_app_by_instance_id_for_uid(const char *appid,
1163 const char *instance_id, uid_t uid)
1168 if (appid == NULL || instance_id == NULL) {
1169 _E("Invalid parameter");
1170 return AUL_R_EINVAL;
1173 b = bundle_create();
1175 _E("Out of memory");
1176 return AUL_R_EINVAL;
1179 ret = bundle_add(b, AUL_K_INSTANCE_ID, instance_id);
1180 if (ret != BUNDLE_ERROR_NONE) {
1181 _E("Failed to add instance id(%s)", instance_id);
1186 ret = app_request_to_launchpad_for_uid(APP_RESUME, appid, b, uid);