2 * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <bundle_cpp.h>
28 #include "app_request.h"
31 #include "include/aul.h"
32 #include "include/aul_app_com.h"
33 #include "include/aul_cmd.h"
34 #include "include/aul_window.h"
38 using namespace aul::internal;
42 constexpr const char kWmBusName[] = "org.enlightenment.wm";
43 constexpr const char kWmObjectPath[] = "/org/enlightenment/wm";
44 constexpr const char kWmInterfaceName[] = "org.enlightenment.wm.proc";
45 constexpr const char kWmMethodNameInfo[] = "GetVisibleWinInfo";
46 constexpr const char kWmMethodNameFocus[] = "GetFocusProc";
47 constexpr const unsigned int kWmDbusTimeout = 5000;
49 GDBusConnection* system_conn;
51 GDBusConnection* GetConn() {
52 if (system_conn == nullptr) {
53 GError* error = nullptr;
54 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
55 if (system_conn == nullptr) {
56 _E("g_bus_get_sync() is failed. error(%s)",
57 error ? error->message : "Unknown");
58 g_clear_error(&error);
68 WindowInfo(unsigned int rid, int x, int y, int w, int h,
69 bool alpha, int visibility, bool focused, int pid, int ppid,
70 int apid, int noti_level, bool opaque)
71 : rid_(rid), x_(x), y_(y), w_(w), h_(h), alpha_(alpha),
72 visibility_(visibility), focused_(focused), pid_(pid),
73 ppid_(ppid), apid_(apid), noti_level_(noti_level), opaque_(opaque) {
76 unsigned int GetResourceId() const {
80 int GetPositionX() const {
84 int GetPositionY() const {
88 int GetWidth() const {
92 int GetHeight() const {
96 bool HasAlpha() const {
100 int GetVisibility() const {
104 bool IsFocused() const {
112 int GetParentPid() const {
116 int GetAncestorPid() const {
120 int GetNotificationLevel() const {
124 bool IsOpaque() const {
144 void WindowInfoDestroyFunc(gpointer data) {
145 auto* info = static_cast<WindowInfo*>(data);
152 class WindowEventListener {
154 WindowEventListener() = default;
156 ~WindowEventListener() {
160 int Register(aul_window_event_cb cb, void* user_data) {
161 std::lock_guard<std::recursive_mutex> lock(GetMutex());
163 user_data_ = user_data;
165 if (conn_ != nullptr)
168 int ret = aul_app_com_create_async("aul_window_event", nullptr,
169 AppComMessageCb, this, &conn_);
170 if (ret != AUL_R_OK) {
171 _E("aul_app_com_create_async() is failed. error(%d)", ret);
179 std::lock_guard<std::recursive_mutex> lock(GetMutex());
181 user_data_ = nullptr;
183 if (conn_ == nullptr)
186 aul_app_com_leave(conn_);
191 static int AppComMessageCb(const char* endpoint, aul_app_com_result_e res,
192 bundle* envelope, void* user_data) {
193 tizen_base::Bundle b(envelope, false, false);
194 std::string event_name = b.GetString(AUL_K_EVENT_NAME);
195 std::string appid = b.GetString(AUL_K_APPID);
196 int wid = std::stoi(b.GetString(AUL_K_WID));
197 int pid = std::stoi(b.GetString(AUL_K_PID));
199 auto* handle = static_cast<WindowEventListener*>(user_data);
200 std::lock_guard<std::recursive_mutex> lock(handle->GetMutex());
202 handle->cb_(event_name.c_str(), appid.c_str(), wid, pid,
209 std::recursive_mutex& GetMutex() const {
214 aul_app_com_connection_h conn_ = nullptr;
215 aul_window_event_cb cb_ = nullptr;
216 void* user_data_ = nullptr;
217 mutable std::recursive_mutex mutex_;
220 WindowEventListener listener;
224 extern "C" API int aul_window_stack_get(aul_window_stack_h* handle) {
225 if (handle == nullptr) {
226 _E("Invalid parameter");
230 GDBusConnection* conn = GetConn();
234 auto* msg = g_dbus_message_new_method_call(kWmBusName,
235 kWmObjectPath, kWmInterfaceName, kWmMethodNameInfo);
236 if (msg == nullptr) {
237 _E("g_dbus_message_new_method_call() is faield");
240 std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> msg_auto(
241 msg, g_object_unref);
243 GError* error = nullptr;
244 auto* reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
245 G_DBUS_SEND_MESSAGE_FLAGS_NONE, kWmDbusTimeout, nullptr, nullptr, &error);
246 if (reply == nullptr || error != nullptr) {
247 _E("g_dbus_connection_send_message_with_reply_sync() is failed. error(%s)",
248 error ? error->message : "Unknown");
249 g_clear_error(&error);
252 std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> reply_auto(
253 reply, g_object_unref);
255 auto* body = g_dbus_message_get_body(reply);
256 if (body == nullptr) {
257 _E("g_dbus_message_get_body() is failed");
261 unsigned int rid = 0;
266 gboolean alpha = FALSE;
268 gboolean focused = FALSE;
273 gboolean opaque = FALSE;
275 GVariantIter* iter = nullptr;
276 g_variant_get(body, "(a(uiiiibibiiiib))", &iter);
280 std::unique_ptr<GVariantIter, decltype(g_variant_iter_free)*> iter_auto(
281 iter, g_variant_iter_free);
283 GList* list = nullptr;
284 while (g_variant_iter_loop(iter, "(uiiiibibiiiib)",
298 auto* info = new (std::nothrow) WindowInfo(rid, x, y, w, h,
299 alpha ? true : false, visibility, focused ? true : false,
300 pid, ppid, apid, noti_level, opaque ? true : false);
301 if (info == nullptr) {
303 g_list_free_full(list, WindowInfoDestroyFunc);
307 list = g_list_append(list, info);
310 *handle = static_cast<aul_window_stack_h>(list);
314 extern "C" API int aul_window_stack_del(aul_window_stack_h handle) {
315 if (handle == nullptr) {
316 _E("Invalid parameter");
320 auto* list = static_cast<GList*>(handle);
321 g_list_free_full(list, WindowInfoDestroyFunc);
325 extern "C" API int aul_window_stack_foreach(aul_window_stack_h handle,
326 void (*iter_cb)(aul_window_info_h info, void* data), void* data) {
327 if (handle == nullptr || iter_cb == nullptr) {
328 _E("Invalid parameter");
332 auto* iter = static_cast<GList*>(handle);
334 iter_cb(static_cast<aul_window_info_h>(iter->data), data);
335 iter = g_list_next(iter);
341 extern "C" API int aul_window_stack_info_get_resource_id(aul_window_info_h info,
343 if (info == nullptr || rid == nullptr) {
344 _E("Invalid parameter");
348 auto* handle = static_cast<WindowInfo*>(info);
349 *rid = handle->GetResourceId();
353 extern "C" API int aul_window_info_get_pid(aul_window_info_h info, int* pid) {
354 if (info == nullptr || pid == nullptr) {
355 _E("Invalid parameter");
359 auto* handle = static_cast<WindowInfo*>(info);
360 *pid = handle->GetPid();
364 extern "C" API int aul_window_info_get_parent_pid(aul_window_info_h info,
366 if (info == nullptr || ppid == nullptr) {
367 _E("Invalid parameter");
371 auto* handle = static_cast<WindowInfo*>(info);
372 *ppid = handle->GetParentPid();
376 extern "C" API int aul_window_info_get_ancestor_pid(aul_window_info_h info,
378 if (info == nullptr || apid == nullptr) {
379 _E("Invalid parameter");
383 auto* handle = static_cast<WindowInfo*>(info);
384 *apid = handle->GetAncestorPid();
388 extern "C" API int aul_window_info_get_visibility(aul_window_info_h info,
390 if (info == nullptr || visibility == nullptr) {
391 _E("Invalid parameter");
395 auto* handle = static_cast<WindowInfo*>(info);
396 *visibility = handle->GetVisibility();
400 extern "C" API int aul_window_info_has_alpha(aul_window_info_h info,
402 if (info == nullptr || alpha == nullptr) {
403 _E("Invalid parameter");
407 auto* handle = static_cast<WindowInfo*>(info);
408 *alpha = handle->HasAlpha();
412 extern "C" API int aul_window_info_is_focused(aul_window_info_h info,
414 if (info == nullptr || focused == nullptr) {
415 _E("Invalid parameter");
419 auto* handle = static_cast<WindowInfo*>(info);
420 *focused = handle->IsFocused();
424 extern "C" API int aul_window_info_get_geometry(aul_window_info_h info,
425 int* x, int* y, int* w, int* h) {
426 if (info == nullptr ||
431 _E("Invalid parameter");
435 auto* handle = static_cast<WindowInfo*>(info);
436 *x = handle->GetPositionX();
437 *y = handle->GetPositionY();
438 *w = handle->GetWidth();
439 *h = handle->GetHeight();
443 extern "C" API int aul_window_info_get_notification_level(
444 aul_window_info_h info, aul_window_notification_level_e* level) {
445 if (info == nullptr || level == nullptr) {
446 _E("Invalid parameter");
450 auto* handle = static_cast<WindowInfo*>(info);
451 *level = static_cast<aul_window_notification_level_e>(
452 handle->GetNotificationLevel());
456 extern "C" API int aul_window_info_get_opaque(aul_window_info_h info,
458 if (info == nullptr || opaque == nullptr) {
459 _E("Invalid parameter");
463 auto* handle = static_cast<WindowInfo*>(info);
464 *opaque = handle->IsOpaque();
468 extern "C" API int aul_window_get_focused_pid(pid_t* pid) {
469 if (pid == nullptr) {
470 _E("Invalid parameter");
474 GDBusConnection* conn = GetConn();
478 auto* msg = g_dbus_message_new_method_call(kWmBusName,
479 kWmObjectPath, kWmInterfaceName, kWmMethodNameFocus);
480 if (msg == nullptr) {
481 _E("g_dbus_message_new_method_call() is failed");
484 std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> msg_auto(
485 msg, g_object_unref);
487 GError* error = nullptr;
488 auto* reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
489 G_DBUS_SEND_MESSAGE_FLAGS_NONE, kWmDbusTimeout, nullptr, nullptr,
491 if (reply == nullptr || error != nullptr) {
492 _E("g_dbus_connection_send_message_with_reply_sync() is failed. error(%s)",
493 error ? error->message : "Unknown");
494 g_clear_error(&error);
497 std::unique_ptr<GDBusMessage, decltype(g_object_unref)*> reply_auto(
498 reply, g_object_unref);
500 auto* body = g_dbus_message_get_body(reply);
501 if (body == nullptr) {
502 _E("g_dbus_message_get_body() is failed");
506 gint focused_pid = -1;
507 g_variant_get(body, "(i)", &focused_pid);
508 *pid = static_cast<pid_t>(focused_pid);
509 _W("Result = %d", focused_pid);
513 extern "C" API int aul_window_attach(const char* parent_appid,
514 const char* child_appid) {
515 if (parent_appid == nullptr || child_appid == nullptr) {
516 _E("Invalid parameter");
520 tizen_base::Bundle b {
521 { AUL_K_PARENT_APPID, parent_appid },
522 { AUL_K_CHILD_APPID, child_appid }
524 int ret = AppRequest(APP_WINDOW_ATTACH, getuid())
528 _E("Failed to send request. error(%d)", ret);
535 extern "C" API int aul_window_detach(const char* child_appid) {
536 if (child_appid == nullptr) {
537 _E("Invalid parameter");
541 tizen_base::Bundle b {{ AUL_K_CHILD_APPID, child_appid }};
542 int ret = AppRequest(APP_WINDOW_DETACH, getuid())
546 _E("Failed to send request. error(%d)", ret);
553 extern "C" API int aul_window_attach_below(const char* parent_appid,
554 const char* child_appid) {
555 if (parent_appid == nullptr || child_appid == nullptr) {
556 _E("Invalid parameter");
560 tizen_base::Bundle b {
561 { AUL_K_PARENT_APPID, parent_appid },
562 { AUL_K_CHILD_APPID, child_appid }
564 int ret = AppRequest(APP_WINDOW_ATTACH_BELOW, getuid())
568 _E("Failed to send request. error(%d)", ret);
575 extern "C" API int aul_window_register_event_cb(aul_window_event_cb callback,
577 if (callback == nullptr) {
578 _E("Invalid parameter");
582 int ret = listener.Register(callback, user_data);
589 extern "C" API void aul_window_deregister_event_cb(void) {
590 listener.Deregister();