summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHwankyu Jhun <h.jhun@samsung.com>2021-07-19 09:39:29 +0900
committerHwankyu Jhun <h.jhun@samsung.com>2021-07-19 11:26:33 +0900
commit6d97b238590c03cc3c0f00a668198f6d89d0a30d (patch)
tree2a5c050edcef5bbd35cb5d2b96fbd00dfb84b7cc
parent018544b502ea7e23a2307f49f96aebc87328740b (diff)
downloadaul-1-6d97b238590c03cc3c0f00a668198f6d89d0a30d.tar.gz
aul-1-6d97b238590c03cc3c0f00a668198f6d89d0a30d.tar.bz2
aul-1-6d97b238590c03cc3c0f00a668198f6d89d0a30d.zip
Refactor aul window
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>
-rw-r--r--include/aul_window.h6
-rw-r--r--packaging/aul.spec1
-rw-r--r--src/aul_window.c404
-rw-r--r--src/aul_window.cc479
-rw-r--r--tool/CMakeLists.txt1
-rw-r--r--tool/aul_window/CMakeLists.txt18
-rw-r--r--tool/aul_window/aul_window.cc163
7 files changed, 665 insertions, 407 deletions
diff --git a/include/aul_window.h b/include/aul_window.h
index 21f0cb96..561e0055 100644
--- a/include/aul_window.h
+++ b/include/aul_window.h
@@ -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.
diff --git a/packaging/aul.spec b/packaging/aul.spec
index 1ce99ea6..807dfe1f 100644
--- a/packaging/aul.spec
+++ b/packaging/aul.spec
@@ -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
index 8c9dfa4b..00000000
--- a/src/aul_window.c
+++ /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
index 00000000..ec5c2249
--- /dev/null
+++ b/src/aul_window.cc
@@ -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;
+}
diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt
index e8274385..acef059d 100644
--- a/tool/CMakeLists.txt
+++ b/tool/CMakeLists.txt
@@ -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
index 00000000..1e20ed20
--- /dev/null
+++ b/tool/aul_window/CMakeLists.txt
@@ -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
index 00000000..38fea00c
--- /dev/null
+++ b/tool/aul_window/aul_window.cc
@@ -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);
+}