Refactor aul window 27/261427/4
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 19 Jul 2021 00:39:29 +0000 (09:39 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Mon, 19 Jul 2021 02:26:33 +0000 (11:26 +0900)
It's implmented using C++ language. The aul_window tool is added for
testing functions.

Change-Id: Iadf8c7c9fdecc5162c6ccd69d31a87b5cf0424c9
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
include/aul_window.h
packaging/aul.spec
src/aul_window.c [deleted file]
src/aul_window.cc [new file with mode: 0644]
tool/CMakeLists.txt
tool/aul_window/CMakeLists.txt [new file with mode: 0644]
tool/aul_window/aul_window.cc [new file with mode: 0644]

index 21f0cb9..561e005 100644 (file)
@@ -1,14 +1,14 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd All Rights Reserved
  *
- * Licensed under the Apache License, Version 2.0 (the License);
+ * 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,
+ * 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.
index 1ce99ea..807dfe1 100644 (file)
@@ -218,6 +218,7 @@ chmod +x %{_aulresdir}/tpk/install.sh
 %{_bindir}/compmgr_tool
 %{_bindir}/appsvc-db-recovery
 %{_bindir}/component-db-recovery
+%{_bindir}/aul_window
 %{_datadir}/aul/miregex/*
 %{_datadir}/aul/preexec_list.txt
 %{_datadir}/appsvc/*
diff --git a/src/aul_window.c b/src/aul_window.c
deleted file mode 100644 (file)
index 8c9dfa4..0000000
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Copyright (c) 2017 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 <stdio.h>
-#include <stdbool.h>
-#include <gio/gio.h>
-#include <glib.h>
-#include <malloc.h>
-
-#include "aul.h"
-#include "launch.h"
-#include "aul_api.h"
-#include "aul_util.h"
-#include "aul_window.h"
-#include "aul_cmd.h"
-
-static GDBusConnection *system_conn;
-
-#define WM_BUS_NAME    "org.enlightenment.wm"
-#define WM_OBJECT_PATH "/org/enlightenment/wm"
-#define WM_INTERFACE_NAME      "org.enlightenment.wm.proc"
-#define WM_METHOD_NAME_INFO    "GetVisibleWinInfo"
-#define WM_METHOD_NAME_FOCUS   "GetFocusProc"
-#define WM_DBUS_TIMEOUT 5000
-
-typedef struct _window_info {
-       unsigned int gid;
-       int x;
-       int y;
-       int w;
-       int h;
-       gboolean alpha;
-       int visibility;
-       gboolean focused;
-       int pid;
-       int ppid;
-       int apid;
-       int noti_level;
-       gboolean opaque;
-} window_info;
-
-API int aul_window_stack_get(aul_window_stack_h *handle)
-{
-       GError *err = NULL;
-       GDBusMessage *msg;
-       GDBusMessage *reply;
-       GDBusConnection *conn;
-       int res = 0;
-       window_info *wi;
-       GVariant *body;
-       GVariantIter *iter = NULL;
-       GList *list = NULL;
-
-       if (system_conn == NULL) {
-               conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
-               if (conn == NULL) {
-                       _E("g_bus_get_sync() is failed. %s", err->message);
-                       g_error_free(err);
-                       return -1;
-               }
-               system_conn = conn;
-       }
-
-       msg = g_dbus_message_new_method_call(WM_BUS_NAME,
-                                               WM_OBJECT_PATH,
-                                               WM_INTERFACE_NAME,
-                                               WM_METHOD_NAME_INFO);
-       if (msg == NULL) {
-               _E("g_dbus_message_new_method_call() is failed.");
-               return -1;
-       }
-
-       reply = g_dbus_connection_send_message_with_reply_sync(system_conn, msg,
-                       G_DBUS_SEND_MESSAGE_FLAGS_NONE, WM_DBUS_TIMEOUT,
-                       NULL, NULL, &err);
-
-       if (!reply) {
-               if (err != NULL) {
-                       _E("Failed to get info [%s]", err->message);
-                       g_error_free(err);
-               }
-               res = -1;
-               goto out;
-       }
-
-       body = g_dbus_message_get_body(reply);
-       if (!body) {
-               res = -1;
-               goto out;
-       }
-
-       wi = malloc(sizeof(window_info));
-       if (wi == NULL) {
-               _E("Out of memory");
-               res = -1;
-               goto out;
-       }
-
-       g_variant_get(body, "(a(uiiiibibiiiib))", &iter);
-       while (iter && g_variant_iter_loop(iter, "(uiiiibibiiiib)",
-                       &wi->gid,
-                       &wi->x,
-                       &wi->y,
-                       &wi->w,
-                       &wi->h,
-                       &wi->alpha,
-                       &wi->visibility,
-                       &wi->focused,
-                       &wi->pid,
-                       &wi->ppid,
-                       &wi->apid,
-                       &wi->noti_level,
-                       &wi->opaque)) {
-               list = g_list_append(list, wi);
-               wi = malloc(sizeof(window_info));
-       }
-
-       free(wi);
-       if (iter)
-               g_variant_iter_free(iter);
-       *handle = list;
-out:
-       if (msg)
-               g_object_unref(msg);
-       if (reply)
-               g_object_unref(reply);
-
-       return res;
-}
-
-static void __free_info(gpointer data)
-{
-       free(data);
-}
-
-API int aul_window_stack_del(aul_window_stack_h handle)
-{
-       if (!handle)
-               return -1;
-
-       g_list_free_full(handle, __free_info);
-       return 0;
-}
-
-API int aul_window_stack_foreach(aul_window_stack_h handle,
-               void (*iter_cb)(aul_window_info_h info, void *data), void *data)
-{
-       GList *i = (GList*)handle;
-
-       if (!iter_cb || !handle)
-               return -1;
-
-       while (i) {
-               iter_cb(i->data, data);
-               i = g_list_next(i);
-       }
-
-       return 0;
-}
-
-API int aul_window_stack_info_get_resource_id(aul_window_info_h info, unsigned int *rid)
-{
-       window_info *wi = info;
-
-       if (!info || !rid)
-               return -1;
-
-       *rid = wi->gid;
-       return 0;
-}
-
-API int aul_window_info_get_pid(aul_window_info_h info, int *pid)
-{
-       window_info *wi = info;
-
-       if (!info || !pid)
-               return -1;
-
-       *pid = wi->pid;
-       return 0;
-}
-
-API int aul_window_info_get_parent_pid(aul_window_info_h info, int *ppid)
-{
-       window_info *wi = info;
-
-       if (!info || !ppid)
-               return -1;
-
-       *ppid = wi->ppid;
-       return 0;
-}
-
-API int aul_window_info_get_ancestor_pid(aul_window_info_h info, int *apid)
-{
-       window_info *wi = info;
-
-       if (!info || !apid)
-               return -1;
-
-       *apid = wi->apid;
-       return 0;
-}
-
-API int aul_window_info_get_visibility(aul_window_info_h info, int *visibility)
-{
-       window_info *wi = info;
-
-       if (!info || !visibility)
-               return -1;
-
-       *visibility = wi->visibility;
-       return 0;
-}
-
-API int aul_window_info_has_alpha(aul_window_info_h info, bool *alpha)
-{
-       window_info *wi = info;
-
-       if (!info || !alpha)
-               return -1;
-
-       *alpha = (bool)(wi->alpha);
-       return 0;
-}
-
-API int aul_window_info_is_focused(aul_window_info_h info, bool *focused)
-{
-       window_info *wi = info;
-
-       if (!info || !focused)
-               return -1;
-
-       *focused = (bool)(wi->focused);
-       return 0;
-}
-
-API int aul_window_info_get_geometry(aul_window_info_h info, int *x, int *y, int *w, int *h)
-{
-       window_info *wi = info;
-
-       if (!info || !x || !y || !w || !h)
-               return -1;
-
-       *x = wi->x;
-       *y = wi->y;
-       *w = wi->w;
-       *h = wi->h;
-       return 0;
-}
-
-API int aul_window_info_get_notification_level(aul_window_info_h info,
-               aul_window_notification_level_e *level)
-{
-       window_info *wi = info;
-
-       if (!info || !level)
-               return -1;
-
-       *level = (aul_window_notification_level_e)wi->noti_level;
-
-       return 0;
-}
-
-API int aul_window_get_focused_pid(pid_t *pid)
-{
-       GError *err = NULL;
-       GDBusMessage *msg;
-       GDBusMessage *reply;
-       GDBusConnection *conn;
-       int res = 0;
-       GVariant *body;
-       gint32 focused_pid = 0;
-
-       if (!pid) {
-               _E("aul_window_get_focused_pid: argument 'pid' cannot be NULL.");
-               return -1;
-       }
-
-       _W("call aul_window_get_focused_pid()");
-       if (system_conn == NULL) {
-               conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
-               if (conn == NULL) {
-                       _E("g_bus_get_sync() is failed. %s", err->message);
-                       g_error_free(err);
-                       return -1;
-               }
-               system_conn = conn;
-       }
-
-       msg = g_dbus_message_new_method_call(WM_BUS_NAME,
-                                               WM_OBJECT_PATH,
-                                               WM_INTERFACE_NAME,
-                                               WM_METHOD_NAME_FOCUS);
-       if (msg == NULL) {
-               _E("g_dbus_message_new_method_call() is failed.");
-               return -1;
-       }
-
-       reply = g_dbus_connection_send_message_with_reply_sync(system_conn, msg,
-                       G_DBUS_SEND_MESSAGE_FLAGS_NONE, WM_DBUS_TIMEOUT,
-                       NULL, NULL, &err);
-
-       if (!reply) {
-               _E("reply is null");
-               if (err != NULL) {
-                       _E("Failed to get info [%s]", err->message);
-                       g_error_free(err);
-               }
-               res = -1;
-               goto out;
-       }
-
-       body = g_dbus_message_get_body(reply);
-       if (!body) {
-               res = -1;
-               _E("Body is null");
-               goto out;
-       }
-
-       g_variant_get(body, "(i)", &focused_pid);
-       *pid = (pid_t)focused_pid;
-       _W("result = %d", focused_pid);
-out:
-       if (msg)
-               g_object_unref(msg);
-       if (reply)
-               g_object_unref(reply);
-
-       return res;
-}
-
-API int aul_window_attach(const char *parent_appid, const char *child_appid)
-{
-       bundle *b;
-       int ret;
-
-       if (parent_appid == NULL || child_appid == NULL)
-               return AUL_R_EINVAL;
-
-       b = bundle_create();
-       if (!b) {
-               _E("out of memory");
-               return AUL_R_ENOMEM;
-       }
-
-       bundle_add_str(b, AUL_K_PARENT_APPID, parent_appid);
-       bundle_add_str(b, AUL_K_CHILD_APPID, child_appid);
-
-       ret = app_send_cmd(AUL_UTIL_PID, APP_WINDOW_ATTACH, b);
-       bundle_free(b);
-
-       return ret;
-}
-
-API int aul_window_detach(const char *child_appid)
-{
-       bundle *b;
-       int ret;
-
-       if (child_appid == NULL)
-               return AUL_R_EINVAL;
-
-       b = bundle_create();
-       if (!b) {
-               _E("out of memory");
-               return AUL_R_ENOMEM;
-       }
-
-       bundle_add_str(b, AUL_K_CHILD_APPID, child_appid);
-
-       ret = app_send_cmd(AUL_UTIL_PID, APP_WINDOW_DETACH, b);
-       bundle_free(b);
-
-       return ret;
-}
-
-API int aul_window_info_get_opaque(aul_window_info_h info, bool *opaque)
-{
-       window_info *wi = info;
-
-       if (!info || !opaque) {
-               _E("Invalid parameter");
-               return -1;
-       }
-
-       *opaque = (bool)wi->opaque;
-       return 0;
-}
diff --git a/src/aul_window.cc b/src/aul_window.cc
new file mode 100644 (file)
index 0000000..ec5c224
--- /dev/null
@@ -0,0 +1,479 @@
+/*
+ * Copyright (c) 2017 - 2021 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 <gio/gio.h>
+#include <glib.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <bundle_cpp.h>
+
+#include <memory>
+#include <string>
+
+#include "app_request.h"
+#include "aul_api.h"
+#include "aul_util.h"
+#include "include/aul.h"
+#include "include/aul_cmd.h"
+#include "include/aul_window.h"
+#include "launch.h"
+
+using namespace aul;
+using namespace aul::internal;
+
+namespace {
+
+constexpr const char kWmBusName[] = "org.enlightenment.wm";
+constexpr const char kWmObjectPath[] = "/org/enlightenment/wm";
+constexpr const char kWmInterfaceName[] = "org.enlightenment.wm.proc";
+constexpr const char kWmMethodNameInfo[] = "GetVisibleWinInfo";
+constexpr const char kWmMethodNameFocus[] = "GetFocusProc";
+constexpr const unsigned int kWmDbusTimeout = 5000;
+
+GDBusConnection* system_conn;
+
+GDBusConnection* GetConn() {
+  if (system_conn == nullptr) {
+    GError* error = nullptr;
+    system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
+    if (system_conn == nullptr) {
+      _E("g_bus_get_sync() is failed. error(%s)",
+          error ? error->message : "Unknown");
+      g_clear_error(&error);
+      return nullptr;
+    }
+  }
+
+  return system_conn;
+}
+
+class WindowInfo {
+ public:
+  WindowInfo(unsigned int rid, int x, int y, int w, int h,
+      bool alpha, int visibility, bool focused, int pid, int ppid,
+      int apid, int noti_level, bool opaque)
+      : rid_(rid), x_(x), y_(y), w_(w), h_(h), alpha_(alpha),
+        visibility_(visibility), focused_(focused), pid_(pid),
+        ppid_(ppid), apid_(apid), noti_level_(noti_level), opaque_(opaque) {
+  }
+
+  unsigned int GetResourceId() const {
+    return rid_;
+  }
+
+  int GetPositionX() const {
+    return x_;
+  }
+
+  int GetPositionY() const {
+    return y_;
+  }
+
+  int GetWidth() const {
+    return w_;
+  }
+
+  int GetHeight() const {
+    return h_;
+  }
+
+  bool HasAlpha() const {
+    return alpha_;
+  }
+
+  int GetVisibility() const {
+    return visibility_;
+  }
+
+  bool IsFocused() const {
+    return focused_;
+  }
+
+  int GetPid() const {
+    return pid_;
+  }
+
+  int GetParentPid() const {
+    return ppid_;
+  }
+
+  int GetAncestorPid() const {
+    return apid_;
+  }
+
+  int GetNotificationLevel() const {
+    return noti_level_;
+  }
+
+  bool IsOpaque() const {
+    return opaque_;
+  }
+
+ private:
+  unsigned int rid_;
+  int x_;
+  int y_;
+  int w_;
+  int h_;
+  bool alpha_;
+  int visibility_;
+  bool focused_;
+  int pid_;
+  int ppid_;
+  int apid_;
+  int noti_level_;
+  bool opaque_;
+};
+
+void WindowInfoDestroyFunc(gpointer data) {
+  auto* info = static_cast<WindowInfo*>(data);
+  if (info == nullptr)
+    return;
+
+  delete info;
+}
+
+}  // namespace
+
+extern "C" API int aul_window_stack_get(aul_window_stack_h* handle) {
+  if (handle == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  GDBusConnection* conn = GetConn();
+  if (conn == nullptr)
+    return AUL_R_ERROR;
+
+  auto* msg = g_dbus_message_new_method_call(kWmBusName,
+      kWmObjectPath, kWmInterfaceName, kWmMethodNameInfo);
+  if (msg == nullptr) {
+    _E("g_dbus_message_new_method_call() is faield");
+    return AUL_R_ERROR;
+  }
+  std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> msg_auto(
+      msg, g_object_unref);
+
+  GError* error = nullptr;
+  auto* reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
+      G_DBUS_SEND_MESSAGE_FLAGS_NONE, kWmDbusTimeout, nullptr, nullptr, &error);
+  if (reply == nullptr || error != nullptr) {
+    _E("g_dbus_connection_send_message_with_reply_sync() is failed. error(%s)",
+        error ? error->message : "Unknown");
+    g_clear_error(&error);
+    return AUL_R_ERROR;
+  }
+  std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> reply_auto(
+      reply, g_object_unref);
+
+  auto* body = g_dbus_message_get_body(reply);
+  if (body == nullptr) {
+    _E("g_dbus_message_get_body() is failed");
+    return AUL_R_ERROR;
+  }
+
+  unsigned int rid = 0;
+  int x = -1;
+  int y = -1;
+  int w = -1;
+  int h = -1;
+  gboolean alpha = FALSE;
+  int visibility = -1;
+  gboolean focused = FALSE;
+  int pid = -1;
+  int ppid = -1;
+  int apid = -1;
+  int noti_level = -1;
+  gboolean opaque = FALSE;
+
+  GVariantIter* iter = nullptr;
+  g_variant_get(body, "(a(uiiiibibiiiib))", &iter);
+  if (iter == nullptr)
+    return AUL_R_ERROR;
+
+  std::unique_ptr<GVariantIter, decltype(g_variant_iter_free)*> iter_auto(
+      iter, g_variant_iter_free);
+
+  GList* list = nullptr;
+  while (g_variant_iter_loop(iter, "(uiiiibibiiiib)",
+        &rid,
+        &x,
+        &y,
+        &w,
+        &h,
+        &alpha,
+        &visibility,
+        &focused,
+        &pid,
+        &ppid,
+        &apid,
+        &noti_level,
+        &opaque)) {
+    auto* info = new (std::nothrow) WindowInfo(rid, x, y, w, h,
+        alpha ? true : false, visibility, focused ? true : false,
+        pid, ppid, apid, noti_level, opaque ? true : false);
+    if (info == nullptr) {
+      _E("Out of memory");
+      g_list_free_full(list, WindowInfoDestroyFunc);
+      return AUL_R_ENOMEM;
+    }
+
+    list = g_list_append(list, info);
+  }
+
+  *handle = static_cast<aul_window_stack_h>(list);
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_stack_del(aul_window_stack_h handle) {
+  if (handle == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* list = static_cast<GList*>(handle);
+  g_list_free_full(list, WindowInfoDestroyFunc);
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_stack_foreach(aul_window_stack_h handle,
+    void (*iter_cb)(aul_window_info_h info, void* data), void* data) {
+  if (handle == nullptr || iter_cb == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* iter = static_cast<GList*>(handle);
+  while (iter) {
+    iter_cb(static_cast<aul_window_info_h>(iter->data), data);
+    iter = g_list_next(iter);
+  }
+
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_stack_info_get_resource_id(aul_window_info_h info,
+    unsigned int* rid) {
+  if (info == nullptr || rid == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* handle = static_cast<WindowInfo*>(info);
+  *rid = handle->GetResourceId();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_info_get_pid(aul_window_info_h info, int* pid) {
+  if (info == nullptr || pid == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* handle = static_cast<WindowInfo*>(info);
+  *pid = handle->GetPid();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_info_get_parent_pid(aul_window_info_h info,
+    int* ppid) {
+  if (info == nullptr || ppid == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* handle = static_cast<WindowInfo*>(info);
+  *ppid = handle->GetParentPid();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_info_get_ancestor_pid(aul_window_info_h info,
+    int* apid) {
+  if (info == nullptr || apid == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* handle = static_cast<WindowInfo*>(info);
+  *apid = handle->GetAncestorPid();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_info_get_visibility(aul_window_info_h info,
+    int* visibility) {
+  if (info == nullptr || visibility == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* handle = static_cast<WindowInfo*>(info);
+  *visibility = handle->GetVisibility();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_info_has_alpha(aul_window_info_h info,
+    bool* alpha) {
+  if (info == nullptr || alpha == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* handle = static_cast<WindowInfo*>(info);
+  *alpha = handle->HasAlpha();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_info_is_focused(aul_window_info_h info,
+    bool* focused) {
+  if (info == nullptr || focused == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* handle = static_cast<WindowInfo*>(info);
+  *focused = handle->IsFocused();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_info_get_geometry(aul_window_info_h info,
+    int* x, int* y, int* w, int* h) {
+  if (info == nullptr ||
+      x == nullptr ||
+      y == nullptr ||
+      w == nullptr ||
+      h == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* handle = static_cast<WindowInfo*>(info);
+  *x = handle->GetPositionX();
+  *y = handle->GetPositionY();
+  *w = handle->GetWidth();
+  *h = handle->GetHeight();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_info_get_notification_level(
+    aul_window_info_h info, aul_window_notification_level_e* level) {
+  if (info == nullptr || level == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* handle = static_cast<WindowInfo*>(info);
+  *level = static_cast<aul_window_notification_level_e>(
+      handle->GetNotificationLevel());
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_info_get_opaque(aul_window_info_h info,
+    bool* opaque) {
+  if (info == nullptr || opaque == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  auto* handle = static_cast<WindowInfo*>(info);
+  *opaque = handle->IsOpaque();
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_get_focused_pid(pid_t* pid) {
+  if (pid == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  GDBusConnection* conn = GetConn();
+  if (conn == nullptr)
+    return AUL_R_ERROR;
+
+  auto* msg = g_dbus_message_new_method_call(kWmBusName,
+      kWmObjectPath, kWmInterfaceName, kWmMethodNameFocus);
+  if (msg == nullptr) {
+    _E("g_dbus_message_new_method_call() is failed");
+    return AUL_R_ERROR;
+  }
+  std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> msg_auto(
+      msg, g_object_unref);
+
+  GError* error = nullptr;
+  auto* reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
+      G_DBUS_SEND_MESSAGE_FLAGS_NONE, kWmDbusTimeout, nullptr, nullptr,
+      &error);
+  if (reply == nullptr || error != nullptr) {
+    _E("g_dbus_connection_send_message_with_reply_sync() is failed. error(%s)",
+        error ? error->message : "Unknown");
+    g_clear_error(&error);
+    return AUL_R_ERROR;
+  }
+  std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> reply_auto(
+      reply, g_object_unref);
+
+  auto* body = g_dbus_message_get_body(reply);
+  if (body == nullptr) {
+    _E("g_dbus_message_get_body() is failed");
+    return AUL_R_ERROR;
+  }
+
+  gint focused_pid = -1;
+  g_variant_get(body, "(i)", &focused_pid);
+  *pid = static_cast<pid_t>(focused_pid);
+  _W("Result = %d", focused_pid);
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_attach(const char* parent_appid,
+    const char* child_appid) {
+  if (parent_appid == nullptr || child_appid == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  tizen_base::Bundle b {
+    { AUL_K_PARENT_APPID, parent_appid },
+    { AUL_K_CHILD_APPID, child_appid }
+  };
+  int ret = AppRequest(APP_WINDOW_ATTACH, getuid())
+      .With(b)
+      .SendSimply();
+  if (ret < 0) {
+    _E("Failed to send request. error(%d)", ret);
+    return ret;
+  }
+
+  return AUL_R_OK;
+}
+
+extern "C" API int aul_window_detach(const char* child_appid) {
+  if (child_appid == nullptr) {
+    _E("Invalid parameter");
+    return AUL_R_EINVAL;
+  }
+
+  tizen_base::Bundle b {{ AUL_K_CHILD_APPID, child_appid }};
+  int ret = AppRequest(APP_WINDOW_DETACH, getuid())
+      .With(b)
+      .SendSimply();
+  if (ret < 0) {
+    _E("Failed to send request. error(%d)", ret);
+    return ret;
+  }
+
+  return AUL_R_OK;
+}
index e827438..acef059 100644 (file)
@@ -3,6 +3,7 @@ ADD_SUBDIRECTORY(app_launcher)
 ADD_SUBDIRECTORY(appgroup_info)
 ADD_SUBDIRECTORY(appid2pid)
 ADD_SUBDIRECTORY(aul_test)
+ADD_SUBDIRECTORY(aul_window)
 ADD_SUBDIRECTORY(compmgr_tool)
 ADD_SUBDIRECTORY(launch_app)
 ADD_SUBDIRECTORY(launch_debug)
diff --git a/tool/aul_window/CMakeLists.txt b/tool/aul_window/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1e20ed2
--- /dev/null
@@ -0,0 +1,18 @@
+SET(TARGET_AUL_WINDOW "aul_window")
+
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} AUL_WINDOW_SRCS)
+
+ADD_EXECUTABLE(${TARGET_AUL_WINDOW} ${AUL_WINDOW_SRCS})
+SET_TARGET_PROPERTIES(${TARGET_AUL_WINDOW} PROPERTIES
+  COMPILE_FLAGS ${CFLAGS} "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_AUL_WINDOW} PROPERTIES
+  LINK_FLAGS "-pie")
+TARGET_LINK_LIBRARIES(${TARGET_AUL_WINDOW} PRIVATE
+  ${TARGET_AUL})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_AUL_WINDOW} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../src
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../include)
+
+INSTALL(TARGETS ${TARGET_AUL_WINDOW} DESTINATION bin)
diff --git a/tool/aul_window/aul_window.cc b/tool/aul_window/aul_window.cc
new file mode 100644 (file)
index 0000000..38fea00
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2021 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.h>
+#include <aul_window.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <map>
+#include <string>
+
+namespace {
+
+using HandleFunc = int (*)(int argc, char** argv);
+
+void PrintUsage(const char* cmdline) {
+  printf("%s <command> ...\n", cmdline);
+  printf(" - command list\n");
+  printf("   foreach_window_stack\n");
+  printf("   get_focused_pid\n");
+  printf("   attach_window <parent_appid> <child_appid>\n");
+  printf("   detach_window <child_appid>\n");
+}
+
+const char* GetNotificationLevelString(aul_window_notification_level_e level) {
+  switch (level) {
+  case AUL_WINDOW_NOTIFICATION_LEVEL_DEFAULT:
+    return "AUL_WINDOW_NOTIFICATION_LEVEL_DEFAULT";
+  case AUL_WINDOW_NOTIFICATION_LEVEL_MEDIUM:
+    return "AUL_WINDOW_NOTIFICATION_LEVEL_MEDIUM";
+  case AUL_WINDOW_NOTIFICATION_LEVEL_HIGH:
+    return "AUL_WINDOW_NOTIFICATION_LEVEL_HIGH";
+  case AUL_WINDOW_NOTIFICATION_LEVEL_TOP:
+    return "AUL_WINDOW_NOTIFICATION_LEVEL_TOP";
+  case AUL_WINDOW_NOTIFICATION_LEVEL_PRIVILEGE:
+    return "AUL_WINDOW_NOTIFICATION_LEVEL_PRIVILEGE";
+  default:
+    return "AUL_WINDOW_NOTIFICATION_LEVEL_NONE";
+  }
+}
+
+void WindowStackIterCb(aul_window_info_h info, void* data) {
+  unsigned int rid = 0;
+  aul_window_stack_info_get_resource_id(info, &rid);
+  int pid = -1;
+  aul_window_info_get_pid(info, &pid);
+  int ppid = -1;
+  aul_window_info_get_parent_pid(info, &ppid);
+  int apid = -1;
+  aul_window_info_get_ancestor_pid(info, &apid);
+  int visibility = -1;
+  aul_window_info_get_visibility(info, &visibility);
+  bool has_alpha = false;
+  aul_window_info_has_alpha(info, &has_alpha);
+  bool is_focused = false;
+  aul_window_info_is_focused(info, &is_focused);
+  aul_window_notification_level_e level = AUL_WINDOW_NOTIFICATION_LEVEL_NONE;
+  aul_window_info_get_notification_level(info, &level);
+  int x = -1;
+  int y = -1;
+  int w = -1;
+  int h = -1;
+  aul_window_info_get_geometry(info, &x, &y, &w, &h);
+  bool opaque = false;
+  aul_window_info_get_opaque(info, &opaque);
+
+  printf("-----------------------------------------------------------------\n");
+  printf(" - Resource ID: %d\n", rid);
+  printf(" - Process ID: %d\n", pid);
+  printf(" - Parent Process ID: %d\n", ppid);
+  printf(" - Ancestor Process ID: %d\n", apid);
+  printf(" - Visibility: %d\n", visibility);
+  printf(" - Has Alpha: %s\n", has_alpha ? "true" : "false");
+  printf(" - Is Focused: %s\n", is_focused ? "true" : "false");
+  printf(" - Notification Level: %s\n", GetNotificationLevelString(level));
+  printf(" - Opaque: %s\n", opaque ? "true" : "false");
+}
+
+int HandleForeachWindowStack(int argc, char** argv) {
+  printf("[%s]\n", argv[1]);
+  aul_window_stack_h handle = nullptr;
+  int ret = aul_window_stack_get(&handle);
+  if (ret != AUL_R_OK) {
+    fprintf(stderr, "aul_window_stack() is failed. error(%d)\n", ret);
+    return ret;
+  }
+
+  printf("=================================================================\n");
+  ret = aul_window_stack_foreach(handle, WindowStackIterCb, nullptr);
+  printf("=================================================================\n");
+  aul_window_stack_del(handle);
+  printf("[%s] result: %d\n", argv[1], ret);
+  return ret;
+}
+
+int HandleGetFocusedPid(int argc, char** argv) {
+  printf("[%s]\n", argv[1]);
+  pid_t pid = -1;
+  int ret = aul_window_get_focused_pid(&pid);
+  printf("[%s] result: %d\n", argv[1], pid);
+  return ret;
+}
+
+int HandleAttachWindow(int argc, char** argv) {
+  if (argc < 4) {
+    PrintUsage(argv[0]);
+    return -1;
+  }
+
+  printf("[%s] parent_appid(%s), child_appid(%s)\n", argv[1], argv[2], argv[3]);
+  int ret = aul_window_attach(argv[2], argv[3]);
+  printf("[%s] result: %d\n", argv[1], ret);
+  return ret;
+}
+
+int HandleDetachWindow(int argc, char** argv) {
+  if (argc < 3) {
+    PrintUsage(argv[0]);
+    return -1;
+  }
+
+  printf("[%s] child_appid(%s)\n", argv[1], argv[2]);
+  int ret = aul_window_detach(argv[2]);
+  printf("[%s] result: %d\n", argv[1], ret);
+  return ret;
+}
+
+std::map<std::string, HandleFunc> handlers = {
+  { "foreach_window_stack", HandleForeachWindowStack },
+  { "get_focused_pid", HandleGetFocusedPid },
+  { "attach_window", HandleAttachWindow },
+  { "detach_window", HandleDetachWindow },
+};
+
+}  // namespace
+
+int main(int argc, char** argv) {
+  if (argc < 2) {
+    PrintUsage(argv[0]);
+    return -1;
+  }
+
+  auto found = handlers.find(argv[1]);
+  if (found == handlers.end()) {
+    PrintUsage(argv[0]);
+    return -1;
+  }
+
+  return found->second(argc, argv);
+}