Add a new internal function for getting proc group info 46/296246/7
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 24 Jul 2023 07:53:05 +0000 (16:53 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 25 Jul 2023 01:24:53 +0000 (10:24 +0900)
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 <h.jhun@samsung.com>
include/aul_cmd.h
include/aul_proc_group.h
src/aul_cmd.c
src/aul_proc_group.cc
tool/aul_test/tests/aul_proc_group_foreach_test.cc [new file with mode: 0644]
tool/aul_test/tests/aul_proc_group_get_test.cc [new file with mode: 0644]

index 4f180b9..d39f946 100644 (file)
@@ -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
 };
index dcb13b6..7766ea1 100644 (file)
@@ -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
index cabc4ab..bb279a0 100644 (file)
@@ -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"
        };
index eddae48..d42104e 100644 (file)
 #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<pid_t> sub_pids)
+      : leader_pid_(leader_pid), sub_pids_(std::move(sub_pids)) {}
+
+  pid_t GetLeaderPid() const {
+    return leader_pid_;
+  }
+
+  const std::vector<pid_t>& GetSubPids() const {
+    return sub_pids_;
+  }
+
+ private:
+  pid_t leader_pid_;
+  std::vector<pid_t> 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<app_pkt_t, decltype(std::free)*> 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<pid_t> 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<aul_proc_group_info_h>(&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<ProcGroupInfo*>(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<ProcGroupInfo*>(h);
+  auto& pids = info->GetSubPids();
+  *sub_pids = const_cast<pid_t*>(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<pid_t> 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<aul_proc_group_info_h>(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<ProcGroupInfo*>(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 (file)
index 0000000..e460db1
--- /dev/null
@@ -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 (file)
index 0000000..367242f
--- /dev/null
@@ -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 <pid>") {}
+
+  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