2 * Copyright (c) 2000 - 2021 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.
17 #include <bundle_internal.h>
22 #include <glib-unix.h>
29 #include <sys/types.h>
37 #include "app_request.h"
38 #include "app_signal.h"
41 #include "aul_app_com.h"
42 #include "aul_error.h"
47 using namespace aul::internal;
51 constexpr const char kRunAulDaemonsPath[] = "/run/aul/daemons/";
52 constexpr const char kLaunchpadProcessPoolSock[] =
53 ".launchpad-process-pool-sock";
54 const int kPadCmdKillLoader = 19;
55 constexpr const int TEP_ISMOUNT_MAX_RETRY_CNT = 20;
59 ResultInfo(int fd, aul_result_cb callback, void* user_data)
60 : fd_(fd), callback_(callback), user_data_(user_data) {}
62 ResultInfo(const ResultInfo&) = delete;
63 ResultInfo& operator = (const ResultInfo&) = delete;
67 g_source_remove(source_);
74 source_ = g_unix_fd_add(fd_,
75 static_cast<GIOCondition>(G_IO_IN | G_IO_HUP | G_IO_ERR),
78 _E("g_unix_fd_add() is failed");
86 void ProcessReadEvent() {
87 int res = aul_sock_recv_result_with_fd(fd_);
89 res = aul_error_convert(res);
93 callback_(res, user_data_);
96 void ProcessErrorEvent() {
97 callback_(AUL_R_ERROR, user_data_);
100 static gboolean FdSourceFunc(int fd, GIOCondition condition,
102 auto* info = static_cast<ResultInfo*>(user_data);
103 if (condition & G_IO_IN)
104 info->ProcessReadEvent();
106 info->ProcessErrorEvent();
110 return G_SOURCE_REMOVE;
115 aul_result_cb callback_;
120 int aul_initialized = 0;
122 void* window_object = nullptr;
123 void* bg_object = nullptr;
124 void* conformant_object = nullptr;
126 int SendCmdForUidOpt(int pid, uid_t uid, int cmd, bundle* kb, int opt) {
127 int res = aul_sock_send_bundle(pid, uid, cmd, kb, opt);
129 res = aul_error_convert(res);
134 int SendCmdNoReplyForUidOpt(int pid, uid_t uid, int cmd, bundle* kb, int opt) {
135 int res = aul_sock_send_bundle(pid, uid, cmd, kb, opt | AUL_SOCK_NOREPLY);
137 res = aul_error_convert(res);
143 const char* env_str = getenv("AUL_PID");
144 if (env_str && isdigit(*env_str)) {
145 int env_pid = atoi(env_str);
146 if (env_pid != getpid()) {
147 _W("pid(%d) is not equal to AUL_PID(%d)",
159 if (CheckEnvPid() != 0)
162 const char* listen_fd = getenv("AUL_LISTEN_FD");
164 if (isdigit(*listen_fd))
165 fd = atoi(listen_fd);
166 setenv("AUL_LISTEN_FD", "-1", 1);
174 extern "C" int aul_is_initialized() {
175 return aul_initialized;
178 extern "C" API int app_send_cmd(int pid, int cmd, bundle* kb) {
179 return SendCmdForUidOpt(pid, getuid(), cmd, kb, AUL_SOCK_NONE);
182 extern "C" API int app_send_cmd_for_uid(int pid, uid_t uid, int cmd,
184 return SendCmdForUidOpt(pid, uid, cmd, kb, AUL_SOCK_NONE);
187 extern "C" API int app_send_cmd_with_queue_for_uid(int pid, uid_t uid, int cmd,
189 return SendCmdForUidOpt(pid, uid, cmd, kb, AUL_SOCK_QUEUE);
192 extern "C" API int app_send_cmd_with_queue_noreply_for_uid(int pid, uid_t uid,
193 int cmd, bundle* kb) {
194 return SendCmdNoReplyForUidOpt(pid, uid, cmd, kb, AUL_SOCK_QUEUE);
197 extern "C" API int app_send_cmd_with_noreply(int pid, int cmd, bundle* kb) {
198 return SendCmdForUidOpt(pid, getuid(), cmd, kb, AUL_SOCK_NOREPLY);
201 extern "C" API int app_send_cmd_to_launchpad(const char* pad_type, uid_t uid,
202 int cmd, bundle* kb) {
203 int fd = aul_sock_create_launchpad_client(pad_type, uid);
207 int res = aul_sock_send_bundle_with_fd(fd, cmd, kb, AUL_SOCK_ASYNC);
214 int len = recv(fd, &res, sizeof(int), 0);
216 if (errno == EAGAIN) {
218 _E("recv timeout: %d(%s)", errno, strerror_r(errno, buf, sizeof(buf)));
220 } else if (errno == EINTR) {
222 _D("recv: %d(%s)", errno, strerror_r(errno, buf, sizeof(buf)));
226 _E("recv error: %d(%s)", errno, strerror_r(errno, buf, sizeof(buf)));
235 extern "C" int app_request_local(int cmd, bundle* kb) {
236 _E("app_request_to_launchpad : Same Process Send Local");
240 case APP_START_ASYNC:
242 case APP_START_RES_ASYNC:
243 case APP_SEND_LAUNCH_REQUEST:
244 return aul_launch_local(bundle_dup(kb));
247 case APP_RESUME_BY_PID:
248 case APP_RESUME_BY_PID_ASYNC:
249 case APP_SEND_RESUME_REQUEST:
250 return aul_resume_local();
252 _E("no support packet");
257 extern "C" int app_request_to_launchpad_for_uid(int cmd, const char* appid,
258 bundle* kb, uid_t uid) {
259 return AppRequest(cmd, uid)
265 extern "C" int aul_initialize() {
267 return AUL_R_ECANCELED;
269 aul_fd = GetPreInitFd();
270 if (aul_fd > 0 && aul_fd < sysconf(_SC_OPEN_MAX)) {
271 int flag = fcntl(aul_fd, F_GETFD);
273 (void)fcntl(aul_fd, F_SETFD, flag);
275 _W("Failed to get preinit fd");
276 aul_fd = aul_sock_create_server(getpid(), getuid());
278 _E("aul_init create sock failed");
288 extern "C" API void aul_finalize() {
291 if (aul_initialized) {
292 aul_sock_destroy_server(aul_fd);
297 extern "C" API int aul_request_data_control_socket_pair(bundle* kb, int* fd) {
301 int clifd = AppRequest(APP_GET_DC_SOCKET_PAIR)
303 .SendSimply(AUL_SOCK_ASYNC);
307 int ret = aul_sock_recv_result_with_fd(clifd);
310 if (ret == -EILLEGALACCESS) {
311 _E("Illegal access in datacontrol socket pair request");
312 return AUL_R_EILLACC;
318 ret = aul_sock_recv_reply_sock_fd(clifd, &fds, 1);
325 extern "C" API int aul_request_message_port_socket_pair(int* fd) {
329 int ret = AppRequest(APP_GET_MP_SOCKET_PAIR)
330 .SendCmdOnly(AUL_SOCK_ASYNC);
333 ret = aul_sock_recv_reply_sock_fd(ret, &fds, 2);
343 extern "C" API int aul_launch_app(const char* appid, bundle* kb) {
344 return aul_launch_app_for_uid(appid, kb, getuid());
347 extern "C" API int aul_launch_app_for_uid(const char* appid, bundle* kb,
349 if (appid == nullptr)
352 return AppRequest(APP_START, uid)
358 extern "C" API int aul_open_app(const char* appid) {
359 return aul_open_app_for_uid(appid, getuid());
362 extern "C" API int aul_open_app_for_uid(const char* appid, uid_t uid) {
363 if (appid == nullptr)
366 return AppRequest(APP_OPEN, uid)
371 extern "C" API int aul_resume_app(const char* appid) {
372 return aul_resume_app_for_uid(appid, getuid());
375 extern "C" API int aul_resume_app_for_uid(const char* appid, uid_t uid) {
376 if (appid == nullptr)
379 return AppRequest(APP_RESUME, uid)
384 extern "C" API int aul_resume_pid(int pid) {
385 return aul_resume_pid_for_uid(pid, getuid());
388 extern "C" API int aul_resume_pid_for_uid(int pid, uid_t uid) {
392 return AppRequest(APP_RESUME_BY_PID, uid)
397 extern "C" API int aul_terminate_pid(int pid) {
398 return aul_terminate_pid_for_uid(pid, getuid());
401 extern "C" API int aul_terminate_pid_for_uid(int pid, uid_t uid) {
405 int ret = AppRequest(APP_TERM_BY_PID, uid)
414 extern "C" API int aul_terminate_bgapp_pid(int pid) {
418 int ret = AppRequest(APP_TERM_BGAPP_BY_PID)
427 extern "C" API int aul_terminate_pid_without_restart(int pid) {
431 return AppRequest(APP_TERM_BY_PID_WITHOUT_RESTART)
436 extern "C" API int aul_terminate_pid_sync_without_restart(int pid) {
437 return aul_terminate_pid_sync_without_restart_for_uid(pid, getuid());
440 extern "C" API int aul_terminate_pid_sync_without_restart_for_uid(int pid,
445 return AppRequest(APP_TERM_BY_PID_SYNC_WITHOUT_RESTART, uid)
450 extern "C" API int aul_terminate_pid_async(int pid) {
451 return aul_terminate_pid_async_for_uid(pid, getuid());
454 extern "C" API int aul_terminate_pid_async_for_uid(int pid, uid_t uid) {
458 return AppRequest(APP_TERM_BY_PID_ASYNC, uid)
463 extern "C" API int aul_kill_pid(int pid) {
467 return AppRequest(APP_KILL_BY_PID)
472 extern "C" API void aul_set_preinit_window(void* evas_object) {
473 window_object = evas_object;
476 extern "C" API void* aul_get_preinit_window(const char* win_name) {
477 return window_object;
480 extern "C" API void aul_set_preinit_background(void* evas_object) {
481 bg_object = evas_object;
484 extern "C" API void* aul_get_preinit_background(void) {
488 extern "C" API void aul_set_preinit_conformant(void* evas_object) {
489 conformant_object = evas_object;
492 extern "C" API void* aul_get_preinit_conformant(void) {
493 return conformant_object;
496 extern "C" API int aul_pause_app(const char* appid) {
497 return aul_pause_app_for_uid(appid, getuid());
500 extern "C" API int aul_pause_app_for_uid(const char* appid, uid_t uid) {
501 if (appid == nullptr)
504 return AppRequest(APP_PAUSE, uid)
506 .Send(AUL_SOCK_QUEUE | AUL_SOCK_NOREPLY);
509 extern "C" API int aul_pause_pid(int pid) {
510 return aul_pause_pid_for_uid(pid, getuid());
513 extern "C" API int aul_pause_pid_for_uid(int pid, uid_t uid) {
517 return AppRequest(APP_PAUSE_BY_PID, uid)
519 .Send(AUL_SOCK_QUEUE | AUL_SOCK_NOREPLY);
522 extern "C" API int aul_reload_appinfo(void) {
523 return AppRequest(AMD_RELOAD_APPINFO)
524 .SetAppIdAsPid(getpid())
528 extern "C" API int aul_is_tep_mount_dbus_done(const char* tep_string) {
529 GError* err = nullptr;
530 GDBusConnection* conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &err);
531 if (conn == nullptr) {
532 _E("g_bus_get_sync() is failed. error(%s)", err ? err->message : "Unknown");
537 std::unique_ptr<GDBusConnection, decltype(g_object_unref)*> conn_ptr(
538 conn, g_object_unref);
540 GDBusMessage* msg = g_dbus_message_new_method_call(TEP_BUS_NAME,
543 TEP_IS_MOUNTED_METHOD);
544 if (msg == nullptr) {
545 _E("g_dbus_message_new_method_call() is failed. error(%s)",
546 err ? err->message : "Unknown");
550 std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> msg_ptr(
551 msg, g_object_unref);
552 g_dbus_message_set_body(msg, g_variant_new("(s)", tep_string));
554 GDBusMessage* reply = g_dbus_connection_send_message_with_reply_sync(conn,
556 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
561 if (reply == nullptr || err != nullptr) {
562 _E("g_dbus_connection_send_message_with_reply_sync() is failed. error(%s)",
563 err ? err->message : "Unknown");
568 std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> reply_ptr(
569 reply, g_object_unref);
571 GVariant* body = g_dbus_message_get_body(reply);
572 if (body == nullptr) {
573 _E("g_dbus_message_get_body() is failed.");
577 int ret = AUL_R_ERROR;
578 g_variant_get(body, "(i)", &ret);
582 extern "C" API int aul_check_tep_mount(const char* tep_path) {
586 while (cnt < TEP_ISMOUNT_MAX_RETRY_CNT) {
587 ret = aul_is_tep_mount_dbus_done(tep_path);
593 /* incase after trying 1 sec, not getting mounted then quit */
595 _E("Not able to mount within 1 sec");
602 extern "C" API int aul_add_loader(const char* loader_path, bundle* kb) {
603 return aul_add_loader_for_uid(loader_path, kb, getuid());
606 extern "C" API int aul_add_loader_for_uid(const char* loader_path, bundle* kb,
608 if (loader_path == nullptr)
611 tizen_base::Bundle b = { {AUL_K_LOADER_PATH, loader_path} };
615 tizen_base::Bundle extra(kb, false, false);
616 auto raw = extra.ToRaw();
617 b.Add(AUL_K_LOADER_EXTRA, (const char*)(raw.first.get()));
618 } catch (const std::bad_alloc&) {
623 return AppRequest(APP_ADD_LOADER, uid)
628 extern "C" API int aul_remove_loader(int loader_id) {
629 return aul_remove_loader_for_uid(loader_id, getuid());
632 extern "C" API int aul_remove_loader_for_uid(int loader_id, uid_t uid) {
636 return AppRequest(APP_REMOVE_LOADER, uid)
637 .With({{AUL_K_LOADER_ID, std::to_string(loader_id)}})
641 extern "C" API int aul_app_register_pid(const char* appid, int pid) {
642 if (appid == nullptr || pid <= 0)
645 return AppRequest(APP_REGISTER_PID)
648 .SendSimply(AUL_SOCK_NOREPLY);
651 extern "C" API int aul_launch_app_async(const char* appid, bundle* kb) {
652 return aul_launch_app_async_for_uid(appid, kb, getuid());
655 extern "C" API int aul_launch_app_async_for_uid(const char* appid, bundle* kb,
657 if (appid == nullptr)
660 return AppRequest(APP_START_ASYNC, uid)
666 extern "C" API int aul_prepare_candidate_process(void) {
667 return AppRequest(APP_PREPARE_CANDIDATE_PROCESS)
671 extern "C" API int aul_terminate_pid_sync(int pid) {
672 return aul_terminate_pid_sync_for_uid(pid, getuid());
675 extern "C" API int aul_terminate_pid_sync_for_uid(int pid, uid_t uid) {
679 return AppRequest(APP_TERM_BY_PID_SYNC, uid)
684 extern "C" API int aul_resume_pid_async(int pid) {
685 return aul_resume_pid_async_for_uid(pid, getuid());
688 extern "C" API int aul_resume_pid_async_for_uid(int pid, uid_t uid) {
692 return AppRequest(APP_RESUME_BY_PID_ASYNC, uid)
697 extern "C" API int aul_resume_app_by_instance_id(const char* appid,
698 const char *instance_id) {
699 return aul_resume_app_by_instance_id_for_uid(appid, instance_id, getuid());
702 extern "C" API int aul_resume_app_by_instance_id_for_uid(const char* appid,
703 const char* instance_id, uid_t uid) {
704 if (appid == nullptr || instance_id == nullptr) {
705 _E("Invalid parameter");
709 return AppRequest(APP_RESUME, uid)
711 .SetInstId(instance_id)
715 extern "C" API int aul_terminate_instance_async(const char* instance_id,
717 return aul_terminate_instance_async_for_uid(instance_id, pid, getuid());
720 extern "C" API int aul_terminate_instance_async_for_uid(const char* instance_id,
721 int pid, uid_t uid) {
722 if (instance_id == nullptr) {
723 _E("Invalid parameter");
727 return AppRequest(APP_TERM_INSTANCE_ASYNC, uid)
729 .SetInstId(instance_id)
733 extern "C" API int aul_terminate_app_with_instance_id(const char* appid,
734 const char* instance_id) {
735 return aul_terminate_app_with_instance_id_for_uid(appid, instance_id,
739 extern "C" API int aul_terminate_app_with_instance_id_for_uid(const char* appid,
740 const char* instance_id, uid_t uid) {
741 if (appid == nullptr || instance_id == nullptr) {
742 _E("Invalid parameter");
746 return AppRequest(APP_TERMINATE, uid)
748 .SetInstId(instance_id)
752 extern "C" API int aul_terminate_app(const char* appid) {
753 return aul_terminate_app_for_uid(appid, getuid());
756 extern "C" API int aul_terminate_app_for_uid(const char* appid, uid_t uid) {
757 if (appid == nullptr) {
758 _E("Invalid parameter");
762 return AppRequest(APP_TERMINATE, uid)
767 extern "C" API int aul_prepare_app_defined_loader(const char* loader_name) {
768 return aul_prepare_app_defined_loader_for_uid(loader_name, getuid());
771 extern "C" API int aul_prepare_app_defined_loader_for_uid(
772 const char* loader_name, uid_t uid) {
773 if (loader_name == nullptr) {
774 _E("Invalid parameter");
778 int ret = AppRequest(APP_PREPARE_APP_DEFINED_LOADER, uid)
779 .With({{AUL_K_LOADER_NAME, loader_name}})
782 _E("Failed to prepare app-defined loader. error(%d)", ret);
786 _I("loader id(%d)", ret);
790 extern "C" API int aul_terminate_pid_async_v2(pid_t pid,
791 aul_result_cb callback, void *user_data) {
792 if (pid < 1 || callback == nullptr) {
793 _E("Invalid parameter");
797 int fd = AppRequest(APP_TERM_BY_PID, getuid())
799 .SendSimply(AUL_SOCK_ASYNC);
801 _E("Failed to send request. error(%d)", fd);
806 auto* info = new ResultInfo(fd, callback, user_data);
808 } catch (const std::exception& e) {
809 _E("Exception occurs. error: %s", e.what());
817 extern "C" API int aul_terminate_app_async(const char* appid,
818 aul_result_cb callback, void *user_data) {
819 if (appid == nullptr || callback == nullptr) {
820 _E("Invalid parameter");
824 int fd = AppRequest(APP_TERMINATE, getuid())
826 .SendSimply(AUL_SOCK_ASYNC);
828 _E("Failed to send request. error(%d)", fd);
833 auto* info = new ResultInfo(fd, callback, user_data);
835 } catch (const std::exception& e) {
836 _E("Exception occurs. error: %s", e.what());
844 extern "C" API int aul_kill_pid_async(pid_t pid,
845 aul_result_cb callback, void *user_data) {
846 if (pid < 1 || callback == nullptr) {
847 _E("Invalid parameter");
851 int fd = AppRequest(APP_KILL_BY_PID, getuid())
853 .SendSimply(AUL_SOCK_ASYNC);
855 _E("Failed to send request. error(%d)", fd);
860 auto* info = new ResultInfo(fd, callback, user_data);
862 } catch (const std::exception& e) {
863 _E("Exception occurs. error: %s", e.what());
871 extern "C" API int aul_kill_loader(const char* loader_name) {
872 return aul_kill_loader_for_uid(loader_name, getuid());
875 extern "C" API int aul_kill_loader_for_uid(const char* loader_name,
877 if (loader_name == nullptr) {
878 _E("Invalid parameter");
882 if (uid < REGULAR_UID_MIN) {
883 uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
884 _W("Use system default user ID(%u)", uid);
887 std::string endpoint = kRunAulDaemonsPath + std::to_string(uid) + "/" +
888 std::string(kLaunchpadProcessPoolSock);
889 if (!std::filesystem::exists(endpoint)) {
890 _E("launchpad socket is not prepared");
894 int fd = aul_sock_create_launchpad_client(kLaunchpadProcessPoolSock, uid);
896 _E("Failed to create launchpad client socket. error(%d)", fd);
897 return aul_error_convert(fd);
900 tizen_base::Bundle b = { {AUL_K_LOADER_NAME, loader_name} };
901 int ret = aul_sock_send_bundle_with_fd(fd, kPadCmdKillLoader, b.GetHandle(),
904 return aul_error_convert(ret);