From bed837f7cee3945eb80cdc3c5d8d747f73f88698 Mon Sep 17 00:00:00 2001 From: jeon Date: Fri, 28 Aug 2020 10:33:32 +0900 Subject: [PATCH 01/16] DSWaylandExtension: enable tizen_surface interface Change-Id: If9b229fecf00ad75d72f6debfb9859dd39c614d0 --- src/DSWaylandExtension/DSWaylandExtension.cpp | 15 +++++++++++++++ src/DSWaylandExtension/DSWaylandExtensionPrivate.h | 3 +++ 2 files changed, 18 insertions(+) diff --git a/src/DSWaylandExtension/DSWaylandExtension.cpp b/src/DSWaylandExtension/DSWaylandExtension.cpp index 6534383..e806860 100644 --- a/src/DSWaylandExtension/DSWaylandExtension.cpp +++ b/src/DSWaylandExtension/DSWaylandExtension.cpp @@ -28,6 +28,7 @@ #include "DSWaylandTizenPolicy.h" #include "DSWaylandTizenAppinfo.h" #include "DSWaylandTizenLaunchEffect.h" +#include "DSWaylandTizenSurface.h" namespace display_server { @@ -58,6 +59,7 @@ bool DSWaylandExtensionPrivate::init(DSWaylandCompositor *compositor) __initTizenPolicy(); __initTizenAppinfo(); __initTizenLaunchEffect(); + __initTizenSurface(); } catch(const std::runtime_error& e) { @@ -122,6 +124,19 @@ bool DSWaylandExtensionPrivate::__initTizenLaunchEffect(void) return true; } +bool DSWaylandExtensionPrivate::__initTizenSurface(void) +{ + __tzSurface = std::make_shared(__compositor); + if (__tzSurface == nullptr) + { + throw std::runtime_error(__func__); + return false; + } + + return true; +} + + DSWaylandExtension::DSWaylandExtension(DSWaylandCompositor *compositor) : DS_INIT_PRIVATE_PTR(DSWaylandExtension) { diff --git a/src/DSWaylandExtension/DSWaylandExtensionPrivate.h b/src/DSWaylandExtension/DSWaylandExtensionPrivate.h index 2c063d3..e6aa09a 100644 --- a/src/DSWaylandExtension/DSWaylandExtensionPrivate.h +++ b/src/DSWaylandExtension/DSWaylandExtensionPrivate.h @@ -31,6 +31,7 @@ class DSWaylandZxdgShellV6; class DSWaylandTizenPolicy; class DSWaylandTizenAppinfo; class DSWaylandTizenLaunchEffect; +class DSWaylandTizenSurface; class DSWaylandExtensionPrivate : public DSObjectPrivate { @@ -48,6 +49,7 @@ private: bool __initTizenPolicy(void); bool __initTizenAppinfo(void); bool __initTizenLaunchEffect(void); + bool __initTizenSurface(void); private: DSWaylandCompositor *__compositor; @@ -55,6 +57,7 @@ private: std::shared_ptr __tzPolicy; std::shared_ptr __tzAppinfo; std::shared_ptr __tzLaunchEffect; + std::shared_ptr __tzSurface; }; -- 2.7.4 From f291785f3d8d14a21458a15cf8c73465da7189ff Mon Sep 17 00:00:00 2001 From: jeon Date: Fri, 28 Aug 2020 11:13:31 +0900 Subject: [PATCH 02/16] tizen_policy_ext: add header for tizen_policy_ext protocol Change-Id: I10c4937f038955082300404d258ad4360e8bab06 --- src/DSWaylandServer/tizen_policy_ext-protocol.c | 54 ++++++++ .../tizen_policy_ext-server-protocol.h | 151 +++++++++++++++++++++ src/meson.build | 2 + 3 files changed, 207 insertions(+) create mode 100644 src/DSWaylandServer/tizen_policy_ext-protocol.c create mode 100644 src/DSWaylandServer/tizen_policy_ext-server-protocol.h diff --git a/src/DSWaylandServer/tizen_policy_ext-protocol.c b/src/DSWaylandServer/tizen_policy_ext-protocol.c new file mode 100644 index 0000000..6b49f50 --- /dev/null +++ b/src/DSWaylandServer/tizen_policy_ext-protocol.c @@ -0,0 +1,54 @@ +#include +#include +#include "wayland-util.h" + +extern const struct wl_interface tizen_rotation_interface; +extern const struct wl_interface wl_surface_interface; + +static const struct wl_interface *types[] = { + NULL, + NULL, + NULL, + NULL, + NULL, + &tizen_rotation_interface, + &wl_surface_interface, + &wl_surface_interface, +}; + +static const struct wl_message tizen_policy_ext_requests[] = { + { "get_rotation", "no", types + 5 }, + { "get_active_angle", "?o", types + 7 }, +}; + +static const struct wl_message tizen_policy_ext_events[] = { + { "active_angle", "u", types + 0 }, +}; + +WL_EXPORT const struct wl_interface tizen_policy_ext_interface3 = { + "tizen_policy_ext", 3, + 2, tizen_policy_ext_requests, + 1, tizen_policy_ext_events, +}; + +static const struct wl_message tizen_rotation_requests[] = { + { "destroy", "", types + 0 }, + { "set_available_angles", "u", types + 0 }, + { "set_preferred_angle", "u", types + 0 }, + { "ack_angle_change", "u", types + 0 }, + { "set_geometry_hint", "3uuuuu", types + 0 }, +}; + +static const struct wl_message tizen_rotation_events[] = { + { "available_angles_done", "u", types + 0 }, + { "preferred_angle_done", "u", types + 0 }, + { "angle_change", "uu", types + 0 }, + { "angle_change_with_resize", "2uuuu", types + 0 }, +}; + +WL_EXPORT const struct wl_interface tizen_rotation_interface = { + "tizen_rotation", 3, + 5, tizen_rotation_requests, + 4, tizen_rotation_events, +}; + diff --git a/src/DSWaylandServer/tizen_policy_ext-server-protocol.h b/src/DSWaylandServer/tizen_policy_ext-server-protocol.h new file mode 100644 index 0000000..4a08b79 --- /dev/null +++ b/src/DSWaylandServer/tizen_policy_ext-server-protocol.h @@ -0,0 +1,151 @@ +#ifndef TIZEN_POLICY_EXT_SERVER_PROTOCOL_H +#define TIZEN_POLICY_EXT_SERVER_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "wayland-server.h" + +struct wl_client; +struct wl_resource; + +struct tizen_policy_ext; +struct tizen_rotation; +struct wl_surface; + +extern const struct wl_interface tizen_policy_ext_interface3; +extern const struct wl_interface tizen_rotation_interface; + +struct tizen_policy_ext_interface { + /** + * get_rotation - (none) + * @id: new rotation object + * @surface: surface object + */ + void (*get_rotation)(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface); + /** + * get_active_angle - get a current active angle + * @surface: (none) + * + * + */ + void (*get_active_angle)(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *surface); +}; + +#define TIZEN_POLICY_EXT_ACTIVE_ANGLE 0 + +#define TIZEN_POLICY_EXT_ACTIVE_ANGLE_SINCE_VERSION 1 + +static inline void +tizen_policy_ext_send_active_angle(struct wl_resource *resource_, uint32_t angle) +{ + wl_resource_post_event(resource_, TIZEN_POLICY_EXT_ACTIVE_ANGLE, angle); +} + +#ifndef TIZEN_ROTATION_ANGLE_ENUM +#define TIZEN_ROTATION_ANGLE_ENUM +enum tizen_rotation_angle { + TIZEN_ROTATION_ANGLE_NONE = 0, + TIZEN_ROTATION_ANGLE_0 = 1, + TIZEN_ROTATION_ANGLE_90 = 2, + TIZEN_ROTATION_ANGLE_180 = 4, + TIZEN_ROTATION_ANGLE_270 = 8, +}; +#endif /* TIZEN_ROTATION_ANGLE_ENUM */ + +struct tizen_rotation_interface { + /** + * destroy - destroy tizen_rotation + * + * + */ + void (*destroy)(struct wl_client *client, + struct wl_resource *resource); + /** + * set_available_angles - (none) + * @angles: (none) + */ + void (*set_available_angles)(struct wl_client *client, + struct wl_resource *resource, + uint32_t angles); + /** + * set_preferred_angle - (none) + * @angle: (none) + */ + void (*set_preferred_angle)(struct wl_client *client, + struct wl_resource *resource, + uint32_t angle); + /** + * ack_angle_change - ack a angle_change + * @serial: a serial to angle_change for + * + * + */ + void (*ack_angle_change)(struct wl_client *client, + struct wl_resource *resource, + uint32_t serial); + /** + * set_geometry_hint - (none) + * @angle: (none) + * @x: (none) + * @y: (none) + * @width: (none) + * @height: (none) + * @since: 3 + */ + void (*set_geometry_hint)(struct wl_client *client, + struct wl_resource *resource, + uint32_t angle, + uint32_t x, + uint32_t y, + uint32_t w, + uint32_t h); +}; + +#define TIZEN_ROTATION_AVAILABLE_ANGLES_DONE 0 +#define TIZEN_ROTATION_PREFERRED_ANGLE_DONE 1 +#define TIZEN_ROTATION_ANGLE_CHANGE 2 +#define TIZEN_ROTATION_ANGLE_CHANGE_WITH_RESIZE 3 + +#define TIZEN_ROTATION_AVAILABLE_ANGLES_DONE_SINCE_VERSION 1 +#define TIZEN_ROTATION_PREFERRED_ANGLE_DONE_SINCE_VERSION 1 +#define TIZEN_ROTATION_ANGLE_CHANGE_SINCE_VERSION 1 +#define TIZEN_ROTATION_ANGLE_CHANGE_WITH_RESIZE_SINCE_VERSION 2 + +static inline void +tizen_rotation_send_available_angles_done(struct wl_resource *resource_, uint32_t angles) +{ + wl_resource_post_event(resource_, TIZEN_ROTATION_AVAILABLE_ANGLES_DONE, angles); +} + +static inline void +tizen_rotation_send_preferred_angle_done(struct wl_resource *resource_, uint32_t angle) +{ + wl_resource_post_event(resource_, TIZEN_ROTATION_PREFERRED_ANGLE_DONE, angle); +} + +static inline void +tizen_rotation_send_angle_change(struct wl_resource *resource_, uint32_t angle, uint32_t serial) +{ + wl_resource_post_event(resource_, TIZEN_ROTATION_ANGLE_CHANGE, angle, serial); +} + +static inline void +tizen_rotation_send_angle_change_with_resize(struct wl_resource *resource_, uint32_t angle, uint32_t serial, uint32_t width, uint32_t height) +{ + wl_resource_post_event(resource_, TIZEN_ROTATION_ANGLE_CHANGE_WITH_RESIZE, angle, serial, width, height); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/meson.build b/src/meson.build index 7042c46..7691d3b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -177,6 +177,8 @@ libds_wayland_srcs = [ 'DSWaylandServer/DSWaylandProtocolTracePrivate.h', 'DSWaylandServer/DSWaylandProtocolTrace.h', 'DSWaylandServer/DSWaylandProtocolTrace.cpp', + 'DSWaylandServer/tizen_policy_ext-server-protocol.h', + 'DSWaylandServer/tizen_policy_ext-protocol.c', ] libds_srcs += libds_wayland_srcs -- 2.7.4 From a3895c82fb2c09e5991a3ca7de362514f926da28 Mon Sep 17 00:00:00 2001 From: jeon Date: Fri, 28 Aug 2020 11:14:42 +0900 Subject: [PATCH 03/16] DSWaylandServer: build a tizen_policy_ext class Change-Id: I66d18becc6b51fd1f2a3b8c6de05e53fa8317fe3 --- src/DSWaylandServer/dswayland-server-tizen_policy_ext.cpp | 12 +++++++----- src/DSWaylandServer/dswayland-server-tizen_policy_ext.h | 3 ++- src/meson.build | 2 ++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/DSWaylandServer/dswayland-server-tizen_policy_ext.cpp b/src/DSWaylandServer/dswayland-server-tizen_policy_ext.cpp index 6a035da..97e129e 100644 --- a/src/DSWaylandServer/dswayland-server-tizen_policy_ext.cpp +++ b/src/DSWaylandServer/dswayland-server-tizen_policy_ext.cpp @@ -1,6 +1,8 @@ /* Protocol XML file : wayland-extension/tizen_policy_ext.xml */ -#include "dswayland-server-tizen-policy-ext.h" +#include +#include "tizen_policy_ext-server-protocol.h" +#include "dswayland-server-tizen_policy_ext.h" #ifndef DS_UNLIKELY #define DS_UNLIKELY(X) X @@ -105,7 +107,7 @@ namespace DSWaylandServer { void tizen_policy_ext::init(struct ::wl_display *display, int version) { - m_global = wl_global_create(display, &::tizen_policy_ext_interface, version, this, bind_func); + m_global = wl_global_create(display, &::tizen_policy_ext_interface3, version, this, bind_func); m_globalVersion = version; m_displayDestroyedListener.notify = tizen_policy_ext::display_destroy_func; m_displayDestroyedListener.parent = this; @@ -114,7 +116,7 @@ namespace DSWaylandServer { const struct wl_interface *tizen_policy_ext::interface() { - return &::tizen_policy_ext_interface; + return &::tizen_policy_ext_interface3; } tizen_policy_ext::Resource *tizen_policy_ext::tizen_policy_ext_allocate() @@ -156,7 +158,7 @@ namespace DSWaylandServer { tizen_policy_ext::Resource *tizen_policy_ext::bind(struct ::wl_client *client, uint32_t id, int version) { DS_ASSERT_X(!wl_client_get_object(client, id), "DSWaylandObject bind", "binding to object %u more than once", id); - struct ::wl_resource *handle = wl_resource_create(client, &::tizen_policy_ext_interface, version, id); + struct ::wl_resource *handle = wl_resource_create(client, &::tizen_policy_ext_interface3, version, id); return bind(handle); } @@ -174,7 +176,7 @@ namespace DSWaylandServer { { if (DS_UNLIKELY(!resource)) return NULL; - if (wl_resource_instance_of(resource, &::tizen_policy_ext_interface, &m_tizen_policy_ext_interface)) + if (wl_resource_instance_of(resource, &::tizen_policy_ext_interface3, &m_tizen_policy_ext_interface)) return static_cast(wl_resource_get_user_data(resource)); return NULL; } diff --git a/src/DSWaylandServer/dswayland-server-tizen_policy_ext.h b/src/DSWaylandServer/dswayland-server-tizen_policy_ext.h index 66d7b92..9069fe7 100644 --- a/src/DSWaylandServer/dswayland-server-tizen_policy_ext.h +++ b/src/DSWaylandServer/dswayland-server-tizen_policy_ext.h @@ -4,7 +4,8 @@ #define __DS_TIZEN_POLICY_EXT_PROTOCOL_H__ #include "wayland-server-core.h" -#include "tizen-policy-ext-server-protocol.h" +#include +#include "tizen_policy_ext-server-protocol.h" #include #include #include diff --git a/src/meson.build b/src/meson.build index 7691d3b..48b1a58 100644 --- a/src/meson.build +++ b/src/meson.build @@ -97,6 +97,8 @@ libds_wayland_srcs = [ 'DSWaylandServer/dswayland-server-tizen-launch.h', 'DSWaylandServer/dswayland-server-input-method.cpp', 'DSWaylandServer/dswayland-server-input-method.h', + 'DSWaylandServer/dswayland-server-tizen_policy_ext.cpp', + 'DSWaylandServer/dswayland-server-tizen_policy_ext.h', 'DSWaylandServer/DSWaylandCallback.cpp', 'DSWaylandServer/DSWaylandCallback.h', 'DSWaylandServer/DSWaylandCallbackPrivate.h', -- 2.7.4 From 12e548b96606eeb6626215f1cedf1ff393f7c2b9 Mon Sep 17 00:00:00 2001 From: jeon Date: Fri, 28 Aug 2020 11:15:51 +0900 Subject: [PATCH 04/16] DSWaylandTizenPolicyExt: Add skeleton codes to get tizen_rotation Change-Id: I81c7b38aa548dde8997954794ea6134a4e575e94 --- src/DSWaylandServer/DSWaylandTizenPolicyExt.cpp | 162 +++++++++++++++++++++ src/DSWaylandServer/DSWaylandTizenPolicyExt.h | 66 +++++++++ .../DSWaylandTizenPolicyExtPrivate.h | 77 ++++++++++ src/meson.build | 3 + 4 files changed, 308 insertions(+) create mode 100644 src/DSWaylandServer/DSWaylandTizenPolicyExt.cpp create mode 100644 src/DSWaylandServer/DSWaylandTizenPolicyExt.h create mode 100644 src/DSWaylandServer/DSWaylandTizenPolicyExtPrivate.h diff --git a/src/DSWaylandServer/DSWaylandTizenPolicyExt.cpp b/src/DSWaylandServer/DSWaylandTizenPolicyExt.cpp new file mode 100644 index 0000000..2ffff5b --- /dev/null +++ b/src/DSWaylandServer/DSWaylandTizenPolicyExt.cpp @@ -0,0 +1,162 @@ +/* +* Copyright © 2020 Samsung Electronics co., Ltd. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the next +* paragraph) shall be included in all copies or substantial portions of the +* Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +*/ + +#include "DSWaylandTizenPolicyExt.h" +#include "DSWaylandTizenPolicyExtPrivate.h" + +namespace display_server +{ + +/* DSWaylandTizenPolicyExt */ +DSWaylandTizenPolicyExtPrivate::DSWaylandTizenPolicyExtPrivate(DSWaylandTizenPolicyExt *p_ptr, DSWaylandCompositor *compositor) + : DSObjectPrivate(p_ptr), + __p_ptr(p_ptr), + __resource_id_cnt(0) +{ + if (!compositor) + return; + + init(compositor->display(), 3); +} + +DSWaylandTizenPolicyExtPrivate::~DSWaylandTizenPolicyExtPrivate() +{ +} + +void DSWaylandTizenPolicyExtPrivate::tizen_policy_ext_bind_resource(Resource *resource) +{ +} + +void DSWaylandTizenPolicyExtPrivate::tizen_policy_ext_destroy_resource(Resource *resource) +{ +} + +void DSWaylandTizenPolicyExtPrivate::tizen_policy_ext_get_rotation(Resource *resource, uint32_t id, struct ::wl_resource *surface) +{ + DSWaylandTizenRotation *tizenRotation = nullptr; + + for (DSWaylandTizenRotation *temp : __rotationList) + if (temp->getRotationSurface() == surface) return; + + tizenRotation = new DSWaylandTizenRotation(resource->client(), id, surface); + if (tizenRotation == nullptr) + { + DSLOG_ERR("DSWaylandTizenPolicyExt", "fail get tizen resource"); + return; + } + + __rotationList.push_back(tizenRotation); +} + +DSWaylandTizenRotation *DSWaylandTizenPolicyExtPrivate::getTizenRotation(struct ::wl_resource *surface) +{ + DSWaylandTizenRotation *tizenRotation = nullptr; + + for (DSWaylandTizenRotation *temp : __rotationList) + { + if (temp->getRotationSurface() == surface) + { + tizenRotation = temp; + break; + } + } + + return tizenRotation; +} + +void DSWaylandTizenPolicyExtPrivate::delTizenRotation(DSWaylandTizenRotation *tizenRotation) +{ + __rotationList.remove(tizenRotation); +} + +DSWaylandTizenPolicyExt::DSWaylandTizenPolicyExt(DSWaylandCompositor *compositor) + : _d_ptr(std::make_unique(this, compositor)) +{ +} + +DSWaylandTizenPolicyExt::~DSWaylandTizenPolicyExt() +{ +} + +DSWaylandTizenRotation *DSWaylandTizenPolicyExt::getTizenRotation(struct ::wl_resource *surface) +{ + DS_GET_PRIV(DSWaylandTizenPolicyExt); + + return priv->getTizenRotation(surface); +} + +void DSWaylandTizenPolicyExt::delTizenRotation(DSWaylandTizenRotation *tizenRotation) +{ + DS_GET_PRIV(DSWaylandTizenPolicyExt); + + priv->delTizenRotation(tizenRotation); +} + +/* DSWaylandTizenRotation */ +DSWaylandTizenRotationPrivate::DSWaylandTizenRotationPrivate(DSWaylandTizenRotation *p_ptr, struct ::wl_client *client, uint32_t id, struct ::wl_resource *surface) + : DSObjectPrivate(p_ptr), + __p_ptr(p_ptr), + __surface(surface), + __resource_id(0) +{ + init(client, id, 3); +} + +DSWaylandTizenRotationPrivate::~DSWaylandTizenRotationPrivate() +{ +} + +void DSWaylandTizenRotationPrivate::tizen_rotation_bind_resource(Resource *resource) +{ +} + +void DSWaylandTizenRotationPrivate::tizen_rotation_destroy_resource(Resource *resource) +{ +} + +void DSWaylandTizenRotationPrivate::tizen_rotation_destroy(Resource *resource) +{ +} + +struct ::wl_resource *DSWaylandTizenRotationPrivate::getRotationSurface(void) +{ + return __surface; +} + +DSWaylandTizenRotation::DSWaylandTizenRotation(struct ::wl_client *client, uint32_t id, struct ::wl_resource *surface) + : _d_ptr(std::make_unique(this, client, id, surface)) +{ +} + +DSWaylandTizenRotation::~DSWaylandTizenRotation() +{ +} + +struct ::wl_resource *DSWaylandTizenRotation::getRotationSurface(void) +{ + DS_GET_PRIV(DSWaylandTizenRotation); + + return priv->getRotationSurface(); +} + +} // namespace display_server diff --git a/src/DSWaylandServer/DSWaylandTizenPolicyExt.h b/src/DSWaylandServer/DSWaylandTizenPolicyExt.h new file mode 100644 index 0000000..eef13dc --- /dev/null +++ b/src/DSWaylandServer/DSWaylandTizenPolicyExt.h @@ -0,0 +1,66 @@ +/* +* Copyright © 2020 Samsung Electronics co., Ltd. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the next +* paragraph) shall be included in all copies or substantial portions of the +* Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +*/ + +#ifndef _DS_WAYLAND_TIZEN_POLICY_EXT_H_ +#define _DS_WAYLAND_TIZEN_POLICY_EXT_H_ + +#include +#include +#include +#include + +namespace display_server +{ + +class DSWaylandTizenPolicyExtPrivate; +class DSWaylandTizenRotationPrivate; + +class DS_DECL_EXPORT DSWaylandTizenRotation : public DSObject +{ +DS_PIMPL_USE_PRIVATE(DSWaylandTizenRotation); + +public: + DSWaylandTizenRotation(struct ::wl_client *client, uint32_t id, struct ::wl_resource *surface); + virtual ~DSWaylandTizenRotation(); + + struct ::wl_resource *getRotationSurface(void); + void sendResourceId(void); + void setResourceId(uint32_t tizenResourceId); + uint32_t getResourceId(void); +}; + +class DS_DECL_EXPORT DSWaylandTizenPolicyExt : public DSObject +{ +DS_PIMPL_USE_PRIVATE(DSWaylandTizenPolicyExt); + +public: + DSWaylandTizenPolicyExt(DSWaylandCompositor *compositor); + virtual ~DSWaylandTizenPolicyExt(); + + DSWaylandTizenRotation *getTizenRotation(struct ::wl_resource *surface); + void delTizenRotation(DSWaylandTizenRotation *resource); +}; + +} + +#endif diff --git a/src/DSWaylandServer/DSWaylandTizenPolicyExtPrivate.h b/src/DSWaylandServer/DSWaylandTizenPolicyExtPrivate.h new file mode 100644 index 0000000..cfa4e79 --- /dev/null +++ b/src/DSWaylandServer/DSWaylandTizenPolicyExtPrivate.h @@ -0,0 +1,77 @@ +/* +* Copyright © 2020 Samsung Electronics co., Ltd. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the next +* paragraph) shall be included in all copies or substantial portions of the +* Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +*/ + +#ifndef _DS_WAYLAND_TIZEN_POLICY_EXT_PRIVATE_H_ +#define _DS_WAYLAND_TIZEN_POLICY_EXT_PRIVATE_H_ + +#include "dswayland-server-tizen_policy_ext.h" +#include "DSWaylandTizenPolicyExt.h" + +namespace display_server +{ + +class DS_DECL_EXPORT DSWaylandTizenRotationPrivate : public DSObjectPrivate, public DSWaylandServer::tizen_rotation +{ +DS_PIMPL_USE_PUBLIC(DSWaylandTizenRotation); + +public: + DSWaylandTizenRotationPrivate() = delete; + DSWaylandTizenRotationPrivate(DSWaylandTizenRotation *p_ptr, struct ::wl_client *client, uint32_t id, struct ::wl_resource *surface); + ~DSWaylandTizenRotationPrivate() override; + + struct ::wl_resource *getRotationSurface(void); + +protected: + void tizen_rotation_bind_resource(Resource *resource) override; + void tizen_rotation_destroy_resource(Resource *resource) override; + void tizen_rotation_destroy(Resource *resource) override; +private: + struct ::wl_resource *__surface; + uint32_t __resource_id; +}; + +class DS_DECL_EXPORT DSWaylandTizenPolicyExtPrivate : public DSObjectPrivate, public DSWaylandServer::tizen_policy_ext +{ +DS_PIMPL_USE_PUBLIC(DSWaylandTizenPolicyExt); + +public: + DSWaylandTizenPolicyExtPrivate() = delete; + DSWaylandTizenPolicyExtPrivate(DSWaylandTizenPolicyExt *p_ptr, DSWaylandCompositor *compositor); + ~DSWaylandTizenPolicyExtPrivate() override; + + DSWaylandTizenRotation *getTizenRotation(struct ::wl_resource *surface); + void delTizenRotation(DSWaylandTizenRotation *resource); + +protected: + void tizen_policy_ext_bind_resource(Resource *resource) override; + void tizen_policy_ext_destroy_resource(Resource *resource) override; + void tizen_policy_ext_get_rotation(Resource *resource, uint32_t id, struct ::wl_resource *surface) override; + +private: + std::list __rotationList; + uint32_t __resource_id_cnt; //TO DO : have to manage more proper class +}; + +} + +#endif diff --git a/src/meson.build b/src/meson.build index 48b1a58..ea39c2c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -179,6 +179,9 @@ libds_wayland_srcs = [ 'DSWaylandServer/DSWaylandProtocolTracePrivate.h', 'DSWaylandServer/DSWaylandProtocolTrace.h', 'DSWaylandServer/DSWaylandProtocolTrace.cpp', + 'DSWaylandServer/DSWaylandTizenPolicyExt.h', + 'DSWaylandServer/DSWaylandTizenPolicyExtPrivate.h', + 'DSWaylandServer/DSWaylandTizenPolicyExt.cpp', 'DSWaylandServer/tizen_policy_ext-server-protocol.h', 'DSWaylandServer/tizen_policy_ext-protocol.c', ] -- 2.7.4 From cbb81338cc9b9bd1fdaa168541f3e3fff9b69e16 Mon Sep 17 00:00:00 2001 From: jeon Date: Fri, 28 Aug 2020 11:16:29 +0900 Subject: [PATCH 05/16] DSWaylandExtension: enable tizen_policy_ext interface Change-Id: Ia1d264562c4c7e4d3abf1573f787db8cc54a0971 --- src/DSWaylandExtension/DSWaylandExtension.cpp | 14 ++++++++++++++ src/DSWaylandExtension/DSWaylandExtensionPrivate.h | 3 +++ 2 files changed, 17 insertions(+) diff --git a/src/DSWaylandExtension/DSWaylandExtension.cpp b/src/DSWaylandExtension/DSWaylandExtension.cpp index e806860..e6c5906 100644 --- a/src/DSWaylandExtension/DSWaylandExtension.cpp +++ b/src/DSWaylandExtension/DSWaylandExtension.cpp @@ -29,6 +29,7 @@ #include "DSWaylandTizenAppinfo.h" #include "DSWaylandTizenLaunchEffect.h" #include "DSWaylandTizenSurface.h" +#include "DSWaylandTizenPolicyExt.h" namespace display_server { @@ -60,6 +61,7 @@ bool DSWaylandExtensionPrivate::init(DSWaylandCompositor *compositor) __initTizenAppinfo(); __initTizenLaunchEffect(); __initTizenSurface(); + __initTizenPolicyExt(); } catch(const std::runtime_error& e) { @@ -136,6 +138,18 @@ bool DSWaylandExtensionPrivate::__initTizenSurface(void) return true; } +bool DSWaylandExtensionPrivate::__initTizenPolicyExt(void) +{ + __tzPolicyExt = std::make_shared(__compositor); + if (__tzPolicyExt == nullptr) + { + throw std::runtime_error(__func__); + return false; + } + + return true; +} + DSWaylandExtension::DSWaylandExtension(DSWaylandCompositor *compositor) : DS_INIT_PRIVATE_PTR(DSWaylandExtension) diff --git a/src/DSWaylandExtension/DSWaylandExtensionPrivate.h b/src/DSWaylandExtension/DSWaylandExtensionPrivate.h index e6aa09a..7ac92cd 100644 --- a/src/DSWaylandExtension/DSWaylandExtensionPrivate.h +++ b/src/DSWaylandExtension/DSWaylandExtensionPrivate.h @@ -32,6 +32,7 @@ class DSWaylandTizenPolicy; class DSWaylandTizenAppinfo; class DSWaylandTizenLaunchEffect; class DSWaylandTizenSurface; +class DSWaylandTizenPolicyExt; class DSWaylandExtensionPrivate : public DSObjectPrivate { @@ -50,6 +51,7 @@ private: bool __initTizenAppinfo(void); bool __initTizenLaunchEffect(void); bool __initTizenSurface(void); + bool __initTizenPolicyExt(void); private: DSWaylandCompositor *__compositor; @@ -58,6 +60,7 @@ private: std::shared_ptr __tzAppinfo; std::shared_ptr __tzLaunchEffect; std::shared_ptr __tzSurface; + std::shared_ptr __tzPolicyExt; }; -- 2.7.4 From 261c4faab542584aabab61027904538d82d5e55b Mon Sep 17 00:00:00 2001 From: jeon Date: Fri, 28 Aug 2020 11:23:54 +0900 Subject: [PATCH 06/16] DSWaylandTizenPolicyExt: add a simple testcase Change-Id: I389834826ed202009e12b39a0b67f6bc1e95767a --- tests/DSWaylandTizenPolicyExt-test.cpp | 47 ++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 tests/DSWaylandTizenPolicyExt-test.cpp diff --git a/tests/DSWaylandTizenPolicyExt-test.cpp b/tests/DSWaylandTizenPolicyExt-test.cpp new file mode 100644 index 0000000..f5868e3 --- /dev/null +++ b/tests/DSWaylandTizenPolicyExt-test.cpp @@ -0,0 +1,47 @@ +/* +* Copyright © 2020 Samsung Electronics co., Ltd. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the next +* paragraph) shall be included in all copies or substantial portions of the +* Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +*/ + +#include "libds-tests.h" +#include "DSWaylandTizenPolicyExt.h" + +using namespace display_server; + +class DSWaylandTizenPolicyExtTest : public ::testing::Test +{ +public: + void SetUp(void) override + {} + void TearDown(void) override + {} +}; + +TEST_F(DSWaylandTizenPolicyExtTest, NewDSWaylandTizenPolicyExt) +{ + DSWaylandCompositor *comp = DSWaylandCompositor::getInstance(); + DSWaylandTizenPolicyExt *tizenPolicyExt = new DSWaylandTizenPolicyExt(comp); + EXPECT_TRUE(tizenPolicyExt != nullptr); + + if (tizenPolicyExt) + delete tizenPolicyExt; + DSWaylandCompositor::releaseInstance(); +} -- 2.7.4 From ec9b525190aee08dc5feb6d1fbedfad1c5110118 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 28 Aug 2020 12:58:25 +0900 Subject: [PATCH 07/16] DSWindowShell: move wm policy functionalities from DSWindow to DSWindowShell move firstCommit, visible and changedGeometry Change-Id: I75a5805587a93091f274cbc99f7813ff70b695c1 --- src/DSWindow/DSWindow.cpp | 43 ------------------------------ src/DSWindow/DSWindowPrivate.h | 5 ---- src/DSWindowShell/DSWindowShellPrivate.cpp | 36 ++++++++++++++++++++++++- src/DSWindowShell/DSWindowShellPrivate.h | 6 ++++- 4 files changed, 40 insertions(+), 50 deletions(-) diff --git a/src/DSWindow/DSWindow.cpp b/src/DSWindow/DSWindow.cpp index e4cf6f1..6267a96 100644 --- a/src/DSWindow/DSWindow.cpp +++ b/src/DSWindow/DSWindow.cpp @@ -41,12 +41,9 @@ DSWindowPrivate::DSWindowPrivate(DSWindow *p_ptr) __committedW(0), __committedH(0), __created(false), - __visible(false), __hasFocus(false), __waylandSurface(nullptr), __winShell(nullptr), - __firstCommit(true), - __changedGeometry(false), __acceptsFocus(true), __allowUserGeometry(false), __title(""), @@ -181,14 +178,6 @@ DSWindowShell *DSWindowPrivate::getWindowShell(void) return __winShell; } -void DSWindowPrivate::sendConfigure(void) -{ - if (__winShell) - { - __winShell->sendConfigure(); - } -} - bool DSWindowPrivate::setVkbdFloating(bool set) { __vkbd_floating = set; @@ -204,34 +193,8 @@ void DSWindowPrivate::__onSurfaceCommitted(std::shared_ptrbufferChanged()) { std::shared_ptr buffer = waylandSurfaceCommitInfo->getBuffer(); - if (buffer) - { - std::shared_ptr bufferSize = buffer->getSize(); - __committedW = bufferSize->w; - __committedH = bufferSize->h; - - if (!__visible) - __visible = true; - } - else - { - __visible = false; - } // emit a signal of the buffer changed pub->__bufferChangedSignal.emit(buffer); @@ -411,8 +374,6 @@ void DSWindow::setPosition(int x, int y) priv->__x = x; priv->__y = y; - priv->__changedGeometry = true; - __windowPositionChangedSignal.emit(nullptr); } @@ -444,8 +405,6 @@ void DSWindow::setSize(unsigned int w, unsigned int h) priv->__w = w; priv->__h = h; - - priv->__changedGeometry = true; } void DSWindow::setSize(stSize size) @@ -454,8 +413,6 @@ void DSWindow::setSize(stSize size) priv->__w = size.w; priv->__h = size.h; - - priv->__changedGeometry = true; } void DSWindow::setZOrder(unsigned int zOrder) diff --git a/src/DSWindow/DSWindowPrivate.h b/src/DSWindow/DSWindowPrivate.h index 3109df7..a6a8200 100644 --- a/src/DSWindow/DSWindowPrivate.h +++ b/src/DSWindow/DSWindowPrivate.h @@ -73,8 +73,6 @@ public: bool setWindowShell(DSWindowShell *winShell); DSWindowShell *getWindowShell(void); - void sendConfigure(void); - bool setVkbdFloating(bool set); bool getVkbdFloating(); @@ -89,12 +87,9 @@ private: unsigned int __zOrder; unsigned int __committedW, __committedH; bool __created; - bool __visible; bool __hasFocus; std::shared_ptr __waylandSurface; DSWindowShell *__winShell; - bool __firstCommit; - bool __changedGeometry; bool __acceptsFocus; bool __allowUserGeometry; std::string __title; diff --git a/src/DSWindowShell/DSWindowShellPrivate.cpp b/src/DSWindowShell/DSWindowShellPrivate.cpp index 897f91c..65778c3 100644 --- a/src/DSWindowShell/DSWindowShellPrivate.cpp +++ b/src/DSWindowShell/DSWindowShellPrivate.cpp @@ -70,8 +70,12 @@ DSWindowShellPrivate::DSWindowShellPrivate(DSWindowShell *p_ptr, DSWindow *windo __reqX(0), __reqY(0), __reqW(0), __reqH(0), __parent(nullptr), - __layer(0) + __layer(0), + __firstCommit(true), + __changedGeometry(false), + __visible(false) { + __window->registerCallbackBufferChanged(this, std::bind(&DSWindowShellPrivate::__onWindowBufferChanged, this, std::placeholders::_1)); } DSWindowShellPrivate::~DSWindowShellPrivate() @@ -172,6 +176,7 @@ bool DSWindowShellPrivate::__handleUserGeometryHint(bool setUserGeometry) __x = __y = __w = __h = 0; __window->setPosition(__x, __y); __window->setSize(__w, __h); + __changedGeometry = true; } else { @@ -187,6 +192,7 @@ bool DSWindowShellPrivate::__handleUserGeometryHint(bool setUserGeometry) __window->setPosition(__x, __y); __window->setSize(__w, __h); + __changedGeometry = true; } } @@ -209,6 +215,7 @@ bool DSWindowShellPrivate::create(int x, int y, unsigned int w, unsigned int h, { __window->setPosition(__x, __y); __window->setSize(__w, __h); + __changedGeometry = true; } return true; @@ -245,6 +252,7 @@ bool DSWindowShellPrivate::setZone(DSZone *zone) __window->setPosition(__x, __y); __window->setSize(__w, __h); + __changedGeometry = true; } } else @@ -336,6 +344,7 @@ bool DSWindowShellPrivate::setPosition(int x, int y) __x = x; __y = y; __window->setPosition(__x, __y); + __changedGeometry = true; } } else @@ -397,6 +406,7 @@ bool DSWindowShellPrivate::setGeometry(int x, int y, unsigned int w, unsigned in __h = h; __window->setPosition(__x, __y); __window->setSize(__w, __h); + __changedGeometry = true; } } else @@ -645,4 +655,28 @@ void DSWindowShellPrivate::sendConfigure(void) } } +void DSWindowShellPrivate::__onWindowBufferChanged(std::shared_ptr buffer) +{ + if (__firstCommit) + { + DSLOG_DBG("DSWindow", "First Commit!!! "); + __firstCommit = false; + } + + if (__changedGeometry) + { + std::shared_ptr bufferSize = buffer->getSize(); + DSLOG_DBG("DSWindow", "Geometry Changed!!! Send Configure... geo(%d,%d,%d,%d) commit(%d,%d)", __x, __y, __w, __h, bufferSize->w, bufferSize->h); + sendConfigure(); + __changedGeometry = false; + } + + if (buffer) { + __visible = true; + } else { + __visible = false; + } + +} + } // namespace display_server diff --git a/src/DSWindowShell/DSWindowShellPrivate.h b/src/DSWindowShell/DSWindowShellPrivate.h index 25e27ae..5057859 100644 --- a/src/DSWindowShell/DSWindowShellPrivate.h +++ b/src/DSWindowShell/DSWindowShellPrivate.h @@ -38,7 +38,7 @@ struct stWindowAuxHint bool deleted; }; -class DSWindowShellPrivate +class DSWindowShellPrivate : public DSObject { DS_PIMPL_USE_PUBLIC(DSWindowShell) @@ -126,6 +126,7 @@ private: bool __create(int x, int y, unsigned int w, unsigned int h, DSWindowShell *pWin, DSWindowShell *pParent); bool __findInChildList(DSWindowShell *parentWinShell); bool __setParent(DSWindowShell *parentWinShell); + void __onWindowBufferChanged(std::shared_ptr buffer); struct stWindowAuxHint* __findAuxHint(int32_t id); void __handleAuxHint(stWindowAuxHint *hint); @@ -141,6 +142,9 @@ private: unsigned int __reqW, __reqH; // requested size by client DSWindowShell *__parent; int __layer; + bool __firstCommit; + bool __changedGeometry; + bool __visible; std::list __childList; std::list __auxHintsList; }; -- 2.7.4 From f5868e767fd2e51ea80f06cde3ac82b6c0488315 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 28 Aug 2020 13:04:31 +0900 Subject: [PATCH 08/16] DSWindowShell: make sendConfigure method be a private method Change-Id: I0d539c18a74c93fac6d53d1f6a2b072651f0ca9c --- src/DSWindowShell/DSWindowShell.cpp | 8 -------- src/DSWindowShell/DSWindowShell.h | 2 -- src/DSWindowShell/DSWindowShellPrivate.cpp | 6 +++--- src/DSWindowShell/DSWindowShellPrivate.h | 6 +++--- 4 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/DSWindowShell/DSWindowShell.cpp b/src/DSWindowShell/DSWindowShell.cpp index 8b9a78b..6798b79 100644 --- a/src/DSWindowShell/DSWindowShell.cpp +++ b/src/DSWindowShell/DSWindowShell.cpp @@ -372,12 +372,4 @@ bool DSWindowShell::getVkbdFloating() return priv->getVkbdFloating(); } -void DSWindowShell::sendConfigure(void) -{ - DS_GET_PRIV(DSWindowShell); - - priv->sendConfigure(); -} - - } // namespace display_server diff --git a/src/DSWindowShell/DSWindowShell.h b/src/DSWindowShell/DSWindowShell.h index 7690094..f2452f7 100644 --- a/src/DSWindowShell/DSWindowShell.h +++ b/src/DSWindowShell/DSWindowShell.h @@ -116,8 +116,6 @@ public: bool setVkbdFloating(bool set); bool getVkbdFloating(); - void sendConfigure(void); - protected: private: diff --git a/src/DSWindowShell/DSWindowShellPrivate.cpp b/src/DSWindowShell/DSWindowShellPrivate.cpp index 65778c3..7435cbf 100644 --- a/src/DSWindowShell/DSWindowShellPrivate.cpp +++ b/src/DSWindowShell/DSWindowShellPrivate.cpp @@ -276,7 +276,7 @@ void DSWindowShellPrivate::setShellSurface(IDSWaylandShellSurface *shellSurface) { __shellSurface = shellSurface; DSLOG_DBG("DSWindowShell", "Set ShellSurface(%p). Send configure", shellSurface); - sendConfigure(); + __sendConfigure(); } IDSWaylandShellSurface *DSWindowShellPrivate::getShellSurface(void) @@ -647,7 +647,7 @@ bool DSWindowShellPrivate::getVkbdFloating() return false; } -void DSWindowShellPrivate::sendConfigure(void) +void DSWindowShellPrivate::__sendConfigure(void) { if (__shellSurface) { @@ -667,7 +667,7 @@ void DSWindowShellPrivate::__onWindowBufferChanged(std::shared_ptr bu { std::shared_ptr bufferSize = buffer->getSize(); DSLOG_DBG("DSWindow", "Geometry Changed!!! Send Configure... geo(%d,%d,%d,%d) commit(%d,%d)", __x, __y, __w, __h, bufferSize->w, bufferSize->h); - sendConfigure(); + __sendConfigure(); __changedGeometry = false; } diff --git a/src/DSWindowShell/DSWindowShellPrivate.h b/src/DSWindowShell/DSWindowShellPrivate.h index 5057859..1d1924c 100644 --- a/src/DSWindowShell/DSWindowShellPrivate.h +++ b/src/DSWindowShell/DSWindowShellPrivate.h @@ -120,18 +120,18 @@ public: bool setVkbdFloating(bool set); bool getVkbdFloating(); - void sendConfigure(void); - private: bool __create(int x, int y, unsigned int w, unsigned int h, DSWindowShell *pWin, DSWindowShell *pParent); bool __findInChildList(DSWindowShell *parentWinShell); bool __setParent(DSWindowShell *parentWinShell); - void __onWindowBufferChanged(std::shared_ptr buffer); + void __sendConfigure(void); struct stWindowAuxHint* __findAuxHint(int32_t id); void __handleAuxHint(stWindowAuxHint *hint); bool __handleUserGeometryHint(bool setUserGeometry); + void __onWindowBufferChanged(std::shared_ptr buffer); + private: DSWindow *__window; IDSWaylandShellSurface *__shellSurface; -- 2.7.4 From 38118b57692a4489e3a2415fccde93dc072a4702 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 28 Aug 2020 13:14:04 +0900 Subject: [PATCH 09/16] DSWindow: remove setWindowShell and getWindowShell methods. bool setWindowShell(DSWindowShell *winShell); DSWindowShell *getWindowShell(void); Change-Id: I64870d9f324619357e2c668d8442ab199b6527b7 --- src/DSWindow/DSWindow.cpp | 31 ------------------------------- src/DSWindow/DSWindow.h | 3 --- src/DSWindow/DSWindowPrivate.h | 4 ---- src/DSZone/DSZone.cpp | 3 --- tests/DSWindow-test.cpp | 6 ------ 5 files changed, 47 deletions(-) diff --git a/src/DSWindow/DSWindow.cpp b/src/DSWindow/DSWindow.cpp index 6267a96..d9e0599 100644 --- a/src/DSWindow/DSWindow.cpp +++ b/src/DSWindow/DSWindow.cpp @@ -43,7 +43,6 @@ DSWindowPrivate::DSWindowPrivate(DSWindow *p_ptr) __created(false), __hasFocus(false), __waylandSurface(nullptr), - __winShell(nullptr), __acceptsFocus(true), __allowUserGeometry(false), __title(""), @@ -161,23 +160,6 @@ bool DSWindowPrivate::isCreated() return __created; } -bool DSWindowPrivate::setWindowShell(DSWindowShell *winShell) -{ - if (__winShell) - { - DSLOG_ERR("DSWindow", "Already exist DSWindowShell..."); - return false; - } - - __winShell = winShell; - return true; -} - -DSWindowShell *DSWindowPrivate::getWindowShell(void) -{ - return __winShell; -} - bool DSWindowPrivate::setVkbdFloating(bool set) { __vkbd_floating = set; @@ -450,19 +432,6 @@ DSWaylandSurface *DSWindow::surface() return priv->__waylandSurface.get(); } - -bool DSWindow::setWindowShell(DSWindowShell *winShell) -{ - DS_GET_PRIV(DSWindow); - return priv->setWindowShell(winShell); -} - -DSWindowShell *DSWindow::getWindowShell(void) -{ - DS_GET_PRIV(DSWindow); - return priv->getWindowShell(); -} - void DSWindow::registerCallbackSizeChanged(DSObject *slot, std::function)> func) { __sizeChangedSignal.connect(slot, func); diff --git a/src/DSWindow/DSWindow.h b/src/DSWindow/DSWindow.h index 2a70cd0..fc4d810 100644 --- a/src/DSWindow/DSWindow.h +++ b/src/DSWindow/DSWindow.h @@ -90,9 +90,6 @@ public: DSWaylandSurface *surface(); - bool setWindowShell(DSWindowShell *winShell); - DSWindowShell *getWindowShell(void); - void registerCallbackSizeChanged(DSObject *slot, std::function)> func); void registerCallbackBufferChanged(DSObject *slot, std::function)> func); void registerCallbackWindowRaiseToTop(DSObject *slot, std::function func); diff --git a/src/DSWindow/DSWindowPrivate.h b/src/DSWindow/DSWindowPrivate.h index a6a8200..3e87830 100644 --- a/src/DSWindow/DSWindowPrivate.h +++ b/src/DSWindow/DSWindowPrivate.h @@ -70,9 +70,6 @@ public: bool setFocus(void); bool isCreated(); - bool setWindowShell(DSWindowShell *winShell); - DSWindowShell *getWindowShell(void); - bool setVkbdFloating(bool set); bool getVkbdFloating(); @@ -89,7 +86,6 @@ private: bool __created; bool __hasFocus; std::shared_ptr __waylandSurface; - DSWindowShell *__winShell; bool __acceptsFocus; bool __allowUserGeometry; std::string __title; diff --git a/src/DSZone/DSZone.cpp b/src/DSZone/DSZone.cpp index 58ce34c..2493f8c 100644 --- a/src/DSZone/DSZone.cpp +++ b/src/DSZone/DSZone.cpp @@ -161,9 +161,6 @@ void DSZone::__onSurfaceCreated(std::shared_ptr waylandSurface // create DSWindowShell std::shared_ptr shell = __createWindowShell(window); - - // set DSWindowShell to DSWindow - window->setWindowShell(shell.get()); } void DSZone::__onSurfaceDestroy(std::shared_ptr waylandSurface) diff --git a/tests/DSWindow-test.cpp b/tests/DSWindow-test.cpp index 88f8b48..1ac52c9 100644 --- a/tests/DSWindow-test.cpp +++ b/tests/DSWindow-test.cpp @@ -119,12 +119,6 @@ TEST_F(DSWindowTest, WindowShellTest) auto winShell = std::make_shared(win.get()); EXPECT_TRUE(winShell != nullptr); - - EXPECT_TRUE(win->setWindowShell(winShell.get()) == true); - - DSWindowShell *getWinShell = nullptr; - getWinShell = win->getWindowShell(); - EXPECT_TRUE(winShell.get() == getWinShell); } TEST_F(DSWindowTest, TitleTest) -- 2.7.4 From a85c49cf9f7be4935972412d67bf2883f50aa555 Mon Sep 17 00:00:00 2001 From: Sung-Jin Park Date: Fri, 28 Aug 2020 10:44:18 +0900 Subject: [PATCH 10/16] DSInput: add winX, winY and get/set APIs for DSInputTouchEvent/DSInputMouseEvent Change-Id: I9a937576f75580a1f13ab7308203bba51df5c5ca Signed-off-by: Sung-Jin Park --- src/DSInput/DSInput.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++---- src/DSInput/DSInputEvent.h | 15 +++++++++++++ 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/DSInput/DSInput.cpp b/src/DSInput/DSInput.cpp index 7a34779..f86c9cf 100644 --- a/src/DSInput/DSInput.cpp +++ b/src/DSInput/DSInput.cpp @@ -505,13 +505,13 @@ void DSInputKeyboardEvent::setKeyname(std::string name) DSInputMouseEvent::DSInputMouseEvent() : DSInputEvent(nullptr, NoneEvent, 0), - __button(0), __x(0), __y(0), __z(0) + __button(0), __x(0), __y(0), __z(0), __winX(0), __winY(0), __winZ(0) { } DSInputMouseEvent::DSInputMouseEvent(std::shared_ptr device, Type type, uint32_t timestamp, int button, int x, int y, int z) : DSInputEvent(device, type, timestamp), - __button(button), __x(x), __y(y), __z(z) + __button(button), __x(x), __y(y), __z(z), __winX(0), __winY(0), __winZ(0) { } @@ -540,16 +540,45 @@ const int DSInputMouseEvent::getZ() return __z; } +const int DSInputMouseEvent::getWinX() +{ + return __winX; +} + +const int DSInputMouseEvent::getWinY() +{ + return __winY; +} + +const int DSInputMouseEvent::getWinZ() +{ + return __winZ; +} + +void DSInputMouseEvent::setWinX(int winX) +{ + __winX = winX; +} + +void DSInputMouseEvent::setWinY(int winY) +{ + __winY = winY; +} + +void DSInputMouseEvent::setWinZ(int winZ) +{ + __winZ = winZ; +} DSInputTouchEvent::DSInputTouchEvent() : DSInputEvent(nullptr, NoneEvent, 0), - __index(0), __x(0), __y(0) + __index(0), __x(0), __y(0), __winX(0), __winY(0) { } DSInputTouchEvent::DSInputTouchEvent(std::shared_ptr device, Type type, uint32_t timestamp, int index, int x, int y) : DSInputEvent(device, type, timestamp), - __index(index), __x(x), __y(y) + __index(index), __x(x), __y(y), __winX(0), __winY(0) { } @@ -572,5 +601,24 @@ const int DSInputTouchEvent::getY() return __y; } +const int DSInputTouchEvent::getWinX() +{ + return __winX; +} + +const int DSInputTouchEvent::getWinY() +{ + return __winY; +} + +void DSInputTouchEvent::setWinX(int winX) +{ + __winX = winX; +} + +void DSInputTouchEvent::setWinY(int winY) +{ + __winY = winY; +} } // namespace display_server diff --git a/src/DSInput/DSInputEvent.h b/src/DSInput/DSInputEvent.h index aa12dc2..1df1f03 100644 --- a/src/DSInput/DSInputEvent.h +++ b/src/DSInput/DSInputEvent.h @@ -96,12 +96,21 @@ public: const int getX(); const int getY(); const int getZ(); + const int getWinX(); + const int getWinY(); + const int getWinZ(); + void setWinX(int winX); + void setWinY(int winY); + void setWinZ(int winZ); protected: int __button; int __x; int __y; int __z; + int __winX; + int __winY; + int __winZ; }; class DSInputTouchEvent : public DSInputEvent @@ -114,11 +123,17 @@ public: const int getIndex(); const int getX(); const int getY(); + const int getWinX(); + const int getWinY(); + void setWinX(int winX); + void setWinY(int winY); protected: int __index; int __x; int __y; + int __winX; + int __winY; }; } -- 2.7.4 From e4ed3575c1e231182da5b17154a1ac4965b9b951 Mon Sep 17 00:00:00 2001 From: Sung-Jin Park Date: Fri, 28 Aug 2020 13:21:00 +0900 Subject: [PATCH 11/16] DSTouch: send touch event with winX, winY coordinates Change-Id: I5e19092c1797d2262dc608686a3bb64bb564b3f7 Signed-off-by: Sung-Jin Park --- src/DSSeat/DSTouch.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/DSSeat/DSTouch.cpp b/src/DSSeat/DSTouch.cpp index c636dd7..37b17fb 100644 --- a/src/DSSeat/DSTouch.cpp +++ b/src/DSSeat/DSTouch.cpp @@ -61,9 +61,10 @@ void DSTouch::processEvent(DSInputTouchEvent *ev, void *data) if (ev->getType() == DSInputEvent::TouchDownEvent) { - DSLOG_DBG("DSTouch", "[touchDown] devicename: %s, timestamp: %u\n", - ev->getDevice()->getName().c_str(), ev->getTimestamp()); - touchDown(ev->getIndex(), ev->getX(), ev->getY()); + DSLOG_DBG("DSTouch", "[touchDown] devicename: %s, timestamp: %u, x: %d (winX: %d), y: %d (winY: %d)\n", + ev->getDevice()->getName().c_str(), ev->getTimestamp(), + ev->getX(), ev->getWinX(), ev->getY(), ev->getWinY()); + touchDown(ev->getIndex(), ev->getWinX(), ev->getWinY()); } else if (ev->getType() == DSInputEvent::TouchUpEvent) { @@ -73,15 +74,16 @@ void DSTouch::processEvent(DSInputTouchEvent *ev, void *data) } else//DSInputEvent::TouchMoveEvent { - DSLOG_DBG("DSTouch", "[touchDown] devicename: %s, timestamp: %u\n", - ev->getDevice()->getName().c_str(), ev->getTimestamp()); - touchMove(ev->getIndex(), ev->getX(), ev->getY()); + DSLOG_DBG("DSTouch", "[touchDown] devicename: %s, timestamp: %u, x: %d (winX: %d), y: %d (winY: %d)\n", + ev->getDevice()->getName().c_str(), ev->getTimestamp(), + ev->getX(), ev->getWinX(), ev->getY(), ev->getWinY()); + touchMove(ev->getIndex(), ev->getWinX(), ev->getWinY()); } } void DSTouch::touchDown(int32_t id, int x, int y) { - if (__dswlTouch) + if (__touchFocus && __dswlTouch) { __dswlTouch->sendDown(id, x, y); } @@ -89,7 +91,7 @@ void DSTouch::touchDown(int32_t id, int x, int y) void DSTouch::touchUp(int32_t id) { - if (__dswlTouch) + if (__touchFocus && __dswlTouch) { __dswlTouch->sendUp(id); } @@ -97,7 +99,7 @@ void DSTouch::touchUp(int32_t id) void DSTouch::touchMove(int32_t id, int x, int y) { - if (__dswlTouch) + if (__touchFocus && __dswlTouch) { __dswlTouch->sendMotion(id, x, y); } -- 2.7.4 From ee75a26177296b0378f0da03ea20e4021f7db773 Mon Sep 17 00:00:00 2001 From: Sung-Jin Park Date: Fri, 28 Aug 2020 13:21:25 +0900 Subject: [PATCH 12/16] DSPointer: send mouse event with winX, winY coordinates Change-Id: Ib327cdf2fd670cfc2cdbdef40bc78c56e7ff5a90 Signed-off-by: Sung-Jin Park --- src/DSSeat/DSPointer.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/DSSeat/DSPointer.cpp b/src/DSSeat/DSPointer.cpp index 12f3c0c..02e3b3b 100644 --- a/src/DSSeat/DSPointer.cpp +++ b/src/DSSeat/DSPointer.cpp @@ -63,9 +63,10 @@ void DSPointer::processEvent(DSInputMouseEvent *ev, void *data) if (ev->getType() == DSInputEvent::MouseInEvent) { - DSLOG_DBG("DSTouch", "[mouseIn] devicename: %s, timestamp: %u\n", - ev->getDevice()->getName().c_str(), ev->getTimestamp()); - mouseIn(ev->getX(), ev->getY()); + DSLOG_DBG("DSTouch", "[mouseIn] devicename: %s, timestamp: %u, x: %d (winX: %d), y: %d (winY: %d)\n", + ev->getDevice()->getName().c_str(), ev->getTimestamp(), + ev->getX(), ev->getWinX(), ev->getY(), ev->getWinY()); + mouseIn(ev->getWinX(), ev->getWinY()); } else if (ev->getType() == DSInputEvent::MouseOutEvent) { @@ -81,9 +82,10 @@ void DSPointer::processEvent(DSInputMouseEvent *ev, void *data) } else if (ev->getType() == DSInputEvent::MouseMoveEvent) { - DSLOG_DBG("DSTouch", "[mouseMove] devicename: %s, timestamp: %u\n", - ev->getDevice()->getName().c_str(), ev->getTimestamp()); - mouseMove(ev->getX(), ev->getY()); + DSLOG_DBG("DSTouch", "[mouseMove] devicename: %s, timestamp: %u, x: %d (winX: %d), y: %d (winY: %d)\n", + ev->getDevice()->getName().c_str(), ev->getTimestamp(), + ev->getX(), ev->getWinX(), ev->getY(), ev->getWinY()); + mouseMove(ev->getWinX(), ev->getWinY()); } else if (ev->getType() == DSInputEvent::MouseUpEvent) { @@ -100,7 +102,7 @@ void DSPointer::processEvent(DSInputMouseEvent *ev, void *data) void DSPointer::mouseDown(uint32_t button) { - if (__dswlPointer) + if (__ptrFocus && __dswlPointer) { __dswlPointer->sendButtonDown(button); } @@ -108,7 +110,7 @@ void DSPointer::mouseDown(uint32_t button) void DSPointer::mouseUp(uint32_t button) { - if (__dswlPointer) + if (__ptrFocus && __dswlPointer) { __dswlPointer->sendButtonUp(button); } @@ -116,7 +118,7 @@ void DSPointer::mouseUp(uint32_t button) void DSPointer::mouseMove(int x, int y) { - if (__dswlPointer) + if (__ptrFocus && __dswlPointer) { __dswlPointer->sendMotion(x, y); } -- 2.7.4 From 90ffb8cc80cbe5f6df404c51abcd01aef519c922 Mon Sep 17 00:00:00 2001 From: Sung-Jin Park Date: Fri, 28 Aug 2020 13:22:13 +0900 Subject: [PATCH 13/16] DSWaylandPointer: fix to return if there is no resource for pointer Change-Id: I955b3a312323f3b3327f1bc67848ca137c160fd2 Signed-off-by: Sung-Jin Park --- src/DSWaylandServer/DSWaylandPointer.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/DSWaylandServer/DSWaylandPointer.cpp b/src/DSWaylandServer/DSWaylandPointer.cpp index 186c5cd..f298c43 100644 --- a/src/DSWaylandServer/DSWaylandPointer.cpp +++ b/src/DSWaylandServer/DSWaylandPointer.cpp @@ -124,6 +124,9 @@ void DSWaylandPointerPrivate::pointer_release(Resource *resource) void DSWaylandPointerPrivate::sendEnter(struct ::wl_resource *wlResource, struct ::wl_resource *surface, int surface_x, int surface_y) { + if (!__wlPointerResource) + return; + wl_fixed_t surface_x_fixed = wl_fixed_from_int(surface_x); wl_fixed_t surface_y_fixed = wl_fixed_from_int(surface_y); @@ -132,11 +135,17 @@ void DSWaylandPointerPrivate::sendEnter(struct ::wl_resource *wlResource, struct void DSWaylandPointerPrivate::sendLeave(struct ::wl_resource *wlResource, struct ::wl_resource *surface) { + if (!__wlPointerResource) + return; + send_leave(__wlPointerResource, __compositor->nextSerial(), surface); } void DSWaylandPointerPrivate::sendMotion(int surface_x, int surface_y) { + if (!__wlPointerResource) + return; + wl_fixed_t surface_x_fixed = wl_fixed_from_int(surface_x); wl_fixed_t surface_y_fixed = wl_fixed_from_int(surface_y); @@ -145,6 +154,9 @@ void DSWaylandPointerPrivate::sendMotion(int surface_x, int surface_y) void DSWaylandPointerPrivate::sendButton(uint32_t button, uint32_t state) { + if (!__wlPointerResource) + return; + send_button(__wlPointerResource, __compositor->nextSerial(), __seat->getCurrentEventTime(), button, state); } -- 2.7.4 From 19cc7a2f2f566cb06bee57990ed1f7def2b46246 Mon Sep 17 00:00:00 2001 From: Sung-Jin Park Date: Fri, 28 Aug 2020 13:23:37 +0900 Subject: [PATCH 14/16] DSSeat: set winX/winY before sending event(s) to touch/pointer Change-Id: I1254f9f1070118317d0007fa117381e9e3f34a31 Signed-off-by: Sung-Jin Park --- src/DSSeat/DSSeat.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/DSSeat/DSSeat.cpp b/src/DSSeat/DSSeat.cpp index 0030478..599d32b 100644 --- a/src/DSSeat/DSSeat.cpp +++ b/src/DSSeat/DSSeat.cpp @@ -425,7 +425,19 @@ void DSSeat::__onPointerEvent(DSInputMouseEvent *ev) //set the window as pointer focus window if (window) + { + int winX; + int winY; + stPosition pos; + + pos = window->getPosition(); + winX = ev->getX() - pos.x; + winY = ev->getY() - pos.y; + ev->setWinX(winX); + ev->setWinY(winY); + __pointer->setFocus(window); + } //send pointer enter to the new pointer focus window std::shared_ptr evMouseIn = std::make_shared(ev->getDevice(), DSInputEvent::MouseInEvent, ev->getTimestamp(), ev->getButton(), 0, 0, 0); @@ -454,7 +466,19 @@ void DSSeat::__onTouchEvent(DSInputTouchEvent *ev) //set the window as touch focus window if (window) + { + int winX; + int winY; + stPosition pos; + + pos = window->getPosition(); + winX = ev->getX() - pos.x; + winY = ev->getY() - pos.y; + ev->setWinX(winX); + ev->setWinY(winY); + __touch->setFocus(window); + } //TODO : emit touch focus changed signal } -- 2.7.4 From 665b841b86489f4315a776cf59b4af6c5734a590 Mon Sep 17 00:00:00 2001 From: dyamy-lee Date: Thu, 20 Aug 2020 12:49:43 +0900 Subject: [PATCH 15/16] add code for TraceProtocol checked rule init with file. logs are alot. -> It should be removed almost for readablilty add rule_print_func as DSLOG_INF -> It should be printed Change-Id: I11985d3e0420758c7f641ec7e4b1ba6187f5afc0 --- src/DSWaylandServer/DSWaylandProtocolTrace.cpp | 1436 +++++++++++++++++++- src/DSWaylandServer/DSWaylandProtocolTrace.h | 1 + .../DSWaylandProtocolTracePrivate.h | 246 +++- 3 files changed, 1674 insertions(+), 9 deletions(-) diff --git a/src/DSWaylandServer/DSWaylandProtocolTrace.cpp b/src/DSWaylandServer/DSWaylandProtocolTrace.cpp index 0f8c9a6..fe89016 100644 --- a/src/DSWaylandServer/DSWaylandProtocolTrace.cpp +++ b/src/DSWaylandServer/DSWaylandProtocolTrace.cpp @@ -23,6 +23,8 @@ #include "DSWaylandProtocolTrace.h" #include "DSWaylandProtocolTracePrivate.h" +#include +#include namespace display_server { @@ -31,10 +33,69 @@ int DSWaylandProtocolTrace::__refCount { 0 }; std::mutex DSWaylandProtocolTrace::__mutex; DSWaylandProtocolTrace* DSWaylandProtocolTrace::__protocolTrace { nullptr }; +static FILE *log_fp_ptrace = NULL; +static struct wl_protocol_logger *ds_wl_protocol_logger; +static ProtocolTrace_Rule_Checker *rc = nullptr; + +static struct +{ + const char *token_char; + const int token_length; + ProtocolTrace_Token token_name; +} token_table[] = +{ + {"\0", 1, PROTOCOLTRACE_TOKEN_EOS}, + {"\t", 1, PROTOCOLTRACE_TOKEN_SPACE}, + {" ", 1, PROTOCOLTRACE_TOKEN_SPACE}, + {"!=", 2, PROTOCOLTRACE_TOKEN_NOT_EQ}, + {"&", 1, PROTOCOLTRACE_TOKEN_AND}, + {"&&", 2, PROTOCOLTRACE_TOKEN_AND}, + {"(", 1, PROTOCOLTRACE_TOKEN_L_BR}, + {")", 1, PROTOCOLTRACE_TOKEN_R_BR}, + {"<", 1, PROTOCOLTRACE_TOKEN_LSS_THAN}, + {"<=", 2, PROTOCOLTRACE_TOKEN_LSS_EQ}, + {"<>", 2, PROTOCOLTRACE_TOKEN_NOT_EQ}, + {"=", 1, PROTOCOLTRACE_TOKEN_EQUAL}, + {"==", 2, PROTOCOLTRACE_TOKEN_EQUAL}, + {">", 1, PROTOCOLTRACE_TOKEN_GRT_THAN}, + {">=", 2, PROTOCOLTRACE_TOKEN_GRT_EQ}, + {"and", 3, PROTOCOLTRACE_TOKEN_AND}, + {"or", 2, PROTOCOLTRACE_TOKEN_OR}, + {"|", 1, PROTOCOLTRACE_TOKEN_OR}, + {"||", 2, PROTOCOLTRACE_TOKEN_OR}, +}; + +const char *get_next_argument(const char *signature, struct argument_details *details) +{ + details->nullable = 0; + for(; *signature; ++signature) + { + switch(*signature) + { + case 'i': + case 'u': + case 'f': + case 's': + case 'o': + case 'n': + case 'a': + case 'h': + details->type = *signature; + return signature +1; + case '?': + details->nullable = 1; + } + } + details->type = '\0'; + return signature; +} + DSWaylandProtocolTrace::DSWaylandProtocolTrace(DSObject *parent) : DS_INIT_PRIVATE_PTR(DSWaylandProtocolTrace) { //init(); + DS_GET_PRIV(DSWaylandProtocolTrace); + priv->__wlCompositor = DSWaylandCompositor::getInstance(); } DSWaylandProtocolTrace::~DSWaylandProtocolTrace() @@ -74,12 +135,72 @@ void DSWaylandProtocolTrace::releaseInstance() bool DSWaylandProtocolTrace::init(void) { - return false; + DS_GET_PRIV(DSWaylandProtocolTrace); + bool ret = false; + char *env_path = nullptr; + char tmp[PATH_MAX] = {0,}; + + rc = priv->rulechecker_init(); + + // set rule file path + env_path = getenv("E_INFO_RULE_FILE"); + DSLOG_DBG("DSWaylandProtocolTrace", "========================== rule file path = %s", env_path); + ret = priv->protocol_rule_init(env_path); + DSLOG_DBG("DSWaylandProtocolTrace", "result of protocol rule init = %d", ret); + + if(env_path) + { + DSLOG_DBG("DSWaylandProtocolTrace", "delete rule file path = %s", env_path); + //delete env_path; + //free(env_path); + env_path = nullptr; + DSLOG_DBG("DSWaylandProtocolTrace", "delete rule file path done."); + } + if(!ret) return ret; + + // set trace file path + DSLOG_DBG("DSWaylandProtocolTrace", "===================================================="); + env_path = getenv("E_INFO_TRACE_FILE"); + DSLOG_DBG("DSWaylandProtocolTrace", "========================== trace file path = %s", env_path); + ret = priv->protocol_trace_init(env_path); + DSLOG_DBG("DSWaylandProtocolTrace", "result of protocol trace init = %d", ret); + if(env_path) + { + DSLOG_DBG("DSWaylandProtocolTrace", "delete trace file path = %s", env_path); + //delete env_path; + //free(env_path); + env_path = nullptr; + DSLOG_DBG("DSWaylandProtocolTrace", "delete trace file path done."); + } + return ret; } int DSWaylandProtocolTrace::enableProtocolTrace(bool state) { + DS_GET_PRIV(DSWaylandProtocolTrace); //following state : enable, disable trace + DSLOG_DBG("DSWaylandProtocolTrace", "state = %d", state); + + if(log_fp_ptrace != nullptr) + { + fclose(log_fp_ptrace); + log_fp_ptrace = nullptr; + } + + if(state) + { + //TODO: can change trace file path by cmd + DSLOG_DBG("DSWaylandProtocolTrace", "state true == %d", state); + priv->protocol_trace_set(); + return 1; + } + else + { + DSLOG_DBG("DSWaylandProtocolTrace", "state false == %d", state); + priv->protocol_trace_unset(); + return 0; + } + return -1; } @@ -94,20 +215,1325 @@ DSWaylandProtocolTracePrivate::~DSWaylandProtocolTracePrivate() } -void DSWaylandProtocolTracePrivate::protocol_rule_init(char *rule_path) +bool DSWaylandProtocolTracePrivate::protocol_rule_init(char *rule_path) +{ + char *argv[2]; + int argc = 2; + + if(!rule_path || strlen(rule_path) <= 0) + return false; + + argv[0] = "file"; + argv[1] = rule_path; + + DSLOG_DBG("DSWaylandProtocolTracePriv", "rule_path = %s", rule_path); + + protocol_rule_set(argc, (const char**)&(argv[0])); + + return true; +} + +bool DSWaylandProtocolTracePrivate::protocol_trace_init(char *trace_path) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> protocol_trace_init"); + if(!trace_path || strlen(trace_path) <= 0) + return false; + + trace_env_path = trace_path; + DSLOG_DBG("DSWaylandProtocolTracePriv", "saved trace path = %s", trace_env_path); + + //enable + protocol_trace_set(); + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << protocol_trace_init"); + /* + log_fp_ptrace = fopen(trace_path, "a"); + + setvbuf(log_fp_ptrace, NULL, _IOLBF, 512); + + if(ds_wl_protocol_logger) + { + wl_protocol_logger_destroy(ds_wl_protocol_logger); + ds_wl_protocol_logger = NULL; + } + ::wl_display *display; + display = __wlCompositor->display(); + ds_wl_protocol_logger = wl_display_add_protocol_logger(display, protocol_trace_func, nullptr); + */ + return true; +} + +bool DSWaylandProtocolTracePrivate::protocol_rule_set(const int argc, const char **argv) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> protocol_rule_set"); + const char * command; + + if(argc == 0) + { + rulechecker_rule_print(rc); + return true; + } + + command = argv[0]; + + if(!strcasecmp(command, "add")) + { + DSLOG_DBG("DSWaylandProtocolTracePriv", "ADD"); + ProtocolTrace_Policy_Type policy_type; + ProtocolTrace_Rule_Set_Result result; + const char * policy = argv[1]; //allow, deny + char merge[8192] = {0,}, rule[8192] = {0,}; + int i, index=0, size_rule, apply = 0; + + if(argc <3) + { + DSLOG_ERR("DSWaylandProtocolTracePriv", "Error: Too few argumens."); + //REPLY("Error : Too few arguments."); + return false; + } + DSLOG_DBG("DSWaylandProtocolTracePriv", "ADD :: go on"); + + if(!strcasecmp(policy, "ALLOW")) + policy_type = PROTOCOLTRACE_TYPE_ALLOW; + else if(!strcasecmp(policy, "DENY")) + policy_type = PROTOCOLTRACE_TYPE_DENY; + else + { + DSLOG_ERR("DSWaylandProtocolTracePriv", "Error : Unknown policy : [%s].\n Policy should be ALLOW or DENY.", policy); + //REPLY; + return false; + } + DSLOG_DBG("DSWaylandProtocolTracePriv", "ADD :: policy_type = %d", policy_type); + + // protocol arguments merge + protocol_arguments_merge(merge, sizeof(merge), argc -2, &(argv[2])); + DSLOG_DBG("DSWaylandProtocolTracePriv", "ADD :: merge = %s", merge); + + size_rule = sizeof(rule) -1; + DSLOG_DBG("DSWaylandProtocolTracePriv", "ADD :: size_rule = %d", size_rule); + + for(i=0; i size_rule) + return false; + continue; + } + if(merge[i] == '+') + { + rule[index++] = ' '; + if(index > size_rule) + return false; + if(apply ==0) + { + const char * plus = "|| type=reply || type=error"; + int len = MIN(size_rule - index, strlen(plus)); + strncat(rule, plus, len); + index += len; + if(index >size_rule) + return false; + apply =1; + } + continue; + } + rule[index++] = merge[i]; + DSLOG_DBG("DSWaylandProtocolTracePriv", "ADD :: rule[%d] = %c", index-1, rule[index-1]); + if(index >size_rule) + return false; + } + DSLOG_DBG("DSWaylandProtocolTracePriv", "ADD :: rule = %s", rule); + + DSLOG_DBG("DSWaylandProtocolTracePriv", "ADD :: rulechecker_rule_add (before) -> rc %d",rc->count); + result = rulechecker_rule_add(rc, policy_type, rule); + DSLOG_DBG("DSWaylandProtocolTracePriv", "ADD :: rulechecker_rule_add (after) -> rc %d",rc->count); + + if(result == PROTOCOLTRACE_RULE_SET_ERR_TOO_MANY_RULES) + { + DSLOG_ERR("DSWaylandProtocolTracePriv", "Error: Too many rules were added."); + return false; + } + else if(result == PROTOCOLTRACE_RULE_SET_ERR_PARSE) + { + DSLOG_ERR("DSWaylandProtocolTracePriv", "Error: An error occured during parsing the rule [%s]", rule); + return false; + } + DSLOG_INF("DSWaylandProtocolTracePriv", "The rule was successfully added"); + rulechecker_rule_print(rc); + + return true; + } + else if(!strcasecmp(command, "remove")) + { + DSLOG_DBG("DSWaylandProtocolTracePriv", "REMOVE"); + const char * remove_idx; + int i; + + if(argc < 2) + { + DSLOG_ERR("DSWaylandProtocolTracePriv", "Error: Too few arguments"); + return false; + } + + for(i =0; icount); + rulechecker_destroy(rc); + rc = rulechecker_init(); + if(!rc) + { + DSLOG_ERR("DSWaylandProtocolTracePriv", "Error: rules not removed"); + return false; + } + DSLOG_DBG("DSWaylandProtocolTracePriv", "REMOVE :: (after destroy) rc = %d", rc->count); + DSLOG_INF("DSWaylandProtocolTracePriv", "Every rules were successfully removed"); + } + else + { + int index = atoi(remove_idx); + DSLOG_DBG("DSWaylandProtocolTracePriv", "REMOVE :: remove idx = %d", index); + + DSLOG_DBG("DSWaylandProtocolTracePriv", "REMOVE :: (before rulechecker_rule_remove) rc = %d", rc->count); + if(isdigit(*remove_idx) && rulechecker_rule_remove(rc, index) == 0) + DSLOG_INF("DSWaylandProtocolTracePriv", "The rule [%d] was successfully removed.", index); + else + DSLOG_ERR("DSWaylandProtocolTracePriv", "Rule remove fail : No such rule [%s]", remove_idx); + + DSLOG_DBG("DSWaylandProtocolTracePriv", "REMOVE :: (after rulechecker_rule_remove) rc = %d", rc->count); + } + } + rulechecker_rule_print(rc); + } + else if(!strcasecmp(command, "file")) + { + DSLOG_DBG("DSWaylandProtocolTracePriv", "FILE"); + if(argc <2) + { + DSLOG_ERR("DSWaylandProtocolTracePriv", "Error: Too few argumens."); + //REPLY("Error : Too few arguments."); + return false; + } + if(!protocol_rule_file_set(argv[1])) + return false; + + rulechecker_rule_print(rc); + + return true; + } + else if(!strcasecmp(command, "print")) + { + rulechecker_rule_print(rc); + return true; + } + else if(!strcasecmp(command, "help")) + { + DSLOG_INF("DSWaylandProtocolTracePriv", "%s", rulechecker_usage_print()); + return true; + } + + DSLOG_ERR("DSWaylandProtocolTracePriv", "%s\nUnkown command : [%s] ", rulechecker_usage_print(), command); + + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << protocol_rule_set"); + + return true; +} + +bool DSWaylandProtocolTracePrivate::protocol_rule_file_set(const char *filename) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> protocol_rule_file_set"); + int fd = -1, rule_len; + char fs[8096], *pfs; + + fd = open(filename, O_RDONLY); + if(fd<0) + { + DSLOG_DBG("DSWaylandProtocolTracePriv", "failed: open '%s'", filename); + return false; + } + + rule_len = read(fd, fs, sizeof(fs)); + pfs = fs; + + while(pfs -fs < rule_len) + { + int i, new_argc =3; + char *new_argv[3] = {"add", }; + char policy[64] = {0,}; + char rule[1024] = {0,}; + + if(pfs[0] == ' ' || pfs[0] == '\n') + { + pfs++; + continue; + } + for(i=0; pfs[i] != ' '; i++) + policy[i] = pfs[i]; + + new_argv[1] = policy; + pfs += (strlen(new_argv[1])+1); + + memset(rule, 0, sizeof(rule)); + for(i=0; pfs[i]!='\n'; i++) + rule[i] = pfs[i]; + + new_argv[2] = rule; + + pfs += (strlen(new_argv[2]) +1); + + if(!protocol_rule_set((const int) new_argc, (const char**) new_argv)) + { + close(fd); + return false; + } + } + close(fd); + + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << protocol_rule_file_set"); + return true; +} + +bool DSWaylandProtocolTracePrivate::protocol_rule_validate(ProtocolTrace_Protocol_Log *log) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> protocol_rule_validate << "); + char *cmd = ""; + + if(!rc) + return false; + + cmd = protocol_cmd_get(log->cmd); + + return rulechecker_rule_validate(rc, log->type, log->target_id, log->name, log->client_pid, cmd); +} + +void DSWaylandProtocolTracePrivate::protocol_trace_set(void) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv","IN >> protocol trace set"); + log_fp_ptrace = fopen(trace_env_path, "a"); + if(!log_fp_ptrace) + { + DSLOG_ERR("DSWaylandProtocolTracePriv","failed open file(%s)", trace_env_path); + return; + } + setvbuf(log_fp_ptrace, NULL, _IOLBF, 512); + DSLOG_DBG("DSWaylandProtocolTracePriv","has log_fp_ptrace"); + + if(ds_wl_protocol_logger) + { + DSLOG_DBG("DSWaylandProtocolTracePriv","if has ds_wl_protocol_logger -> destroy"); + wl_protocol_logger_destroy(ds_wl_protocol_logger); + ds_wl_protocol_logger = NULL; + } + ::wl_display *display; + display = __wlCompositor->display(); + DSLOG_DBG("DSWaylandProtocolTracePriv","get display "); + + ds_wl_protocol_logger = wl_display_add_protocol_logger(display, protocol_trace_func, nullptr); + DSLOG_DBG("DSWaylandProtocolTracePriv","OUT << protocol trace set"); +} + +void DSWaylandProtocolTracePrivate::protocol_trace_unset(void) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv","IN >> protocol_trace_unset"); + if(ds_wl_protocol_logger) + { + wl_protocol_logger_destroy(ds_wl_protocol_logger); + ds_wl_protocol_logger = NULL; + } + DSLOG_DBG("DSWaylandProtocolTracePriv","OUT << protocol_trace_unset"); +} + +void DSWaylandProtocolTracePrivate::wl_protocol_cb_client_destroy(struct wl_listener *listener, void *data) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv","IN >> wl_protocol_cb_client_destroy"); + + struct wl_client *wc = (struct wl_client *)data; + struct timespec tp; + unsigned int time; + pid_t client_pid =-1; + + + char strbuf[512], *str_buff = strbuf; + int str_r, str_l; + + str_buff[0] = '\0'; + str_r = sizeof(strbuf); + + wl_client_get_credentials(wc, &client_pid, nullptr, nullptr); + + clock_gettime(CLOCK_MONOTONIC, &tp); + time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000); + + //TODO: get client name + BUF_SNPRINTF("[%10.3f] Server [PID:%d] client destroying", time/1000.0, client_pid); + + if(log_fp_ptrace) + fprintf(log_fp_ptrace, "%s\n", strbuf); + else + DSLOG_INF("DSWaylandProtocolTracePriv", "%s", strbuf); + + wl_list_remove(&listener->link); + //free(listener); + delete listener; + listener = nullptr; + + DSLOG_DBG("DSWaylandProtocolTracePriv","OUT << wl_protocol_cb_client_destroy"); + +} + +void DSWaylandProtocolTracePrivate::protocol_client_destroy_listener_reg(struct wl_client *client) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv","IN >> protocol_client_destroy_listener_reg"); + + struct wl_listener *destroy_listener; + + destroy_listener = wl_client_get_destroy_listener(client, wl_protocol_cb_client_destroy); + if(destroy_listener) return; + + destroy_listener = (struct wl_listener *)calloc(1, sizeof(wl_listener)); + //EINA_SAFETY_ON_NULL_RETURN(destroy_listener); + + destroy_listener->notify = wl_protocol_cb_client_destroy; + wl_client_add_destroy_listener(client, destroy_listener); + + DSLOG_DBG("DSWaylandProtocolTracePriv","OUT << protocol_client_destroy_listener_reg"); +} + +void DSWaylandProtocolTracePrivate::protocol_trace_func(void *user_data, enum wl_protocol_logger_type direction, const struct wl_protocol_logger_message *message) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv","IN >> protocol_trace_func"); + + int i; + struct argument_details arg; + struct wl_client *wc = wl_resource_get_client(message->resource); + const char *signature = message->message->signature; + pid_t client_pid = -1; + struct timespec tp; + unsigned int time; + + char strbuf[512], *str_buff = strbuf; + int str_r, str_l; + + str_buff[0] = '\0'; + str_r = sizeof(strbuf); + + if(wc) + { + DSLOG_DBG("DSWaylandProtocolTracePriv","has wl_client"); + protocol_client_destroy_listener_reg(wc); + wl_client_get_credentials(wc, &client_pid, nullptr, nullptr); + } + + DSLOG_DBG("DSWaylandProtocolTracePriv","go on"); + + clock_gettime(CLOCK_MONOTONIC, &tp); + time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000); + + ProtocolTrace_Protocol_Log elog = {PROTOCOL_TYPE_REQUEST,}; + DSLOG_DBG("DSWaylandProtocolTracePriv", "before get info protocol log => type: %s, client_pit: %d, target_id: %d, name: %s, cmd: %s", elog.type, elog.client_pid, elog.target_id, elog.name, elog.cmd); + elog.type = (direction == WL_PROTOCOL_LOGGER_EVENT)? PROTOCOL_TYPE_EVENT:PROTOCOL_TYPE_REQUEST; + elog.client_pid = client_pid; + elog.target_id = wl_resource_get_id(message->resource); + snprintf(elog.name, PATH_MAX,"%s:%s", wl_resource_get_class(message->resource), message->message->name); + + DSLOG_DBG("DSWaylandProtocolTracePriv", "after get info protocol log => type: %s, client_pit: %d, target_id: %d, name: %s, cmd: %s", elog.type, elog.client_pid, elog.target_id, elog.name, elog.cmd); + + if(!protocol_rule_validate(&elog)) return; + + BUF_SNPRINTF("[%10.3f] %s%d%s%s@%u.%s(", + time / 1000.0, + elog.type ? "Server->Client [PID:" : "Server<-Client [PID:", + client_pid, "]", + wl_resource_get_class(message->resource), + wl_resource_get_id(message->resource), + message->message->name); + + for (i=0; iarguments_count; i++) + { + signature = get_next_argument(signature, &arg); + if(i>0) BUF_SNPRINTF(", "); + + switch(arg.type) + { + case 'u': + BUF_SNPRINTF("%u", message->arguments[i].u); + break; + case 'i': + BUF_SNPRINTF("%i", message->arguments[i].i); + break; + case 'f': + BUF_SNPRINTF("%f", wl_fixed_to_double(message->arguments[i].f)); + break; + case 's': + BUF_SNPRINTF("\"%s\"", message->arguments[i].s); + break; + case 'o': + if(message->arguments[i].o) + BUF_SNPRINTF("%s@%u", wl_resource_get_class((struct wl_resource*)message->arguments[i].o), + wl_resource_get_id((struct wl_resource*)message->arguments[i].o)); + else + BUF_SNPRINTF("nil"); + break; + case 'n': + BUF_SNPRINTF("new id %s@", (message->message->types[i]) ? message->message->types[i]->name : "[unknown]"); + if(message->arguments[i].n != 0) + BUF_SNPRINTF("%u", message->arguments[i].n); + else + BUF_SNPRINTF("nil"); + break; + case 'a': + BUF_SNPRINTF("array"); + break; + case 'h': + BUF_SNPRINTF("fd %d", message->arguments[i].h); + break; + } + } + + BUF_SNPRINTF("), cmd: %s", elog.cmd ? elog.cmd : "cmd is NULL"); + + if(log_fp_ptrace) + fprintf(log_fp_ptrace, "%s\n", strbuf); + else + DSLOG_INF("DSWaylandProtocolTracePriv","%s", strbuf); + + DSLOG_DBG("DSWaylandProtocolTracePriv","OUT << protocol_trace_func"); + +} + +ProtocolTrace_Tree_Node *DSWaylandProtocolTracePrivate::bintree_create_node(ProtocolTrace_Tree *tree) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv","IN >> bintree_create_node"); + + ProtocolTrace_Tree_Node *node = (ProtocolTrace_Tree_Node*) calloc(1, sizeof(ProtocolTrace_Tree_Node) + tree->size); + // enia safety + + node->left = nullptr; + node->right = nullptr; + + DSLOG_DBG("DSWaylandProtocolTracePriv","OUT << bintree_create_node"); + return node; +} + +ProtocolTrace_Tree *DSWaylandProtocolTracePrivate::bintree_create_tree(int size) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_create_tree"); + + ProtocolTrace_Tree *tree = (ProtocolTrace_Tree *)calloc(1, sizeof(ProtocolTrace_Tree) + size); + // eina safety + + tree->size = size; + tree->head = nullptr; + DSLOG_DBG("DSWaylandProtocolTracePriv", "bintree create treee => size : %d", tree->size); + + DSLOG_DBG("DSWaylandProtocolTracePriv","OUT << bintree_create_tree"); + + return tree; +} + +void DSWaylandProtocolTracePrivate::bintree_destroy_tree(ProtocolTrace_Tree *tree) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_destroy_tree"); + if(tree->head) + bintree_remove_node_recursive(tree->head); + //free(tree); + delete tree; + + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << bintree_destroy_tree"); +} + +ProtocolTrace_Tree_Node *DSWaylandProtocolTracePrivate::bintree_get_head(ProtocolTrace_Tree *tree) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_get_head >> OUT"); + return tree->head; +} + +ProtocolTrace_Tree_Node *DSWaylandProtocolTracePrivate::bintree_get_left_child(ProtocolTrace_Tree_Node *node) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_get_left_child >> OUT"); + return node->left; +} + +void *DSWaylandProtocolTracePrivate::bintree_get_node_data(ProtocolTrace_Tree_Node *node) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_get_node_data >> OUT"); + return (void*)(node+1); +} + +ProtocolTrace_Tree_Node *DSWaylandProtocolTracePrivate::bintree_get_right_child(ProtocolTrace_Tree_Node *node) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_get_right_child >> OUT"); + return node->right; +} + +void DSWaylandProtocolTracePrivate::bintree_inorder_traverse(ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Traverse_Cb func, void *arg) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_inorder_traverse"); + if(tree->head) + bintree_inorder_traverse_recursive(tree, tree->head, tree->head, func, arg); + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << bintree_inorder_traverse"); +} + +int DSWaylandProtocolTracePrivate::bintree_inorder_traverse_recursive(ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Node *node, ProtocolTrace_Tree_Node *parent, ProtocolTrace_Tree_Traverse_Cb func, void *arg) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_inorder_traverse_recursive >> "); + if(node->left) + if(bintree_inorder_traverse_recursive(tree, node->left, node, func, arg)!=0) + return 1; + + if(func(tree, node, parent, arg)) + return 1; + + if(node->right) + if(bintree_inorder_traverse_recursive(tree,node->right, node, func, arg)!=0) + return 1; + return 0; +} + +void DSWaylandProtocolTracePrivate::bintree_postorder_traverse(ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Traverse_Cb func, void *arg) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_postorder_traverse"); + if(tree->head) + bintree_postorder_traverse_recursive(tree, tree->head, tree->head, func, arg); + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << bintree_postorder_traverse"); +} + +int DSWaylandProtocolTracePrivate::bintree_postorder_traverse_recursive(ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Node *node, ProtocolTrace_Tree_Node *parent, ProtocolTrace_Tree_Traverse_Cb func, void *arg) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_postorder_traverse_recursive >> "); + if(node->left) + if(bintree_postorder_traverse_recursive(tree, node->left, node, func, arg)!=0) + return 1; + if(node->right) + if(bintree_postorder_traverse_recursive(tree, node->right, node, func, arg)!=0) + return 1; + + return func(tree, node,parent, arg); +} + +void DSWaylandProtocolTracePrivate::bintree_remove_node(ProtocolTrace_Tree_Node *node) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_remove_node"); + //free(node); + delete node; + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << bintree_remove_node"); +} + +void DSWaylandProtocolTracePrivate::bintree_remove_node_recursive(ProtocolTrace_Tree_Node *node) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_remove_node_recursive"); + if(node->left) + bintree_remove_node_recursive(node->left); + if(node->right) + bintree_remove_node_recursive(node->right); + + bintree_remove_node(node); + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << bintree_remove_node_recursive"); +} + +void DSWaylandProtocolTracePrivate::bintree_set_head(ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Node *head) { + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_set_head"); + tree->head = head; + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << bintree_set_head"); } -void DSWaylandProtocolTracePrivate::protocol_trace_init(char *trace_path) +void DSWaylandProtocolTracePrivate::bintree_set_left_child(ProtocolTrace_Tree_Node *node, ProtocolTrace_Tree_Node *child) { + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_set_left_child"); + node->left = child; + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << bintree_set_left_child"); +} + +void DSWaylandProtocolTracePrivate::bintree_set_right_child(ProtocolTrace_Tree_Node *node, ProtocolTrace_Tree_Node *child) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> bintree_set_right_child"); + node->right = child; + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << bintree_set_right_child"); +} + +ProtocolTrace_Token DSWaylandProtocolTracePrivate::parser_next_token_get(const char **string) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> parser_next_token_get"); + DSLOG_DBG("DSWaylandProtocolTracePriv", "parameter string = %s",*string); + + static int token_cnt = sizeof(token_table) / sizeof(token_table[0]); + int i, compare_res, found =0, first, last; + + first = 0; + last = token_cnt -1; + + i = (first + last) /2; + while(1) + { + compare_res = strncmp(*string, token_table[i].token_char, token_table[i].token_length); + DSLOG_DBG("DSWaylandProtocolTracePriv", "parser_next_token_get:: i = %d// compare string -> string = %s ,vs, token_char = %s",i,*string, token_table[i].token_char); + while(compare_res == 0) + { + found = 1; + i++; + if(i==token_cnt) + break; + compare_res = strncmp(*string, token_table[i].token_char, token_table[i].token_length); + } + + if(found) + { + i--; + DSLOG_DBG("DSWaylandProtocolTracePriv", "parm string (before)=> %s",*string); + *string += token_table[i].token_length; + DSLOG_DBG("DSWaylandProtocolTracePriv", "parm string (after = add token length) => %s",*string); + DSLOG_DBG("DSWaylandProtocolTracePriv", "parser next token => %d, token_table name = %d",i,token_table[i].token_name); + return token_table[i].token_name; + } + + if(first >= last) + break; + + if(compare_res > 0) + first = i+1; + else + last = i-1; + + i = (first + last) /2; + + } + if(isalpha(**string)) + { + (*string)++; + DSLOG_DBG("DSWaylandProtocolTracePriv", "string is alpha >> next? = %c",**string); + while(isalpha(**string) || isdigit(**string) || **string == '_' || **string == '-') + { + (*string)++; + } + DSLOG_DBG("DSWaylandProtocolTracePriv", "string is alpha >> end alpha = %c",**string); + + return PROTOCOLTRACE_TOKEN_SYMBOL; + } + if(isdigit(**string)) + { + DSLOG_DBG("DSWaylandProtocolTracePriv", "string is digit = %c",**string); + (*string)++; + while(isdigit(**string)) + (*string)++; + + return PROTOCOLTRACE_TOKEN_NUMBER; + } + + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << parser_next_token_get"); + return PROTOCOLTRACE_TOKEN_UNKNOWN; } -void DSWaylandProtocolTracePrivate::protocol_rule_set(void) +ProtocolTrace_Tree *DSWaylandProtocolTracePrivate::protocol_parser_rule_string_parse(const char *string) { + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> protocol_parser_rule_string_parse"); + DSLOG_DBG("DSWaylandProtocolTracePriv", "parameter string = %s", string); + + ProtocolTrace_Tree *tree; + ProtocolTrace_Tree_Node *node; + ProtocolTrace_Token_Data token; + + token.string = &string; + DSLOG_DBG("DSWaylandProtocolTracePriv", "token = %s", *token.string); + parser_token_process(&token); + DSLOG_DBG("DSWaylandProtocolTracePriv", "token(after parser) = %s, %d", *token.string, token.last_token); + + tree = bintree_create_tree(sizeof(ProtocolTrace_Rule_Node)); + if(!tree) return nullptr; + + node = parser_token_parse(tree, &token); + DSLOG_DBG("DSWaylandProtocolTracePriv", "get node"); + + if(!node) + { + DSLOG_DBG("DSWaylandProtocolTracePriv", "node is null"); + bintree_destroy_tree(tree); + DSLOG_DBG("DSWaylandProtocolTracePriv", "finish destroy tree & return null"); + return nullptr; + } + + bintree_set_head(tree, node); + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << protocol_parser_rule_string_parse "); + + return tree; } -void DSWaylandProtocolTracePrivate::protocol_rule_file_set(void) +ProtocolTrace_Tree_Node *DSWaylandProtocolTracePrivate::parser_statement_parse(ProtocolTrace_Tree *tree, ProtocolTrace_Token_Data *token) { + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> parser_statement_parse"); + DSLOG_DBG("DSWaylandProtocolTracePriv", "(parameter) token->string = %s, token->last symbol =%s", *token->string, token->last_symbol); + DSLOG_DBG("DSWaylandProtocolTracePriv", "(parameter) tree_size = %d", tree->size); + + ProtocolTrace_Tree_Node *node = nullptr; + ProtocolTrace_Rule_Node *data; + + if(token->last_token == PROTOCOLTRACE_TOKEN_L_BR) + { + DSLOG_DBG("DSWaylandProtocolTracePriv", "last token = %d", PROTOCOLTRACE_TOKEN_L_BR); + parser_token_process(token); + + node = parser_token_parse(tree, token); + if(!node) + return nullptr; + + if(token->last_token != PROTOCOLTRACE_TOKEN_R_BR) + goto fail; + + DSLOG_DBG("DSWaylandProtocolTracePriv", "not fail"); + parser_token_process(token); + + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << parser_statement_parse"); + return node; + } + + if(token->last_token != PROTOCOLTRACE_TOKEN_SYMBOL) + goto fail; + + node = bintree_create_node(tree); + //eina safty + + data = (ProtocolTrace_Rule_Node *) bintree_get_node_data(node); + + strncpy(data->variable_name, token->last_symbol, token->symbol_len); + data->variable_name[token->symbol_len] = '\0'; + + if(!strcasecmp(data->variable_name, "all")) + { + DSLOG_DBG("DSWaylandProtocolTracePriv", "data = all"); + data->node_type = PROTOCOLTRACE_NODE_TYPE_ALL; + parser_token_process(token); + + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << parser_statement_parse"); + return node; + } + + data->node_type = PROTOCOLTRACE_NODE_TYPE_DATA; + + parser_token_process(token); + + switch(token->last_token) + { + case PROTOCOLTRACE_TOKEN_NOT_EQ: + data->comparer = PROTOCOLTRACE_COMPARER_NOT_EQ; + break; + case PROTOCOLTRACE_TOKEN_EQUAL: + data->comparer = PROTOCOLTRACE_COMPARER_EQUAL; + break; + case PROTOCOLTRACE_TOKEN_LSS_THAN: + data->comparer = PROTOCOLTRACE_COMPARER_LESS_EQ; + break; + case PROTOCOLTRACE_TOKEN_GRT_THAN: + data->comparer = PROTOCOLTRACE_COMPARER_GREATER; + break; + case PROTOCOLTRACE_TOKEN_GRT_EQ: + data->comparer = PROTOCOLTRACE_COMPARER_GREATE_EQ; + break; + default: + goto fail; + } + + parser_token_process(token); + + if(token->last_token == PROTOCOLTRACE_TOKEN_NUMBER) + { + data->value_type = PROTOCOLTRACE_DATA_TYPE_INTEGER; + data->value.integer = atoi(token->last_symbol); + } + else if (token->last_token == PROTOCOLTRACE_TOKEN_SYMBOL) + { + data->value_type = PROTOCOLTRACE_DATA_TYPE_STRING; + strncpy(data->value.string, token->last_symbol, token->symbol_len); + data->value.string[token->symbol_len] = '\0'; + } + else + { + goto fail; + } + + parser_token_process(token); + + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << parser_statement_parse"); + return node; + fail: + if(node) + bintree_remove_node_recursive(node); + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << parser_statement_parse"); + return nullptr; +} + +ProtocolTrace_Tree_Node *DSWaylandProtocolTracePrivate::parser_token_parse(ProtocolTrace_Tree *tree, ProtocolTrace_Token_Data *token) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> parser_token_parse"); + DSLOG_DBG("DSWaylandProtocolTracePriv", "(parameter) string = %s, last token = %d, last symbol = %s", *token->string, token->last_token, token->last_symbol); + + ProtocolTrace_Tree_Node *node, *left = nullptr, *right = nullptr; + ProtocolTrace_Rule_Node *data; + + node = parser_statement_parse(tree,token); + + if(!node) + { + DSLOG_ERR("DSWaylandProtocolTracePriv", "PARSE statement error\n"); + goto fail; + } + + while(token->last_token == PROTOCOLTRACE_TOKEN_AND) + { + left = node; + node = nullptr; + + parser_token_process(token); + + right = parser_statement_parse(tree, token); + if(!right) + goto fail; + + node = bintree_create_node(tree); + // eina safety + + data = (ProtocolTrace_Rule_Node *) bintree_get_node_data(node); + data->node_type = PROTOCOLTRACE_NODE_TYPE_AND; + bintree_set_left_child(node, left); + bintree_set_right_child(node, right); + } + + if(token->last_token == PROTOCOLTRACE_TOKEN_OR) + { + left = node; + node = nullptr; + + parser_token_process(token); + + right = parser_token_parse(tree, token); + if(!right) + goto fail; + + node = bintree_create_node(tree); + //eina safety + + data = (ProtocolTrace_Rule_Node *) bintree_get_node_data(node); + data->node_type = PROTOCOLTRACE_NODE_TYPE_OR; + bintree_set_left_child(node, left); + bintree_set_right_child(node, right); + } + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << parser_token_parse"); + return node; + + fail: + DSLOG_DBG("DSWaylandProtocolTracePriv", "[fail] recursive remove node"); + if(left) + bintree_remove_node_recursive(left); + DSLOG_DBG("DSWaylandProtocolTracePriv", "return null"); + return nullptr; +} + +void DSWaylandProtocolTracePrivate::parser_token_process(ProtocolTrace_Token_Data *token) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> parser_token_process"); + do + { + token->last_symbol = *(token->string); + DSLOG_DBG("DSWaylandProtocolTracePriv", "last symbol = %c", token->last_symbol); + token->last_token = parser_next_token_get(token->string); + DSLOG_DBG("DSWaylandProtocolTracePriv", "last token = %d", token->last_token); + token->symbol_len = *(token->string) - token->last_symbol; + DSLOG_DBG("DSWaylandProtocolTracePriv", "last_symbol : %s , last_token : %d, symbol_len : %d", token->last_symbol, token->last_token, token->symbol_len); + } while (token->last_token == PROTOCOLTRACE_TOKEN_SPACE); + + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << parser_token_process"); +} + +void DSWaylandProtocolTracePrivate::protocol_arguments_merge(char *target, int target_size, int argc, const char **argv) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> protocol_arguments_merge"); + DSLOG_DBG("DSWaylandProtocolTracePriv", "(parameter) target = %s", target); + DSLOG_DBG("DSWaylandProtocolTracePriv", "(parameter) target size= %d", target_size); + + int i, len; + + for(i=0; i> protocol_cmd_get"); + char *p; + if(!path) return nullptr; + + p = strrchr(path, '/'); + + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << protocol_cmd_get"); + return (p)?p+1:path; +} + +void DSWaylandProtocolTracePrivate::rulechecker_destroy(ProtocolTrace_Rule_Checker *rc) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> rulechecker_destroy"); + + int i; + for(i=rc->count-1; i>=0; i--) + rulechecker_rule_remove(rc,i); + + //free(rc); + delete rc; + + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << rulechecker_destroy"); +} + +ProtocolTrace_Rule_Checker *DSWaylandProtocolTracePrivate::rulechecker_init() +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> rulechecker_init"); + + ProtocolTrace_Rule_Checker *rc = (ProtocolTrace_Rule_Checker *) calloc(1, sizeof(ProtocolTrace_Rule_Checker)); + if (!rc) + return nullptr; + + rc->count = 0; + + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << rulechecker_init"); + + return rc; +} + +int DSWaylandProtocolTracePrivate::rulechecker_int_compare(ProtocolTrace_Comparer comparer, int int2, int int1) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> rulechecker_int_compare >> "); + + switch (comparer) + { + case PROTOCOLTRACE_COMPARER_EQUAL: + return int1 == int2; + case PROTOCOLTRACE_COMPARER_LESS: + return int1 < int2; + case PROTOCOLTRACE_COMPARER_GREATER: + return int1 > int2; + case PROTOCOLTRACE_COMPARER_LESS_EQ: + return int1 <= int2; + case PROTOCOLTRACE_COMPARER_GREATE_EQ: + return int1 >= int2; + case PROTOCOLTRACE_COMPARER_NOT_EQ: + return int1 != int2; + } + return 0; +} + +ProtocolTrace_Rule_Set_Result DSWaylandProtocolTracePrivate::rulechecker_rule_add(ProtocolTrace_Rule_Checker *rc, ProtocolTrace_Policy_Type policy, const char *rule_string) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> rulechecker_rule_add"); + DSLOG_DBG("DSWaylandProtocolTracePriv", "rc->count = %d", rc->count); + + if(rc->count == MAX_RULE) + return PROTOCOLTRACE_RULE_SET_ERR_TOO_MANY_RULES; + + rc->rules[rc->count].tree = protocol_parser_rule_string_parse(rule_string); + if(!rc->rules[rc->count].tree) + { + DSLOG_DBG("DSWaylandProtocolTracePriv", "parse error"); + return PROTOCOLTRACE_RULE_SET_ERR_PARSE; + } + + rc->rules[rc->count].policy = policy; + rc->count++; + DSLOG_DBG("DSWaylandProtocolTracePriv", "rc->rules[rc->count].policy = %d", rc->rules[rc->count -1].policy); + DSLOG_DBG("DSWaylandProtocolTracePriv", "rc->count = %d", rc->count -1); + + return PROTOCOLTRACE_RULE_SET_OK; +} + +void DSWaylandProtocolTracePrivate::rulechecker_rule_print(ProtocolTrace_Rule_Checker *rc) +{ + char *reply; + int *len; + ProtocolTrace_Reply_Buffer buffer = {&reply, len}; + int i; + + DSLOG_INF("DSWaylandProtocolTracePriv"," --------------------------[ Protocol Filter Rules ]--------------------------\n"); + DSLOG_INF("DSWaylandProtocolTracePriv"," No Policy Rule\n"); + DSLOG_INF("DSWaylandProtocolTracePriv"," -----------------------------------------------------------------------------\n"); + + for(i =0; i < rc->count; i++) + { + DSLOG_INF("DSWaylandProtocolTracePriv"," %3d %10s \"", i, rc->rules[i].policy == PROTOCOLTRACE_TYPE_ALLOW ? "ALLOW" : "DENY"); + bintree_inorder_traverse(rc->rules[i].tree, rule_print_func, (void*) & buffer); + DSLOG_INF("DSWaylandProtocolTracePriv","\"\n"); + + } +} + +ProtocolTrace_Rule_Set_Result DSWaylandProtocolTracePrivate::rulechecker_rule_remove(ProtocolTrace_Rule_Checker *rc, int index) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> rulechecker_rule_remove"); + + if(index <0 || index >= rc->count) + return PROTOCOLTRACE_RULE_SET_ERR_NO_RULE; + + bintree_destroy_tree(rc->rules[index].tree); + rc->count--; + if(index!=rc->count) + memmove(&rc->rules[index], &rc->rules[index+1], sizeof(ProtocolTrace_Rule)*(rc->count - index)); + + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << rulechecker_rule_remove"); + + return PROTOCOLTRACE_RULE_SET_OK; +} + +int DSWaylandProtocolTracePrivate::rulechecker_rule_validate(ProtocolTrace_Rule_Checker *rc, int type, int target_id, const char *name, int pid, char *cmd) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> rulechecker_rule_validate"); + + ProtocolTrace_Validate_Args args = {type, target_id, name, pid, cmd}; + ProtocolTrace_Tree_Node *node; + ProtocolTrace_Rule_Node *data; + ProtocolTrace_Policy_Type default_policy = PROTOCOLTRACE_TYPE_DENY; + int i; + + for(i=rc->count-1; i>=0; i--) + { + bintree_postorder_traverse(rc->rules[i].tree, rule_validate_func, &args); + node = (ProtocolTrace_Tree_Node *) bintree_get_head(rc->rules[i].tree); + data = (ProtocolTrace_Rule_Node *) bintree_get_node_data(node); + + if(data->result == PROTOCOLTRACE_RESULT_TRUE) + { + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << rulechecker_rule_validate"); + return rc->rules[i].policy == PROTOCOLTRACE_TYPE_ALLOW; + } + } + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << rulechecker_rule_validate"); + return default_policy == PROTOCOLTRACE_TYPE_ALLOW; +} + +int DSWaylandProtocolTracePrivate::rulechecker_string_compare(ProtocolTrace_Comparer comparer, char *str2, char *str1) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> rulechecker_string_compare >> "); + + int result = strcasecmp(str2, str1); + + switch (comparer) + { + case PROTOCOLTRACE_COMPARER_EQUAL: + return result == 0; + case PROTOCOLTRACE_COMPARER_LESS: + return result < 0; + case PROTOCOLTRACE_COMPARER_GREATER: + return result > 0; + case PROTOCOLTRACE_COMPARER_LESS_EQ: + return result <= 0; + case PROTOCOLTRACE_COMPARER_GREATE_EQ: + return result >= 0; + case PROTOCOLTRACE_COMPARER_NOT_EQ: + return result != 0; + } + return 0; +} + +const char * DSWaylandProtocolTracePrivate::rulechecker_usage_print() +{ + return + "##########################################################\n" + "### Enlightenment Protocol Log filtering. ###\n" + "##########################################################\n" + "\n" + "-----------------------------------------------------------------\n" + "How to read enlightenment_info protocol messages :\n" + "[timestamp] Server --> Client [PID: [pid]] interface@id.message(arguments..) cmd: CMD\n" + " ex)\n" + "[1476930.145] Server --> Client [PID: 103] wl_touch@10.down(758, 6769315, wl_surface@23, 0, 408.000, 831.000) cmd: /usr/bin/launchpad-loader\n" + " ==> type = event && pid = 103 && cmd = launchpad-loader && iface = wl_touch && msg = up\n" + "[4234234.123] Server <-- Client [PID: 123] wl_seat@32.get_touch(new id wl_touch@22) cmd: /usr/bin/launchpad-loader\n" + " ==> type = request && pid = 123 && cmd = launchpad-loader && iface = wl_seat && msg = get_touch\n" + "-----------------------------------------------------------------\n" + "Usage : enlightenment_info -protocol_rule add [POLICY] [RULE]\n" + " enlightenment_info -protocol_rule remove [INDEX]\n" + " enlightenment_info -protocol_rule file [RULE_FILE]\n" + " enlightenment_info -protocol_rule print\n" + " enlightenment_info -protocol_rule help\n" + " [POLICY] : allow / deny \n" + " [RULE] : C Language-style boolean expression syntax. [VARIABLE] [COMPAROTOR] [VALUE]\n" + " [VARIABLE] : type / iface / msg / cmd(command) / pid\n" + " [COMPARATOR] : & / && / and / | / || / or / = / == / != / > / >= / < / <=\n" + " [VALUE] : string / number \n" + " ex)\n" + " enlightenment_info -protocol_rule add allow \"(type=request) && (iface == wl_pointer and (msg = down or msg = up))\"\n" + " enlightenment_info -protocol_rule add deny cmd!= launch-loader\n" + " enlightenment_info -protocol_rule remove all\n" + " enlightenment_info -protocol_rule remove 3\n" + "\n"; +} + +int DSWaylandProtocolTracePrivate::rule_print_func(ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Node *node, ProtocolTrace_Tree_Node *parent, void *arg) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> rule_print_func"); + ProtocolTrace_Reply_Buffer *buffer = (ProtocolTrace_Reply_Buffer *)arg; + char *reply = *buffer->reply; + int *len = buffer->len; + char *operators[] = {"==", "<", ">", "<=", ">=", "!=" }; + ProtocolTrace_Rule_Node *data; + + data = (ProtocolTrace_Rule_Node *)bintree_get_node_data(node); + + if(data->node_type == PROTOCOLTRACE_NODE_TYPE_ALL) + DSLOG_INF("DSWaylandProtocolTracePriv", "------------------------------------------------- ALL"); + else if(data->node_type == PROTOCOLTRACE_NODE_TYPE_AND) + DSLOG_INF("DSWaylandProtocolTracePriv", "------------------------------------------------- AND"); + else if(data->node_type == PROTOCOLTRACE_NODE_TYPE_OR) + DSLOG_INF("DSWaylandProtocolTracePriv", "------------------------------------------------- OR"); + else // data->node_type == PROTOCOLTRACE_NODE_TYPE_DATA + { + if(node == bintree_get_left_child(parent)) + DSLOG_INF("DSWaylandProtocolTracePriv", "------------------------------------------------- ("); + DSLOG_INF("DSWaylandProtocolTracePriv", "------------------------------------------------- %s %s ", data->variable_name, operators[data->comparer]); + + if(data->value_type == PROTOCOLTRACE_DATA_TYPE_INTEGER) + DSLOG_INF("DSWaylandProtocolTracePriv", "------------------------------------------------- %d", data->value.integer); + else + DSLOG_INF("DSWaylandProtocolTracePriv", "------------------------------------------------- %s", data->value.string); + + if(node == bintree_get_right_child(parent)) + DSLOG_INF("DSWaylandProtocolTracePriv", "------------------------------------------------- )"); + } + + *buffer->reply = reply; + DSLOG_DBG("DSWaylandProtocolTracePriv", "buffer->reply = %s", reply); + + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << rule_print_func"); + return 0; +} + +int DSWaylandProtocolTracePrivate::rule_validate_func(ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Node *node, ProtocolTrace_Tree_Node *parent, void *arg) +{ + DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> rule_validate_func "); + + ProtocolTrace_Validate_Args *args = (ProtocolTrace_Validate_Args *)arg; + ProtocolTrace_Tree_Node *left, *right; + ProtocolTrace_Rule_Node *data, *left_data =nullptr, *right_data = nullptr; + + data = (ProtocolTrace_Rule_Node *)bintree_get_node_data(node); + data->result = PROTOCOLTRACE_RESULT_UNKNOWN; + + if(data->node_type == PROTOCOLTRACE_NODE_TYPE_AND || data->node_type == PROTOCOLTRACE_NODE_TYPE_OR) + { + left = bintree_get_left_child(node); + right = bintree_get_right_child(node); + if(!left || !right) + { + DSLOG_ERR("DSWaylandProtocolTracePriv", "Node error"); + return -1; + } + + left_data = (ProtocolTrace_Rule_Node *)bintree_get_node_data(left); + right_data = (ProtocolTrace_Rule_Node *)bintree_get_node_data(right); + } + + if(data->node_type == PROTOCOLTRACE_NODE_TYPE_ALL) + { + data->result = PROTOCOLTRACE_RESULT_TRUE; + } + else if(data->node_type == PROTOCOLTRACE_NODE_TYPE_DATA) + { + char iface[64]; + char *msg = nullptr; + + if(args->name) + msg = ":";//index(args->name, ":"); + if(msg) + { + int min = MIN(sizeof(iface)-1, msg-args->name); + strncpy(iface, args->name, min); + iface[min] = '\0'; + msg++; + } + if(!strcasecmp(data->variable_name, "TYPE")) + { + char *type_string; + if(args->type == 0) + type_string = "REQUEST"; + else if(args->type == 1) + type_string = "EVENT"; + else + { + DSLOG_ERR("DSWaylandProtocolTracePriv", "Invalid type %d", args->type); + return -1; + } + + if(rulechecker_string_compare(data->comparer, data->value.string, type_string)) + data->result = PROTOCOLTRACE_RESULT_TRUE; + else + data->result = PROTOCOLTRACE_RESULT_FALSE; + } + else if(!strcasecmp(data->variable_name, "IFACE")) + { + if(msg && rulechecker_string_compare(data->comparer, data->value.string, iface)) + data->result = PROTOCOLTRACE_RESULT_TRUE; + else + data->result = PROTOCOLTRACE_RESULT_FALSE; + } + else if(!strcasecmp(data->variable_name, "MSG")) + { + if(msg && rulechecker_string_compare(data->comparer, data->value.string, msg)) + data->result = PROTOCOLTRACE_RESULT_TRUE; + else + data->result = PROTOCOLTRACE_RESULT_FALSE; + } + else if(!strcasecmp(data->variable_name, "PID")) + { + if(rulechecker_int_compare(data->comparer, data->value.integer, args->pid)) + data->result = PROTOCOLTRACE_RESULT_TRUE; + else + data->result = PROTOCOLTRACE_RESULT_FALSE; + } + else if(!strcasecmp(data->variable_name, "CMD") || !strcasecmp(data->variable_name, "COMMAND")) + { + if(msg && rulechecker_string_compare(data->comparer, data->value.string, args->cmd)) + data->result = PROTOCOLTRACE_RESULT_TRUE; + else + data->result = PROTOCOLTRACE_RESULT_FALSE; + } + } + else if(data->node_type == PROTOCOLTRACE_NODE_TYPE_AND) + { + if(left_data->result == PROTOCOLTRACE_RESULT_TRUE && right_data->result == PROTOCOLTRACE_RESULT_TRUE) + data->result = PROTOCOLTRACE_RESULT_TRUE; + else + data->result = PROTOCOLTRACE_RESULT_FALSE; + } + else if(data->node_type == PROTOCOLTRACE_NODE_TYPE_OR) + { + if(left_data->result == PROTOCOLTRACE_RESULT_TRUE || right_data->result == PROTOCOLTRACE_RESULT_TRUE) + data->result = PROTOCOLTRACE_RESULT_TRUE; + else + data->result = PROTOCOLTRACE_RESULT_FALSE; + } + else + { + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << rule_validate_func "); + return -1; + } + + DSLOG_DBG("DSWaylandProtocolTracePriv", "OUT << rule_validate_func "); + return 0; } } // namespace display_server \ No newline at end of file diff --git a/src/DSWaylandServer/DSWaylandProtocolTrace.h b/src/DSWaylandServer/DSWaylandProtocolTrace.h index b9526df..70a5d6c 100644 --- a/src/DSWaylandServer/DSWaylandProtocolTrace.h +++ b/src/DSWaylandServer/DSWaylandProtocolTrace.h @@ -26,6 +26,7 @@ #include #include +#include "DSWaylandCompositor.h" namespace display_server { diff --git a/src/DSWaylandServer/DSWaylandProtocolTracePrivate.h b/src/DSWaylandServer/DSWaylandProtocolTracePrivate.h index d43ed9d..8c22087 100644 --- a/src/DSWaylandServer/DSWaylandProtocolTracePrivate.h +++ b/src/DSWaylandServer/DSWaylandProtocolTracePrivate.h @@ -25,9 +25,199 @@ #define __DS_WAYLAND_PROTOCOL_TRACE_PRIVATE_H__ #include "DSWaylandProtocolTrace.h" +//#include "DSWaylandProtocolTraceStruct.h" +#include +#include +#include +#include + +#define PATH_MAX 255 //tmp 255 + +#ifndef MAX +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#endif + +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +#define BUF_SNPRINTF(fmt, ARG...) do { \ + str_l = snprintf(str_buff, str_r, fmt, ##ARG); \ + str_buff += str_l; \ + str_r -= str_l; \ +} while(0) + + +/* +#ifndef REPLY + #define REPLY(fmt, ARG...) \ + do { \ + if (reply && len && *len > 0) \ + { \ + int s = snprintf(reply, *len, fmt, ##ARG); \ + reply += s; \ + *len -= s; \ + } \ + } while (0) +#endif +*/ +#define MAX_RULE 64 +#define STRING_MAX 64 namespace display_server { +typedef struct _ProtocolTrace_Tree_Node ProtocolTrace_Tree_Node; +typedef struct _ProtocolTrace_Tree ProtocolTrace_Tree; +typedef struct _ProtocolTrace_Token_Data ProtocolTrace_Token_Data; +typedef struct _ProtocolTrace_Rule_Node ProtocolTrace_Rule_Node; +typedef struct _ProtocolTrace_Rule ProtocolTrace_Rule; +typedef struct _ProtocolTrace_Rule_Checker ProtocolTrace_Rule_Checker; +typedef struct _ProtocolTrace_Protocol_Log ProtocolTrace_Protocol_Log; + +typedef int (*ProtocolTrace_Tree_Traverse_Cb) (ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Node *node, ProtocolTrace_Tree_Node *parent, void *arg); + +struct _ProtocolTrace_Tree_Node +{ + ProtocolTrace_Tree_Node *left; + ProtocolTrace_Tree_Node *right; +}; + +struct _ProtocolTrace_Tree +{ + int size; + ProtocolTrace_Tree_Node *head; +}; + +typedef enum +{ + PROTOCOLTRACE_TOKEN_UNKNOWN = 0, + PROTOCOLTRACE_TOKEN_L_BR =1, + PROTOCOLTRACE_TOKEN_R_BR =2, + PROTOCOLTRACE_TOKEN_NOT_EQ=3, + PROTOCOLTRACE_TOKEN_EQUAL=4, + PROTOCOLTRACE_TOKEN_LSS_THAN=5, + PROTOCOLTRACE_TOKEN_LSS_EQ =6, + PROTOCOLTRACE_TOKEN_GRT_THAN=7, + PROTOCOLTRACE_TOKEN_GRT_EQ =8, + PROTOCOLTRACE_TOKEN_AND=9, + PROTOCOLTRACE_TOKEN_OR=10, + PROTOCOLTRACE_TOKEN_SPACE=11, + PROTOCOLTRACE_TOKEN_SYMBOL=12, + PROTOCOLTRACE_TOKEN_NUMBER=13, + PROTOCOLTRACE_TOKEN_EOS=14, +} ProtocolTrace_Token; + +struct _ProtocolTrace_Token_Data +{ + const char **string; + ProtocolTrace_Token last_token; + const char *last_symbol; + int symbol_len; +}; +typedef enum +{ + PROTOCOLTRACE_NODE_TYPE_NONE, + PROTOCOLTRACE_NODE_TYPE_AND, + PROTOCOLTRACE_NODE_TYPE_OR, + PROTOCOLTRACE_NODE_TYPE_DATA, + PROTOCOLTRACE_NODE_TYPE_ALL +} ProtocolTrace_Node_Type; + +typedef enum +{ + PROTOCOLTRACE_COMPARER_EQUAL, + PROTOCOLTRACE_COMPARER_LESS, + PROTOCOLTRACE_COMPARER_GREATER, + PROTOCOLTRACE_COMPARER_LESS_EQ, + PROTOCOLTRACE_COMPARER_GREATE_EQ, + PROTOCOLTRACE_COMPARER_NOT_EQ +} ProtocolTrace_Comparer; + +typedef enum +{ + PROTOCOLTRACE_DATA_TYPE_INTEGER, + PROTOCOLTRACE_DATA_TYPE_STRING +} ProtocolTrace_Data_Type; + +typedef enum +{ + PROTOCOLTRACE_RESULT_UNKNOWN, + PROTOCOLTRACE_RESULT_TRUE, + PROTOCOLTRACE_RESULT_FALSE +} ProtocolTrace_Result_Type; + +struct _ProtocolTrace_Rule_Node +{ + ProtocolTrace_Node_Type node_type; + char variable_name[STRING_MAX]; + ProtocolTrace_Comparer comparer; + ProtocolTrace_Data_Type value_type; + + union + { + char string[STRING_MAX]; + int integer; + }value; + + ProtocolTrace_Result_Type result; +}; + +typedef enum +{ + PROTOCOLTRACE_POLICY_TYPE_UNDEFINED, + PROTOCOLTRACE_TYPE_ALLOW, + PROTOCOLTRACE_TYPE_DENY +} ProtocolTrace_Policy_Type; + +struct _ProtocolTrace_Rule +{ + ProtocolTrace_Policy_Type policy; + ProtocolTrace_Tree *tree; +}; + +struct _ProtocolTrace_Rule_Checker +{ + ProtocolTrace_Rule rules[MAX_RULE]; + int count; +}; +typedef enum +{ + PROTOCOLTRACE_RULE_SET_OK, + PROTOCOLTRACE_RULE_SET_ERR_TOO_MANY_RULES, + PROTOCOLTRACE_RULE_SET_ERR_PARSE, + PROTOCOLTRACE_RULE_SET_ERR_NO_RULE + } ProtocolTrace_Rule_Set_Result; +typedef enum{ + PROTOCOL_TYPE_REQUEST, + PROTOCOL_TYPE_EVENT +} ProtocolTrace_Protocol_Type; +struct _ProtocolTrace_Protocol_Log +{ + ProtocolTrace_Protocol_Type type; + int client_pid; + int target_id; + char name[PATH_MAX +1]; + char cmd[PATH_MAX +1]; +}; +struct argument_details { + char type; + int nullable; +}; + +typedef struct +{ + int type; + int target_id; + const char *name; + int pid; + char *cmd; +} ProtocolTrace_Validate_Args; + +typedef struct +{ + char **reply; + int *len; +} ProtocolTrace_Reply_Buffer; class DSWaylandProtocolTracePrivate : public DSObjectPrivate { @@ -40,11 +230,59 @@ public: protected: - void protocol_rule_init(char *rule_path); - void protocol_trace_init(char *trace_path); - void protocol_rule_set(void); - void protocol_rule_file_set(void); + bool protocol_rule_init(char *rule_path); + bool protocol_trace_init(char *trace_path); + + bool protocol_rule_set(const int argc, const char **argv); + bool protocol_rule_file_set(const char *filename); + static bool protocol_rule_validate(ProtocolTrace_Protocol_Log *log); + + void protocol_trace_set(void); + void protocol_trace_unset(void); + +private: + DSWaylandCompositor *__wlCompositor; + char *trace_env_path = nullptr; + + static void wl_protocol_cb_client_destroy(struct wl_listener *listener, void *data); + static void protocol_client_destroy_listener_reg(struct wl_client *client); + static void protocol_trace_func(void *user_data, enum wl_protocol_logger_type direction, const struct wl_protocol_logger_message *message); + + ProtocolTrace_Tree_Node *bintree_create_node(ProtocolTrace_Tree *tree); + ProtocolTrace_Tree *bintree_create_tree(int size); + void bintree_destroy_tree(ProtocolTrace_Tree *tree); + static ProtocolTrace_Tree_Node *bintree_get_head(ProtocolTrace_Tree *tree); + static ProtocolTrace_Tree_Node *bintree_get_left_child(ProtocolTrace_Tree_Node *node); + static void * bintree_get_node_data(ProtocolTrace_Tree_Node *node); + static ProtocolTrace_Tree_Node *bintree_get_right_child(ProtocolTrace_Tree_Node *node); + void bintree_inorder_traverse(ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Traverse_Cb func, void *arg); + int bintree_inorder_traverse_recursive(ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Node *node, ProtocolTrace_Tree_Node *parent, ProtocolTrace_Tree_Traverse_Cb func, void *arg); + static void bintree_postorder_traverse(ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Traverse_Cb func, void *arg); + static int bintree_postorder_traverse_recursive(ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Node *node, ProtocolTrace_Tree_Node *parent, ProtocolTrace_Tree_Traverse_Cb func, void *arg); + void bintree_remove_node(ProtocolTrace_Tree_Node *node); + void bintree_remove_node_recursive(ProtocolTrace_Tree_Node *node); + void bintree_set_head(ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Node *head); + void bintree_set_left_child(ProtocolTrace_Tree_Node *node, ProtocolTrace_Tree_Node *child); + void bintree_set_right_child(ProtocolTrace_Tree_Node *node, ProtocolTrace_Tree_Node *child); + ProtocolTrace_Token parser_next_token_get(const char **string); + ProtocolTrace_Tree *protocol_parser_rule_string_parse(const char *string); + ProtocolTrace_Tree_Node *parser_statement_parse(ProtocolTrace_Tree *tree, ProtocolTrace_Token_Data *token); + ProtocolTrace_Tree_Node *parser_token_parse(ProtocolTrace_Tree *tree, ProtocolTrace_Token_Data *token); + void parser_token_process(ProtocolTrace_Token_Data *token); + static void protocol_arguments_merge(char *target, int target_size, int argc, const char **argv); + static char * protocol_cmd_get(char *path); + void rulechecker_destroy(ProtocolTrace_Rule_Checker *rc); + ProtocolTrace_Rule_Checker *rulechecker_init(); + static int rulechecker_int_compare(ProtocolTrace_Comparer comparer, int int2, int int1); + ProtocolTrace_Rule_Set_Result rulechecker_rule_add(_ProtocolTrace_Rule_Checker *rc, ProtocolTrace_Policy_Type policy, const char *rule_string); + void rulechecker_rule_print(ProtocolTrace_Rule_Checker *rc); + ProtocolTrace_Rule_Set_Result rulechecker_rule_remove(ProtocolTrace_Rule_Checker *rc, int index); + static int rulechecker_rule_validate(ProtocolTrace_Rule_Checker *rc, int type, int target_id, const char *name, int pid, char *cmd); + static int rulechecker_string_compare(ProtocolTrace_Comparer comparer, char *str2, char *str1); + const char * rulechecker_usage_print(); + static int rule_print_func(ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Node *node, ProtocolTrace_Tree_Node *parent, void *arg); + static int rule_validate_func(ProtocolTrace_Tree *tree, ProtocolTrace_Tree_Node *node, ProtocolTrace_Tree_Node *parent, void *arg); }; } -- 2.7.4 From c755d4d90af069ab069c03a9e537e522ec8c6144 Mon Sep 17 00:00:00 2001 From: dyamy-lee Date: Thu, 20 Aug 2020 15:08:23 +0900 Subject: [PATCH 16/16] add func of update rule and add test code Change-Id: Ia7891fb079711b6198b786604e4708fa3c900fe5 --- src/DSWaylandServer/DSWaylandProtocolTrace.cpp | 16 ++++++ src/DSWaylandServer/DSWaylandProtocolTrace.h | 2 +- tests/DSWaylandProtocolTrace-test.cpp | 71 +++++++++++++++++++++++++- 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/DSWaylandServer/DSWaylandProtocolTrace.cpp b/src/DSWaylandServer/DSWaylandProtocolTrace.cpp index fe89016..869bcb7 100644 --- a/src/DSWaylandServer/DSWaylandProtocolTrace.cpp +++ b/src/DSWaylandServer/DSWaylandProtocolTrace.cpp @@ -204,6 +204,18 @@ int DSWaylandProtocolTrace::enableProtocolTrace(bool state) return -1; } + +bool DSWaylandProtocolTrace::updateProtocolRule(const int argc, const char **argv) +{ + DS_GET_PRIV(DSWaylandProtocolTrace); + DSLOG_DBG("DSWaylandProtocolTrace", "argc = %d, argv[0] = %s, argv[1] = %s", argc, argv[0], argv[1]); + + bool ret = false; + ret = priv->protocol_rule_set(argc, argv); + + return ret; +} + DSWaylandProtocolTracePrivate::DSWaylandProtocolTracePrivate(DSWaylandProtocolTrace *p_ptr) : DSObjectPrivate(p_ptr), __p_ptr(p_ptr) { @@ -265,6 +277,7 @@ bool DSWaylandProtocolTracePrivate::protocol_trace_init(char *trace_path) bool DSWaylandProtocolTracePrivate::protocol_rule_set(const int argc, const char **argv) { DSLOG_DBG("DSWaylandProtocolTracePriv", "IN >> protocol_rule_set"); + DSLOG_DBG("DSWaylandProtocolTracePriv", "(parameter) argc = %d, argv[0] = %s", argc, argv[0]); const char * command; if(argc == 0) @@ -408,6 +421,8 @@ bool DSWaylandProtocolTracePrivate::protocol_rule_set(const int argc, const char } } rulechecker_rule_print(rc); + + return true; } else if(!strcasecmp(command, "file")) { @@ -532,6 +547,7 @@ void DSWaylandProtocolTracePrivate::protocol_trace_set(void) display = __wlCompositor->display(); DSLOG_DBG("DSWaylandProtocolTracePriv","get display "); + //check working ds_wl_protocol_logger = wl_display_add_protocol_logger(display, protocol_trace_func, nullptr); DSLOG_DBG("DSWaylandProtocolTracePriv","OUT << protocol trace set"); } diff --git a/src/DSWaylandServer/DSWaylandProtocolTrace.h b/src/DSWaylandServer/DSWaylandProtocolTrace.h index 70a5d6c..b53e999 100644 --- a/src/DSWaylandServer/DSWaylandProtocolTrace.h +++ b/src/DSWaylandServer/DSWaylandProtocolTrace.h @@ -45,7 +45,7 @@ public: bool init(void); int enableProtocolTrace(bool state); - //int registerProtocolRule(void); + bool updateProtocolRule(const int argc, const char **argv); private: static std::mutex __mutex; diff --git a/tests/DSWaylandProtocolTrace-test.cpp b/tests/DSWaylandProtocolTrace-test.cpp index e02cf3e..63d0e67 100644 --- a/tests/DSWaylandProtocolTrace-test.cpp +++ b/tests/DSWaylandProtocolTrace-test.cpp @@ -45,15 +45,82 @@ TEST_F(DSWaylandProtocolTraceTest, NewDSWaylandProtocolTrace) DSWaylandProtocolTrace::releaseInstance(); } -TEST_F(DSWaylandProtocolTraceTest, BasicMethods) +TEST_F(DSWaylandProtocolTraceTest, DSWaylandProtocolTraceInit) { DSWaylandProtocolTrace *pTrace = DSWaylandProtocolTrace::getInstance(); - bool trace_state = false; //disable if(pTrace) { EXPECT_TRUE(pTrace->init() == true); + DSWaylandProtocolTrace::releaseInstance(); + } +} + +TEST_F(DSWaylandProtocolTraceTest, DSWaylandProtocolTraceUpdateRule) +{ + DSWaylandProtocolTrace *pTrace = DSWaylandProtocolTrace::getInstance(); + + if(pTrace) + { + pTrace->init(); + + int argc = 3; + char *argv[3]; + argv[0] = "add"; + argv[1] = "ALLOW"; + argv[2] = "all"; + EXPECT_TRUE(pTrace->updateProtocolRule(argc, (const char**)&(argv[0])) == true); + + argc = 2; + argv[0] = "remove"; + argv[1] = "all"; + argv[2] = nullptr; + EXPECT_TRUE(pTrace->updateProtocolRule(argc, (const char**)&(argv[0])) == true); + + argc = 1; + argv[0] = "print"; + argv[1] = nullptr; + argv[2] = nullptr; + EXPECT_TRUE(pTrace->updateProtocolRule(argc, (const char**)&(argv[0])) == true); + + argc = 1; + argv[0] = "help"; + argv[1] = nullptr; + argv[2] = nullptr; + EXPECT_TRUE(pTrace->updateProtocolRule(argc, (const char**)&(argv[0])) == true); + + argc = 1; + argv[0] = "command"; + argv[1] = nullptr; + argv[2] = nullptr; + EXPECT_TRUE(pTrace->updateProtocolRule(argc, (const char**)&(argv[0])) == true); + DSWaylandProtocolTrace::releaseInstance(); + } + +} + +TEST_F(DSWaylandProtocolTraceTest, DSWaylandProtocolTraceEnableTraceFalse) +{ + DSWaylandProtocolTrace *pTrace = DSWaylandProtocolTrace::getInstance(); + bool trace_state = false; //disable + + if(pTrace) + { + pTrace->init(); EXPECT_TRUE(pTrace->enableProtocolTrace(trace_state) == 0); DSWaylandProtocolTrace::releaseInstance(); } +} + +TEST_F(DSWaylandProtocolTraceTest, DSWaylandProtocolTraceEnableTraceTrue) +{ + DSWaylandProtocolTrace *pTrace = DSWaylandProtocolTrace::getInstance(); + bool trace_state = true; + + if(pTrace) + { + pTrace->init(); + EXPECT_TRUE(pTrace->enableProtocolTrace(trace_state) == 1); + DSWaylandProtocolTrace::releaseInstance(); + } } \ No newline at end of file -- 2.7.4