Add new internal APIs
[platform/core/appfw/aul-1.git] / src / launch.cc
1 /*
2  * Copyright (c) 2000 - 2021 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <bundle_internal.h>
18 #include <ctype.h>
19 #include <dirent.h>
20 #include <fcntl.h>
21 #include <gio/gio.h>
22 #include <glib-unix.h>
23 #include <glib.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/stat.h>
28 #include <sys/time.h>
29 #include <sys/types.h>
30 #include <ttrace.h>
31
32 #include <memory>
33 #include <utility>
34
35 #include "app_request.h"
36 #include "app_signal.h"
37 #include "aul.h"
38 #include "aul_api.h"
39 #include "aul_app_com.h"
40 #include "aul_error.h"
41 #include "aul_sock.h"
42 #include "aul_util.h"
43 #include "launch.h"
44
45 using namespace aul::internal;
46
47 namespace {
48
49 constexpr const int TEP_ISMOUNT_MAX_RETRY_CNT = 20;
50
51 class ResultInfo {
52  public:
53   ResultInfo(int fd, aul_result_cb callback, void* user_data)
54       : fd_(fd), callback_(callback), user_data_(user_data) {}
55
56   ResultInfo(const ResultInfo&) = delete;
57   ResultInfo& operator = (const ResultInfo&) = delete;
58
59   ~ResultInfo() {
60     if (source_ != 0)
61       g_source_remove(source_);
62
63     if (fd_ > -1)
64       close(fd_);
65   }
66
67   bool Watch() {
68     source_ = g_unix_fd_add(fd_,
69         static_cast<GIOCondition>(G_IO_IN | G_IO_HUP | G_IO_ERR),
70         FdSourceFunc, this);
71     if (source_ == 0) {
72       _E("g_unix_fd_add() is failed");
73       return false;
74     }
75
76     return true;
77   }
78
79  private:
80   void ProcessReadEvent() {
81     int res = aul_sock_recv_result_with_fd(fd_);
82     if (res < 0)
83       res = aul_error_convert(res);
84     else
85       res = AUL_R_OK;
86
87     callback_(res, user_data_);
88   }
89
90   void ProcessErrorEvent() {
91     callback_(AUL_R_ERROR, user_data_);
92   }
93
94   static gboolean FdSourceFunc(int fd, GIOCondition condition,
95       void* user_data) {
96     auto* info = static_cast<ResultInfo*>(user_data);
97     if (condition & G_IO_IN)
98       info->ProcessReadEvent();
99     else
100       info->ProcessErrorEvent();
101
102     info->source_ = 0;
103     delete info;
104     return G_SOURCE_REMOVE;
105   }
106
107  private:
108   int fd_;
109   aul_result_cb callback_;
110   void *user_data_;
111   guint source_ = 0;
112 };
113
114 int aul_initialized = 0;
115 int aul_fd;
116 void* window_object = nullptr;
117 void* bg_object = nullptr;
118 void* conformant_object = nullptr;
119
120 int SendCmdForUidOpt(int pid, uid_t uid, int cmd, bundle* kb, int opt) {
121   int res = aul_sock_send_bundle(pid, uid, cmd, kb, opt);
122   if (res < 0)
123     res = aul_error_convert(res);
124
125   return res;
126 }
127
128 int SendCmdNoReplyForUidOpt(int pid, uid_t uid, int cmd, bundle* kb, int opt) {
129   int res = aul_sock_send_bundle(pid, uid, cmd, kb, opt | AUL_SOCK_NOREPLY);
130   if (res < 0)
131     res = aul_error_convert(res);
132
133   return res;
134 }
135
136 int CheckEnvPid() {
137   const char* env_str = getenv("AUL_PID");
138   if (env_str && isdigit(*env_str)) {
139     int env_pid = atoi(env_str);
140     if (env_pid != getpid()) {
141       _W("pid(%d) is not equal to AUL_PID(%d)",
142           getpid(), env_pid);
143       return -1;
144     }
145   }
146
147   return 0;
148 }
149
150 int GetPreInitFd() {
151   int fd = -1;
152
153   if (CheckEnvPid() != 0)
154     return fd;
155
156   const char* listen_fd = getenv("AUL_LISTEN_FD");
157   if (listen_fd) {
158     if (isdigit(*listen_fd))
159       fd = atoi(listen_fd);
160     setenv("AUL_LISTEN_FD", "-1", 1);
161   }
162
163   return fd;
164 }
165
166 }  // namespace
167
168 extern "C" int aul_is_initialized() {
169   return aul_initialized;
170 }
171
172 extern "C" API int app_send_cmd(int pid, int cmd, bundle* kb) {
173   return SendCmdForUidOpt(pid, getuid(), cmd, kb, AUL_SOCK_NONE);
174 }
175
176 extern "C" API int app_send_cmd_for_uid(int pid, uid_t uid, int cmd,
177     bundle* kb) {
178   return SendCmdForUidOpt(pid, uid, cmd, kb, AUL_SOCK_NONE);
179 }
180
181 extern "C" API int app_send_cmd_with_queue_for_uid(int pid, uid_t uid, int cmd,
182     bundle* kb) {
183   return SendCmdForUidOpt(pid, uid, cmd, kb, AUL_SOCK_QUEUE);
184 }
185
186 extern "C" API int app_send_cmd_with_queue_noreply_for_uid(int pid, uid_t uid,
187     int cmd, bundle* kb) {
188   return SendCmdNoReplyForUidOpt(pid, uid, cmd, kb, AUL_SOCK_QUEUE);
189 }
190
191 extern "C" API int app_send_cmd_with_noreply(int pid, int cmd, bundle* kb) {
192   return SendCmdForUidOpt(pid, getuid(), cmd, kb, AUL_SOCK_NOREPLY);
193 }
194
195 extern "C" API int app_send_cmd_to_launchpad(const char* pad_type, uid_t uid,
196     int cmd, bundle* kb) {
197   int fd = aul_sock_create_launchpad_client(pad_type, uid);
198   if (fd < 0)
199     return -1;
200
201   int res = aul_sock_send_bundle_with_fd(fd, cmd, kb, AUL_SOCK_ASYNC);
202   if (res < 0) {
203     close(fd);
204     return res;
205   }
206
207 retry_recv:
208   int len = recv(fd, &res, sizeof(int), 0);
209   if (len == -1) {
210     if (errno == EAGAIN) {
211       char buf[1024];
212       _E("recv timeout: %d(%s)", errno, strerror_r(errno, buf, sizeof(buf)));
213       res = -EAGAIN;
214     } else if (errno == EINTR) {
215       char buf[1024];
216       _D("recv: %d(%s)", errno, strerror_r(errno, buf, sizeof(buf)));
217       goto retry_recv;
218     } else {
219       char buf[1024];
220       _E("recv error: %d(%s)", errno, strerror_r(errno, buf, sizeof(buf)));
221       res = -ECOMM;
222     }
223   }
224
225   close(fd);
226   return res;
227 }
228
229 extern "C" int app_request_local(int cmd, bundle* kb) {
230   _E("app_request_to_launchpad : Same Process Send Local");
231   switch (cmd) {
232   case APP_START:
233   case APP_START_RES:
234   case APP_START_ASYNC:
235   case WIDGET_UPDATE:
236   case APP_START_RES_ASYNC:
237   case APP_SEND_LAUNCH_REQUEST:
238     return aul_launch_local(bundle_dup(kb));
239   case APP_OPEN:
240   case APP_RESUME:
241   case APP_RESUME_BY_PID:
242   case APP_RESUME_BY_PID_ASYNC:
243   case APP_SEND_RESUME_REQUEST:
244     return aul_resume_local();
245   default:
246     _E("no support packet");
247     return AUL_R_LOCAL;
248   }
249 }
250
251 extern "C" int app_request_to_launchpad_for_uid(int cmd, const char* appid,
252     bundle* kb, uid_t uid) {
253   return AppRequest(cmd, uid)
254       .With(kb)
255       .SetAppId(appid)
256       .Send();
257 }
258
259 extern "C" int aul_initialize() {
260   if (aul_initialized)
261     return AUL_R_ECANCELED;
262
263   aul_fd = GetPreInitFd();
264   if (aul_fd > 0 && aul_fd < sysconf(_SC_OPEN_MAX)) {
265     int flag = fcntl(aul_fd, F_GETFD);
266     flag |= FD_CLOEXEC;
267     (void)fcntl(aul_fd, F_SETFD, flag);
268   } else {
269     _W("Failed to get preinit fd");
270     aul_fd = aul_sock_create_server(getpid(), getuid());
271     if (aul_fd < 0) {
272       _E("aul_init create sock failed");
273       return AUL_R_ECOMM;
274     }
275   }
276   aul_notify_start();
277
278   aul_initialized = 1;
279   return aul_fd;
280 }
281
282 extern "C" API void aul_finalize() {
283   aul_launch_fini();
284
285   if (aul_initialized) {
286     aul_sock_destroy_server(aul_fd);
287     aul_fd = -1;
288   }
289 }
290
291 extern "C" API int aul_request_data_control_socket_pair(bundle* kb, int* fd) {
292   if (fd == nullptr)
293     return AUL_R_EINVAL;
294
295   int clifd = AppRequest(APP_GET_DC_SOCKET_PAIR)
296       .With(kb)
297       .SendSimply(AUL_SOCK_ASYNC);
298   if (clifd <= 0)
299     return AUL_R_ERROR;
300
301   int ret = aul_sock_recv_result_with_fd(clifd);
302   if (ret < 0) {
303     close(clifd);
304     if (ret == -EILLEGALACCESS) {
305       _E("Illegal access in datacontrol socket pair request");
306       return AUL_R_EILLACC;
307     }
308     return ret;
309   }
310
311   int fds[2] = { 0, };
312   ret = aul_sock_recv_reply_sock_fd(clifd, &fds, 1);
313   if (ret == 0)
314     fd[0] = fds[0];
315
316   return ret;
317 }
318
319 extern "C" API int aul_request_message_port_socket_pair(int* fd) {
320   if (fd == nullptr)
321     return AUL_R_EINVAL;
322
323   int ret = AppRequest(APP_GET_MP_SOCKET_PAIR)
324       .SendCmdOnly(AUL_SOCK_ASYNC);
325   if (ret > 0) {
326     int fds[2] = {0, };
327     ret = aul_sock_recv_reply_sock_fd(ret, &fds, 2);
328     if (ret == 0) {
329       fd[0] = fds[0];
330       fd[1] = fds[1];
331     }
332   }
333
334   return ret;
335 }
336
337 extern "C" API int aul_launch_app(const char* appid, bundle* kb) {
338   return aul_launch_app_for_uid(appid, kb, getuid());
339 }
340
341 extern "C" API int aul_launch_app_for_uid(const char* appid, bundle* kb,
342     uid_t uid) {
343   if (appid == nullptr)
344     return AUL_R_EINVAL;
345
346   return AppRequest(APP_START, uid)
347       .With(kb)
348       .SetAppId(appid)
349       .Send();
350 }
351
352 extern "C" API int aul_open_app(const char* appid) {
353   return aul_open_app_for_uid(appid, getuid());
354 }
355
356 extern "C" API int aul_open_app_for_uid(const char* appid, uid_t uid) {
357   if (appid == nullptr)
358     return AUL_R_EINVAL;
359
360   return AppRequest(APP_OPEN, uid)
361       .SetAppId(appid)
362       .Send();
363 }
364
365 extern "C" API int aul_resume_app(const char* appid) {
366   return aul_resume_app_for_uid(appid, getuid());
367 }
368
369 extern "C" API int aul_resume_app_for_uid(const char* appid, uid_t uid) {
370   if (appid == nullptr)
371     return AUL_R_EINVAL;
372
373   return AppRequest(APP_RESUME, uid)
374       .SetAppId(appid)
375       .Send();
376 }
377
378 extern "C" API int aul_resume_pid(int pid) {
379   return aul_resume_pid_for_uid(pid, getuid());
380 }
381
382 extern "C" API int aul_resume_pid_for_uid(int pid, uid_t uid) {
383   if (pid <= 0)
384     return AUL_R_EINVAL;
385
386   return AppRequest(APP_RESUME_BY_PID, uid)
387       .SetAppIdAsPid(pid)
388       .Send();
389 }
390
391 extern "C" API int aul_terminate_pid(int pid) {
392   return aul_terminate_pid_for_uid(pid, getuid());
393 }
394
395 extern "C" API int aul_terminate_pid_for_uid(int pid, uid_t uid) {
396   if (pid <= 0)
397     return AUL_R_EINVAL;
398
399   int ret = AppRequest(APP_TERM_BY_PID, uid)
400       .SetAppIdAsPid(pid)
401       .Send();
402   if (ret == pid)
403     ret = AUL_R_OK;
404
405   return ret;
406 }
407
408 extern "C" API int aul_terminate_bgapp_pid(int pid) {
409   if (pid <= 0)
410     return AUL_R_EINVAL;
411
412   int ret = AppRequest(APP_TERM_BGAPP_BY_PID)
413       .SetAppIdAsPid(pid)
414       .Send();
415   if (ret == pid)
416     ret = AUL_R_OK;
417
418   return ret;
419 }
420
421 extern "C" API int aul_terminate_pid_without_restart(int pid) {
422   if (pid <= 0)
423     return AUL_R_EINVAL;
424
425   return AppRequest(APP_TERM_BY_PID_WITHOUT_RESTART)
426       .SetAppIdAsPid(pid)
427       .Send();
428 }
429
430 extern "C" API int aul_terminate_pid_sync_without_restart(int pid) {
431   return aul_terminate_pid_sync_without_restart_for_uid(pid, getuid());
432 }
433
434 extern "C" API int aul_terminate_pid_sync_without_restart_for_uid(int pid,
435     uid_t uid) {
436   if (pid <= 0)
437     return AUL_R_EINVAL;
438
439   return AppRequest(APP_TERM_BY_PID_SYNC_WITHOUT_RESTART, uid)
440       .SetAppIdAsPid(pid)
441       .Send();
442 }
443
444 extern "C" API int aul_terminate_pid_async(int pid) {
445   return aul_terminate_pid_async_for_uid(pid, getuid());
446 }
447
448 extern "C" API int aul_terminate_pid_async_for_uid(int pid, uid_t uid) {
449   if (pid <= 0)
450     return AUL_R_EINVAL;
451
452   return AppRequest(APP_TERM_BY_PID_ASYNC, uid)
453       .SetAppIdAsPid(pid)
454       .Send();
455 }
456
457 extern "C" API int aul_kill_pid(int pid) {
458   if (pid <= 0)
459     return AUL_R_EINVAL;
460
461   return AppRequest(APP_KILL_BY_PID)
462       .SetAppIdAsPid(pid)
463       .Send();
464 }
465
466 extern "C" API void aul_set_preinit_window(void* evas_object) {
467   window_object = evas_object;
468 }
469
470 extern "C" API void* aul_get_preinit_window(const char* win_name) {
471   return window_object;
472 }
473
474 extern "C" API void aul_set_preinit_background(void* evas_object) {
475   bg_object = evas_object;
476 }
477
478 extern "C" API void* aul_get_preinit_background(void) {
479   return bg_object;
480 }
481
482 extern "C" API void aul_set_preinit_conformant(void* evas_object) {
483   conformant_object = evas_object;
484 }
485
486 extern "C" API void* aul_get_preinit_conformant(void) {
487   return conformant_object;
488 }
489
490 extern "C" API int aul_pause_app(const char* appid) {
491   return aul_pause_app_for_uid(appid, getuid());
492 }
493
494 extern "C" API int aul_pause_app_for_uid(const char* appid, uid_t uid) {
495   if (appid == nullptr)
496     return AUL_R_EINVAL;
497
498   return AppRequest(APP_PAUSE, uid)
499       .SetAppId(appid)
500       .Send(AUL_SOCK_QUEUE | AUL_SOCK_NOREPLY);
501 }
502
503 extern "C" API int aul_pause_pid(int pid) {
504   return aul_pause_pid_for_uid(pid, getuid());
505 }
506
507 extern "C" API int aul_pause_pid_for_uid(int pid, uid_t uid) {
508   if (pid <= 0)
509     return AUL_R_EINVAL;
510
511   return AppRequest(APP_PAUSE_BY_PID, uid)
512       .SetAppIdAsPid(pid)
513       .Send(AUL_SOCK_QUEUE | AUL_SOCK_NOREPLY);
514 }
515
516 extern "C" API int aul_reload_appinfo(void) {
517   return AppRequest(AMD_RELOAD_APPINFO)
518       .SetAppIdAsPid(getpid())
519       .Send();
520 }
521
522 extern "C" API int aul_is_tep_mount_dbus_done(const char* tep_string) {
523   GError* err = nullptr;
524   GDBusConnection* conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &err);
525   if (conn == nullptr) {
526     _E("g_bus_get_sync() is failed. error(%s)", err ? err->message : "Unknown");
527     g_clear_error(&err);
528     return AUL_R_ERROR;
529   }
530
531   std::unique_ptr<GDBusConnection, decltype(g_object_unref)*> conn_ptr(
532       conn, g_object_unref);
533
534   GDBusMessage* msg = g_dbus_message_new_method_call(TEP_BUS_NAME,
535           TEP_OBJECT_PATH,
536           TEP_INTERFACE_NAME,
537           TEP_IS_MOUNTED_METHOD);
538   if (msg == nullptr) {
539     _E("g_dbus_message_new_method_call() is failed. error(%s)",
540         err ? err->message : "Unknown");
541     return AUL_R_ERROR;
542   }
543
544   std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> msg_ptr(
545       msg, g_object_unref);
546   g_dbus_message_set_body(msg, g_variant_new("(s)", tep_string));
547
548   GDBusMessage* reply = g_dbus_connection_send_message_with_reply_sync(conn,
549           msg,
550           G_DBUS_SEND_MESSAGE_FLAGS_NONE,
551           500,
552           nullptr,
553           nullptr,
554           &err);
555   if (reply == nullptr || err != nullptr) {
556     _E("g_dbus_connection_send_message_with_reply_sync() is failed. error(%s)",
557         err ? err->message : "Unknown");
558     g_clear_error(&err);
559     return AUL_R_ERROR;
560   }
561
562   std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> reply_ptr(
563       reply, g_object_unref);
564
565   GVariant* body = g_dbus_message_get_body(reply);
566   if (body == nullptr) {
567     _E("g_dbus_message_get_body() is failed.");
568     return AUL_R_ERROR;
569   }
570
571   int ret = AUL_R_ERROR;
572   g_variant_get(body, "(i)", &ret);
573   return ret;
574 }
575
576 extern "C" API int aul_check_tep_mount(const char* tep_path) {
577   if (tep_path) {
578     int ret = -1;
579     int cnt = 0;
580     while (cnt < TEP_ISMOUNT_MAX_RETRY_CNT) {
581       ret = aul_is_tep_mount_dbus_done(tep_path);
582       if (ret == 1)
583         break;
584       usleep(50 * 1000);
585       cnt++;
586     }
587     /* incase after trying 1 sec, not getting mounted then quit */
588     if (ret != 1) {
589       _E("Not able to mount within 1 sec");
590       return -1;
591     }
592   }
593   return 0;
594 }
595
596 extern "C" API int aul_add_loader(const char* loader_path, bundle* kb) {
597   return aul_add_loader_for_uid(loader_path, kb, getuid());
598 }
599
600 extern "C" API int aul_add_loader_for_uid(const char* loader_path, bundle* kb,
601     uid_t uid) {
602   if (loader_path == nullptr)
603     return AUL_R_EINVAL;
604
605   tizen_base::Bundle b = { {AUL_K_LOADER_PATH, loader_path} };
606
607   if (kb) {
608     try {
609       tizen_base::Bundle extra(kb, false, false);
610       auto raw = extra.ToRaw();
611       b.Add(AUL_K_LOADER_EXTRA, (const char*)(raw.first.get()));
612     } catch (const std::bad_alloc&) {
613       return AUL_R_EINVAL;
614     }
615   }
616
617   return AppRequest(APP_ADD_LOADER, uid)
618       .With(std::move(b))
619       .SendSimply();
620 }
621
622 extern "C" API int aul_remove_loader(int loader_id) {
623   return aul_remove_loader_for_uid(loader_id, getuid());
624 }
625
626 extern "C" API int aul_remove_loader_for_uid(int loader_id, uid_t uid) {
627   if (loader_id <= 0)
628     return AUL_R_EINVAL;
629
630   return AppRequest(APP_REMOVE_LOADER, uid)
631       .With({{AUL_K_LOADER_ID, std::to_string(loader_id)}})
632       .SendSimply();
633 }
634
635 extern "C" API int aul_app_register_pid(const char* appid, int pid) {
636   if (appid == nullptr || pid <= 0)
637     return AUL_R_EINVAL;
638
639   return AppRequest(APP_REGISTER_PID)
640       .SetAppId(appid)
641       .SetPid(pid)
642       .SendSimply(AUL_SOCK_NOREPLY);
643 }
644
645 extern "C" API int aul_launch_app_async(const char* appid, bundle* kb) {
646   return aul_launch_app_async_for_uid(appid, kb, getuid());
647 }
648
649 extern "C" API int aul_launch_app_async_for_uid(const char* appid, bundle* kb,
650     uid_t uid) {
651   if (appid == nullptr)
652     return AUL_R_EINVAL;
653
654   return AppRequest(APP_START_ASYNC, uid)
655       .With(kb)
656       .SetAppId(appid)
657       .Send();
658 }
659
660 extern "C" API int aul_prepare_candidate_process(void) {
661   return AppRequest(APP_PREPARE_CANDIDATE_PROCESS)
662       .SendCmdOnly();
663 }
664
665 extern "C" API int aul_terminate_pid_sync(int pid) {
666   return aul_terminate_pid_sync_for_uid(pid, getuid());
667 }
668
669 extern "C" API int aul_terminate_pid_sync_for_uid(int pid, uid_t uid) {
670   if (pid <= 0)
671     return AUL_R_EINVAL;
672
673   return AppRequest(APP_TERM_BY_PID_SYNC, uid)
674       .SetAppIdAsPid(pid)
675       .Send();
676 }
677
678 extern "C" API int aul_resume_pid_async(int pid) {
679   return aul_resume_pid_async_for_uid(pid, getuid());
680 }
681
682 extern "C" API int aul_resume_pid_async_for_uid(int pid, uid_t uid) {
683   if (pid <= 0)
684     return AUL_R_EINVAL;
685
686   return AppRequest(APP_RESUME_BY_PID_ASYNC, uid)
687       .SetAppIdAsPid(pid)
688       .Send();
689 }
690
691 extern "C" API int aul_resume_app_by_instance_id(const char* appid,
692     const char *instance_id) {
693   return aul_resume_app_by_instance_id_for_uid(appid, instance_id, getuid());
694 }
695
696 extern "C" API int aul_resume_app_by_instance_id_for_uid(const char* appid,
697     const char* instance_id, uid_t uid) {
698   if (appid == nullptr || instance_id == nullptr) {
699     _E("Invalid parameter");
700     return AUL_R_EINVAL;
701   }
702
703   return AppRequest(APP_RESUME, uid)
704       .SetAppId(appid)
705       .SetInstId(instance_id)
706       .Send();
707 }
708
709 extern "C" API int aul_terminate_instance_async(const char* instance_id,
710     int pid) {
711   return aul_terminate_instance_async_for_uid(instance_id, pid, getuid());
712 }
713
714 extern "C" API int aul_terminate_instance_async_for_uid(const char* instance_id,
715     int pid, uid_t uid) {
716   if (instance_id == nullptr) {
717     _E("Invalid parameter");
718     return AUL_R_EINVAL;
719   }
720
721   return AppRequest(APP_TERM_INSTANCE_ASYNC, uid)
722       .SetAppIdAsPid(pid)
723       .SetInstId(instance_id)
724       .Send();
725 }
726
727 extern "C" API int aul_terminate_app_with_instance_id(const char* appid,
728     const char* instance_id) {
729   return aul_terminate_app_with_instance_id_for_uid(appid, instance_id,
730       getuid());
731 }
732
733 extern "C" API int aul_terminate_app_with_instance_id_for_uid(const char* appid,
734     const char* instance_id, uid_t uid) {
735   if (appid == nullptr || instance_id == nullptr) {
736     _E("Invalid parameter");
737     return AUL_R_EINVAL;
738   }
739
740   return AppRequest(APP_TERMINATE, uid)
741       .SetAppId(appid)
742       .SetInstId(instance_id)
743       .Send();
744 }
745
746 extern "C" API int aul_terminate_app(const char* appid) {
747   return aul_terminate_app_for_uid(appid, getuid());
748 }
749
750 extern "C" API int aul_terminate_app_for_uid(const char* appid, uid_t uid) {
751   if (appid == nullptr) {
752     _E("Invalid parameter");
753     return AUL_R_EINVAL;
754   }
755
756   return AppRequest(APP_TERMINATE, uid)
757       .SetAppId(appid)
758       .Send();
759 }
760
761 extern "C" API int aul_prepare_app_defined_loader(const char* loader_name) {
762   return aul_prepare_app_defined_loader_for_uid(loader_name, getuid());
763 }
764
765 extern "C" API int aul_prepare_app_defined_loader_for_uid(
766     const char* loader_name, uid_t uid) {
767   if (loader_name == nullptr) {
768     _E("Invalid parameter");
769     return AUL_R_EINVAL;
770   }
771
772   int ret = AppRequest(APP_PREPARE_APP_DEFINED_LOADER, uid)
773       .With({{AUL_K_LOADER_NAME, loader_name}})
774       .SendSimply();
775   if (ret < 0) {
776     _E("Failed to prepare app-defined loader. error(%d)", ret);
777     return ret;
778   }
779
780   _I("loader id(%d)", ret);
781   return ret;
782 }
783
784 extern "C" API int aul_terminate_pid_async_v2(pid_t pid,
785     aul_result_cb callback, void *user_data) {
786   if (pid < 1 || callback == nullptr) {
787     _E("Invalid parameter");
788     return AUL_R_EINVAL;
789   }
790
791   int fd = AppRequest(APP_TERM_BY_PID, getuid())
792       .SetAppIdAsPid(pid)
793       .SendSimply(AUL_SOCK_ASYNC);
794   if (fd < 0) {
795     _E("Failed to send request. error(%d)", fd);
796     return fd;
797   }
798
799   try {
800     auto* info = new ResultInfo(fd, callback, user_data);
801     info->Watch();
802   } catch (const std::exception& e) {
803     _E("Exception occurs. error: %s", e.what());
804     close(fd);
805     return AUL_R_ERROR;
806   }
807
808   return AUL_R_OK;
809 }
810
811 extern "C" API int aul_terminate_app_async(const char* appid,
812     aul_result_cb callback, void *user_data) {
813   if (appid == nullptr || callback == nullptr) {
814     _E("Invalid parameter");
815     return AUL_R_EINVAL;
816   }
817
818   int fd = AppRequest(APP_TERMINATE, getuid())
819       .SetAppId(appid)
820       .SendSimply(AUL_SOCK_ASYNC);
821   if (fd < 0) {
822     _E("Failed to send request. error(%d)", fd);
823     return fd;
824   }
825
826   try {
827     auto* info = new ResultInfo(fd, callback, user_data);
828     info->Watch();
829   } catch (const std::exception& e) {
830     _E("Exception occurs. error: %s", e.what());
831     close(fd);
832     return AUL_R_ERROR;
833   }
834
835   return AUL_R_OK;
836 }
837
838 extern "C" API int aul_kill_pid_async(pid_t pid,
839     aul_result_cb callback, void *user_data) {
840   if (pid < 1 || callback == nullptr) {
841     _E("Invalid parameter");
842     return AUL_R_EINVAL;
843   }
844
845   int fd = AppRequest(APP_KILL_BY_PID, getuid())
846       .SetAppIdAsPid(pid)
847       .SendSimply(AUL_SOCK_ASYNC);
848   if (fd < 0) {
849     _E("Failed to send request. error(%d)", fd);
850     return fd;
851   }
852
853   try {
854     auto* info = new ResultInfo(fd, callback, user_data);
855     info->Watch();
856   } catch (const std::exception& e) {
857     _E("Exception occurs. error: %s", e.what());
858     close(fd);
859     return AUL_R_ERROR;
860   }
861
862   return AUL_R_OK;
863 }