--- /dev/null
+#include "tc_main.h"
+#include "mockclient.h"
+#include "mockcompositor.h"
+#include <libds-tizen/clipboard.h>
+#include <tizen-extension-client-protocol.h>
+
+#define TIZEN_CLIPBOARD_VERSION 2
+
+class MockClipboardCompositor : public MockCompositor
+{
+public:
+ MockClipboardCompositor()
+ : MockCompositor(&MockClipboardCompositor::TestSetup, this)
+ {
+ ds_inf("%s : this(%p)", __func__, this);
+
+ // initialize the flags to check
+ bSurfaceDestroyed = false;
+
+ bDestroyed = false;
+ bShow = false;
+ bHide = false;
+ mSetDataOnly = 0;
+
+ mAllowed = 0;
+ }
+
+ ~MockClipboardCompositor()
+ {
+ ds_inf("%s : this(%p)", __func__, this);
+ }
+
+ static void TestSetup(void *data)
+ {
+ MockClipboardCompositor *mockComp =
+ static_cast<MockClipboardCompositor *>(data);
+ Compositor *comp = mockComp->compositor;
+
+ ds_inf("%s: mockComp(%p)", __func__, mockComp);
+
+ // new surface listener
+ mockComp->mNewSurfaceListener.notify =
+ MockClipboardCompositor::NewSurfaceCallback;
+ mockComp->mNewSurfaceListener.parent = mockComp;
+ ds_compositor_add_new_surface_listener(comp->compositor,
+ &mockComp->mNewSurfaceListener);
+
+ mockComp->mClipboard = ds_tizen_clipboard_create(comp->display);
+
+ // destroy listener
+ mockComp->mDestroyListener.notify =
+ MockClipboardCompositor::DestroyCallback;
+ mockComp->mDestroyListener.parent = mockComp;
+ ds_tizen_clipboard_add_destroy_listener(mockComp->mClipboard,
+ &mockComp->mDestroyListener);
+
+ // show listener
+ mockComp->mShowListener.notify =
+ MockClipboardCompositor::ShowCallback;
+ mockComp->mShowListener.parent = mockComp;
+ ds_tizen_clipboard_add_show_listener(mockComp->mClipboard,
+ &mockComp->mShowListener);
+
+ // hide listener
+ mockComp->mHideListener.notify =
+ MockClipboardCompositor::HideCallback;
+ mockComp->mHideListener.parent = mockComp;
+ ds_tizen_clipboard_add_hide_listener(
+ mockComp->mClipboard,
+ &mockComp->mHideListener);
+
+ // set_data_only listener
+ mockComp->mSetDataOnlyListener.notify =
+ MockClipboardCompositor::SetDataOnlyCallback;
+ mockComp->mSetDataOnlyListener.parent = mockComp;
+ ds_tizen_clipboard_add_set_data_only_listener(
+ mockComp->mClipboard,
+ &mockComp->mSetDataOnlyListener);
+ }
+
+ static void NewSurfaceCallback(struct wl_listener *listener, void *data)
+ {
+ MockClipboardCompositor *mockComp =
+ reinterpret_cast<NewSurfaceListener *>(listener)->parent;
+ struct ds_surface *surface = static_cast<struct ds_surface *>(data);
+
+ ds_inf("%s: mockComp(%p), surface(%p)", __func__, mockComp, surface);
+
+ mockComp->mSurface = surface;
+
+ // del surface listener
+ mockComp->mDelSurfaceListener.notify =
+ MockClipboardCompositor::DelSurfaceCallback;
+ mockComp->mDelSurfaceListener.parent = mockComp;
+ ds_surface_add_destroy_listener(surface,
+ &mockComp->mDelSurfaceListener);
+ }
+
+ static void DelSurfaceCallback(struct wl_listener *listener, void *data)
+ {
+ MockClipboardCompositor *mockComp =
+ reinterpret_cast<DelSurfaceListener *>(listener)->parent;
+ struct ds_surface *surface = static_cast<struct ds_surface *>(data);
+
+ ds_inf("%s: mockComp(%p), surface(%p)", __func__, mockComp, surface);
+
+ if (ds_surface_get_wl_resource(mockComp->mSurface) ==
+ ds_surface_get_wl_resource(surface)) {
+ ds_inf("%s: surface is deleted.", __func__);
+ mockComp->bSurfaceDestroyed = true;
+ }
+ }
+
+ static void DestroyCallback(struct wl_listener *listener, void *data)
+ {
+ ds_inf("%s", __func__);
+
+ MockClipboardCompositor *mockComp =
+ reinterpret_cast<DestroyListener *>(listener)->parent;
+
+ mockComp->bDestroyed = true;
+ }
+
+ static void ShowCallback(struct wl_listener *listener, void *data)
+ {
+ ds_inf("%s", __func__);
+
+ MockClipboardCompositor *mockComp =
+ reinterpret_cast<ShowListener *>(listener)->parent;
+ struct ds_surface *surface = static_cast<struct ds_surface *>(data);
+
+ ds_inf("%s: mockComp(%p), surface(%p)", __func__, mockComp, surface);
+
+ mockComp->bShow = true;
+ }
+
+ static void HideCallback(struct wl_listener *listener,
+ void *data)
+ {
+ ds_inf("%s", __func__);
+
+ MockClipboardCompositor *mockComp =
+ reinterpret_cast<SetDataOnlyListener *>(listener)->parent;
+ struct ds_surface *surface = static_cast<struct ds_surface *>(data);
+
+ ds_inf("%s: mockComp(%p), surface(%p)", __func__, mockComp, surface);
+
+ mockComp->bHide = true;
+ }
+
+ static void SetDataOnlyCallback(struct wl_listener *listener,
+ void *data)
+ {
+ ds_inf("%s", __func__);
+
+ MockClipboardCompositor *mockComp =
+ reinterpret_cast<HideListener *>(listener)->parent;
+ struct ds_tizen_clipboard_client *client =
+ static_cast<struct ds_tizen_clipboard_client *>(data);
+
+ ds_inf("%s: mockComp(%p), client(%p)", __func__, mockComp, client);
+
+ mockComp->mSetDataOnly =
+ ds_tizen_clipboard_client_get_data_only(client);
+
+ ds_tizen_clipboard_client_send_allowed_data_only(client,
+ mockComp->mAllowed);
+ }
+
+ void SendDataSelected()
+ {
+ ds_inf("%s", __func__);
+
+ ds_tizen_clipboard_send_data_selected(mClipboard, mSurface);
+ }
+
+ void SetAllowedDataOnly(uint32_t allowed)
+ {
+ ds_inf("%s", __func__);
+
+ mAllowed = allowed;
+ }
+
+public:
+ bool bSurfaceDestroyed;
+ bool bDestroyed;
+ bool bShow;
+ bool bHide;
+ uint32_t mSetDataOnly;
+
+ uint32_t mAllowed;
+
+private:
+ struct ds_surface *mSurface;
+ struct NewSurfaceListener : ::wl_listener {
+ MockClipboardCompositor *parent;
+ };
+ NewSurfaceListener mNewSurfaceListener;
+ struct DelSurfaceListener : ::wl_listener {
+ MockClipboardCompositor *parent;
+ };
+ DelSurfaceListener mDelSurfaceListener;
+
+ struct ds_tizen_clipboard *mClipboard;
+ struct DestroyListener : ::wl_listener {
+ MockClipboardCompositor *parent;
+ };
+ DestroyListener mDestroyListener;
+ struct ShowListener : ::wl_listener {
+ MockClipboardCompositor *parent;
+ };
+ ShowListener mShowListener;
+ struct HideListener : ::wl_listener {
+ MockClipboardCompositor *parent;
+ };
+ HideListener mHideListener;
+ struct SetDataOnlyListener : ::wl_listener {
+ MockClipboardCompositor *parent;
+ };
+ SetDataOnlyListener mSetDataOnlyListener;
+};
+
+class MockClipboardClient : public MockClient
+{
+public:
+ MockClipboardClient()
+ : bDataSelectedEvent(false),
+ mAllowedDataOnly(0),
+ compositor_res(nullptr),
+ tizen_clipboard(nullptr)
+ {}
+ MockClipboardClient(const struct wl_registry_listener *listener)
+ : MockClient(listener, this)
+ {
+ ds_inf("%s", __func__);
+
+ bDataSelectedEvent = false;
+ mAllowedDataOnly = 0;
+ }
+ ~MockClipboardClient()
+ {
+ ds_inf("%s", __func__);
+ }
+
+ void SetWlCompositor(struct wl_compositor *global_res)
+ {
+ ds_inf("%s", __func__);
+
+ compositor_res = global_res;
+ }
+
+ struct wl_compositor *GetWlCompositor()
+ {
+ ds_inf("%s", __func__);
+
+ return compositor_res;
+ }
+
+ void SetTizenClipboard(struct tizen_clipboard *global_res)
+ {
+ ds_inf("%s", __func__);
+
+ tizen_clipboard = global_res;
+ }
+
+ struct tizen_clipboard *GetTizenClipboard()
+ {
+ ds_inf("%s", __func__);
+
+ return tizen_clipboard;
+ }
+
+public:
+ bool bDataSelectedEvent;
+ uint32_t mAllowedDataOnly;
+
+private:
+ struct wl_compositor *compositor_res;
+ struct tizen_clipboard *tizen_clipboard;
+};
+
+static void
+client_tizen_clipboard_cb_data_selected(void *data,
+ struct tizen_clipboard *clipboard, struct wl_surface *surface)
+{
+ ds_inf("%s", __func__);
+
+ MockClipboardClient *client = static_cast<MockClipboardClient *>(data);
+
+ client->bDataSelectedEvent = true;
+}
+
+static void
+client_tizen_clipboard_cb_allowed_data_only(void *data,
+ struct tizen_clipboard *clipboard, uint32_t allowed)
+{
+ ds_inf("%s", __func__);
+
+ MockClipboardClient *client = static_cast<MockClipboardClient *>(data);
+
+ client->mAllowedDataOnly = allowed;
+}
+
+static const struct tizen_clipboard_listener clipboard_cb_listener = {
+ .data_selected = client_tizen_clipboard_cb_data_selected,
+ .allowed_data_only = client_tizen_clipboard_cb_allowed_data_only
+};
+
+static void
+client_registry_cb_global(void *data, struct wl_registry *registry,
+ uint32_t name, const char *interface, uint32_t version)
+{
+ ds_inf("%s", __func__);
+
+ MockClipboardClient *client = static_cast<MockClipboardClient *>(data);
+ struct wl_compositor *compositor_res;
+ struct tizen_clipboard *tizen_clipboard;
+
+ if (!strcmp(interface, "wl_compositor")) {
+ compositor_res = (struct wl_compositor *)wl_registry_bind(registry,
+ name, &wl_compositor_interface, 1);
+ if (compositor_res == nullptr) {
+ ds_err("wl_registry_bind() failed. wl_compositor resource.");
+ return;
+ }
+ client->SetWlCompositor(compositor_res);
+ } else if (!strcmp(interface, "tizen_clipboard")) {
+ tizen_clipboard = (struct tizen_clipboard *)wl_registry_bind(registry,
+ name, &tizen_clipboard_interface, TIZEN_CLIPBOARD_VERSION);
+ if (tizen_clipboard == nullptr) {
+ ds_err("wl_registry_bind() failed. tizen_clipboard resource.");
+ return;
+ }
+ client->SetTizenClipboard(tizen_clipboard);
+
+ tizen_clipboard_add_listener(tizen_clipboard, &clipboard_cb_listener,
+ client);
+ }
+}
+
+static void
+client_registry_cb_global_remove(void *data, struct wl_registry *registry,
+ uint32_t name)
+{
+ ds_inf("%s", __func__);
+
+ MockClipboardClient *client = static_cast<MockClipboardClient *>(data);
+ struct wl_compositor *compositor_res = client->GetWlCompositor();
+ struct tizen_clipboard *clipboard_res = client->GetTizenClipboard();
+
+ tizen_clipboard_destroy(clipboard_res);
+ wl_compositor_destroy(compositor_res);
+}
+
+static const struct wl_registry_listener registry_listener = {
+ .global = client_registry_cb_global,
+ .global_remove = client_registry_cb_global_remove
+};
+
+class ClipboardTest : public ::testing::Test
+{
+public:
+ void SetUp(void) override;
+ void TearDown(void) override;
+
+ MockClipboardCompositor *comp;
+ MockClipboardClient *client;
+ struct wl_compositor *compositor_res;
+ struct tizen_clipboard *clipboard_res;
+ struct wl_surface *surface_res;
+};
+
+void
+ClipboardTest::SetUp(void)
+{
+ //ds_log_init(DS_DBG, NULL);
+
+ ds_inf("%s", __func__);
+
+ comp = new MockClipboardCompositor();
+ client = new MockClipboardClient(®istry_listener);
+ compositor_res = client->GetWlCompositor();
+ clipboard_res = client->GetTizenClipboard();
+ surface_res = wl_compositor_create_surface(compositor_res);
+
+ client->RoundTrip();
+}
+
+void
+ClipboardTest::TearDown(void)
+{
+ ds_inf("%s", __func__);
+
+ wl_surface_destroy(surface_res);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bSurfaceDestroyed);
+
+ delete client;
+ delete comp;
+}
+
+TEST_F(ClipboardTest, Create_P)
+{
+ EXPECT_TRUE(true);
+}
+
+TEST_F(ClipboardTest, Req_TizenClipboardShow)
+{
+ tizen_clipboard_show(clipboard_res, surface_res);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bShow);
+ EXPECT_FALSE(comp->bHide);
+}
+
+TEST_F(ClipboardTest, Req_TizenClipboardHide)
+{
+ tizen_clipboard_hide(clipboard_res, surface_res);
+ client->RoundTrip();
+ EXPECT_FALSE(comp->bShow);
+ EXPECT_TRUE(comp->bHide);
+}
+
+TEST_F(ClipboardTest, Req_TizenClipboardSetDataOnly)
+{
+ tizen_clipboard_set_data_only(clipboard_res, 1);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->mSetDataOnly == 1);
+}
+
+TEST_F(ClipboardTest, Ev_TizenClipboardDataSelected)
+{
+ tizen_clipboard_show(clipboard_res, surface_res);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bShow);
+
+ comp->SendDataSelected();
+ comp->Process();
+
+ client->RoundTrip();
+ EXPECT_TRUE(client->bDataSelectedEvent);
+}
+
+TEST_F(ClipboardTest, Ev_TizenClipboardAllowedDataOnly)
+{
+ // set the value of allowed to be 1 at compositor
+ comp->SetAllowedDataOnly(1);
+
+ // send a client's request
+ tizen_clipboard_set_data_only(clipboard_res, 1);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->mSetDataOnly);
+
+ comp->Process();
+
+ client->RoundTrip();
+ EXPECT_TRUE(client->mAllowedDataOnly == 1);
+}