Refactor App Group API 32/279632/3
authorHwankyu Jhun <h.jhun@samsung.com>
Fri, 12 Aug 2022 10:45:39 +0000 (19:45 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 16 Aug 2022 10:02:23 +0000 (10:02 +0000)
The app group API is implemented using C++ language.

Change-Id: I8047911920e0c6d3b70582621e2f85abef278c6b
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
CMakeLists.txt
aul/app_group/app_group_info.cc [new file with mode: 0644]
aul/app_group/app_group_info.hh [new file with mode: 0644]
include/aul_app_group.h
src/app_group.c [deleted file]
src/app_group.cc [new file with mode: 0644]

index 5fd9ace..dcd0144 100644 (file)
@@ -64,8 +64,9 @@ AUX_SOURCE_DIRECTORY(src SRCS)
 AUX_SOURCE_DIRECTORY(aul AUL_SRCS)
 AUX_SOURCE_DIRECTORY(aul/api AUL_API_SRCS)
 AUX_SOURCE_DIRECTORY(aul/app_control AUL_APP_CONTROL_SRCS)
-AUX_SOURCE_DIRECTORY(aul/app_manager AUL_APP_MANAGER_SRCS)
+AUX_SOURCE_DIRECTORY(aul/app_group AUL_APP_GROUP_SRCS)
 AUX_SOURCE_DIRECTORY(aul/app_info AUL_APP_INFO_SRCS)
+AUX_SOURCE_DIRECTORY(aul/app_manager AUL_APP_MANAGER_SRCS)
 AUX_SOURCE_DIRECTORY(aul/common AUL_COMMON_SRCS)
 AUX_SOURCE_DIRECTORY(aul/component AUL_COMPONENT_SRCS)
 AUX_SOURCE_DIRECTORY(aul/socket AUL_SOCKET_SRCS)
@@ -75,6 +76,7 @@ ADD_LIBRARY(${TARGET_AUL} SHARED
   ${AUL_SRCS}
   ${AUL_API_SRCS}
   ${AUL_APP_CONTROL_SRCS}
+  ${AUL_APP_GROUP_SRCS}
   ${AUL_APP_MANAGER_SRCS}
   ${AUL_APP_INFO_SRCS}
   ${AUL_COMMON_SRCS}
diff --git a/aul/app_group/app_group_info.cc b/aul/app_group/app_group_info.cc
new file mode 100644 (file)
index 0000000..d6bd8c1
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2022 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 "aul/app_group/app_group_info.hh"
+
+#include "include/aul.h"
+#include "aul/common/exception.hh"
+
+namespace aul {
+
+AppGroupInfo::Builder& AppGroupInfo::Builder::SetId(
+    const tizen_base::Bundle& b) {
+  id_ = std::move(b.GetString(AUL_K_INSTANCE_ID));
+  return *this;
+}
+
+AppGroupInfo::Builder& AppGroupInfo::Builder::SetPid(
+    const tizen_base::Bundle& b) {
+  auto pid_str = b.GetString(AUL_K_PID);
+  if (pid_str.empty())
+    return *this;
+
+  pid_ = std::stoi(pid_str);
+  return *this;
+}
+
+AppGroupInfo::Builder& AppGroupInfo::Builder::SetAppId(
+    const tizen_base::Bundle& b) {
+  appid_ = std::move(b.GetString(AUL_K_APPID));
+  return *this;
+}
+
+AppGroupInfo::Builder& AppGroupInfo::Builder::SetPkgId(
+    const tizen_base::Bundle& b) {
+  pkgid_ = std::move(b.GetString(AUL_K_PKGID));
+  return *this;
+}
+
+AppGroupInfo::Builder& AppGroupInfo::Builder::SetWid(
+    const tizen_base::Bundle& b) {
+  auto wid_str = b.GetString(AUL_K_WID);
+  if (wid_str.empty())
+    return *this;
+
+  wid_ = std::stoi(wid_str);
+  return *this;
+}
+
+AppGroupInfo::Builder& AppGroupInfo::Builder::SetFg(
+    const tizen_base::Bundle& b) {
+  auto fg_str = b.GetString(AUL_K_FG_FLAG);
+  if (fg_str.empty())
+    return *this;
+
+  fg_ = std::stoi(fg_str) ? true : false;
+  return *this;
+}
+
+AppGroupInfo::Builder& AppGroupInfo::Builder::SetStatus(
+    const tizen_base::Bundle& b) {
+  auto status_str = b.GetString(AUL_K_STATUS);
+  if (status_str.empty())
+    return *this;
+
+  status_ = std::stoi(status_str);
+  return *this;
+}
+
+AppGroupInfo::Builder::operator AppGroupInfo*() {
+  Validate();
+  return new (std::nothrow) AppGroupInfo(std::move(id_), pid_,
+      std::move(appid_), std::move(pkgid_), wid_, fg_, status_);
+}
+
+void AppGroupInfo::Builder::Validate() {
+  if (id_.empty() ||
+      pid_ < 1 ||
+      appid_.empty() ||
+      pkgid_.empty() ||
+      wid_ < 0 ||
+      status_ < 0) {
+    _E("id(%s), pid(%d), appid(%s), pkgid(%s), wid(%d), status(%d)",
+        id_.c_str(), pid_, appid_.c_str(), pkgid_.c_str(), wid_, status_);
+    THROW(AUL_R_ERROR);
+  }
+}
+
+AppGroupInfo::AppGroupInfo(std::string id, pid_t pid, std::string appid,
+    std::string pkgid, int wid, bool fg, int status)
+    : id_(std::move(id)),
+      pid_(pid),
+      appid_(std::move(appid)),
+      pkgid_(std::move(pkgid)),
+      wid_(wid),
+      fg_(fg),
+      status_(status) {
+}
+
+const std::string& AppGroupInfo::GetId() const {
+  return id_;
+}
+
+pid_t AppGroupInfo::GetPid() const {
+  return pid_;
+}
+
+const std::string& AppGroupInfo::GetAppId() const {
+  return appid_;
+}
+
+const std::string& AppGroupInfo::GetPkgId() const {
+  return pkgid_;
+}
+
+int AppGroupInfo::GetWid() const {
+  return wid_;
+}
+
+bool AppGroupInfo::IsFg() const {
+  return fg_;
+}
+
+int AppGroupInfo::GetStatus() const {
+  return status_;
+}
+
+}  // namespace aul
diff --git a/aul/app_group/app_group_info.hh b/aul/app_group/app_group_info.hh
new file mode 100644 (file)
index 0000000..62da7b4
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2022 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.
+ *
+ */
+
+#ifndef AUL_APP_GROUP_APP_GROUP_INFO_HH
+#define AUL_APP_GROUP_APP_GROUP_INFO_HH
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <bundle_cpp.h>
+
+#include <string>
+
+namespace aul {
+
+class AppGroupInfo {
+ public:
+  class Builder {
+   public:
+    Builder& SetId(const tizen_base::Bundle& b);
+    Builder& SetPid(const tizen_base::Bundle& b);
+    Builder& SetAppId(const tizen_base::Bundle& b);
+    Builder& SetPkgId(const tizen_base::Bundle& b);
+    Builder& SetWid(const tizen_base::Bundle& b);
+    Builder& SetFg(const tizen_base::Bundle& b);
+    Builder& SetStatus(const tizen_base::Bundle& b);
+    operator AppGroupInfo*();
+
+   private:
+    void Validate();
+
+   private:
+    std::string id_;
+    pid_t pid_ = -1;
+    std::string appid_;
+    std::string pkgid_;
+    int wid_ = -1;
+    bool fg_ = false;
+    int status_ = -1;
+  };
+
+  AppGroupInfo(std::string id, pid_t pid, std::string appid,
+      std::string pkgid, int wid, bool fg, int status);
+
+  const std::string& GetId() const;
+  pid_t GetPid() const;
+  const std::string& GetAppId() const;
+  const std::string& GetPkgId() const;
+  int GetWid() const;
+  bool IsFg() const;
+  int GetStatus() const;
+
+ private:
+  std::string id_;
+  pid_t pid_ = -1;
+  std::string appid_;
+  std::string pkgid_;
+  int wid_ = -1;
+  bool fg_ = false;
+  int status_ = -1;
+};
+
+}  // namespace aul
+
+#endif  // AUL_APP_GROUP_APP_GROUP_INFO_HH
index 1eb8c44..bf86a93 100644 (file)
@@ -31,6 +31,10 @@ extern "C" {
  */
 typedef struct aul_app_group_info_s *aul_app_group_info_h;
 
+typedef void (*aul_app_group_leader_id_cb)(const char *leader_id, void* user_data);
+
+typedef void (*aul_app_group_info_cb)(aul_app_group_info_h info, void *user_data);
+
 /**
  * @brief Gets the ID.
  * @since_tizen 5.5
@@ -136,7 +140,7 @@ int aul_app_group_info_get_status(aul_app_group_info_h h, int *status);
  *
  * @remarks This function is only for App Framework internally.
  */
-int aul_app_group_foreach_leader_ids(void (*callback)(const char *, void *),
+int aul_app_group_foreach_leader_ids(aul_app_group_leader_id_cb callback,
                void *user_data);
 
 /**
@@ -152,8 +156,7 @@ int aul_app_group_foreach_leader_ids(void (*callback)(const char *, void *),
  * @remarks This function is only for App Framework internally.
  */
 int aul_app_group_foreach_group_info(const char *leader_id,
-               void (*callback)(aul_app_group_info_h, void *),
-               void *user_data);
+               aul_app_group_info_cb callback, void *user_data);
 
 /**
  * @brief Retrieves the idle instances.
@@ -166,8 +169,7 @@ int aul_app_group_foreach_group_info(const char *leader_id,
  *
  * @remarks This function is only for App Framework internally.
  */
-int aul_app_group_foreach_idle_info(
-               void (*callback)(aul_app_group_info_h, void *),
+int aul_app_group_foreach_idle_info(aul_app_group_info_cb callback,
                void *user_data);
 
 /**
diff --git a/src/app_group.c b/src/app_group.c
deleted file mode 100644 (file)
index 0ae5c73..0000000
+++ /dev/null
@@ -1,734 +0,0 @@
-/*
- * Copyright (c) 2015 - 2019 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.
- */
-
-#define _GNU_SOURCE
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <bundle_internal.h>
-
-#include "aul.h"
-#include "aul_api.h"
-#include "aul_util.h"
-#include "aul_sock.h"
-#include "launch.h"
-#include "aul_app_group.h"
-#include "aul_error.h"
-
-struct aul_app_group_info_s {
-       const char *id;
-       pid_t pid;
-       const char *appid;
-       const char *pkgid;
-       int wid;
-       bool fg;
-       int status;
-};
-
-API int aul_app_group_get_window(int pid)
-{
-       int ret;
-       bundle *b;
-       char buf[128];
-
-       if (pid < 1) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       b = bundle_create();
-       if (b == NULL) {
-               _E("out of memory");
-               return AUL_R_ENOMEM;
-       }
-
-       snprintf(buf, 128, "%d", pid);
-       bundle_add_str(b, AUL_K_PID, buf);
-       ret = app_send_cmd(AUL_UTIL_PID, APP_GROUP_GET_WINDOW, b);
-       bundle_free(b);
-
-       return ret;
-}
-
-API int aul_app_group_set_window(int wid)
-{
-       int ret;
-       bundle *b;
-       char buf[128];
-
-       if (wid < 1) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       b = bundle_create();
-       if (b == NULL) {
-               _E("out of memory");
-               return AUL_R_ENOMEM;
-       }
-
-       snprintf(buf, 128, "%d", wid);
-       bundle_add_str(b, AUL_K_WID, buf);
-       ret = app_send_cmd_with_noreply(AUL_UTIL_PID, APP_GROUP_SET_WINDOW, b);
-       bundle_free(b);
-
-       return ret;
-}
-
-API void aul_app_group_get_leader_pids(int *cnt, int **pids)
-{
-       int ret;
-       int fd;
-       app_pkt_t *pkt = NULL;
-       int c;
-
-       if (cnt == NULL || pids == NULL) {
-               _E("Invalid parameter");
-               return;
-       }
-
-       *cnt = 0;
-       *pids = NULL;
-       fd = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
-                       APP_GROUP_GET_LEADER_PIDS, NULL, 0, AUL_SOCK_ASYNC);
-       if (fd < 0)
-               return;
-
-       ret = aul_sock_recv_reply_pkt(fd, &pkt);
-       if (ret < 0 || pkt == NULL)
-               return;
-
-       c = pkt->len / sizeof(int);
-       if (c > 0 && pkt->len <= AUL_SOCK_MAXBUFF - AUL_PKT_HEADER_SIZE) {
-               *pids = malloc(pkt->len);
-               if (*pids == NULL) {
-                       _E("out of memory");
-                       free(pkt);
-                       return;
-               }
-
-               memcpy(*pids, pkt->data, pkt->len);
-               *cnt = c;
-       }
-
-       free(pkt);
-}
-
-API void aul_app_group_get_group_pids(int leader_pid, int *cnt, int **pids)
-{
-       int ret;
-       int fd;
-       app_pkt_t *pkt = NULL;
-       bundle *b;
-       char buf[128];
-       int c;
-
-       if (leader_pid < 1 || cnt == NULL || pids == NULL) {
-               _E("Invalid parameter");
-               return;
-       }
-
-       *cnt = 0;
-       *pids = NULL;
-       b = bundle_create();
-       if (b == NULL) {
-               _E("out of memory");
-               return;
-       }
-
-       snprintf(buf, 128, "%d", leader_pid);
-       bundle_add_str(b, AUL_K_LEADER_PID, buf);
-
-       fd = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
-                       APP_GROUP_GET_GROUP_PIDS, b, AUL_SOCK_ASYNC);
-
-       if (fd > 0) {
-               ret = aul_sock_recv_reply_pkt(fd, &pkt);
-       } else {
-               bundle_free(b);
-               return;
-       }
-
-       if (ret < 0 || pkt == NULL) {
-               bundle_free(b);
-               return;
-       }
-
-       c = pkt->len / sizeof(int);
-       if (c > 0 && pkt->len <= AUL_SOCK_MAXBUFF - AUL_PKT_HEADER_SIZE) {
-               *pids = malloc(pkt->len);
-               if (*pids == NULL) {
-                       _E("out of memory");
-                       goto clear;
-               }
-
-               memcpy(*pids, pkt->data, pkt->len);
-               *cnt = c;
-       }
-
-clear:
-       free(pkt);
-       bundle_free(b);
-}
-
-API int aul_app_group_get_leader_pid(int pid)
-{
-       int ret;
-       bundle *b;
-       char buf[128];
-
-       if (pid < 1) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       b = bundle_create();
-       if (b == NULL) {
-               _E("out of memory");
-               return -1;
-       }
-
-       snprintf(buf, 128, "%d", pid);
-       bundle_add_str(b, AUL_K_PID, buf);
-       ret = app_send_cmd(AUL_UTIL_PID, APP_GROUP_GET_LEADER_PID, b);
-       bundle_free(b);
-
-       return ret;
-}
-
-API int aul_app_group_clear_top(void)
-{
-       unsigned char dummy[1] = { 0 };
-       return aul_sock_send_raw(AUL_UTIL_PID, getuid(), APP_GROUP_CLEAR_TOP, dummy, 0, AUL_SOCK_NONE);
-}
-
-API int aul_app_group_is_top(void)
-{
-       int lpid = aul_app_group_get_leader_pid(getpid());
-
-       if (lpid > 0) {
-               int cnt;
-               int *pids = NULL;
-               aul_app_group_get_group_pids(lpid, &cnt, &pids);
-               if (cnt > 0) {
-                       if (pids[cnt-1] == getpid()) {
-                               free(pids);
-                               return 1;
-                       }
-
-                       free(pids);
-                       return 0;
-               }
-       }
-
-       return 1;
-}
-
-API int aul_app_group_get_fg_flag(int pid)
-{
-       int ret;
-       bundle *b;
-       char buf[128];
-
-       if (pid < 1) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       b = bundle_create();
-       if (b == NULL) {
-               _E("out of memory");
-               return -1;
-       }
-
-       snprintf(buf, 128, "%d", pid);
-       bundle_add_str(b, AUL_K_PID, buf);
-       ret = app_send_cmd(AUL_UTIL_PID, APP_GROUP_GET_FG, b);
-       bundle_free(b);
-
-       return ret;
-}
-
-API void aul_app_group_lower(int *exit)
-{
-       int ret;
-       unsigned char dummy[1] = { 0 };
-
-       if (exit == NULL) {
-               _E("Invalid parameter");
-               return;
-       }
-
-       ret = aul_sock_send_raw(AUL_UTIL_PID, getuid(), APP_GROUP_LOWER,
-                       dummy, 0, AUL_SOCK_NONE);
-       if (ret < 0)
-               return;
-       *exit = ret;
-}
-
-API void aul_app_group_get_idle_pids(int *cnt, int **pids)
-{
-       int ret;
-       int fd;
-       app_pkt_t *pkt = NULL;
-       int c;
-
-       if (cnt == NULL || pids == NULL) {
-               _E("Invalid parameter");
-               return;
-       }
-
-       *cnt = 0;
-       *pids = NULL;
-       fd = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
-                       APP_GROUP_GET_IDLE_PIDS, NULL, 0, AUL_SOCK_ASYNC);
-
-       if (fd > 0)
-               ret = aul_sock_recv_reply_pkt(fd, &pkt);
-       else
-               return;
-
-       if (pkt == NULL || ret < 0)
-               return;
-
-       c = pkt->len / sizeof(int);
-       if (c > 0 && pkt->len <= AUL_SOCK_MAXBUFF - AUL_PKT_HEADER_SIZE) {
-               *pids = malloc(pkt->len);
-               if (*pids == NULL) {
-                       _E("out of memory");
-                       free(pkt);
-                       return;
-               }
-
-               memcpy(*pids, pkt->data, pkt->len);
-               *cnt = c;
-       }
-
-       free(pkt);
-}
-
-API int aul_app_group_activate_below(const char *below_appid)
-{
-       int ret;
-       bundle *b;
-
-       if (below_appid == NULL)
-               return AUL_R_EINVAL;
-
-       b = bundle_create();
-
-       if (b == NULL) {
-               _E("out of memory");
-               return -1;
-       }
-
-       bundle_add_str(b, AUL_K_APPID, below_appid);
-       ret = app_send_cmd(AUL_UTIL_PID, APP_GROUP_ACTIVATE_BELOW, b);
-       bundle_free(b);
-
-       return ret;
-}
-
-API int aul_app_group_activate_above(const char *above_appid)
-{
-       int ret;
-       bundle *b;
-
-       if (above_appid == NULL)
-               return AUL_R_EINVAL;
-
-       b = bundle_create();
-
-       if (b == NULL) {
-               _E("out of memory");
-               return -1;
-       }
-
-       bundle_add_str(b, AUL_K_APPID, above_appid);
-       ret = app_send_cmd(AUL_UTIL_PID, APP_GROUP_ACTIVATE_ABOVE, b);
-       bundle_free(b);
-
-       return ret;
-}
-
-API int aul_app_group_set_window_v2(const char *id, int wid)
-{
-       char buf[32];
-       bundle *b;
-       int ret;
-
-       if (!id || wid < 0) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       b = bundle_create();
-       if (!b) {
-               _E("Out of memory");
-               return AUL_R_ERROR;
-       }
-
-       bundle_add(b, AUL_K_INSTANCE_ID, id);
-       snprintf(buf, sizeof(buf), "%d", wid);
-       bundle_add(b, AUL_K_WID, buf);
-
-       ret = app_send_cmd_with_noreply(AUL_UTIL_PID, APP_GROUP_SET_WINDOW_V2,
-                       b);
-       bundle_free(b);
-
-       return ret;
-}
-
-API int aul_app_group_lower_v2(const char *id, bool *exit)
-{
-       bundle *b;
-       int ret;
-
-       if (!id | !exit) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       b = bundle_create();
-       if (!b) {
-               _E("Out of memory");
-               return AUL_R_ERROR;
-       }
-
-       bundle_add(b, AUL_K_INSTANCE_ID, id);
-
-       ret = app_send_cmd(AUL_UTIL_PID, APP_GROUP_LOWER_V2, b);
-       bundle_free(b);
-       if (ret < 0)
-               return ret;;
-
-       *exit = (bool)ret;
-
-       return AUL_R_OK;
-}
-
-API int aul_app_group_foreach_leader_ids(void (*callback)(const char *, void *),
-               void *user_data)
-{
-       app_pkt_t *pkt = NULL;
-       const char **str_arr;
-       int len = 0;
-       bundle *b;
-       int ret;
-       int fd;
-       int i;
-
-       if (!callback) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       fd = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
-                       APP_GROUP_GET_LEADER_IDS, NULL, 0, AUL_SOCK_ASYNC);
-       if (fd < 0) {
-               _E("Failed to send the request. result(%d)", fd);
-               return aul_error_convert(fd);
-       }
-
-       ret = aul_sock_recv_reply_pkt(fd, &pkt);
-       if (ret < 0 || pkt == NULL) {
-               _E("Failed to receive the packet. result(%d)", ret);
-               return aul_error_convert(ret);
-       }
-
-       b = bundle_decode((const bundle_raw *)pkt->data, pkt->len);
-       if (!b) {
-               _E("Failed to decode bundle data(%s:%d)",
-                               (const char *)pkt->data, pkt->len);
-               free(pkt);
-               return AUL_R_ERROR;
-       }
-       free(pkt);
-
-       str_arr = bundle_get_str_array(b, AUL_K_LEADER_IDS, &len);
-       if (str_arr == NULL || len == 0) {
-               _E("Failed to get data");
-               bundle_free(b);
-               return AUL_R_ERROR;
-       }
-
-       for (i = 0; i < len; i++)
-               callback(str_arr[i], user_data);
-
-       bundle_free(b);
-
-       return AUL_R_OK;
-}
-
-struct app_group_cb_info_s {
-       void (*callback)(aul_app_group_info_h, void *);
-       void *user_data;
-};
-
-static void __foreach_group_info(app_pkt_t *pkt, void *user_data)
-{
-       struct app_group_cb_info_s *cb_info;
-       struct aul_app_group_info_s info = { 0, };
-       bundle *b = NULL;
-       const char *val;
-
-       cb_info = (struct app_group_cb_info_s *)user_data;
-       if (!pkt || !cb_info) {
-               _E("Invalid parameter");
-               return;
-       }
-
-       if (pkt->cmd == APP_GET_INFO_ERROR) {
-               _E("Failed to get app group info");
-               return;
-       }
-
-       if (pkt->opt & AUL_SOCK_BUNDLE)
-               b = bundle_decode(pkt->data, pkt->len);
-
-       if (!b)
-               return;
-
-       info.id = bundle_get_val(b, AUL_K_INSTANCE_ID);
-       if (!info.id)
-               goto end;
-
-       val = bundle_get_val(b, AUL_K_PID);
-       if (!val)
-               goto end;
-
-       if (isdigit(val[0]))
-               info.pid = atoi(val);
-
-       info.appid = bundle_get_val(b, AUL_K_APPID);
-       if (!info.appid)
-               goto end;
-
-       info.pkgid = bundle_get_val(b, AUL_K_PKGID);
-       if (!info.pkgid)
-               goto end;
-
-       val = bundle_get_val(b, AUL_K_WID);
-       if (!val)
-               goto end;
-
-       if (isdigit(val[0]))
-               info.wid = atoi(val);
-
-       val = bundle_get_val(b, AUL_K_FG_FLAG);
-       if (!val)
-               goto end;
-
-       if (isdigit(val[0]))
-               info.fg = (bool)atoi(val);
-
-       val = bundle_get_val(b, AUL_K_STATUS);
-       if (!val)
-               goto end;
-
-       if (isdigit(val[0]))
-               info.status = atoi(val);
-
-       cb_info->callback(&info, cb_info->user_data);
-
-end:
-       bundle_free(b);
-}
-
-API int aul_app_group_foreach_group_info(const char *leader_id,
-               void (*callback)(aul_app_group_info_h, void *),
-               void *user_data)
-{
-       struct app_group_cb_info_s cb_info = {callback, user_data};
-       bundle *b;
-       int ret;
-       int fd;
-
-       if (!leader_id || !callback) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       b = bundle_create();
-       if (!b) {
-               _E("Out of memory");
-               return AUL_R_ERROR;
-       }
-
-       bundle_add(b, AUL_K_LEADER_ID, leader_id);
-
-       fd = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
-                       APP_GROUP_GET_GROUP_INFO, b, AUL_SOCK_ASYNC);
-       if (fd < 0) {
-               bundle_free(b);
-               return aul_error_convert(fd);
-       }
-       bundle_free(b);
-
-       ret = aul_sock_recv_pkt_with_cb(fd, __foreach_group_info, &cb_info);
-       if (ret < 0)
-               return aul_error_convert(ret);
-
-       return ret;
-}
-
-API int aul_app_group_foreach_idle_info(
-               void (*callback)(aul_app_group_info_h, void *),
-               void *user_data)
-{
-       struct app_group_cb_info_s cb_info = {callback, user_data};
-       int ret;
-       int fd;
-
-       if (!callback) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       fd = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
-                       APP_GROUP_GET_IDLE_INFO, NULL, 0, AUL_SOCK_ASYNC);
-       if (fd < 0)
-               return aul_error_convert(fd);
-
-       ret = aul_sock_recv_pkt_with_cb(fd, __foreach_group_info, &cb_info);
-       if (ret < 0)
-               return aul_error_convert(ret);
-
-       return ret;
-}
-
-API int aul_app_group_info_get_id(aul_app_group_info_h h, const char **id)
-{
-       if (!h | !id) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       *id = h->id;
-
-       return AUL_R_OK;
-}
-
-API int aul_app_group_info_get_pid(aul_app_group_info_h h, pid_t *pid)
-{
-       if (!h || !pid) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       *pid = h->pid;
-
-       return AUL_R_OK;
-}
-
-API int aul_app_group_info_get_appid(aul_app_group_info_h h, const char **appid)
-{
-       if (!h || !appid) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       *appid = h->appid;
-
-       return AUL_R_OK;
-}
-
-
-API int aul_app_group_info_get_pkgid(aul_app_group_info_h h, const char **pkgid)
-{
-       if (!h || !pkgid) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       *pkgid = h->pkgid;
-
-       return AUL_R_OK;
-}
-
-API int aul_app_group_info_get_window(aul_app_group_info_h h, int *wid)
-{
-       if (!h || !wid) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       *wid = h->wid;
-
-       return AUL_R_OK;
-}
-
-API int aul_app_group_info_get_fg_flag(aul_app_group_info_h h, bool *fg_flag)
-{
-       if (!h || !fg_flag) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       *fg_flag = h->fg;
-
-       return AUL_R_OK;
-}
-
-API int aul_app_group_info_get_status(aul_app_group_info_h h, int *status)
-{
-       if (!h || !status) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       *status = h->status;
-
-       return AUL_R_OK;
-}
-
-static int __send_cmd_with_wid(int cmd, int wid)
-{
-       char buf[12];
-       bundle *b;
-       int ret;
-
-       if (wid <= 0) {
-               _E("Invalid parameter");
-               return AUL_R_EINVAL;
-       }
-
-       b = bundle_create();
-       if (!b) {
-               _E("Out of memory");
-               return AUL_R_ENOMEM;
-       }
-
-       snprintf(buf, sizeof(buf), "%d", wid);
-       bundle_add(b, AUL_K_WID, buf);
-
-       ret = app_send_cmd_with_noreply(AUL_UTIL_PID, cmd, b);
-       bundle_free(b);
-       return ret;
-}
-
-API int aul_app_group_add(int wid)
-{
-       return __send_cmd_with_wid(APP_GROUP_ADD, wid);
-}
-
-API int aul_app_group_remove(int wid)
-{
-       return __send_cmd_with_wid(APP_GROUP_REMOVE, wid);
-}
diff --git a/src/app_group.cc b/src/app_group.cc
new file mode 100644 (file)
index 0000000..dc2d1a0
--- /dev/null
@@ -0,0 +1,513 @@
+/*
+ * Copyright (c) 2015 - 2022 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_app_group.h"
+
+#include <bundle_cpp.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "app_request.h"
+#include "aul_api.h"
+#include "aul_util.h"
+#include "include/aul.h"
+#include "include/aul_error.h"
+#include "include/aul_sock.h"
+#include "launch.h"
+
+#include "aul/app_group/app_group_info.hh"
+#include "aul/common/exception.hh"
+
+using namespace aul;
+using namespace aul::internal;
+
+struct aul_app_group_info_s {
+  void* dummy;
+};
+
+namespace {
+
+constexpr const int kMaxPacketLength = AUL_SOCK_MAXBUFF - AUL_PKT_HEADER_SIZE;
+
+AppGroupInfo* CreateAppGroupInfo(const tizen_base::Bundle& b) {
+  return  AppGroupInfo::Builder()
+      .SetId(b)
+      .SetPid(b)
+      .SetAppId(b)
+      .SetPkgId(b)
+      .SetWid(b)
+      .SetFg(b)
+      .SetStatus(b);
+}
+
+std::vector<std::shared_ptr<AppGroupInfo>> ReceiveAppGroupInfos(int fd) {
+  std::vector<std::shared_ptr<AppGroupInfo>> infos;
+  int ret = aul_sock_recv_pkt_with_cb(fd,
+      [](app_pkt_t* pkt, void* user_data) {
+        if (pkt->cmd == APP_GET_INFO_ERROR || !(pkt->opt & AUL_SOCK_BUNDLE))
+          return;
+
+        bundle* kb = bundle_decode(pkt->data, pkt->len);
+        if (kb == nullptr) {
+          _E("bundle_decode() is failed");
+          return;
+        }
+
+        tizen_base::Bundle b(kb, false, true);
+        try {
+          auto* info = CreateAppGroupInfo(b);
+          if (info == nullptr) {
+            _E("Out of memory");
+            return;
+          }
+
+          auto* info_array =
+              static_cast<std::vector<std::shared_ptr<AppGroupInfo>>*>(
+                  user_data);
+          info_array->emplace_back(info);
+        } catch (const Exception& e) {
+          _E("Exception occurs. error(%s)", e.what());
+        }
+      }, &infos);
+  if (ret < 0)
+    THROW(aul_error_convert(ret));
+
+  return infos;
+}
+
+std::vector<std::string> ReceiveLeaderIds(int fd) {
+  app_pkt_t* pkt = nullptr;
+  int ret = aul_sock_recv_reply_pkt(fd, &pkt);
+  if (ret < 0 || pkt == nullptr)
+    THROW(AUL_R_ERROR);
+
+  auto pkt_auto = std::unique_ptr<app_pkt_t, decltype(std::free)*>(
+      pkt, std::free);
+
+  bundle* kb = bundle_decode(pkt->data, pkt->len);
+  if (kb == nullptr) {
+    _E("bundle_decode() is failed. data(%s:%d)", pkt->data, pkt->len);
+    THROW(AUL_R_ERROR);
+  }
+
+  tizen_base::Bundle b(kb, false, true);
+  return b.GetStringArray(AUL_K_LEADER_IDS);
+}
+
+void ReceivePids(int fd, int* cnt, int** pids) {
+  app_pkt_t* pkt = nullptr;
+  int ret = aul_sock_recv_reply_pkt(fd, &pkt);
+  if (ret < 0 || pkt == nullptr)
+    THROW(AUL_R_ERROR);
+
+  auto pkt_auto = std::unique_ptr<app_pkt_t, decltype(std::free)*>(
+      pkt, std::free);
+
+  int count = pkt->len / sizeof(int);
+  if (count > 0 && pkt->len <= kMaxPacketLength) {
+    *pids = reinterpret_cast<int*>(calloc(1, pkt->len));
+    if (*pids == nullptr) {
+      _E("Out of memory");
+      THROW(AUL_R_ENOMEM);
+    }
+
+    memcpy(*pids, pkt->data, pkt->len);
+    *cnt = count;
+  }
+}
+
+}  // namespace
+
+extern "C" API int aul_app_group_get_window(int pid) {
+  if (pid < 1) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  return AppRequest(APP_GROUP_GET_WINDOW, getuid())
+      .SetPid(pid)
+      .SendSimply();
+}
+
+extern "C" API int aul_app_group_set_window(int wid) {
+  if (wid < 1) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  tizen_base::Bundle b { { AUL_K_WID, std::to_string(wid) } };
+  return AppRequest(APP_GROUP_SET_WINDOW, getuid())
+      .With(std::move(b))
+      .SendSimply(AUL_SOCK_NOREPLY);
+}
+
+extern "C" API void aul_app_group_get_leader_pids(int* cnt, int** pids) {
+  if (cnt == nullptr || pids == nullptr) {
+    _E("Invalid parameter");
+    return;
+  }
+
+  *cnt = 0;
+  *pids = nullptr;
+
+  int fd = AppRequest(APP_GROUP_GET_LEADER_PIDS, getuid())
+      .SendCmdOnly(AUL_SOCK_ASYNC);
+  if (fd < 0)
+    return;
+
+  try {
+    ReceivePids(fd, cnt, pids);
+  } catch (const Exception& e) {
+    _E("Exception occurs. error(%s)", e.what());
+  }
+}
+
+extern "C" API void aul_app_group_get_group_pids(int leader_pid, int* cnt,
+    int** pids) {
+  if (leader_pid < 1 || cnt == nullptr || pids == nullptr) {
+    _E("Invalid parameter");
+    return;
+  }
+
+  *cnt = 0;
+  *pids = nullptr;
+
+  tizen_base::Bundle b { { AUL_K_LEADER_PID, std::to_string(leader_pid) } };
+  int fd = AppRequest(APP_GROUP_GET_GROUP_PIDS, getuid())
+      .With(std::move(b))
+      .SendSimply(AUL_SOCK_ASYNC);
+  if (fd < 0)
+    return;
+
+  try {
+    ReceivePids(fd, cnt, pids);
+  } catch (const Exception& e) {
+    _E("Exception occurs. error(%s)", e.what());
+  }
+}
+
+extern "C" API int aul_app_group_get_leader_pid(int pid) {
+  if (pid < 1) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  return AppRequest(APP_GROUP_GET_LEADER_PID, getuid())
+      .SetPid(pid)
+      .SendSimply();
+}
+
+extern "C" API int aul_app_group_clear_top(void) {
+  return AppRequest(APP_GROUP_CLEAR_TOP, getuid())
+      .SendCmdOnly();
+}
+
+extern "C" API int aul_app_group_is_top(void) {
+  int leader_pid = aul_app_group_get_leader_pid(getpid());
+  if (leader_pid < 1)
+    return 1;
+
+  int cnt = 0;
+  int* pids = nullptr;
+  aul_app_group_get_group_pids(leader_pid, &cnt, &pids);
+  auto pids_auto = std::unique_ptr<int, decltype(std::free)*>(pids, std::free);
+  if (cnt > 0 && pids != nullptr) {
+    if (pids[cnt - 1] == getpid())
+      return 1;
+
+    return 0;
+  }
+
+  return 1;
+}
+
+extern "C" API int aul_app_group_get_fg_flag(int pid) {
+  if (pid < 1) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  return AppRequest(APP_GROUP_GET_FG, getuid())
+      .SetPid(pid)
+      .SendSimply();
+}
+
+extern "C" API void aul_app_group_lower(int* exit) {
+  if (exit == nullptr) {
+    _E("Invalid parameter");
+    return;
+  }
+
+  int ret = AppRequest(APP_GROUP_LOWER, getuid())
+      .SendCmdOnly();
+  if (ret < 0)
+    return;
+
+  *exit = ret;
+}
+
+extern "C" API void aul_app_group_get_idle_pids(int* cnt, int** pids) {
+  if (cnt == nullptr || pids == nullptr) {
+    _E("Invalid parameter");
+    return;
+  }
+
+  *cnt = 0;
+  *pids = nullptr;
+  int fd = AppRequest(APP_GROUP_GET_IDLE_PIDS, getuid())
+      .SendCmdOnly(AUL_SOCK_ASYNC);
+  if (fd < 0)
+    return;
+
+  try {
+    ReceivePids(fd, cnt, pids);
+  } catch (const Exception& e) {
+    _E("Exception occurs. error(%s)", e.what());
+  }
+}
+
+extern "C" API int aul_app_group_activate_below(const char* below_appid) {
+  if (below_appid == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  return AppRequest(APP_GROUP_ACTIVATE_BELOW, getuid())
+      .SetAppId(below_appid)
+      .SendSimply();
+}
+
+extern "C" API int aul_app_group_activate_above(const char* above_appid) {
+  if (above_appid == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  return AppRequest(APP_GROUP_ACTIVATE_ABOVE, getuid())
+      .SetAppId(above_appid)
+      .SendSimply();
+}
+
+extern "C" API int aul_app_group_set_window_v2(const char* inst_id, int wid) {
+  if (inst_id == nullptr || wid < 1) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  tizen_base::Bundle b {
+    { AUL_K_INSTANCE_ID, inst_id },
+    { AUL_K_WID, std::to_string(wid) }
+  };
+
+  return AppRequest(APP_GROUP_SET_WINDOW_V2, getuid())
+      .With(std::move(b))
+      .SendSimply(AUL_SOCK_NOREPLY);
+}
+
+extern "C" API int aul_app_group_lower_v2(const char* inst_id, bool* exit) {
+  if (inst_id == nullptr || exit == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  int ret = AppRequest(APP_GROUP_LOWER_V2, getuid())
+      .SetInstId(inst_id)
+      .SendSimply();
+  if (ret < 0)
+    return ret;
+
+  *exit = (ret == 0) ? false : true;
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_app_group_foreach_leader_ids(
+    aul_app_group_leader_id_cb callback, void* user_data) {
+  if (callback == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  int fd = AppRequest(APP_GROUP_GET_LEADER_IDS, getuid())
+      .SendCmdOnly(AUL_SOCK_ASYNC);
+  if (fd < 0)
+    return aul_error_convert(fd);
+
+  try {
+    for (auto const& id : ReceiveLeaderIds(fd))
+      callback(id.c_str(), user_data);
+  } catch (const Exception& e) {
+    _E("Exception occurs. error(%s)", e.what());
+    return e.GetErrorCode();
+  }
+
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_app_group_foreach_group_info(const char* leader_id,
+    aul_app_group_info_cb callback, void* user_data) {
+  if (leader_id == nullptr || callback == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  tizen_base::Bundle b { { AUL_K_LEADER_ID, leader_id } };
+  int fd = AppRequest(APP_GROUP_GET_GROUP_INFO, getuid())
+      .With(std::move(b))
+      .SendSimply(AUL_SOCK_ASYNC);
+  if (fd < 0)
+    return aul_error_convert(fd);
+
+  try {
+    for (auto const& info : ReceiveAppGroupInfos(fd))
+      callback(reinterpret_cast<aul_app_group_info_h>(info.get()), user_data);
+  } catch (const Exception& e) {
+    _E("Exception occurs. error(%s)", e.what());
+  }
+
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_app_group_foreach_idle_info(
+    aul_app_group_info_cb callback, void* user_data) {
+  if (callback == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  int fd = AppRequest(APP_GROUP_GET_IDLE_INFO, getuid())
+      .SendCmdOnly(AUL_SOCK_ASYNC);
+  if (fd < 0)
+    return aul_error_convert(fd);
+
+  try {
+    for (auto const& info : ReceiveAppGroupInfos(fd))
+      callback(reinterpret_cast<aul_app_group_info_h>(info.get()), user_data);
+  } catch (const Exception& e) {
+    _E("Exception occurs. error(%s)", e.what());
+  }
+
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_app_group_info_get_id(aul_app_group_info_h h,
+    const char** id) {
+  if (h == nullptr || id == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* info = reinterpret_cast<AppGroupInfo*>(h);
+  *id = info->GetId().c_str();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_app_group_info_get_pid(aul_app_group_info_h h,
+    pid_t* pid) {
+  if (h == nullptr || pid == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* info = reinterpret_cast<AppGroupInfo*>(h);
+  *pid = info->GetPid();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_app_group_info_get_appid(aul_app_group_info_h h,
+    const char** appid) {
+  if (h == nullptr || appid == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* info = reinterpret_cast<AppGroupInfo*>(h);
+  *appid = info->GetAppId().c_str();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_app_group_info_get_pkgid(aul_app_group_info_h h,
+    const char** pkgid) {
+  if (h == nullptr || pkgid == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* info = reinterpret_cast<AppGroupInfo*>(h);
+  *pkgid = info->GetPkgId().c_str();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_app_group_info_get_window(aul_app_group_info_h h,
+    int* wid) {
+  if (h == nullptr || wid == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* info = reinterpret_cast<AppGroupInfo*>(h);
+  *wid = info->GetWid();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_app_group_info_get_fg_flag(aul_app_group_info_h h,
+    bool* fg_flag) {
+  if (h == nullptr || fg_flag == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* info = reinterpret_cast<AppGroupInfo*>(h);
+  *fg_flag = info->IsFg();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_app_group_info_get_status(aul_app_group_info_h h,
+    int* status) {
+  if (h == nullptr || status == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* info = reinterpret_cast<AppGroupInfo*>(h);
+  *status = info->GetStatus();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_app_group_add(int wid) {
+  if (wid < 1) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  tizen_base::Bundle b { { AUL_K_WID, std::to_string(wid) } };
+  return AppRequest(APP_GROUP_ADD, getuid())
+      .With(std::move(b))
+      .SendSimply(AUL_SOCK_NOREPLY);
+}
+
+extern "C" API int aul_app_group_remove(int wid) {
+  if (wid < 1) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  tizen_base::Bundle b { { AUL_K_WID, std::to_string(wid) } };
+  return AppRequest(APP_GROUP_REMOVE, getuid())
+      .With(std::move(b))
+      .SendSimply(AUL_SOCK_NOREPLY);
+}