--- /dev/null
+#include "tc_main.h"
+#include "mockclient.h"
+#include "mockcompositor.h"
+#include <libds-tizen/memory_flusher.h>
+#include <tizen-surface-client-protocol.h>
+
+#define TIZEN_MEMORY_FLUSHER_VERSION 2
+
+class MockMemoryFlusherCompositor : public MockCompositor
+{
+public:
+ MockMemoryFlusherCompositor()
+ : MockCompositor(&MockMemoryFlusherCompositor::TestSetup, this)
+ {
+ ds_inf("%s : this(%p)", __func__, this);
+
+ // initialize the flags to check
+ bSurfaceDestroyed = false;
+
+ bDestroyed = false;
+ bGetFlusherInfo = false;
+ bDestroyFlusherInfo = false;
+ }
+
+ ~MockMemoryFlusherCompositor()
+ {
+ ds_inf("%s : this(%p)", __func__, this);
+ }
+
+ static void TestSetup(void *data)
+ {
+ MockMemoryFlusherCompositor *mockComp =
+ static_cast<MockMemoryFlusherCompositor *>(data);
+ Compositor *comp = mockComp->compositor;
+
+ ds_inf("%s: mockComp(%p)", __func__, mockComp);
+
+ // new surface listener
+ mockComp->mNewSurfaceListener.notify =
+ MockMemoryFlusherCompositor::NewSurfaceCallback;
+ mockComp->mNewSurfaceListener.parent = mockComp;
+ ds_compositor_add_new_surface_listener(comp->compositor,
+ &mockComp->mNewSurfaceListener);
+
+ mockComp->mMemoryFlusher =
+ ds_tizen_memory_flusher_create(comp->display);
+
+ // destroy listener
+ mockComp->mDestroyListener.notify =
+ MockMemoryFlusherCompositor::DestroyCallback;
+ mockComp->mDestroyListener.parent = mockComp;
+ ds_tizen_memory_flusher_add_destroy_listener(mockComp->mMemoryFlusher,
+ &mockComp->mDestroyListener);
+
+ // get_flusher_info listener
+ mockComp->mGetFlusherInfoListener.notify =
+ MockMemoryFlusherCompositor::GetFlusherInfoCallback;
+ mockComp->mGetFlusherInfoListener.parent = mockComp;
+ ds_tizen_memory_flusher_add_get_flusher_info_listener(
+ mockComp->mMemoryFlusher,
+ &mockComp->mGetFlusherInfoListener);
+ }
+
+ static void NewSurfaceCallback(struct wl_listener *listener, void *data)
+ {
+ MockMemoryFlusherCompositor *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 =
+ MockMemoryFlusherCompositor::DelSurfaceCallback;
+ mockComp->mDelSurfaceListener.parent = mockComp;
+ ds_surface_add_destroy_listener(surface,
+ &mockComp->mDelSurfaceListener);
+ }
+
+ static void DelSurfaceCallback(struct wl_listener *listener, void *data)
+ {
+ MockMemoryFlusherCompositor *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__);
+
+ MockMemoryFlusherCompositor *mockComp =
+ reinterpret_cast<DestroyListener *>(listener)->parent;
+
+ mockComp->bDestroyed = true;
+ }
+
+ static void GetFlusherInfoCallback(struct wl_listener *listener,
+ void *data)
+ {
+ ds_inf("%s", __func__);
+
+ MockMemoryFlusherCompositor *mockComp =
+ reinterpret_cast<GetFlusherInfoListener *>(listener)->parent;
+ struct ds_tizen_memory_flusher_info *info =
+ static_cast<struct ds_tizen_memory_flusher_info *>(data);
+
+ ds_inf("%s: mockComp(%p), info(%p)", __func__, mockComp, info);
+
+ mockComp->bGetFlusherInfo = true;
+
+ mockComp->mInfo = info;
+ mockComp->mSurface =
+ ds_tizen_memory_flusher_info_get_surface(mockComp->mInfo);
+
+ // info destroy listener
+ mockComp->mFlusherInfoDestroyListener.notify =
+ MockMemoryFlusherCompositor::FlusherInfoDestroyCallback;
+ mockComp->mFlusherInfoDestroyListener.parent = mockComp;
+ ds_tizen_memory_flusher_info_add_destroy_listener(mockComp->mInfo,
+ &mockComp->mFlusherInfoDestroyListener);
+ }
+
+ static void FlusherInfoDestroyCallback(struct wl_listener *listener,
+ void *data)
+ {
+ ds_inf("%s", __func__);
+
+ MockMemoryFlusherCompositor *mockComp =
+ reinterpret_cast<FlusherInfoDestroyListener *>(listener)->parent;
+ struct ds_tizen_memory_flusher_info *info =
+ static_cast<struct ds_tizen_memory_flusher_info *>(data);
+
+ ds_inf("%s: mockComp(%p), info(%p)", __func__, mockComp, info);
+
+ if (mockComp->mInfo == info) {
+ ds_inf("%s: info is deleted.", __func__);
+ mockComp->bDestroyFlusherInfo = true;
+ }
+ }
+
+ void SendMemoryFlusherInfoFlush()
+ {
+ ds_inf("%s", __func__);
+
+ ds_tizen_memory_flusher_info_send_flush(mInfo);
+ }
+
+ void SendMemoryFlusherInfoFreeFlush()
+ {
+ ds_inf("%s", __func__);
+
+ ds_tizen_memory_flusher_info_send_free_flush(mInfo);
+ }
+
+public:
+ bool bSurfaceDestroyed;
+ bool bDestroyed;
+ bool bGetFlusherInfo;
+ bool bDestroyFlusherInfo;
+
+private:
+ struct ds_tizen_memory_flusher_info *mInfo;
+ struct ds_surface *mSurface;
+
+ struct NewSurfaceListener : ::wl_listener {
+ MockMemoryFlusherCompositor *parent;
+ };
+ NewSurfaceListener mNewSurfaceListener;
+
+ struct DelSurfaceListener : ::wl_listener {
+ MockMemoryFlusherCompositor *parent;
+ };
+ DelSurfaceListener mDelSurfaceListener;
+
+ struct ds_tizen_memory_flusher *mMemoryFlusher;
+
+ struct DestroyListener : ::wl_listener {
+ MockMemoryFlusherCompositor *parent;
+ };
+ DestroyListener mDestroyListener;
+
+ struct GetFlusherInfoListener : ::wl_listener {
+ MockMemoryFlusherCompositor *parent;
+ };
+ GetFlusherInfoListener mGetFlusherInfoListener;
+
+ struct FlusherInfoDestroyListener : ::wl_listener {
+ MockMemoryFlusherCompositor *parent;
+ };
+ FlusherInfoDestroyListener mFlusherInfoDestroyListener;
+};
+
+class MockMemoryFlusherClient : public MockClient
+{
+public:
+ MockMemoryFlusherClient()
+ : bFlushEvent(false),
+ bFreeFlushEvent(false),
+ compositor_res(nullptr),
+ tizen_surface_shm(nullptr)
+ {}
+ MockMemoryFlusherClient(const struct wl_registry_listener *listener)
+ : MockClient(listener, this)
+ {
+ ds_inf("%s", __func__);
+
+ bFlushEvent = false;
+ bFreeFlushEvent = false;
+ }
+ ~MockMemoryFlusherClient()
+ {
+ 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 SetTizenSurfaceShm(struct tizen_surface_shm *global_res)
+ {
+ ds_inf("%s", __func__);
+
+ tizen_surface_shm = global_res;
+ }
+
+ struct tizen_surface_shm *GetTizenSurfaceShm()
+ {
+ ds_inf("%s", __func__);
+
+ return tizen_surface_shm;
+ }
+
+public:
+ bool bFlushEvent;
+ bool bFreeFlushEvent;
+
+private:
+ struct wl_compositor *compositor_res;
+ struct tizen_surface_shm *tizen_surface_shm;
+};
+
+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__);
+
+ MockMemoryFlusherClient *client = static_cast<MockMemoryFlusherClient *>(data);
+ struct wl_compositor *compositor_res;
+ struct tizen_surface_shm *surface_shm_res;
+
+ 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_surface_shm")) {
+ surface_shm_res = (struct tizen_surface_shm *)wl_registry_bind(registry,
+ name, &tizen_surface_shm_interface, TIZEN_MEMORY_FLUSHER_VERSION);
+ if (surface_shm_res == nullptr) {
+ ds_err("wl_registry_bind() failed. tizen_surface_shm resource.");
+ return;
+ }
+ client->SetTizenSurfaceShm(surface_shm_res);
+ }
+}
+
+static void
+client_registry_cb_global_remove(void *data, struct wl_registry *registry,
+ uint32_t name)
+{
+ ds_inf("%s", __func__);
+
+ MockMemoryFlusherClient *client = static_cast<MockMemoryFlusherClient *>(data);
+ struct wl_compositor *compositor_res = client->GetWlCompositor();
+ struct tizen_surface_shm *surface_shm_res = client->GetTizenSurfaceShm();
+
+ tizen_surface_shm_destroy(surface_shm_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
+};
+
+static void
+client_tizen_surface_shm_flusher_cb_flush(void *data,
+ struct tizen_surface_shm_flusher *surface_shm_flusher_res)
+{
+ ds_inf("%s", __func__);
+
+ MockMemoryFlusherClient *client = static_cast<MockMemoryFlusherClient *>(data);
+
+ client->bFlushEvent = true;
+}
+
+static void
+client_tizen_surface_shm_flusher_cb_free_flush(void *data,
+ struct tizen_surface_shm_flusher *surface_shm_flusher_res)
+{
+ ds_inf("%s", __func__);
+
+ MockMemoryFlusherClient *client = static_cast<MockMemoryFlusherClient *>(data);
+
+ client->bFreeFlushEvent = true;
+}
+
+static const struct
+tizen_surface_shm_flusher_listener surface_shm_flusher_cb_listener = {
+ .flush = client_tizen_surface_shm_flusher_cb_flush,
+ .free_flush = client_tizen_surface_shm_flusher_cb_free_flush,
+};
+
+class MemoryFlusherTest : public ::testing::Test
+{
+public:
+ void SetUp(void) override;
+ void TearDown(void) override;
+
+ MockMemoryFlusherCompositor *comp;
+ MockMemoryFlusherClient *client;
+ struct wl_compositor *compositor_res;
+ struct tizen_surface_shm *surface_shm_res;
+ struct wl_surface *surface_res;
+ struct tizen_surface_shm_flusher *surface_shm_flusher_res;
+};
+
+void
+MemoryFlusherTest::SetUp(void)
+{
+ //ds_log_init(DS_DBG, NULL);
+
+ ds_inf("%s", __func__);
+
+ comp = new MockMemoryFlusherCompositor();
+ client = new MockMemoryFlusherClient(®istry_listener);
+ compositor_res = client->GetWlCompositor();
+ surface_shm_res = client->GetTizenSurfaceShm();
+ surface_res = wl_compositor_create_surface(compositor_res);
+
+ surface_shm_flusher_res =
+ tizen_surface_shm_get_flusher(surface_shm_res, surface_res);
+
+ tizen_surface_shm_flusher_add_listener(surface_shm_flusher_res,
+ &surface_shm_flusher_cb_listener, client);
+
+ client->RoundTrip();
+}
+
+void
+MemoryFlusherTest::TearDown(void)
+{
+ ds_inf("%s", __func__);
+
+ tizen_surface_shm_flusher_destroy(surface_shm_flusher_res);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bDestroyFlusherInfo);
+
+ wl_surface_destroy(surface_res);
+ client->RoundTrip();
+ EXPECT_TRUE(comp->bSurfaceDestroyed);
+
+ delete client;
+ delete comp;
+}
+
+TEST_F(MemoryFlusherTest, Create_P)
+{
+ EXPECT_TRUE(true);
+ EXPECT_TRUE(comp->bGetFlusherInfo);
+}
+
+TEST_F(MemoryFlusherTest, Ev_TizenSurfaceShmFlusherFlush)
+{
+ comp->SendMemoryFlusherInfoFlush();
+ comp->Process();
+
+ client->RoundTrip();
+ EXPECT_TRUE(client->bFlushEvent);
+}
+
+TEST_F(MemoryFlusherTest, Ev_TizenSurfaceShmFlusherFreeFlush)
+{
+ comp->SendMemoryFlusherInfoFreeFlush();
+ comp->Process();
+
+ client->RoundTrip();
+ EXPECT_TRUE(client->bFreeFlushEvent);
+}