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()
120 __call_aul_handler(AUL_SUSPEND, NULL);
124 static int app_prepare_to_wake()
127 __call_aul_handler(AUL_WAKE, NULL);
131 static int __send_cmd_for_uid_opt(int pid, uid_t uid, int cmd, bundle *kb, int opt)
135 res = aul_sock_send_bundle(pid, uid, cmd, kb, opt);
137 res = aul_error_convert(res);
142 static int __send_cmd_async_for_uid_opt(int pid, uid_t uid,
143 int cmd, bundle *kb, int opt)
147 res = aul_sock_send_bundle(pid, uid, cmd, kb, AUL_SOCK_NOREPLY);
149 res = aul_error_convert(res);
155 * @brief encode kb and send it to 'pid'
156 * @param[in] pid receiver's pid
157 * @param[in] cmd message's status (APP_START | APP_RESULT)
160 API int app_send_cmd(int pid, int cmd, bundle *kb)
162 return __send_cmd_for_uid_opt(pid, getuid(), cmd, kb, AUL_SOCK_NONE);
165 API int app_send_cmd_for_uid(int pid, uid_t uid, int cmd, bundle *kb)
167 return __send_cmd_for_uid_opt(pid, uid, cmd, kb, AUL_SOCK_NONE);
170 API int app_send_cmd_with_queue_for_uid(int pid, uid_t uid, int cmd, bundle *kb)
172 return __send_cmd_for_uid_opt(pid, uid, cmd, kb, AUL_SOCK_QUEUE);
175 API int app_send_cmd_with_queue_noreply_for_uid(int pid, uid_t uid,
178 return __send_cmd_async_for_uid_opt(pid, uid, cmd, kb, AUL_SOCK_QUEUE);
181 API int app_send_cmd_with_noreply(int pid, int cmd, bundle *kb)
183 return __send_cmd_for_uid_opt(pid, getuid(), cmd, kb, AUL_SOCK_NOREPLY);
186 API int app_send_cmd_to_launchpad(const char *pad_type, uid_t uid, int cmd, bundle *kb)
192 fd = aul_sock_create_launchpad_client(pad_type, uid);
196 res = aul_sock_send_bundle_with_fd(fd, cmd,
204 len = recv(fd, &res, sizeof(int), 0);
206 if (errno == EAGAIN) {
207 _E("recv timeout: %s", strerror(errno));
209 } else if (errno == EINTR) {
210 _D("recv: %s", strerror(errno));
213 _E("recv error: %s", strerror(errno));
223 static void __clear_internal_key(bundle *kb)
225 bundle_del(kb, AUL_K_CALLER_PID);
226 bundle_del(kb, AUL_K_APPID);
227 bundle_del(kb, AUL_K_WAIT_RESULT);
228 bundle_del(kb, AUL_K_SEND_RESULT);
229 bundle_del(kb, AUL_K_ARGV0);
232 static inline void __set_stime(bundle *kb)
235 char tmp[MAX_LOCAL_BUFSZ];
237 gettimeofday(&tv, NULL);
238 snprintf(tmp, MAX_LOCAL_BUFSZ, "%ld/%ld", tv.tv_sec, tv.tv_usec);
239 bundle_add(kb, AUL_K_STARTTIME, tmp);
242 static int __app_start_internal(gpointer data)
246 kb = (bundle *) data;
253 static int __app_launch_local(bundle *b)
255 if (!aul_is_initialized())
256 return AUL_R_ENOINIT;
259 _E("bundle for APP_START is NULL");
261 if (g_idle_add(__app_start_internal, b) > 0)
267 static int __app_resume_local()
269 if (!aul_is_initialized())
270 return AUL_R_ENOINIT;
278 * @brief start caller with kb
279 * @return callee's pid
281 int app_request_to_launchpad(int cmd, const char *appid, bundle *kb)
283 return app_request_to_launchpad_for_uid(cmd, appid, kb, getuid());
286 int app_request_to_launchpad_for_uid(int cmd, const char *appid, bundle *kb, uid_t uid)
292 traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "AUL:REQ_TO_PAD");
293 SECURE_LOGD("launch request : %s", appid);
295 kb = bundle_create();
298 __clear_internal_key(kb);
301 bundle_del(kb, AUL_K_APPID);
302 bundle_add(kb, AUL_K_APPID, appid);
307 case APP_PAUSE_BY_PID:
308 ret = app_send_cmd_with_queue_noreply_for_uid(AUL_UTIL_PID,
312 ret = app_send_cmd_with_queue_for_uid(AUL_UTIL_PID, uid, cmd,
317 _D("launch request result : %d", ret);
318 if (ret == AUL_R_LOCAL) {
319 _E("app_request_to_launchpad : Same Process Send Local");
324 case APP_START_ASYNC:
327 ret = __app_launch_local(b);
331 case APP_RESUME_BY_PID:
332 case APP_RESUME_BY_PID_ASYNC:
333 ret = __app_resume_local();
336 _E("no support packet");
345 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
350 static int __send_result_to_launchpad(int fd, int res)
352 if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
353 if (errno == EPIPE) {
354 _E("send failed due to EPIPE.\n");
358 _E("send fail to client");
364 static int widget_get_content(int clifd, bundle *kb)
368 char *widget_id = NULL;
369 char *instance_id = NULL;
370 char *content_info = NULL;
372 bundle_get_str(kb, AUL_K_WIDGET_ID, &widget_id);
373 bundle_get_str(kb, AUL_K_WIDGET_INSTANCE_ID, &instance_id);
375 ret = aul_sock_recv_reply_sock_fd(clifd, &fd, 1);
377 _E("failed to recv sock fd");
381 if (!widget_id || !instance_id) {
382 aul_sock_send_raw_with_fd(fd, -EINVAL, 0, 0, AUL_SOCK_NOREPLY);
386 __call_aul_handler(AUL_WIDGET_CONTENT, kb);
388 bundle_get_str(kb, AUL_K_WIDGET_CONTENT_INFO, &content_info);
390 ret = aul_sock_send_raw_with_fd(fd, 0,
391 (unsigned char *)content_info,
392 strlen(content_info) + 1, AUL_SOCK_NOREPLY);
394 ret = aul_sock_send_raw_with_fd(fd, -ENOENT,
395 NULL, 0, AUL_SOCK_NOREPLY);
399 _E("failed to send content %d (%d)", fd, ret);
405 * @brief caller & callee's sock handler
407 int aul_sock_handler(int fd)
410 bundle *kbundle = NULL;
418 if ((pkt = aul_sock_recv_pkt(fd, &clifd, &cr)) == NULL) {
423 if (pkt->opt & AUL_SOCK_NOREPLY) {
425 } else if (pkt->cmd != WIDGET_GET_CONTENT) {
426 ret = __send_result_to_launchpad(clifd, 0);
433 if (pkt->opt & AUL_SOCK_BUNDLE) {
434 kbundle = bundle_decode(pkt->data, pkt->len);
440 case APP_START: /* run in callee */
442 case APP_START_ASYNC:
446 case APP_OPEN: /* run in callee */
448 case APP_RESUME_BY_PID:
452 case APP_TERM_BY_PID: /* run in callee */
453 case APP_TERM_BY_PID_ASYNC:
454 case APP_TERM_BY_PID_SYNC:
458 case APP_TERM_BGAPP_BY_PID:
462 case APP_TERM_REQ_BY_PID: /* run in callee */
463 app_subapp_terminate_request();
466 case APP_RESULT: /* run in caller */
468 pid_str = bundle_get_val(kbundle, AUL_K_CALLEE_PID);
472 app_result(pkt->cmd, kbundle, pid);
475 case APP_KEY_EVENT: /* run in caller */
476 app_key_event(kbundle);
479 case APP_PAUSE_BY_PID:
482 case APP_COM_MESSAGE:
483 app_com_recv(kbundle);
486 app_prepare_to_wake();
489 app_prepare_to_suspend();
491 case APP_STATUS_NOTIFICATION:
492 app_status_event(kbundle);
494 case WIDGET_GET_CONTENT:
495 widget_get_content(clifd, kbundle);
498 _E("no support packet");
502 bundle_free(kbundle);
512 int aul_make_bundle_from_argv(int argc, char **argv, bundle **kb)
518 *kb = bundle_create();
525 if ((argv != NULL) && (argv[0] != NULL)) {
526 buf = strdup(argv[0]);
532 bundle_add(*kb, AUL_K_ARGV0, buf);
534 if (buf) { /*Prevent FIX: ID 38717 */
540 if (ac + 1 == argc) {
541 if (bundle_add(*kb, argv[ac], "") < 0) {
542 _E("bundle add error pos - %d", ac);
543 return AUL_R_ECANCELED;
546 if (bundle_add(*kb, argv[ac], argv[ac + 1]) < 0) {
547 _E("bundle add error pos - %d", ac);
548 return AUL_R_ECANCELED;
557 int aul_register_init_callback(
558 int (*aul_handler) (aul_type type, bundle *, void *), void *data)
560 /* Save start handler function in static var */
561 _aul_handler = aul_handler;
569 return AUL_R_ECANCELED;
572 aul_fd = aul_sock_create_server(getpid(), getuid());
574 _E("aul_init create sock failed");
583 API void aul_finalize()
593 API int aul_request_data_control_socket_pair(bundle *kb, int *fd)
603 __clear_internal_key(b);
610 ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(), APP_GET_DC_SOCKET_PAIR, b, AUL_SOCK_ASYNC);
612 ret = aul_sock_recv_reply_sock_fd(ret, fds, 1);
623 API int aul_request_message_port_socket_pair(int *fd)
631 ret = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
632 APP_GET_MP_SOCKET_PAIR, NULL, 0, AUL_SOCK_ASYNC);
634 ret = aul_sock_recv_reply_sock_fd(ret, fds, 2);
644 API int aul_launch_app(const char *appid, bundle *kb)
646 return aul_launch_app_for_uid(appid, kb, getuid());
649 API int aul_launch_app_for_uid(const char *appid, bundle *kb, uid_t uid)
656 ret = app_request_to_launchpad_for_uid(APP_START, appid, kb, uid);
660 API int aul_open_app(const char *appid)
662 return aul_open_app_for_uid(appid, getuid());
665 API int aul_open_app_for_uid(const char *appid, uid_t uid)
672 ret = app_request_to_launchpad_for_uid(APP_OPEN, appid, NULL, uid);
676 API int aul_resume_app(const char *appid)
678 return aul_resume_app_for_uid(appid, getuid());
681 API int aul_resume_app_for_uid(const char *appid, uid_t uid)
688 ret = app_request_to_launchpad_for_uid(APP_RESUME, appid, NULL, uid);
692 API int aul_resume_pid(int pid)
694 return aul_resume_pid_for_uid(pid, getuid());
697 API int aul_resume_pid_for_uid(int pid, uid_t uid)
699 char pid_str[MAX_PID_STR_BUFSZ];
705 snprintf(pid_str, sizeof(pid_str), "%d", pid);
706 ret = app_request_to_launchpad_for_uid(APP_RESUME_BY_PID,
711 API int aul_terminate_pid(int pid)
713 return aul_terminate_pid_for_uid(pid, getuid());
716 API int aul_terminate_pid_for_uid(int pid, uid_t uid)
718 char pid_str[MAX_PID_STR_BUFSZ];
724 snprintf(pid_str, sizeof(pid_str), "%d", pid);
725 ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID,
733 API int aul_terminate_bgapp_pid(int pid)
735 char pid_str[MAX_PID_STR_BUFSZ];
741 snprintf(pid_str, sizeof(pid_str), "%d", pid);
742 ret = app_request_to_launchpad(APP_TERM_BGAPP_BY_PID, pid_str, NULL);
749 API int aul_terminate_pid_without_restart(int pid)
751 char pid_str[MAX_PID_STR_BUFSZ];
757 snprintf(pid_str, sizeof(pid_str), "%d", pid);
758 ret = app_request_to_launchpad(APP_TERM_BY_PID_WITHOUT_RESTART,
763 API int aul_terminate_pid_sync_without_restart(int pid)
765 return aul_terminate_pid_sync_without_restart_for_uid(pid, getuid());
768 API int aul_terminate_pid_sync_without_restart_for_uid(int pid, uid_t uid)
770 char pid_str[MAX_PID_STR_BUFSZ];
776 snprintf(pid_str, sizeof(pid_str), "%d", pid);
777 ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_SYNC_WITHOUT_RESTART,
782 API int aul_terminate_pid_async(int pid)
784 return aul_terminate_pid_async_for_uid(pid, getuid());
787 API int aul_terminate_pid_async_for_uid(int pid, uid_t uid)
789 char pid_str[MAX_PID_STR_BUFSZ];
795 snprintf(pid_str, sizeof(pid_str), "%d", pid);
796 ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_ASYNC, pid_str,
801 API int aul_kill_pid(int pid)
803 char pid_str[MAX_PID_STR_BUFSZ];
809 snprintf(pid_str, sizeof(pid_str), "%d", pid);
810 ret = app_request_to_launchpad(APP_KILL_BY_PID, pid_str, NULL);
814 API int aul_set_data_control_provider_cb(data_control_provider_handler_fn handler)
816 __dc_handler = handler;
820 API int aul_unset_data_control_provider_cb(void)
826 API void aul_set_preinit_window(void *evas_object)
828 __window_object = evas_object;
831 API void* aul_get_preinit_window(const char *win_name)
833 return __window_object;
836 API void aul_set_preinit_background(void *evas_object)
838 __bg_object = evas_object;
841 API void* aul_get_preinit_background(void)
846 API void aul_set_preinit_conformant(void *evas_object)
848 __conformant_object = evas_object;
851 API void* aul_get_preinit_conformant(void)
853 return __conformant_object;
856 API int aul_pause_app(const char *appid)
858 return aul_pause_app_for_uid(appid, getuid());
861 API int aul_pause_app_for_uid(const char *appid, uid_t uid)
868 ret = app_request_to_launchpad_for_uid(APP_PAUSE, appid, NULL, uid);
872 API int aul_pause_pid(int pid)
874 return aul_pause_pid_for_uid(pid, getuid());
877 API int aul_pause_pid_for_uid(int pid, uid_t uid)
879 char pid_str[MAX_PID_STR_BUFSZ];
885 snprintf(pid_str, sizeof(pid_str), "%d", pid);
886 ret = app_request_to_launchpad_for_uid(APP_PAUSE_BY_PID,
891 API int aul_reload_appinfo(void)
893 char pid_str[MAX_PID_STR_BUFSZ];
895 snprintf(pid_str, sizeof(pid_str), "%d", getpid());
897 return app_request_to_launchpad(AMD_RELOAD_APPINFO, pid_str, NULL);
900 API int aul_is_tep_mount_dbus_done(const char *tep_string)
903 GDBusConnection *conn;
904 GDBusMessage *msg = NULL;
905 GDBusMessage *reply = NULL;
907 int ret = AUL_R_ERROR;
909 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
911 _E("g_bus_get_sync() is failed. %s", err->message);
916 msg = g_dbus_message_new_method_call(TEP_BUS_NAME,
919 TEP_IS_MOUNTED_METHOD);
921 _E("g_dbus_message_new_method_call() is failed. %s",
925 g_dbus_message_set_body(msg, g_variant_new("(s)", tep_string));
927 reply = g_dbus_connection_send_message_with_reply_sync(conn,
929 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
935 _E("g_dbus_connection_send_message_with_reply_sync() "
936 "is failed. %s", err->message);
940 body = g_dbus_message_get_body(reply);
942 _E("g_dbus_message_get_body() is failed.");
946 g_variant_get(body, "(i)", &ret);
952 g_object_unref(reply);
954 g_object_unref(conn);
961 API int aul_check_tep_mount(const char *tep_path)
966 while (cnt < TEP_ISMOUNT_MAX_RETRY_CNT) {
967 rv = aul_is_tep_mount_dbus_done(tep_path);
973 /* incase after trying 1 sec, not getting mounted then quit */
975 _E("Not able to mount within 1 sec");
982 API int aul_add_loader(const char *loader_path, bundle *kb)
984 return aul_add_loader_for_uid(loader_path, kb, getuid());
987 API int aul_add_loader_for_uid(const char *loader_path, bundle *kb, uid_t uid)
991 bundle_raw *kb_raw = NULL;
994 if (loader_path == NULL)
1001 bundle_add_str(b, AUL_K_LOADER_PATH, loader_path);
1004 ret = bundle_encode(kb, &kb_raw, &len);
1005 if (ret != BUNDLE_ERROR_NONE) {
1007 return AUL_R_EINVAL;
1010 bundle_add_str(b, AUL_K_LOADER_EXTRA, (const char *)kb_raw);
1013 ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid, APP_ADD_LOADER, b);
1021 API int aul_remove_loader(int loader_id)
1023 return aul_remove_loader_for_uid(loader_id, getuid());
1026 API int aul_remove_loader_for_uid(int loader_id, uid_t uid)
1028 char lid[MAX_PID_STR_BUFSZ];
1033 return AUL_R_EINVAL;
1035 b = bundle_create();
1037 _E("out of memory");
1041 snprintf(lid, sizeof(lid), "%d", loader_id);
1042 bundle_add_str(b, AUL_K_LOADER_ID, lid);
1044 ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid, APP_REMOVE_LOADER, b);
1050 API int aul_app_register_pid(const char *appid, int pid)
1052 char pid_str[MAX_PID_STR_BUFSZ];
1056 if (!appid || pid <= 0)
1057 return AUL_R_EINVAL;
1059 b = bundle_create();
1061 _E("out of memory");
1065 bundle_add_str(b, AUL_K_APPID, appid);
1066 snprintf(pid_str, sizeof(pid_str), "%d", pid);
1067 bundle_add_str(b, AUL_K_PID, pid_str);
1069 ret = app_send_cmd_with_noreply(AUL_UTIL_PID, APP_REGISTER_PID, b);
1075 API int aul_launch_app_async(const char *appid, bundle *kb)
1077 return aul_launch_app_async_for_uid(appid, kb, getuid());
1080 API int aul_launch_app_async_for_uid(const char *appid, bundle *kb, uid_t uid)
1085 return AUL_R_EINVAL;
1087 ret = app_request_to_launchpad_for_uid(APP_START_ASYNC, appid, kb, uid);
1091 API int aul_prepare_candidate_process(void)
1093 unsigned char dummy[1] = { 0 };
1095 return aul_sock_send_raw(AUL_UTIL_PID, getuid(),
1096 APP_PREPARE_CANDIDATE_PROCESS, dummy, 0, AUL_SOCK_NONE);
1099 API int aul_terminate_pid_sync(int pid)
1101 return aul_terminate_pid_sync_for_uid(pid, getuid());
1104 API int aul_terminate_pid_sync_for_uid(int pid, uid_t uid)
1106 char pid_str[MAX_PID_STR_BUFSZ];
1110 return AUL_R_EINVAL;
1112 snprintf(pid_str, sizeof(pid_str), "%d", pid);
1113 ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_SYNC, pid_str,
1118 API int aul_resume_pid_async(int pid)
1120 return aul_resume_pid_async_for_uid(pid, getuid());
1123 API int aul_resume_pid_async_for_uid(int pid, uid_t uid)
1125 char pid_str[MAX_PID_STR_BUFSZ];
1129 return AUL_R_EINVAL;
1131 snprintf(pid_str, sizeof(pid_str), "%d", pid);
1132 ret = app_request_to_launchpad_for_uid(APP_RESUME_BY_PID_ASYNC,
1133 pid_str, NULL, uid);