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>
31 #include <bundle_internal.h>
33 #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 void __clear_internal_key(bundle *kb);
52 static inline void __set_stime(bundle *kb);
54 int aul_is_initialized()
56 return aul_initialized;
59 static int __send_cmd_for_uid_opt(int pid, uid_t uid, int cmd, bundle *kb, int opt)
63 res = aul_sock_send_bundle(pid, uid, cmd, kb, opt);
65 res = aul_error_convert(res);
70 static int __send_cmd_noreply_for_uid_opt(int pid, uid_t uid,
71 int cmd, bundle *kb, int opt)
75 res = aul_sock_send_bundle(pid, uid, cmd, kb, opt | AUL_SOCK_NOREPLY);
77 res = aul_error_convert(res);
82 static int __send_cmd_async_for_uid_opt(int pid, uid_t uid,
83 int cmd, bundle *kb, int opt)
87 res = aul_sock_send_bundle(pid, uid, cmd, kb, opt | AUL_SOCK_ASYNC);
89 res = aul_error_convert(res);
95 * @brief encode kb and send it to 'pid'
96 * @param[in] pid receiver's pid
97 * @param[in] cmd message's status (APP_START | APP_RESULT)
100 API int app_send_cmd(int pid, int cmd, bundle *kb)
102 return __send_cmd_for_uid_opt(pid, getuid(), cmd, kb, AUL_SOCK_NONE);
105 API int app_send_cmd_for_uid(int pid, uid_t uid, int cmd, bundle *kb)
107 return __send_cmd_for_uid_opt(pid, uid, cmd, kb, AUL_SOCK_NONE);
110 API int app_send_cmd_with_queue_for_uid(int pid, uid_t uid, int cmd, bundle *kb)
112 return __send_cmd_for_uid_opt(pid, uid, cmd, kb, AUL_SOCK_QUEUE);
115 API int app_send_cmd_with_queue_noreply_for_uid(int pid, uid_t uid,
118 return __send_cmd_noreply_for_uid_opt(pid, uid, cmd, kb, AUL_SOCK_QUEUE);
121 API int app_send_cmd_with_noreply(int pid, int cmd, bundle *kb)
123 return __send_cmd_for_uid_opt(pid, getuid(), cmd, kb, AUL_SOCK_NOREPLY);
126 API int app_send_cmd_to_launchpad(const char *pad_type, uid_t uid, int cmd, bundle *kb)
133 fd = aul_sock_create_launchpad_client(pad_type, uid);
137 res = aul_sock_send_bundle_with_fd(fd, cmd,
145 len = recv(fd, &res, sizeof(int), 0);
147 if (errno == EAGAIN) {
148 _E("recv timeout: %d(%s)",
150 strerror_r(errno, buf, sizeof(buf)));
152 } else if (errno == EINTR) {
155 strerror_r(errno, buf, sizeof(buf)));
158 _E("recv error: %d(%s)",
160 strerror_r(errno, buf, sizeof(buf)));
170 static void __clear_internal_key(bundle *kb)
172 bundle_del(kb, AUL_K_CALLER_PID);
173 bundle_del(kb, AUL_K_APPID);
174 bundle_del(kb, AUL_K_WAIT_RESULT);
175 bundle_del(kb, AUL_K_SEND_RESULT);
176 bundle_del(kb, AUL_K_ARGV0);
179 static inline void __set_stime(bundle *kb)
182 char tmp[MAX_LOCAL_BUFSZ];
184 gettimeofday(&tv, NULL);
185 snprintf(tmp, MAX_LOCAL_BUFSZ, "%ld/%ld", tv.tv_sec, tv.tv_usec);
186 bundle_del(kb, AUL_K_STARTTIME);
187 bundle_add(kb, AUL_K_STARTTIME, tmp);
191 * @brief start caller with kb
192 * @return callee's pid
194 int app_request_to_launchpad(int cmd, const char *appid, bundle *kb)
196 return app_request_to_launchpad_for_uid(cmd, appid, kb, getuid());
199 int app_request_to_launchpad_for_uid(int cmd, const char *appid, bundle *kb, uid_t uid)
204 char buf[MAX_PID_STR_BUFSZ];
206 traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "AUL:REQ_TO_PAD");
207 _W("request cmd(%d) : appid(%s), target_uid(%d)", cmd, appid, uid);
209 kb = bundle_create();
212 __clear_internal_key(kb);
215 bundle_del(kb, AUL_K_APPID);
216 bundle_add(kb, AUL_K_APPID, appid);
218 snprintf(buf, sizeof(buf), "%d", uid);
219 bundle_del(kb, AUL_K_TARGET_UID);
220 bundle_add(kb, AUL_K_TARGET_UID, buf);
224 case APP_PAUSE_BY_PID:
225 ret = app_send_cmd_with_queue_noreply_for_uid(AUL_UTIL_PID,
228 case APP_SEND_LAUNCH_REQUEST:
229 ret = __send_cmd_async_for_uid_opt(AUL_UTIL_PID,
230 uid, cmd, kb, AUL_SOCK_QUEUE);
233 ret = app_send_cmd_with_queue_for_uid(AUL_UTIL_PID, uid, cmd,
238 _W("request cmd(%d) result : %d", cmd, ret);
239 if (ret == AUL_R_LOCAL) {
240 _E("app_request_to_launchpad : Same Process Send Local");
245 case APP_START_ASYNC:
247 case APP_START_RES_ASYNC:
248 case APP_SEND_LAUNCH_REQUEST:
250 ret = aul_launch_local(b);
254 case APP_RESUME_BY_PID:
255 case APP_RESUME_BY_PID_ASYNC:
256 ret = aul_resume_local();
259 _E("no support packet");
268 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
273 static int __get_preinit_fd(void)
276 const char *listen_fd;
278 listen_fd = getenv("AUL_LISTEN_FD");
280 if (isdigit(*listen_fd))
281 fd = atoi(listen_fd);
282 unsetenv("AUL_LISTEN_FD");
293 return AUL_R_ECANCELED;
295 aul_fd = __get_preinit_fd();
296 if (aul_fd > 0 && aul_fd < sysconf(_SC_OPEN_MAX)) {
297 flag = fcntl(aul_fd, F_GETFD);
299 (void)fcntl(aul_fd, F_SETFD, flag);
301 _W("Failed to get preinit fd");
302 aul_fd = aul_sock_create_server(getpid(), getuid());
304 _E("aul_init create sock failed");
315 API void aul_finalize()
319 if (aul_initialized) {
320 aul_sock_destroy_server(aul_fd);
327 API int aul_request_data_control_socket_pair(bundle *kb, int *fd)
338 __clear_internal_key(b);
345 clifd = aul_sock_send_bundle(AUL_UTIL_PID, getuid(), APP_GET_DC_SOCKET_PAIR, b, AUL_SOCK_ASYNC);
350 ret = aul_sock_recv_result_with_fd(clifd);
353 if (ret == -EILLEGALACCESS) {
354 _E("Illegal access in datacontrol socket pair request");
355 return AUL_R_EILLACC;
360 ret = aul_sock_recv_reply_sock_fd(clifd, &fds, 1);
370 API int aul_request_message_port_socket_pair(int *fd)
378 ret = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
379 APP_GET_MP_SOCKET_PAIR, NULL, 0, AUL_SOCK_ASYNC);
381 ret = aul_sock_recv_reply_sock_fd(ret, &fds, 2);
391 API int aul_launch_app(const char *appid, bundle *kb)
393 return aul_launch_app_for_uid(appid, kb, getuid());
396 API int aul_launch_app_for_uid(const char *appid, bundle *kb, uid_t uid)
403 ret = app_request_to_launchpad_for_uid(APP_START, appid, kb, uid);
407 API int aul_open_app(const char *appid)
409 return aul_open_app_for_uid(appid, getuid());
412 API int aul_open_app_for_uid(const char *appid, uid_t uid)
419 ret = app_request_to_launchpad_for_uid(APP_OPEN, appid, NULL, uid);
423 API int aul_resume_app(const char *appid)
425 return aul_resume_app_for_uid(appid, getuid());
428 API int aul_resume_app_for_uid(const char *appid, uid_t uid)
435 ret = app_request_to_launchpad_for_uid(APP_RESUME, appid, NULL, uid);
439 API int aul_resume_pid(int pid)
441 return aul_resume_pid_for_uid(pid, getuid());
444 API int aul_resume_pid_for_uid(int pid, uid_t uid)
446 char pid_str[MAX_PID_STR_BUFSZ];
452 snprintf(pid_str, sizeof(pid_str), "%d", pid);
453 ret = app_request_to_launchpad_for_uid(APP_RESUME_BY_PID,
458 API int aul_terminate_pid(int pid)
460 return aul_terminate_pid_for_uid(pid, getuid());
463 API int aul_terminate_pid_for_uid(int pid, uid_t uid)
465 char pid_str[MAX_PID_STR_BUFSZ];
471 snprintf(pid_str, sizeof(pid_str), "%d", pid);
472 ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID,
480 API int aul_terminate_bgapp_pid(int pid)
482 char pid_str[MAX_PID_STR_BUFSZ];
488 snprintf(pid_str, sizeof(pid_str), "%d", pid);
489 ret = app_request_to_launchpad(APP_TERM_BGAPP_BY_PID, pid_str, NULL);
496 API int aul_terminate_pid_without_restart(int pid)
498 char pid_str[MAX_PID_STR_BUFSZ];
504 snprintf(pid_str, sizeof(pid_str), "%d", pid);
505 ret = app_request_to_launchpad(APP_TERM_BY_PID_WITHOUT_RESTART,
510 API int aul_terminate_pid_sync_without_restart(int pid)
512 return aul_terminate_pid_sync_without_restart_for_uid(pid, getuid());
515 API int aul_terminate_pid_sync_without_restart_for_uid(int pid, uid_t uid)
517 char pid_str[MAX_PID_STR_BUFSZ];
523 snprintf(pid_str, sizeof(pid_str), "%d", pid);
524 ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_SYNC_WITHOUT_RESTART,
529 API int aul_terminate_pid_async(int pid)
531 return aul_terminate_pid_async_for_uid(pid, getuid());
534 API int aul_terminate_pid_async_for_uid(int pid, uid_t uid)
536 char pid_str[MAX_PID_STR_BUFSZ];
542 snprintf(pid_str, sizeof(pid_str), "%d", pid);
543 ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_ASYNC, pid_str,
548 API int aul_kill_pid(int pid)
550 char pid_str[MAX_PID_STR_BUFSZ];
556 snprintf(pid_str, sizeof(pid_str), "%d", pid);
557 ret = app_request_to_launchpad(APP_KILL_BY_PID, pid_str, NULL);
561 API void aul_set_preinit_window(void *evas_object)
563 __window_object = evas_object;
566 API void* aul_get_preinit_window(const char *win_name)
568 return __window_object;
571 API void aul_set_preinit_background(void *evas_object)
573 __bg_object = evas_object;
576 API void* aul_get_preinit_background(void)
581 API void aul_set_preinit_conformant(void *evas_object)
583 __conformant_object = evas_object;
586 API void* aul_get_preinit_conformant(void)
588 return __conformant_object;
591 API int aul_pause_app(const char *appid)
593 return aul_pause_app_for_uid(appid, getuid());
596 API int aul_pause_app_for_uid(const char *appid, uid_t uid)
603 ret = app_request_to_launchpad_for_uid(APP_PAUSE, appid, NULL, uid);
607 API int aul_pause_pid(int pid)
609 return aul_pause_pid_for_uid(pid, getuid());
612 API int aul_pause_pid_for_uid(int pid, uid_t uid)
614 char pid_str[MAX_PID_STR_BUFSZ];
620 snprintf(pid_str, sizeof(pid_str), "%d", pid);
621 ret = app_request_to_launchpad_for_uid(APP_PAUSE_BY_PID,
626 API int aul_reload_appinfo(void)
628 char pid_str[MAX_PID_STR_BUFSZ];
630 snprintf(pid_str, sizeof(pid_str), "%d", getpid());
632 return app_request_to_launchpad(AMD_RELOAD_APPINFO, pid_str, NULL);
635 API int aul_is_tep_mount_dbus_done(const char *tep_string)
638 GDBusConnection *conn;
639 GDBusMessage *msg = NULL;
640 GDBusMessage *reply = NULL;
642 int ret = AUL_R_ERROR;
644 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
646 _E("g_bus_get_sync() is failed. %s", err->message);
651 msg = g_dbus_message_new_method_call(TEP_BUS_NAME,
654 TEP_IS_MOUNTED_METHOD);
656 _E("g_dbus_message_new_method_call() is failed. %s",
660 g_dbus_message_set_body(msg, g_variant_new("(s)", tep_string));
662 reply = g_dbus_connection_send_message_with_reply_sync(conn,
664 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
670 _E("g_dbus_connection_send_message_with_reply_sync() "
671 "is failed. %s", err->message);
675 body = g_dbus_message_get_body(reply);
677 _E("g_dbus_message_get_body() is failed.");
681 g_variant_get(body, "(i)", &ret);
687 g_object_unref(reply);
689 g_object_unref(conn);
696 API int aul_check_tep_mount(const char *tep_path)
701 while (cnt < TEP_ISMOUNT_MAX_RETRY_CNT) {
702 rv = aul_is_tep_mount_dbus_done(tep_path);
708 /* incase after trying 1 sec, not getting mounted then quit */
710 _E("Not able to mount within 1 sec");
717 API int aul_add_loader(const char *loader_path, bundle *kb)
719 return aul_add_loader_for_uid(loader_path, kb, getuid());
722 API int aul_add_loader_for_uid(const char *loader_path, bundle *kb, uid_t uid)
726 bundle_raw *kb_raw = NULL;
728 char buf[MAX_PID_STR_BUFSZ];
730 if (loader_path == NULL)
737 snprintf(buf, sizeof(buf), "%d", uid);
738 bundle_add_str(b, AUL_K_TARGET_UID, buf);
739 bundle_add_str(b, AUL_K_LOADER_PATH, loader_path);
742 ret = bundle_encode(kb, &kb_raw, &len);
743 if (ret != BUNDLE_ERROR_NONE) {
748 bundle_add_str(b, AUL_K_LOADER_EXTRA, (const char *)kb_raw);
751 ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid, APP_ADD_LOADER, b);
759 API int aul_remove_loader(int loader_id)
761 return aul_remove_loader_for_uid(loader_id, getuid());
764 API int aul_remove_loader_for_uid(int loader_id, uid_t uid)
766 char buf[MAX_PID_STR_BUFSZ];
779 snprintf(buf, sizeof(buf), "%d", loader_id);
780 bundle_add_str(b, AUL_K_LOADER_ID, buf);
781 snprintf(buf, sizeof(buf), "%d", uid);
782 bundle_add_str(b, AUL_K_TARGET_UID, buf);
784 ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid, APP_REMOVE_LOADER, b);
790 API int aul_app_register_pid(const char *appid, int pid)
792 char pid_str[MAX_PID_STR_BUFSZ];
796 if (!appid || pid <= 0)
805 bundle_add_str(b, AUL_K_APPID, appid);
806 snprintf(pid_str, sizeof(pid_str), "%d", pid);
807 bundle_add_str(b, AUL_K_PID, pid_str);
809 ret = app_send_cmd_with_noreply(AUL_UTIL_PID, APP_REGISTER_PID, b);
815 API int aul_launch_app_async(const char *appid, bundle *kb)
817 return aul_launch_app_async_for_uid(appid, kb, getuid());
820 API int aul_launch_app_async_for_uid(const char *appid, bundle *kb, uid_t uid)
827 ret = app_request_to_launchpad_for_uid(APP_START_ASYNC, appid, kb, uid);
831 API int aul_prepare_candidate_process(void)
833 unsigned char dummy[1] = { 0 };
835 return aul_sock_send_raw(AUL_UTIL_PID, getuid(),
836 APP_PREPARE_CANDIDATE_PROCESS, dummy, 0, AUL_SOCK_NONE);
839 API int aul_terminate_pid_sync(int pid)
841 return aul_terminate_pid_sync_for_uid(pid, getuid());
844 API int aul_terminate_pid_sync_for_uid(int pid, uid_t uid)
846 char pid_str[MAX_PID_STR_BUFSZ];
852 snprintf(pid_str, sizeof(pid_str), "%d", pid);
853 ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_SYNC, pid_str,
858 API int aul_resume_pid_async(int pid)
860 return aul_resume_pid_async_for_uid(pid, getuid());
863 API int aul_resume_pid_async_for_uid(int pid, uid_t uid)
865 char pid_str[MAX_PID_STR_BUFSZ];
871 snprintf(pid_str, sizeof(pid_str), "%d", pid);
872 ret = app_request_to_launchpad_for_uid(APP_RESUME_BY_PID_ASYNC,
877 API int aul_resume_app_by_instance_id(const char *appid,
878 const char *instance_id)
880 return aul_resume_app_by_instance_id_for_uid(appid,
881 instance_id, getuid());
884 API int aul_resume_app_by_instance_id_for_uid(const char *appid,
885 const char *instance_id, uid_t uid)
890 if (appid == NULL || instance_id == NULL) {
891 _E("Invalid parameter");
901 ret = bundle_add(b, AUL_K_INSTANCE_ID, instance_id);
902 if (ret != BUNDLE_ERROR_NONE) {
903 _E("Failed to add instance id(%s)", instance_id);
908 ret = app_request_to_launchpad_for_uid(APP_RESUME, appid, b, uid);