2 * Copyright (c) 2012 - 2022 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_cpp.h>
18 #include <bundle_internal.h>
19 #include <glib-unix.h>
22 #include <sys/types.h>
30 #include "app_request.h"
32 #include "aul_error.h"
34 #include "menu_db_util.h"
35 #include "include/aul.h"
36 #include "include/aul_error.h"
37 #include "include/aul_sock.h"
39 using namespace aul::internal;
43 constexpr const char* kAppInfoKeys[] = {
52 constexpr const char kPathAmdReady[] = "/run/.amd_ready";
56 ResultInfo(pid_t pid, int fd, aul_appid_cb callback, void* user_data)
57 : pid_(pid), fd_(fd), callback_(callback), user_data_(user_data) {}
59 ResultInfo(const ResultInfo&) = delete;
60 ResultInfo& operator = (const ResultInfo&) = delete;
64 g_source_remove(source_);
71 source_ = g_unix_fd_add(fd_,
72 static_cast<GIOCondition>(G_IO_IN | G_IO_HUP | G_IO_ERR),
75 _E("g_unix_fd_add() is failed");
83 void ProcessReadEvent() {
84 app_pkt_t* pkt = nullptr;
85 int ret = aul_sock_recv_reply_pkt(fd_, &pkt);
86 if (ret < 0 || pkt == nullptr) {
91 auto pkt_auto = std::unique_ptr<app_pkt_t, decltype(std::free)*>(
93 if (pkt->cmd != APP_GET_INFO_OK) {
98 char appid[256] = { 0, };
99 snprintf(appid, sizeof(appid), "%s", pkt->data);
100 SECURE_LOGD("pid: %d, appid: %s", pid_, appid);
101 callback_(AUL_R_OK, pid_, appid, user_data_);
104 void ProcessErrorEvent() {
105 callback_(AUL_R_ERROR, pid_, "", user_data_);
108 static gboolean FdSourceFunc(int fd, GIOCondition condition,
109 gpointer user_data) {
110 auto* info = static_cast<ResultInfo*>(user_data);
111 _E("GIOCondition: %d", static_cast<int>(condition));
112 if (condition & G_IO_IN)
113 info->ProcessReadEvent();
115 info->ProcessErrorEvent();
119 return G_SOURCE_REMOVE;
125 aul_appid_cb callback_;
131 static std::atomic<bool> amd_ready = false;
135 if (access(kPathAmdReady, F_OK) == 0) {
136 amd_ready.exchange(true);
151 auto* appid = getenv("AUL_APPID");
152 if (appid != nullptr)
153 appid_ = std::string(appid);
155 auto* pkgid = getenv("AUL_PKGID");
156 if (pkgid != nullptr)
157 pkgid_ = std::string(pkgid);
159 auto* root_path = getenv("AUL_ROOT_PATH");
160 if (root_path != nullptr)
161 root_path_ = std::string(root_path);
166 const std::string& GetPreInitAppId() const {
170 const std::string& GetPreInitPkgId() const {
174 const std::string& GetPreInitRootPath() const {
178 void SetPreInitAppId(std::string appid) {
179 appid_ = std::move(appid);
182 void SetPreInitPkgId(std::string pkgid) {
183 pkgid_ = std::move(pkgid);
186 void SetPreInitRootPath(std::string root_path) {
187 root_path_ = std::move(root_path);
191 bool initialized_ = false;
194 std::string root_path_;
197 int SendAndReceive(int cmd, uid_t uid,
198 std::vector<tizen_base::Bundle>* results) {
199 int fd = AppRequest(cmd, uid).SendSimply(AUL_SOCK_ASYNC);
203 int ret = aul_sock_recv_pkt_with_cb(fd,
204 [](app_pkt_t* pkt, void* user_data) {
205 if (pkt == nullptr) {
206 _E("Invalid parameter");
211 if (pkt->opt & AUL_SOCK_BUNDLE)
212 b = bundle_decode(pkt->data, pkt->len);
217 auto* res = static_cast<std::vector<tizen_base::Bundle>*>(user_data);
218 res->push_back(tizen_base::Bundle(b, false, true));
221 return aul_error_convert(ret);
226 int SetAppInfo(aul_app_info* info, const tizen_base::Bundle& b) {
227 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
228 for (unsigned int i = 0; i < ARRAY_SIZE(kAppInfoKeys); ++i) {
229 if (b.GetType(kAppInfoKeys[i]) == BUNDLE_TYPE_NONE)
233 info->pid = std::stoi(b.GetString(AUL_K_PID));
234 info->appid = const_cast<char*>(bundle_get_val(b.GetHandle(), AUL_K_APPID));
235 info->app_path = const_cast<char*>(bundle_get_val(b.GetHandle(), AUL_K_EXEC));
236 info->pkgid = const_cast<char*>(bundle_get_val(b.GetHandle(), AUL_K_PKGID));
237 info->instance_id = const_cast<char*>(
238 bundle_get_val(b.GetHandle(), AUL_K_INSTANCE_ID));
239 info->status = std::stoi(b.GetString(AUL_K_STATUS));
240 info->is_sub_app = std::stoi(b.GetString(AUL_K_IS_SUBAPP));
241 info->pkg_name = info->appid;
245 int GetRunningAppInfoWithCb(int cmd, uid_t uid, aul_app_info_iter_fn cb,
250 std::vector<tizen_base::Bundle> results;
251 int ret = SendAndReceive(cmd, uid, &results);
256 for (auto const& b : results) {
257 if (SetAppInfo(&info, b) != 0)
260 cb(&info, user_data);
268 int GetPkgIdFromDB(int pid, char* buf, int len, uid_t uid) {
269 auto appid = context.GetPreInitAppId();
271 _E("Failed to get pre-initialized appid");
275 auto* menu_info = _get_app_info_from_db_by_appid_user(appid.c_str(), uid);
276 if (menu_info == nullptr) {
277 _E("Failed to get app info. appid(%s)", appid.c_str());
281 snprintf(buf, len, "%s", _get_pkgid(menu_info));
282 _free_app_info_from_db(menu_info);
288 extern "C" API int aul_app_get_pid(const char* appid) {
289 return aul_app_get_pid_for_uid(appid, getuid());
292 extern "C" API int aul_app_get_pid_for_uid(const char* appid, uid_t uid) {
293 if (appid == nullptr)
296 return AppRequest(APP_GET_PID, uid)
301 extern "C" API int aul_app_is_running(const char* appid) {
302 return aul_app_is_running_for_uid(appid, getuid());
305 extern "C" API int aul_app_is_running_for_uid(const char* appid, uid_t uid) {
306 if (appid == nullptr)
309 int ret = AppRequest(APP_IS_RUNNING, uid)
315 extern "C" API int aul_app_get_running_app_info(aul_app_info_iter_fn iter_fn,
317 return aul_app_get_running_app_info_for_uid(iter_fn, user_data, getuid());
320 extern "C" API int aul_app_get_running_app_info_for_uid(
321 aul_app_info_iter_fn iter_fn, void* user_data, uid_t uid) {
322 return GetRunningAppInfoWithCb(APP_RUNNING_INFO, uid, iter_fn, user_data);
325 extern "C" API int aul_app_get_all_running_app_info(
326 aul_app_info_iter_fn iter_fn, void* user_data) {
327 return aul_app_get_all_running_app_info_for_uid(iter_fn, user_data, getuid());
330 extern "C" API int aul_app_get_all_running_app_info_for_uid(
331 aul_app_info_iter_fn iter_fn, void* user_data, uid_t uid) {
332 return GetRunningAppInfoWithCb(APP_ALL_RUNNING_INFO, uid, iter_fn, user_data);
335 extern "C" API int aul_app_get_running_app_instance_info(
336 aul_app_info_iter_fn iter_fn, void* user_data) {
337 return aul_app_get_running_app_instance_info_for_uid(iter_fn, user_data,
341 extern "C" API int aul_app_get_running_app_instance_info_for_uid(
342 aul_app_info_iter_fn iter_fn, void *user_data, uid_t uid) {
343 return GetRunningAppInfoWithCb(APP_RUNNING_INSTANCE_INFO, uid, iter_fn,
347 extern "C" API void aul_set_preinit_appid(const char* appid) {
348 context.Initialize();
349 context.SetPreInitAppId(appid ? appid : "");
352 extern "C" API void aul_set_preinit_pkgid(const char* pkgid) {
353 context.Initialize();
354 context.SetPreInitPkgId(pkgid ? pkgid : "");
357 extern "C" API void aul_set_preinit_root_path(const char* root_path) {
358 context.Initialize();
359 context.SetPreInitRootPath(root_path ? root_path : "");
362 extern "C" API const char* aul_get_preinit_root_path(void) {
363 context.Initialize();
364 return context.GetPreInitRootPath().c_str();
367 extern "C" API int aul_app_get_pkgname_bypid(int pid, char* pkgname, int len) {
368 return aul_app_get_appid_bypid(pid, pkgname, len);
371 extern "C" API int aul_app_get_appid_bypid(int pid, char* appid, int len) {
372 return aul_app_get_appid_bypid_for_uid(pid, appid, len, getuid());
375 extern "C" API int aul_app_get_appid_bypid_for_uid(int pid, char* appid,
376 int len, uid_t uid) {
377 if (pid < 1 || appid == nullptr) {
378 _E("Invalid parameter");
382 if (getpid() == pid || getpgid(getpid()) == pid) {
383 context.Initialize();
384 auto& preinit_appid = context.GetPreInitAppId();
385 if (!preinit_appid.empty()) {
386 snprintf(appid, len, "%s", preinit_appid.c_str());
391 int fd = AppRequest(APP_GET_APPID_BYPID, uid)
393 .SendSimply(AUL_SOCK_ASYNC);
397 app_pkt_t* pkt = nullptr;
398 int ret = aul_sock_recv_reply_pkt(fd, &pkt);
399 if (ret < 0 || pkt == nullptr)
402 auto pkt_auto = std::unique_ptr<app_pkt_t, decltype(std::free)*>(
404 if (pkt->cmd != APP_GET_INFO_OK)
407 snprintf(appid, len, "%s", pkt->data);
411 extern "C" API int aul_app_get_pkgid_bypid(int pid, char* pkgid, int len) {
412 return aul_app_get_pkgid_bypid_for_uid(pid, pkgid, len, getuid());
415 extern "C" API int aul_app_get_pkgid_bypid_for_uid(int pid, char* pkgid,
416 int len, uid_t uid) {
417 if (pid < 1 || pkgid == nullptr) {
418 _E("Invalid parameter");
422 if (getpid() == pid || getpgid(getpid()) == pid) {
423 context.Initialize();
424 auto& preinit_pkgid = context.GetPreInitPkgId();
425 if (!preinit_pkgid.empty()) {
426 snprintf(pkgid, len, "%s", preinit_pkgid.c_str());
430 if (GetPkgIdFromDB(pid, pkgid, len, uid) == 0)
434 int fd = AppRequest(APP_GET_PKGID_BYPID, uid)
436 .SendSimply(AUL_SOCK_ASYNC);
440 app_pkt_t* pkt = nullptr;
441 int ret = aul_sock_recv_reply_pkt(fd, &pkt);
442 if (ret < 0 || pkt == nullptr)
445 auto pkt_auto = std::unique_ptr<app_pkt_t, decltype(std::free)*>(
447 if (pkt->cmd != APP_GET_INFO_OK)
450 snprintf(pkgid, len, "%s", pkt->data);
454 extern "C" API int aul_update_rua_stat_for_uid(bundle* b, uid_t uid) {
456 _E("Invalid parameter");
460 return AppRequest(APP_UPDATE_RUA_STAT, uid)
465 extern "C" API int aul_add_rua_history_for_uid(bundle* b, uid_t uid) {
467 _E("Invalid parameter");
471 return AppRequest(APP_ADD_HISTORY, uid)
476 extern "C" API int aul_delete_rua_history_for_uid(bundle* b, uid_t uid) {
477 tizen_base::Bundle kb;
479 kb = std::move(tizen_base::Bundle(b, false, false));
481 return AppRequest(APP_REMOVE_HISTORY, uid)
486 extern "C" API int aul_set_default_app_by_operation(bundle* b) {
490 return AppRequest(APP_SET_APP_CONTROL_DEFAULT_APP, getuid())
495 extern "C" API int aul_unset_default_app_by_operation(const char* appid) {
496 if (appid == nullptr)
499 int ret = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
500 APP_UNSET_APP_CONTROL_DEFAULT_APP,
501 reinterpret_cast<unsigned char*>(const_cast<char*>(appid)),
502 strlen(appid), AUL_SOCK_NONE);
504 return aul_error_convert(ret);
509 extern "C" API int aul_app_get_last_caller_pid(int pid) {
510 return aul_app_get_last_caller_pid_for_uid(pid, getuid());
513 extern "C" API int aul_app_get_last_caller_pid_for_uid(int pid, uid_t uid) {
515 _E("Invalid parameter");
519 return AppRequest(APP_GET_LAST_CALLER_PID, uid)
524 extern "C" API int aul_set_alias_appid(const char* alias_appid,
526 if (alias_appid == nullptr || appid == nullptr) {
527 _E("Invalid parameter");
531 tizen_base::Bundle b { { AUL_K_ALIAS_APPID, alias_appid } };
533 return AppRequest(APP_SET_ALIAS_APPID, getuid())
539 extern "C" API int aul_unset_alias_appid(const char* alias_appid) {
540 if (alias_appid == nullptr) {
541 _E("Invalid parameter");
545 tizen_base::Bundle b { { AUL_K_ALIAS_APPID, alias_appid } };
546 return AppRequest(APP_UNSET_ALIAS_APPID, getuid())
551 extern "C" API int aul_enable_alias_info(const char* appid) {
552 if (appid == nullptr) {
553 _E("Invalid parameter");
557 return AppRequest(APP_ENABLE_ALIAS_INFO, getuid())
562 extern "C" API int aul_disable_alias_info(const char* appid) {
563 if (appid == nullptr) {
564 _E("Invalid parameter");
568 return AppRequest(APP_DISABLE_ALIAS_INFO, getuid())
573 extern "C" API int aul_set_auto_restart(bundle* b) {
574 tizen_base::Bundle kb { { AUL_K_AUTO_RESTART, "true" } };
578 if (bundle_encode(b, &raw, &len) != BUNDLE_ERROR_NONE)
581 kb.Add(AUL_K_RESTART_EXTRA, reinterpret_cast<char*>(raw));
582 bundle_free_encoded_rawdata(&raw);
585 return AppRequest(APP_SET_AUTO_RESTART, getuid())
590 extern "C" API int aul_unset_auto_restart(void) {
591 tizen_base::Bundle kb { { AUL_K_AUTO_RESTART, "false" } };
592 return AppRequest(APP_SET_AUTO_RESTART, getuid())
597 extern "C" API int aul_app_get_instance_id_bypid(int pid, char* instance_id,
599 return aul_app_get_instance_id_bypid_for_uid(pid, instance_id, len, getuid());
602 extern "C" API int aul_app_get_instance_id_bypid_for_uid(int pid,
603 char* instance_id, int len, uid_t uid) {
604 if (pid < 1 || instance_id == nullptr) {
605 _E("Invalid parameter");
609 int fd = AppRequest(APP_GET_INSTANCE_ID_BYPID, uid)
611 .SendSimply(AUL_SOCK_ASYNC);
615 app_pkt_t* pkt = nullptr;
616 int ret = aul_sock_recv_reply_pkt(fd, &pkt);
617 if (ret < 0 || pkt == nullptr)
620 auto pkt_auto = std::unique_ptr<app_pkt_t, decltype(std::free)*>(
622 if (pkt->cmd != APP_GET_INFO_OK)
625 snprintf(instance_id, len, "%s", pkt->data);
629 extern "C" API int aul_app_is_running_with_instance_id(const char* appid,
630 const char* instance_id, bool* running) {
631 if (appid == nullptr || instance_id == nullptr || running == nullptr) {
632 _E("Invalid parameter");
636 int ret = AppRequest(APP_IS_RUNNING, getuid())
638 .SetInstId(instance_id)
643 *running = ret ? true : false;
647 extern "C" API int aul_get_default_app(bundle* b, char** appid) {
648 if (b == nullptr || appid == nullptr) {
649 _E("Invalid parameter");
653 int fd = AppRequest(APP_GET_APP_CONTROL_DEFAULT_APP, getuid())
655 .SendSimply(AUL_SOCK_ASYNC);
659 app_pkt_t* pkt = nullptr;
660 int ret = aul_sock_recv_reply_pkt(fd, &pkt);
661 if (ret < 0 || pkt == nullptr) {
662 _E("aul_sock_recv_reply_pkt() is failed. error(%d)", ret);
663 return aul_error_convert(ret);
666 auto pkt_auto = std::unique_ptr<app_pkt_t, decltype(std::free)*>(
668 if (pkt->cmd != APP_GET_INFO_OK) {
669 _E("Failed to get default app. error(%d)", pkt->cmd);
670 return aul_error_convert(pkt->cmd);
673 if (!(pkt->opt & AUL_SOCK_BUNDLE)) {
674 _E("Invalid protocol");
678 bundle* res_b = bundle_decode(pkt->data, pkt->len);
679 if (res_b == nullptr) {
680 _E("bundle_decode() is failed");
684 tizen_base::Bundle kb(res_b, false, true);
685 auto value = kb.GetString(AUL_K_APPID);
687 _E("Failed to get appid");
691 *appid = strdup(value.c_str());
692 if (*appid == nullptr) {
693 _E("strdup() is failed. appid(%s)", value.c_str());
700 extern "C" API int aul_package_pre_event_send(uid_t uid, bundle* b) {
702 _E("Invalid paremeter");
709 return AppRequest(PKG_PRE_EVENT_SEND, uid)
714 extern "C" API int aul_app_get_appid_bypid_async(pid_t pid,
715 aul_appid_cb callback, void* user_data) {
716 if (pid < 1 || callback == nullptr) {
717 _E("Invalid parameter");
721 if (getpid() == pid || getpgid(getpid()) == pid) {
722 context.Initialize();
723 auto& preinit_appid = context.GetPreInitAppId();
724 if (!preinit_appid.empty()) {
725 callback(AUL_R_OK, pid, preinit_appid.c_str(), user_data);
730 int fd = AppRequest(APP_GET_APPID_BYPID, getuid())
732 .SendSimply(AUL_SOCK_ASYNC);
737 auto* result_info = new ResultInfo(pid, fd, callback, user_data);
738 result_info->Watch();
739 } catch (const std::exception& e) {
740 _E("Exception occurs. error: %s", e.what());