From 9e44b120754dee72362c2f3324cfc1f9ed11c480 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 24 Jul 2023 16:53:05 +0900 Subject: [PATCH] Add a new internal function for getting proc group info aul_proc_group_foreach() is added to retrieves the process group information. Adds: - aul_proc_group_info_get_leader_pid() - aul_proc_group_info_get_sub_pids() - aul_proc_group_info_destroy() - aul_proc_group_foreach() - aul_proc_group_get() Change-Id: I07f699088cf4c6e4eaf251df5df8153e2d8e1ea4 Signed-off-by: Hwankyu Jhun --- include/aul_cmd.h | 2 + include/aul_proc_group.h | 99 +++++++++++- src/aul_cmd.c | 2 + src/aul_proc_group.cc | 167 +++++++++++++++++++++ tool/aul_test/tests/aul_proc_group_foreach_test.cc | 58 +++++++ tool/aul_test/tests/aul_proc_group_get_test.cc | 66 ++++++++ 6 files changed, 393 insertions(+), 1 deletion(-) create mode 100644 tool/aul_test/tests/aul_proc_group_foreach_test.cc create mode 100644 tool/aul_test/tests/aul_proc_group_get_test.cc diff --git a/include/aul_cmd.h b/include/aul_cmd.h index 4f180b9..d39f946 100644 --- a/include/aul_cmd.h +++ b/include/aul_cmd.h @@ -220,6 +220,8 @@ enum app_cmd { BOOT_SEQUENCE_RELOAD = 175, PKG_PRE_EVENT_SEND = 176, + PROC_GROUP_FOREACH = 177, + PROC_GROUP_GET = 178, APP_CMD_MAX }; diff --git a/include/aul_proc_group.h b/include/aul_proc_group.h index dcb13b6..7766ea1 100644 --- a/include/aul_proc_group.h +++ b/include/aul_proc_group.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2021 - 2023 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,69 @@ extern "C" { #endif /** + * @brief The process group information handle. + * @since_tizen 8.0 + */ +typedef void *aul_proc_group_info_h; + +/** + * @brief Called when the process group info is delivered. + * @remarks This function is only for App Framework internally. + * @details You must not release @a h using aul_proc_group_info_destroy(). + * It's managed by platform. + * @since_tizen 8.0 + * @param[in] h The process group info handle + * @param[in] user_data The user data passed from the registration function + * @see aul_proc_group_foreach() + */ +typedef void (*aul_proc_group_cb)(aul_proc_group_info_h h, void *user_data); + +/** + * @brief Gets the leader process ID from the process group info handle. + * @remarks This function is only for App Framework internally. + * @since_tizen 8.0 + * @param[in] h The process group info handle + * @param[out] leader_pid The leader pid of the process group + * @return @c 0 on success, + * otherwise a negative error value + * @retval #AUL_R_OK Successful + * @retval #AUL_R_EINVAL Invalid parameter + * @see aul_proc_group_foreach() + */ +int aul_proc_group_info_get_leader_pid(aul_proc_group_info_h h, pid_t *leader_pid); + +/** + * @brief Gets the sub process IDs from the process group info handle. + * @remarks This function is only for App Framework internally. + * @details You must not release the @c sub_pids using free(). + * It's managed by platform. + * The sub_pids is only valid in the callback function. + * @since_tizen 8.0 + * @param[in] h The process group info handle + * @param[out] sub_pids The sub pids of the process group + * @param[out] length The length of the sub pids + * @return @c 0 on success, + * otherwise a negative error value + * @retval #AUL_R_OK Successful + * @retval #AUL_R_EINVAL Invalid parameter + * @see aul_proc_group_foreach() + */ +int aul_proc_group_info_get_sub_pids(aul_proc_group_info_h h, const pid_t **sub_pids, size_t *length); + +/** + * @brief Releases the process group info handle. + * @remarks This function is only for App Framework internally. + * @since_tizen 8.0 + * @param[in] h The process group info handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #AUL_R_OK Sucessful + * @retval #AUL_R_EINVAL Invalid parameter + * @see aul_proc_group_get() + */ +int aul_proc_group_info_destroy(aul_proc_group_info_h h); + +/** * @brief Adds the process to the process group. * @remarks This function is only for App Framework internally. * @remarks If the pid is not equal to the process ID of the caller, @@ -60,6 +123,40 @@ int aul_proc_group_add(pid_t pid); */ int aul_proc_group_remove(pid_t pid); +/** + * @brief Retrieves the process group information. + * @remarks This function is only for App Framework internally. + * @remarks This definition is only available for platform level signed applications. + * @param[in] callback The callback function + * @param[in] user_data The user data to be passed the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #AUL_R_OK Successful + * @retval #AUL_R_EINVAL Invalid parameter + * @retval #AUL_R_ECOMM Communication error + * @retval #AUL_R_EILLACC Permission denied + * @see aul_proc_group_cb() + */ +int aul_proc_group_foreach(aul_proc_group_cb callback, void *user_data); + +/** + * @brief Gets the specific process group info. + * @remarks This function is only for App Framework internally. + * @remarks This definition is only available for platform level signed applications. + * @details You must release the @c h using aul_proc_group_info_destroy(). + * @since_tizen 8.0 + * @param[in] pid The process ID + * @param[out] h The process group info handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #AUL_R_OK Successful + * @retval #AUL_R_EINVAL Invalid parameter + * @retval #AUL_R_ENOENT No such group info + * @retval #AUL_R_ENOMEM Out of memory + * @see aul_proc_group_info_destroy() + */ +int aul_proc_group_get(pid_t pid, aul_proc_group_info_h *h); + #ifdef __cplusplus } #endif diff --git a/src/aul_cmd.c b/src/aul_cmd.c index cabc4ab..bb279a0 100644 --- a/src/aul_cmd.c +++ b/src/aul_cmd.c @@ -222,6 +222,8 @@ API const char *aul_cmd_convert_to_string(int cmd) "BOOT_SEQUENCE_RELOAD", "PKG_PRE_EVENT_SEND", + "PROC_GROUP_FOREACH", + "PROC_GROUP_GET", "CUSTOM_COMMAND" }; diff --git a/src/aul_proc_group.cc b/src/aul_proc_group.cc index eddae48..d42104e 100644 --- a/src/aul_proc_group.cc +++ b/src/aul_proc_group.cc @@ -28,9 +28,70 @@ #include "include/aul_error.h" #include "include/aul_sock.h" +#include "aul/common/file_descriptor.hh" + using namespace aul; using namespace aul::internal; +namespace { + +class ProcGroupInfo { + public: + ProcGroupInfo(pid_t leader_pid, std::vector sub_pids) + : leader_pid_(leader_pid), sub_pids_(std::move(sub_pids)) {} + + pid_t GetLeaderPid() const { + return leader_pid_; + } + + const std::vector& GetSubPids() const { + return sub_pids_; + } + + private: + pid_t leader_pid_; + std::vector sub_pids_; +}; + +int SendAndReceive(int cmd, pid_t pid, bundle** response) { + int fd = AppRequest(cmd, getuid()) + .SetPid(pid) + .SendSimply(AUL_SOCK_ASYNC); + if (fd < 0 || fd >= sysconf(_SC_OPEN_MAX)) { + _E("Failed to send request. error(%d)", fd); + return fd; + } + + FileDescriptor fd_closer(fd); + app_pkt_t* pkt = nullptr; + int ret = aul_sock_recv_reply_pkt(fd, &pkt); + if (ret < 0) { + _E("Failed to receive reply packet. error(%d)", ret); + return AUL_R_ECOMM; + } + + std::unique_ptr pkt_auto(pkt, std::free); + if (!(pkt->opt & AUL_SOCK_BUNDLE)) { + _E("Invalid protocol"); + return AUL_R_ECOMM; + } + + if (pkt->cmd != APP_GET_INFO_OK) { + _E("Failed to get result"); + return AUL_R_ERROR; + } + + *response = bundle_decode(pkt->data, pkt->len); + if (*response == nullptr) { + _E("bundle_decode() is failed"); + return AUL_R_ERROR; + } + + return AUL_R_OK; +} + +} // namespace + extern "C" API int aul_proc_group_add(pid_t pid) { if (pid < 1) { _E("Invalid parameter"); @@ -64,3 +125,109 @@ extern "C" API int aul_proc_group_remove(pid_t pid) { return AUL_R_OK; } + +extern "C" API int aul_proc_group_foreach(aul_proc_group_cb callback, + void *user_data) { + if (callback == nullptr) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + bundle* response = nullptr; + int ret = SendAndReceive(PROC_GROUP_FOREACH, 0, &response); + if (ret != AUL_R_OK) + return ret; + + tizen_base::Bundle b(response, false, true); + auto length_str = b.GetString("__K_LENGTH"); + int length = std::stoi(length_str); + for (int i = 0; i < length; ++i) { + auto group = b.GetStringArray(std::to_string(i)); + if (group.size() == 0) { + _E("Invalid size. index(%d)", i); + continue; + } + + pid_t leader_pid = std::stoi(group[0]); + std::vector sub_pids; + for (size_t index = 1; index < group.size(); ++index) + sub_pids.push_back(std::stoi(group[index])); + + ProcGroupInfo info(leader_pid, std::move(sub_pids)); + callback(static_cast(&info), user_data); + } + + return AUL_R_OK; +} + +extern "C" API int aul_proc_group_info_get_leader_pid(aul_proc_group_info_h h, + pid_t* leader_pid) { + if (h == nullptr || leader_pid == nullptr) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + auto* info = static_cast(h); + *leader_pid = info->GetLeaderPid(); + return AUL_R_OK; +} + +extern "C" API int aul_proc_group_info_get_sub_pids(aul_proc_group_info_h h, + const pid_t** sub_pids, size_t* length) { + if (h == nullptr || sub_pids == nullptr || length == nullptr) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + auto* info = static_cast(h); + auto& pids = info->GetSubPids(); + *sub_pids = const_cast(pids.data()); + *length = pids.size(); + return AUL_R_OK; +} + +extern "C" API int aul_proc_group_get(pid_t pid, + aul_proc_group_info_h *h) { + if (pid < 2 || h == nullptr) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + bundle* response = nullptr; + int ret = SendAndReceive(PROC_GROUP_GET, pid, &response); + if (ret != AUL_R_OK) + return ret; + + tizen_base::Bundle b(response, false, true); + auto group = b.GetStringArray("__K_GROUP_INFO"); + if (group.size() == 0) { + _E("There is no group info. pid(%d)", pid); + return AUL_R_ENOENT; + } + + pid_t leader_pid = std::stoi(group[0]); + std::vector sub_pids; + for (size_t index = 1; index < group.size(); ++index) + sub_pids.push_back(std::stoi(group[index])); + + auto* info = new (std::nothrow) ProcGroupInfo(leader_pid, + std::move(sub_pids)); + if (info == nullptr) { + _E("Out of memory"); + return AUL_R_ENOMEM; + } + + *h = static_cast(info); + return AUL_R_OK; +} + +extern "C" API int aul_proc_group_info_destroy(aul_proc_group_info_h h) { + if (h == nullptr) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + auto* handle = static_cast(h); + delete handle; + return AUL_R_OK; +} diff --git a/tool/aul_test/tests/aul_proc_group_foreach_test.cc b/tool/aul_test/tests/aul_proc_group_foreach_test.cc new file mode 100644 index 0000000..e460db1 --- /dev/null +++ b/tool/aul_test/tests/aul_proc_group_foreach_test.cc @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "include/aul.h" +#include "include/aul_proc_group.h" + +#include "aul_test.hh" +#include "log_private.hh" + +namespace aul_test { + +class AulProcGroupForeachTest : public AulTest { + public: + AulProcGroupForeachTest() + : AulTest("foreach_proc_group", "aul_proc_group_foreach", + "foreach_proc_group") {} + + virtual ~AulProcGroupForeachTest() {} + + void SetUp() override {} + + void TearDown() override {} + + int Test(int argc, char** argv) override { + _D("[aul_proc_group_foreach test]"); + return aul_proc_group_foreach(AulProcGroupCb, this); + } + + static void AulProcGroupCb(aul_proc_group_info_h info, void* user_data) { + pid_t leader_pid = -1; + aul_proc_group_info_get_leader_pid(info, &leader_pid); + const pid_t* sub_pids = nullptr; + size_t length = 0; + aul_proc_group_info_get_sub_pids(info, &sub_pids, &length); + + _D("[GROUP]"); + _D(" - Leader: %d", leader_pid); + for (size_t i = 0; i < length; ++i) + _D(" - Sub: %d", sub_pids[i]); + } +}; + +AUL_TEST_REGISTER(AulProcGroupForeachTest, foreach_proc_group_test); + +} // namespace aul_test diff --git a/tool/aul_test/tests/aul_proc_group_get_test.cc b/tool/aul_test/tests/aul_proc_group_get_test.cc new file mode 100644 index 0000000..367242f --- /dev/null +++ b/tool/aul_test/tests/aul_proc_group_get_test.cc @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "include/aul.h" +#include "include/aul_proc_group.h" + +#include "aul_test.hh" +#include "log_private.hh" + +namespace aul_test { + +class AulProcGroupGetTest : public AulTest { + public: + AulProcGroupGetTest() + : AulTest("get_proc_group", "aul_proc_group_get", + "get_proc_group ") {} + + virtual ~AulProcGroupGetTest() {} + + void SetUp() override {} + + void TearDown() override {} + + int Test(int argc, char** argv) override { + if (argc < 3) { + Usage(); + return -1; + } + + _D("[aul_proc_group_get test] %s", argv[2]); + aul_proc_group_info_h info = nullptr; + int ret = aul_proc_group_get(atoi(argv[2]), &info); + if (ret != AUL_R_OK) + return ret; + + pid_t leader_pid = -1; + aul_proc_group_info_get_leader_pid(info, &leader_pid); + const pid_t* sub_pids = nullptr; + size_t length = 0; + aul_proc_group_info_get_sub_pids(info, &sub_pids, &length); + + _D("[GROUP]"); + _D(" - Leader: %d", leader_pid); + for (size_t i = 0; i < length; ++i) + _D(" - Sub: %d", sub_pids[i]); + + return aul_proc_group_info_destroy(info); + } +}; + +AUL_TEST_REGISTER(AulProcGroupGetTest, get_proc_group_test); + +} // namespace aul_test -- 2.7.4