1 #include <libds/output.h>
2 #include <libds/backend/wayland.h>
3 #include <libds-tizen/screenshooter.h>
4 #ifdef TIZEN_SCREENMIRROR_STOP
5 #undef TIZEN_SCREENMIRROR_STOP
7 #include <tizen-extension-client-protocol.h>
8 #include <wayland-tbm-client.h>
9 #include <tbm_surface.h>
12 #include "mockclient.h"
13 #include "mockcompositor.h"
15 #define TIZEN_SCREENSHOOTER_VERSION 3
16 #define SHM_BUF_WIDTH 1920
17 #define SHM_BUF_HEIGHT 1080
18 #define SHM_BUF_STRIDE 7680 //width * 4
19 #define SHM_BUF_FORMAT WL_SHM_FORMAT_XRGB8888
21 class MockScreenShooterCompositor : public MockCompositor
24 MockScreenShooterCompositor()
25 : MockCompositor(&MockScreenShooterCompositor::TestSetup, this)
27 ds_inf("%s : this(%p)", __func__, this);
31 bDestroyMirror = false;
34 bAutoRotation = false;
38 mScreenShooter = nullptr;
39 mScreenMirror = nullptr;
42 mDestroyListener = {};
43 mNewScreenMirrorListener = {};
44 mScreenShootListener = {};
45 mScreenMirrorDestroyListener = {};
46 mScreenMirrorSetStretchListener = {};
47 mScreenMirrorQueueListener = {};
48 mScreenMirrorDequeueListener = {};
49 mScreenMirrorStartListener = {};
50 mScreenMirrorStopListener = {};
51 mScreenMirrorAutoRotationListener = {};
54 ~MockScreenShooterCompositor()
56 ds_inf("%s : this(%p)", __func__, this);
59 static void TestSetup(void *data)
61 MockScreenShooterCompositor *mockComp =
62 static_cast<MockScreenShooterCompositor *>(data);
63 Compositor *comp = mockComp->compositor;
65 ds_inf("%s: mockComp(%p)", __func__, mockComp);
67 mockComp->mBackend = ds_wl_backend_create(comp->display, NULL);
68 mockComp->new_output.notify = screenshooter_backend_handle_new_output;
69 ds_backend_add_new_output_listener(mockComp->mBackend, &mockComp->new_output);
70 ds_backend_start(mockComp->mBackend);
72 mockComp->mScreenShooter =
73 ds_tizen_screenshooter_create(comp->display);
75 // add destroy listener
76 mockComp->mDestroyListener.notify =
77 MockScreenShooterCompositor::DestroyCallback;
78 mockComp->mDestroyListener.parent = mockComp;
79 ds_tizen_screenshooter_add_destroy_listener(mockComp->mScreenShooter,
80 &mockComp->mDestroyListener);
82 // add newscreenmirror listener
83 mockComp->mNewScreenMirrorListener.notify =
84 MockScreenShooterCompositor::NewScreenMirrorCallback;
85 mockComp->mNewScreenMirrorListener.parent = mockComp;
86 ds_tizen_screenshooter_add_get_screenmirror_listener(mockComp->mScreenShooter,
87 &mockComp->mNewScreenMirrorListener);
90 mockComp->mScreenShootListener.notify =
91 MockScreenShooterCompositor::ScreenShootCallback;
92 mockComp->mScreenShootListener.parent = mockComp;
93 ds_tizen_screenshooter_add_shoot_listener(mockComp->mScreenShooter,
94 &mockComp->mScreenShootListener);
97 static void screenshooter_backend_handle_new_output(struct wl_listener *listener,
100 MockScreenShooterCompositor *mockComp;
102 mockComp = wl_container_of(listener, mockComp, new_output);
103 mockComp->mOutput = static_cast<struct ds_output *>(data);
105 ds_inf("New ds_output(%p)", mockComp->mOutput);
107 ds_output_create_global(mockComp->mOutput);
108 ds_inf("create output global");
111 static void DestroyCallback(struct wl_listener *listener, void *data)
113 ds_inf("%s", __func__);
115 MockScreenShooterCompositor *mockComp =
116 reinterpret_cast<DestroyListener *>(listener)->parent;
118 mockComp->bDestroyed = true;
121 static void NewScreenMirrorCallback(struct wl_listener *listener,
124 ds_inf("%s", __func__);
126 MockScreenShooterCompositor *mockComp =
127 reinterpret_cast<NewScreenMirrorListener *>(listener)->parent;
128 struct ds_tizen_screenmirror *mirror =
129 static_cast<struct ds_tizen_screenmirror *>(data);
131 ds_inf("%s: mockComp(%p), mirror(%p)", __func__, mockComp, mirror);
133 mockComp->bMirror = true;
134 mockComp->mScreenMirror = mirror;
136 // add destroy listener
137 mockComp->mScreenMirrorDestroyListener.notify =
138 MockScreenShooterCompositor::ScreenMirrorDestroyCallback;
139 mockComp->mScreenMirrorDestroyListener.parent = mockComp;
140 ds_tizen_screenmirror_add_destroy_listener(mockComp->mScreenMirror,
141 &mockComp->mScreenMirrorDestroyListener);
143 // add set_stretch listener
144 mockComp->mScreenMirrorSetStretchListener.notify =
145 MockScreenShooterCompositor::ScreenMirrorSetStretchCallback;
146 mockComp->mScreenMirrorSetStretchListener.parent = mockComp;
147 ds_tizen_screenmirror_add_set_stretch_listener(mockComp->mScreenMirror,
148 &mockComp->mScreenMirrorSetStretchListener);
150 // add queue listener
151 mockComp->mScreenMirrorQueueListener.notify =
152 MockScreenShooterCompositor::ScreenMirrorQueueCallback;
153 mockComp->mScreenMirrorQueueListener.parent = mockComp;
154 ds_tizen_screenmirror_add_queue_listener(mockComp->mScreenMirror,
155 &mockComp->mScreenMirrorQueueListener);
157 // add dequeue listener
158 mockComp->mScreenMirrorDequeueListener.notify =
159 MockScreenShooterCompositor::ScreenMirrorDequeueCallback;
160 mockComp->mScreenMirrorDequeueListener.parent = mockComp;
161 ds_tizen_screenmirror_add_dequeue_listener(mockComp->mScreenMirror,
162 &mockComp->mScreenMirrorDequeueListener);
164 // add start listener
165 mockComp->mScreenMirrorStartListener.notify =
166 MockScreenShooterCompositor::ScreenMirrorStartCallback;
167 mockComp->mScreenMirrorStartListener.parent = mockComp;
168 ds_tizen_screenmirror_add_start_listener(mockComp->mScreenMirror,
169 &mockComp->mScreenMirrorStartListener);
172 mockComp->mScreenMirrorStopListener.notify =
173 MockScreenShooterCompositor::ScreenMirrorStopCallback;
174 mockComp->mScreenMirrorStopListener.parent = mockComp;
175 ds_tizen_screenmirror_add_stop_listener(mockComp->mScreenMirror,
176 &mockComp->mScreenMirrorStopListener);
178 // add auto rotation listener
179 mockComp->mScreenMirrorAutoRotationListener.notify =
180 MockScreenShooterCompositor::ScreenMirrorAutoRotationCallback;
181 mockComp->mScreenMirrorAutoRotationListener.parent = mockComp;
182 ds_tizen_screenmirror_add_auto_rotation_listener(mockComp->mScreenMirror,
183 &mockComp->mScreenMirrorAutoRotationListener);
186 static void ScreenShootCallback(struct wl_listener *listener,
189 ds_inf("%s", __func__);
191 MockScreenShooterCompositor *mockComp =
192 reinterpret_cast<ScreenShootListener *>(listener)->parent;
193 struct ds_tizen_screenshooter_event_shoot *event =
194 static_cast<struct ds_tizen_screenshooter_event_shoot *>(data);
197 ds_inf("%s: mockComp(%p), output(%p), buffer(%p), client(%p), auto_rotate:%d",
198 __func__, mockComp, event->output, event->buffer, event->client,
199 event->auto_rotation ? 1 : 0);
201 mockComp->bShoot = true;
202 ds_tizen_screenshooter_send_shoot_done(mockComp->mScreenShooter, event->client);
205 static void ScreenMirrorDestroyCallback(struct wl_listener *listener,
208 ds_inf("%s", __func__);
210 MockScreenShooterCompositor *mockComp =
211 reinterpret_cast<ScreenMirrorDestroyListener *>(listener)->parent;
212 struct ds_tizen_screenmirror *mirror =
213 static_cast<struct ds_tizen_screenmirror *>(data);
215 ds_inf("%s: mockComp(%p), info(%p)", __func__, mockComp, mirror);
217 if (mockComp->mScreenMirror == mirror) {
218 ds_inf("%s: info is deleted.", __func__);
219 mockComp->bDestroyMirror = true;
223 static void ScreenMirrorSetStretchCallback(struct wl_listener *listener,
226 ds_inf("%s", __func__);
228 MockScreenShooterCompositor *mockComp =
229 reinterpret_cast<ScreenMirrorSetStretchListener *>(listener)->parent;
230 enum ds_tizen_screenmirror_stretch *stretch = (enum ds_tizen_screenmirror_stretch *)data;
232 ds_inf("%s: mockComp(%p), stretch(%d)", __func__, mockComp, *stretch);
235 static void ScreenMirrorQueueCallback(struct wl_listener *listener,
238 ds_inf("%s", __func__);
240 MockScreenShooterCompositor *mockComp =
241 reinterpret_cast<ScreenMirrorQueueListener *>(listener)->parent;
242 struct ds_buffer *buffer =
243 static_cast<struct ds_buffer *>(data);
245 ds_inf("%s: mockComp(%p), queue(%p)", __func__, mockComp, buffer);
248 static void ScreenMirrorDequeueCallback(struct wl_listener *listener,
251 ds_inf("%s", __func__);
253 MockScreenShooterCompositor *mockComp =
254 reinterpret_cast<ScreenMirrorDequeueListener *>(listener)->parent;
255 struct ds_buffer *buffer =
256 static_cast<struct ds_buffer *>(data);
258 ds_inf("%s: mockComp(%p), dequeue(%p)", __func__, mockComp, buffer);
260 ds_tizen_screenmirror_send_dequeued(mockComp->mScreenMirror, buffer);
263 static void ScreenMirrorStartCallback(struct wl_listener *listener,
266 ds_inf("%s", __func__);
268 MockScreenShooterCompositor *mockComp =
269 reinterpret_cast<ScreenMirrorDequeueListener *>(listener)->parent;
271 ds_inf("%s: mockComp(%p), start", __func__, mockComp);
273 mockComp->bStart = true;
276 static void ScreenMirrorStopCallback(struct wl_listener *listener,
279 ds_inf("%s", __func__);
281 MockScreenShooterCompositor *mockComp =
282 reinterpret_cast<ScreenMirrorDequeueListener *>(listener)->parent;
284 ds_inf("%s: mockComp(%p), stop", __func__, mockComp);
286 mockComp->bStart = false;
289 static void ScreenMirrorAutoRotationCallback(struct wl_listener *listener,
292 ds_inf("%s", __func__);
294 MockScreenShooterCompositor *mockComp =
295 reinterpret_cast<ScreenMirrorDequeueListener *>(listener)->parent;
296 uint32_t *set = (uint32_t *)data;
298 ds_inf("%s: mockComp(%p), autorotation(%d)", __func__, mockComp, *set);
301 mockComp->bAutoRotation = true;
303 mockComp->bAutoRotation = false;
316 struct ds_backend *mBackend;
317 struct ds_buffer *mBuffer;
318 struct ds_output *mOutput;
319 struct ds_tizen_screenshooter *mScreenShooter;
320 struct ds_tizen_screenmirror *mScreenMirror;
321 struct wl_listener new_output;
323 struct DestroyListener : ::wl_listener {
324 MockScreenShooterCompositor *parent;
326 DestroyListener mDestroyListener;
328 struct NewScreenMirrorListener : ::wl_listener {
329 MockScreenShooterCompositor *parent;
331 NewScreenMirrorListener mNewScreenMirrorListener;
333 struct ScreenShootListener : ::wl_listener {
334 MockScreenShooterCompositor *parent;
336 ScreenShootListener mScreenShootListener;
338 struct ScreenMirrorDestroyListener : ::wl_listener {
339 MockScreenShooterCompositor *parent;
341 ScreenMirrorDestroyListener mScreenMirrorDestroyListener;
343 struct ScreenMirrorSetStretchListener : ::wl_listener {
344 MockScreenShooterCompositor *parent;
346 ScreenMirrorSetStretchListener mScreenMirrorSetStretchListener;
348 struct ScreenMirrorQueueListener : ::wl_listener {
349 MockScreenShooterCompositor *parent;
351 ScreenMirrorQueueListener mScreenMirrorQueueListener;
353 struct ScreenMirrorDequeueListener : ::wl_listener {
354 MockScreenShooterCompositor *parent;
356 ScreenMirrorDequeueListener mScreenMirrorDequeueListener;
358 struct ScreenMirrorStartListener : ::wl_listener {
359 MockScreenShooterCompositor *parent;
361 ScreenMirrorStartListener mScreenMirrorStartListener;
363 struct ScreenMirrorStopListener : ::wl_listener {
364 MockScreenShooterCompositor *parent;
366 ScreenMirrorStopListener mScreenMirrorStopListener;
368 struct ScreenMirrorAutoRotationListener : ::wl_listener {
369 MockScreenShooterCompositor *parent;
371 ScreenMirrorAutoRotationListener mScreenMirrorAutoRotationListener;
374 class MockScreenShooterClient : public MockClient
377 MockScreenShooterClient()
378 : bShootEvent(false),
379 bMirrorStartEvent(false),
380 bMirrorStopEvent(false),
384 screenshooter_res(nullptr),
385 screenmirror_res(nullptr)
387 MockScreenShooterClient(const struct wl_registry_listener *listener)
388 : MockClient(listener, this)
390 ds_inf("%s", __func__);
393 bMirrorStartEvent = false;
394 bMirrorStopEvent = false;
395 output_res = nullptr;
398 screenshooter_res = nullptr;
399 screenmirror_res = nullptr;
401 ~MockScreenShooterClient()
403 ds_inf("%s", __func__);
406 void SetWlOutput(struct wl_output *global_res)
408 ds_inf("%s", __func__);
410 output_res = global_res;
413 struct wl_output *GetWlOutput()
415 ds_inf("%s", __func__);
420 void SetWlShm(struct wl_shm *global_res)
422 ds_inf("%s", __func__);
424 shm_res = global_res;
427 struct wl_shm *GetWlShm()
429 ds_inf("%s", __func__);
434 void SetWlShmPool(struct wl_shm_pool *_shm_pool)
436 ds_inf("%s", __func__);
438 shm_pool = _shm_pool;
441 struct wl_shm_pool *GetWlShmPool()
443 ds_inf("%s", __func__);
448 void SetTizenScreenShooter(struct tizen_screenshooter *resource)
450 ds_inf("%s", __func__);
452 screenshooter_res = resource;
455 struct tizen_screenshooter *GetTizenScreenShooter()
457 ds_inf("%s", __func__);
459 return screenshooter_res;
463 void SetTizenScreenMirror(struct tizen_screenmirror *resource)
465 ds_inf("%s", __func__);
467 screenmirror_res = resource;
470 struct tizen_screenmirror *GetTizenScreenMirror()
472 ds_inf("%s", __func__);
474 return screenmirror_res;
479 bool bMirrorStartEvent;
480 bool bMirrorStopEvent;
483 struct wl_output *output_res;
484 struct wl_shm *shm_res;
485 struct wl_shm_pool *shm_pool;
486 struct tizen_screenshooter *screenshooter_res;
487 struct tizen_screenmirror *screenmirror_res;
491 client_tizen_screenshooter_cb_format(void *data,
492 struct tizen_screenshooter *screenshooter_res, uint32_t format)
497 client_tizen_screenshooter_cb_noti(void *data,
498 struct tizen_screenshooter *screenshooter_res, uint32_t noti)
504 client_tizen_screenshooter_cb_done(void *data,
505 struct tizen_screenshooter *screenshooter_res)
507 MockScreenShooterClient *client = static_cast<MockScreenShooterClient *>(data);
509 client->bShootEvent = true;
513 tizen_screenshooter_listener screenshooter_cb_listener = {
514 client_tizen_screenshooter_cb_format,
515 client_tizen_screenshooter_cb_noti,
516 client_tizen_screenshooter_cb_done,
520 _client_tizen_screenshooter_destroy_anonymous_file(int fd)
529 _client_tizen_screenshooter_create_anonymous_file(off_t size)
531 static const char tempname[] = "/shooter-XXXXXX";
538 path = getenv("XDG_RUNTIME_DIR");
544 name_size = strlen(path) + sizeof(tempname);
545 name = (char *)malloc(name_size);
549 snprintf(name, name_size, "%s%s", path, tempname);
560 ret = ftruncate(fd, size);
569 static struct wl_shm_pool *
570 _client_tizen_screenshooter_create_shm_pool(struct wl_shm *shm, int size)
572 struct wl_shm_pool *shm_pool = NULL;
576 fd = _client_tizen_screenshooter_create_anonymous_file(size);
580 data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
584 memset(data, 0xff, size);
587 shm_pool = wl_shm_create_pool(shm, fd, size);
588 if (shm_pool == NULL)
591 _client_tizen_screenshooter_destroy_anonymous_file(fd);
597 _client_tizen_screenshooter_destroy_anonymous_file(fd);
603 _client_tizen_screenshooter_destroy_shm_pool(struct wl_shm_pool *shm_pool)
608 wl_shm_pool_destroy(shm_pool);
612 client_registry_cb_global(void *data, struct wl_registry *registry,
613 uint32_t name, const char *interface, uint32_t version)
615 ds_inf("%s", __func__);
617 MockScreenShooterClient *client = static_cast<MockScreenShooterClient *>(data);
618 struct tizen_screenshooter *screenshooter_res;
619 struct wl_shm *shm_res;
620 struct wl_shm_pool *shm_pool;
621 struct wl_output *output_res;
623 if (!strcmp(interface, "wl_shm")) {
624 shm_res = (struct wl_shm *)wl_registry_bind(registry,
625 name, &wl_shm_interface, 1);
626 if (shm_res == nullptr) {
627 ds_err("wl_registry_bind() failed. wl_shm resource.");
630 shm_pool = _client_tizen_screenshooter_create_shm_pool(shm_res, SHM_BUF_WIDTH * 4 * SHM_BUF_HEIGHT);
631 if (shm_pool == NULL) {
632 ds_err("wl_registry_bind() failed. wl_shm_pool create fail.");
633 wl_shm_destroy(shm_res);
636 client->SetWlShm(shm_res);
637 client->SetWlShmPool(shm_pool);
638 } else if (!strcmp(interface, "wl_output")) {
639 output_res = (struct wl_output *)wl_registry_bind(registry,
640 name, &wl_output_interface, 1);
641 if (output_res == nullptr) {
642 ds_err("wl_registry_bind() failed. wl_output resource.");
645 client->SetWlOutput(output_res);
646 } else if (!strcmp(interface, "tizen_screenshooter")) {
647 screenshooter_res = (struct tizen_screenshooter *)wl_registry_bind(registry,
648 name, &tizen_screenshooter_interface, TIZEN_SCREENSHOOTER_VERSION);
649 if (screenshooter_res == nullptr) {
650 ds_err("wl_registry_bind() failed. tizen_screenshooter resource.");
653 client->SetTizenScreenShooter(screenshooter_res);
655 tizen_screenshooter_add_listener(screenshooter_res,
656 &screenshooter_cb_listener, client);
661 client_registry_cb_global_remove(void *data, struct wl_registry *registry,
664 ds_inf("%s", __func__);
666 MockScreenShooterClient *client = static_cast<MockScreenShooterClient *>(data);
667 struct wl_shm *shm_res = client->GetWlShm();
668 struct wl_shm_pool *shm_pool = client->GetWlShmPool();
669 struct tizen_screenshooter *screenshooter_res = client->GetTizenScreenShooter();
670 struct tizen_screenmirror *screenmirror_res = client->GetTizenScreenMirror();
672 if (screenmirror_res)
673 tizen_screenmirror_destroy(screenmirror_res);
674 tizen_screenshooter_destroy(screenshooter_res);
675 _client_tizen_screenshooter_destroy_shm_pool(shm_pool);
676 wl_shm_destroy(shm_res);
679 static const struct wl_registry_listener registry_listener = {
680 .global = client_registry_cb_global,
681 .global_remove = client_registry_cb_global_remove
684 class ScreenShooterTest : public ::testing::Test
687 void SetUp(void) override;
688 void TearDown(void) override;
690 MockScreenShooterCompositor *comp;
691 MockScreenShooterClient *client;
692 struct wl_output *output_res;
693 struct wl_shm *shm_res;
694 struct wl_shm_pool *shm_pool;
695 struct wl_buffer *buffer_res1;
696 struct wl_buffer *buffer_res2;
697 struct wl_buffer *buffer_res3;
698 struct tizen_screenshooter *screenshooter_res;
699 struct tizen_screenmirror *screenmirror_res;
703 ScreenShooterTest::SetUp(void)
705 //ds_log_init(DS_DBG, NULL);
707 ds_inf("%s", __func__);
709 comp = new MockScreenShooterCompositor();
710 client = new MockScreenShooterClient(®istry_listener);
711 output_res = client->GetWlOutput();
712 shm_res = client->GetWlShm();
713 shm_pool = client->GetWlShmPool();
714 screenshooter_res = client->GetTizenScreenShooter();
720 ScreenShooterTest::TearDown(void)
722 ds_inf("%s", __func__);
730 TEST_F(ScreenShooterTest, Create_P)
735 TEST_F(ScreenShooterTest, Req_TizenScreenShooterShot)
737 buffer_res1 = wl_shm_pool_create_buffer(shm_pool, 0,
738 SHM_BUF_WIDTH, SHM_BUF_HEIGHT, SHM_BUF_STRIDE, SHM_BUF_FORMAT);
739 tizen_screenshooter_shoot(screenshooter_res, output_res, buffer_res1);
741 EXPECT_TRUE(comp->bShoot);
743 EXPECT_TRUE(client->bShootEvent);