haltest: enhance tdm_client voutput test
[platform/core/uifw/libtdm.git] / haltests / src / tc_tdm_client.cpp
1 /**************************************************************************
2  *
3  * Copyright 2017 Samsung Electronics co., Ltd. All Rights Reserved.
4  *
5  * Contact: Konstantin Drabeniuk <k.drabeniuk@samsung.com>
6  * Contact: Andrii Sokolenko <a.sokolenko@samsung.com>
7  * Contact: Roman Marchenko <r.marchenko@samsung.com>
8  * Contact: Sergey Sizonov <s.sizonov@samsung.com>
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the
12  * "Software"), to deal in the Software without restriction, including
13  * without limitation the rights to use, copy, modify, merge, publish,
14  * distribute, sub license, and/or sell copies of the Software, and to
15  * permit persons to whom the Software is furnished to do so, subject to
16  * the following conditions:
17  *
18  * The above copyright notice and this permission notice (including the
19  * next paragraph) shall be included in all copies or substantial portions
20  * of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29  *
30 **************************************************************************/
31
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <sys/signalfd.h>
35 #include <poll.h>
36 #include <sys/prctl.h>
37
38 #include "tc_tdm.h"
39 #include "tdm_client.h"
40
41 /* LCOV_EXCL_START */
42
43 enum {
44         TDM_UT_PIPE_MSG_NONE,
45         TDM_UT_PIPE_MSG_REPLY,
46         TDM_UT_PIPE_MSG_SERVER_READY,
47         TDM_UT_PIPE_MSG_SERVER_FAILED,
48         TDM_UT_PIPE_MSG_DPMS_ON,
49         TDM_UT_PIPE_MSG_DPMS_OFF,
50         TDM_UT_PIPE_MSG_TERMINATE_SERVER,
51 };
52
53 #define TDM_UT_WAIT(fmt, ...) \
54         do { \
55                 char ch; \
56                 do { \
57                         printf(fmt" [n]):next ", ##__VA_ARGS__); \
58                         ch = tc_tdm_getchar(); \
59                 } while (ch != 'n'); \
60         } while (0)
61
62 static int _tc_tdm_pipe_read_msg(int fd);
63 static bool _tc_tdm_pipe_write_msg(int fd, int reply_fd, int msg);
64 static pid_t _tc_tdm_client_server_fork(int *pipe_to_parent, int *pipe_to_child);
65
66 class TDMClient : public TDMEnv
67 {
68 public:
69         static pid_t server_pid;
70
71         /* 0: read, 1: write */
72         static int pipe_parent[2];
73         static int pipe_child[2];
74
75         tdm_client *client;
76         tdm_client_output *output;
77         tdm_client_vblank *vblank;
78         tdm_client_voutput *voutput;
79
80         double vrefresh_interval, start, end;
81
82         TDMClient();
83
84         void SetUp(void);
85         void TearDown(void);
86         bool PrepareClient(void);
87         bool PrepareOutput(void);
88         bool PrepareVblank(void);
89
90         static void TearDownTestCase(void);
91         static void ServerFork(void);
92         static void ServerKill(void);
93 };
94
95 pid_t TDMClient::server_pid = -1;
96 int TDMClient::pipe_parent[2] = {-1, -1};
97 int TDMClient::pipe_child[2] = {-1, -1};
98
99 void TDMClient::TearDownTestCase(void)
100 {
101         ServerKill();
102 }
103
104 void TDMClient::ServerFork(void)
105 {
106         if (server_pid > 0)
107                 return;
108
109         server_pid = _tc_tdm_client_server_fork(pipe_parent, pipe_child);
110         ASSERT_GT(server_pid, 0);
111 }
112
113 void TDMClient::ServerKill(void)
114 {
115         if (pipe_child[0] >= 0)
116                 close(pipe_child[0]);
117         if (pipe_child[1] >= 0) {
118                 if (server_pid > 0) {
119                         bool ret = _tc_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_TERMINATE_SERVER);
120                         if (ret) {
121                                 if (waitpid(server_pid, NULL, 0) == server_pid)
122                                         TDM_INFO("*** server terminated ***");
123                                 else
124                                         TDM_ERR("*** failed to terminate server ***");
125                         } else {
126                                 if (kill(server_pid, 9) < 0)
127                                         TDM_ERR("*** failed to kill server ***");
128                         }
129                 }
130                 close(pipe_child[1]);
131         }
132
133         if (pipe_parent[0] >= 0)
134                 close(pipe_parent[0]);
135         if (pipe_parent[1] >= 0)
136                 close(pipe_parent[1]);
137
138         server_pid = -1;
139         pipe_parent[0] = pipe_parent[1] = -1;
140         pipe_child[0] = pipe_child[1] = -1;
141 }
142
143 TDMClient::TDMClient()
144 {
145         client = NULL;
146         output = NULL;
147         vblank = NULL;
148         voutput = NULL;
149         vrefresh_interval = start = end = 0.0;
150 }
151
152 void TDMClient::SetUp(void)
153 {
154         TDMEnv::SetUp();
155
156         if (server_pid == -1)
157                 ServerFork();
158 }
159
160 void TDMClient::TearDown(void)
161 {
162         if (vblank)
163                 tdm_client_vblank_destroy(vblank);
164         if (client)
165                 tdm_client_destroy(client);
166
167         TDMEnv::TearDown();
168 }
169
170 bool TDMClient::PrepareClient(void)
171 {
172         tdm_error ret;
173         client = tdm_client_create(&ret);
174         TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
175         TDM_UT_RETURN_FALSE_IF_FAIL(client != NULL);
176
177         return true;
178 }
179
180 bool TDMClient::PrepareOutput(void)
181 {
182         tdm_error ret;
183
184         TDM_UT_RETURN_FALSE_IF_FAIL(client != NULL);
185
186         output = tdm_client_get_output(client, NULL, &ret);
187         TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
188         TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
189
190         return true;
191 }
192
193 bool TDMClient::PrepareVblank(void)
194 {
195         tdm_error ret;
196         unsigned int refresh;
197
198         TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
199
200         vblank = tdm_client_output_create_vblank(output, &ret);
201         TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
202         TDM_UT_RETURN_FALSE_IF_FAIL(vblank != NULL);
203
204         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_client_output_get_refresh_rate(output, &refresh) == TDM_ERROR_NONE);
205         TDM_UT_RETURN_FALSE_IF_FAIL(refresh > 0);
206
207         vrefresh_interval = 1.0 / (double)refresh;
208         TDM_UT_RETURN_FALSE_IF_FAIL(vrefresh_interval > 0);
209
210         return true;
211 }
212
213 char
214 tc_tdm_getchar(void)
215 {
216         int c = getchar();
217         int ch = c;
218
219         if (ch == '\n' || ch == '\r')
220                 ch = 'y';
221         else if (ch < 'a')
222                 ch += ('a' - 'A');
223
224         while (c != '\n' && c != EOF)
225                 c = getchar();
226
227         return ch;
228 }
229
230 static int
231 _tc_tdm_pipe_read_msg(int fd)
232 {
233         ssize_t len;
234         int msg;
235
236         do {
237                 len = read(fd, &msg, sizeof msg);
238         } while (len < 0 && errno == EINTR);
239
240         if (len <= 0)
241                 msg = TDM_UT_PIPE_MSG_NONE;
242
243         return msg;
244 }
245
246 static bool
247 _tc_tdm_pipe_write_msg(int fd, int reply_fd, int msg)
248 {
249         ssize_t len = write(fd, &msg, sizeof msg);
250         TDM_UT_RETURN_FALSE_IF_FAIL(len == sizeof msg);
251
252         if (reply_fd >= 0) {
253                 int reply = _tc_tdm_pipe_read_msg(reply_fd);
254                 TDM_UT_RETURN_FALSE_IF_FAIL(reply == TDM_UT_PIPE_MSG_REPLY);
255         }
256
257         return true;
258 }
259
260 static bool
261 _tc_tdm_server_set_output_dpms(tdm_display *dpy, int msg)
262 {
263         tdm_error ret;
264         tdm_output *output;
265         tdm_output_dpms dpms;
266
267         output = tdm_display_find_output(dpy, "primary", &ret);
268         TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
269         TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
270
271         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_dpms(output, &dpms) == TDM_ERROR_NONE);
272
273         switch (msg) {
274         case TDM_UT_PIPE_MSG_DPMS_ON:
275                 if (dpms != TDM_OUTPUT_DPMS_ON)
276                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON) == TDM_ERROR_NONE);
277                 break;
278         case TDM_UT_PIPE_MSG_DPMS_OFF:
279                 if (dpms != TDM_OUTPUT_DPMS_OFF)
280                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
281                 break;
282         default:
283                 break;
284         }
285
286         return true;
287 }
288
289 static void
290 _tc_tdm_test_server_cb_output_mode_change(tdm_output *output, unsigned int index, void *user_data)
291 {
292         const tdm_output_mode *modes, *mode;
293         int count = 0;
294         tdm_error ret;
295
296         ret = tdm_output_get_available_modes(output, &modes, &count);
297         TDM_UT_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
298         TDM_UT_RETURN_IF_FAIL((int)index < count);
299
300         mode = &modes[index];
301
302         ret = tdm_output_set_mode(output, mode);
303         TDM_UT_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
304
305         ret = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON);
306         TDM_UT_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
307
308         ret = tdm_output_commit(output, 0, NULL, NULL);
309         TDM_UT_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
310 }
311
312 static void
313 _tc_tdm_output_cb_destroy_handler(tdm_output *output, void *user_data)
314 {
315         tdm_error ret;
316
317         tdm_output_remove_mode_change_request_handler(output, _tc_tdm_test_server_cb_output_mode_change, NULL);
318         tdm_output_remove_destroy_handler(output, _tc_tdm_output_cb_destroy_handler, NULL);
319
320         ret = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF);
321         TDM_UT_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
322 }
323
324 static void
325 _tc_tdm_output_cb_create_handler(tdm_display *dpy, tdm_output *output, void *user_data)
326 {
327         tdm_error ret = TDM_ERROR_NONE;
328
329         ret = tdm_output_add_mode_change_request_handler(output, _tc_tdm_test_server_cb_output_mode_change, NULL);
330         TDM_UT_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
331
332         ret = tdm_output_add_destroy_handler(output, _tc_tdm_output_cb_destroy_handler, NULL);
333         TDM_UT_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
334 }
335
336 static void
337 _tc_tdm_server_run(int *pipe_parent, int *pipe_child)
338 {
339         tdm_display *dpy = NULL;
340         tdm_error ret;
341         struct pollfd fds[2];
342         int tdm_fd, err;
343         int output_count = 0;
344         int virtual_conf;
345
346         dpy = tdm_display_init(&ret);
347         TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed);
348         TDM_UT_GOTO_IF_FAIL(dpy != NULL, failed);
349
350         TDM_UT_GOTO_IF_FAIL(tdm_display_get_output_count(dpy, &output_count) == TDM_ERROR_NONE, failed);
351
352         for (int o = 0; o < output_count; o++) {
353                 tdm_output *output = tdm_display_get_output(dpy, o, &ret);
354                 TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed);
355                 TDM_UT_GOTO_IF_FAIL(output != NULL, failed);
356
357                 if (!tc_tdm_output_is_connected(output))
358                         continue;
359
360                 TDM_UT_GOTO_IF_FAIL(tc_tdm_output_prepare(dpy, output, true) == true, failed);
361         }
362
363         virtual_conf = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0);
364         if (virtual_conf) {
365                 ret = tdm_display_add_output_create_handler(dpy, _tc_tdm_output_cb_create_handler, NULL);
366                 TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed);
367         }
368
369         TDM_UT_GOTO_IF_FAIL(_tc_tdm_pipe_write_msg(pipe_parent[1], -1, TDM_UT_PIPE_MSG_SERVER_READY) == true, done);
370
371         TDM_INFO("*** server ready ***");
372
373         ret = tdm_display_get_fd(dpy, &tdm_fd);
374         TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, done);
375
376         fds[0].events = POLLIN;
377         fds[0].fd = tdm_fd;
378         fds[0].revents = 0;
379
380         fds[1].events = POLLIN;
381         fds[1].fd = pipe_child[0];
382         fds[1].revents = 0;
383
384         while (1) {
385                 /* make sure all events are flushed to clients before falling in sleep */
386                 tdm_display_flush(dpy);
387
388                 err = poll(fds, 2, -1);
389                 if (err < 0) {
390                         if (errno == EINTR || errno == EAGAIN) {
391                                 continue;
392                         } else {
393                                 TDM_ERR("server-process: poll failed: %m\n");
394                                 goto done;
395                         }
396                 }
397
398                 if (fds[0].revents & POLLIN)
399                         ret = tc_tdm_display_handle_events(dpy);
400
401                 if (fds[1].revents & POLLIN) {
402                         int msg = _tc_tdm_pipe_read_msg(pipe_child[0]);
403                         _tc_tdm_pipe_write_msg(pipe_parent[1], -1, TDM_UT_PIPE_MSG_REPLY);
404
405                         switch (msg) {
406                         case TDM_UT_PIPE_MSG_DPMS_ON:
407                         case TDM_UT_PIPE_MSG_DPMS_OFF:
408                                 _tc_tdm_server_set_output_dpms(dpy, msg);
409                                 break;
410                         case TDM_UT_PIPE_MSG_TERMINATE_SERVER:
411                                 goto done;
412                         default:
413                                 break;
414                         }
415                 }
416         }
417
418 done:
419         if (dpy)
420                 tdm_display_deinit(dpy);
421         return;
422
423 failed:
424         TDM_UT_GOTO_IF_FAIL(_tc_tdm_pipe_write_msg(pipe_parent[1], -1, TDM_UT_PIPE_MSG_SERVER_FAILED) == true, done);
425         TDM_INFO("*** server failed ***");
426
427         if (dpy)
428                 tdm_display_deinit(dpy);
429         return;
430
431 }
432
433 static void _tc_tdm_client_sig_handler(int sig)
434 {
435         TDM_UT_ERR("got signal: %d", sig);
436         kill(TDMClient::server_pid, 9);
437         abort();
438 }
439
440 static pid_t
441 _tc_tdm_client_server_fork(int *pipe_parent, int *pipe_child)
442 {
443         pid_t pid;
444         int msg;
445
446         TDM_UT_GOTO_IF_FAIL(pipe(pipe_parent) == 0, failed);
447         TDM_UT_GOTO_IF_FAIL(pipe(pipe_child) == 0, failed);
448
449         signal(SIGCHLD, SIG_IGN);
450         signal(SIGSEGV, _tc_tdm_client_sig_handler);
451
452         prctl(PR_SET_PDEATHSIG, SIGHUP);
453
454         pid = fork();
455         TDM_UT_GOTO_IF_FAIL(pid >= 0, failed);
456
457         if (pid == 0) {
458                 _tc_tdm_server_run(pipe_parent, pipe_child);
459                 close(pipe_child[0]);
460                 close(pipe_child[1]);
461                 close(pipe_parent[0]);
462                 close(pipe_parent[1]);
463
464 #ifdef TIZEN_TEST_GCOV
465                 __gcov_flush();
466 #endif
467
468                 exit(0);
469         }
470
471         msg = _tc_tdm_pipe_read_msg(pipe_parent[0]);
472         TDM_UT_GOTO_IF_FAIL(msg == TDM_UT_PIPE_MSG_SERVER_READY, failed);
473
474         TDM_INFO("*** server fork done ***");
475
476         return pid;
477
478 failed:
479         return -1;
480 }
481
482 TEST_P(TDMClient, ClientCreate)
483 {
484         tdm_error ret;
485
486         client = tdm_client_create(&ret);
487         ASSERT_EQ(ret, TDM_ERROR_NONE);
488         ASSERT_NE(client, NULL);
489 }
490
491 TEST_P(TDMClient, ClientCreateNullOther)
492 {
493         client = tdm_client_create(NULL);
494         ASSERT_NE(client, NULL);
495 }
496
497 TEST_P(TDMClient, ClientDestroy)
498 {
499         tdm_error ret;
500
501         client = tdm_client_create(&ret);
502         ASSERT_EQ(ret, TDM_ERROR_NONE);
503         ASSERT_NE(client, NULL);
504
505         tdm_client_destroy(client);
506         client = NULL;
507 }
508
509 TEST_P(TDMClient, ClientNullObject)
510 {
511         tdm_client_destroy(NULL);
512 }
513
514 /* tdm_client_get_fd */
515 TEST_P(TDMClient, ClientGetFd)
516 {
517         int fd = TDM_UT_INVALID_VALUE;
518
519         ASSERT_EQ(PrepareClient(), true);
520
521         ASSERT_EQ(tdm_client_get_fd(client, &fd), TDM_ERROR_NONE);
522         ASSERT_GE(fd, 0);
523 }
524
525 TEST_P(TDMClient, ClientGetFdNullObject)
526 {
527         int fd = TDM_UT_INVALID_VALUE;
528         ASSERT_EQ(tdm_client_get_fd(NULL, &fd), TDM_ERROR_INVALID_PARAMETER);
529         ASSERT_EQ(fd, TDM_UT_INVALID_VALUE);
530 }
531
532 TEST_P(TDMClient, ClientGetFdNullOther)
533 {
534         ASSERT_EQ(PrepareClient(), true);
535
536         ASSERT_EQ(tdm_client_get_fd(client, NULL), TDM_ERROR_INVALID_PARAMETER);
537 }
538
539 static void
540 _tc_tdm_client_vblank_cb(unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
541 {
542         bool *done = (bool *)user_data;
543         if (done)
544                 *done = true;
545 }
546
547 /* tdm_client_handle_events_timeout */
548 TEST_P(TDMClient, ClientHandleEvent)
549 {
550         bool done = false;
551
552         ASSERT_EQ(PrepareClient(), true);
553
554         ASSERT_EQ(tdm_client_wait_vblank(client, NULL, 1, 1, 0, _tc_tdm_client_vblank_cb, &done), TDM_ERROR_NONE);
555         ASSERT_EQ(done, false);
556
557         while (!done)
558                 ASSERT_EQ(tdm_client_handle_events(client), TDM_ERROR_NONE);
559 }
560
561 TEST_P(TDMClient, ClientHandleEventNullObject)
562 {
563         ASSERT_EQ(tdm_client_handle_events(NULL), TDM_ERROR_INVALID_PARAMETER);
564 }
565
566 /* tdm_client_wait_vblank, deprecated */
567 TEST_P(TDMClient, ClientWaitVblank)
568 {
569         bool done = false;
570
571         ASSERT_EQ(PrepareClient(), true);
572
573         ASSERT_EQ(tdm_client_wait_vblank(client, NULL, 1, 1, 0, _tc_tdm_client_vblank_cb, &done), TDM_ERROR_NONE);
574         ASSERT_EQ(done, false);
575
576         while (!done)
577                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
578 }
579
580 /* tdm_client_get_output */
581 TEST_P(TDMClient, ClientGetOutput)
582 {
583         tdm_error ret;
584
585         ASSERT_EQ(PrepareClient(), true);
586
587         output = tdm_client_get_output(client, NULL, &ret);
588         ASSERT_EQ(ret, TDM_ERROR_NONE);
589         ASSERT_NE(output, NULL);
590 }
591
592 TEST_P(TDMClient, ClientGetOutputPrimary)
593 {
594         tdm_error ret;
595
596         ASSERT_EQ(PrepareClient(), true);
597
598         output = tdm_client_get_output(client, (char*)"primary", &ret);
599         ASSERT_EQ(ret, TDM_ERROR_NONE);
600         ASSERT_NE(output, NULL);
601 }
602
603 TEST_P(TDMClient, ClientGetOutputDefault)
604 {
605         tdm_error ret;
606
607         ASSERT_EQ(PrepareClient(), true);
608
609         output = tdm_client_get_output(client, (char*)"default", &ret);
610         ASSERT_EQ(ret, TDM_ERROR_NONE);
611         ASSERT_NE(output, NULL);
612 }
613
614 TEST_P(TDMClient, ClientGetOutputInvalidName)
615 {
616         tdm_error ret;
617
618         ASSERT_EQ(PrepareClient(), true);
619
620         output = tdm_client_get_output(client, (char*)"invalid", &ret);
621         ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
622         ASSERT_EQ(output, NULL);
623 }
624
625 TEST_P(TDMClient, ClientGetOutputNullObject)
626 {
627         tdm_error ret;
628
629         output = tdm_client_get_output(NULL, NULL, &ret);
630         ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
631         ASSERT_EQ(output, NULL);
632 }
633
634 TEST_P(TDMClient, ClientGetOutputNullOther)
635 {
636         ASSERT_EQ(PrepareClient(), true);
637
638         output = tdm_client_get_output(client, NULL, NULL);
639         ASSERT_NE(output, NULL);
640 }
641
642 static void
643 _tc_tdm_client_output_change_dpms_cb(tdm_client_output *output,
644                                                                          tdm_output_change_type type,
645                                                                          tdm_value value,
646                                                                          void *user_data)
647 {
648         bool *done = (bool *)user_data;
649
650         switch (type) {
651         case TDM_OUTPUT_CHANGE_DPMS:
652                 if (done)
653                         *done = true;
654                 break;
655         default:
656                 break;
657         }
658 }
659
660 /* tdm_client_output_add_change_handler */
661 TEST_P(TDMClient, ClientOutputAddChangeHandler)
662 {
663         bool done = false;
664         tdm_output_dpms dpms;
665
666         ASSERT_EQ(PrepareClient(), true);
667         ASSERT_EQ(PrepareOutput(), true);
668
669         ASSERT_EQ(tdm_client_output_add_change_handler(output, _tc_tdm_client_output_change_dpms_cb, &done), TDM_ERROR_NONE);
670         ASSERT_EQ(_tc_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_OFF), true);
671
672         while (!done)
673                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
674
675         ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
676         ASSERT_EQ(dpms, TDM_OUTPUT_DPMS_OFF);
677
678         ASSERT_EQ(_tc_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_ON), true);
679         while (dpms != TDM_OUTPUT_DPMS_ON) {
680                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
681                 ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
682         }
683 }
684
685 TEST_P(TDMClient, ClientOutputAddChangeHandlerTwice)
686 {
687         ASSERT_EQ(PrepareClient(), true);
688         ASSERT_EQ(PrepareOutput(), true);
689
690         ASSERT_EQ(tdm_client_output_add_change_handler(output, _tc_tdm_client_output_change_dpms_cb, NULL), TDM_ERROR_NONE);
691         ASSERT_EQ(tdm_client_output_add_change_handler(output, _tc_tdm_client_output_change_dpms_cb, NULL), TDM_ERROR_BAD_REQUEST);
692 }
693
694 TEST_P(TDMClient, ClientOutputAddChangeHandlerNullObject)
695 {
696         ASSERT_EQ(tdm_client_output_add_change_handler(NULL, _tc_tdm_client_output_change_dpms_cb, NULL), TDM_ERROR_INVALID_PARAMETER);
697 }
698
699 TEST_P(TDMClient, ClientOutputAddChangeHandlerNullOther)
700 {
701         ASSERT_EQ(PrepareClient(), true);
702         ASSERT_EQ(PrepareOutput(), true);
703
704         ASSERT_EQ(tdm_client_output_add_change_handler(output, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
705 }
706
707 /* tdm_client_output_remove_change_handler */
708 TEST_P(TDMClient, ClientOutputRemoveChangeHandler)
709 {
710         ASSERT_EQ(PrepareClient(), true);
711         ASSERT_EQ(PrepareOutput(), true);
712
713         ASSERT_EQ(tdm_client_output_add_change_handler(output, _tc_tdm_client_output_change_dpms_cb, NULL), TDM_ERROR_NONE);
714         tdm_client_output_remove_change_handler(output, _tc_tdm_client_output_change_dpms_cb, NULL);
715 }
716
717 TEST_P(TDMClient, ClientOutputRemoveChangeHandlerDifferentData)
718 {
719         bool done = (bool)TDM_UT_INVALID_VALUE;
720
721         ASSERT_EQ(PrepareClient(), true);
722         ASSERT_EQ(PrepareOutput(), true);
723
724         ASSERT_EQ(tdm_client_output_add_change_handler(output, _tc_tdm_client_output_change_dpms_cb, &done), TDM_ERROR_NONE);
725         tdm_client_output_remove_change_handler(output, _tc_tdm_client_output_change_dpms_cb, NULL);
726 }
727
728 static void
729 _tc_tdm_client_output_change_dpms_cb2(tdm_client_output *output,
730                                                                           tdm_output_change_type type,
731                                                                           tdm_value value,
732                                                                           void *user_data)
733 {
734         switch (type) {
735         case TDM_OUTPUT_CHANGE_DPMS:
736                 tdm_client_output_remove_change_handler(output, _tc_tdm_client_output_change_dpms_cb2, user_data);
737                 break;
738         default:
739                 break;
740         }
741 }
742
743 TEST_P(TDMClient, ClientOutputRemoveChangeHandlerInHandler)
744 {
745         tdm_output_dpms dpms = TDM_OUTPUT_DPMS_ON;
746
747         ASSERT_EQ(PrepareClient(), true);
748         ASSERT_EQ(PrepareOutput(), true);
749
750         ASSERT_EQ(tdm_client_output_add_change_handler(output, _tc_tdm_client_output_change_dpms_cb2, NULL), TDM_ERROR_NONE);
751         ASSERT_EQ(_tc_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_OFF), true);
752         ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
753         while (dpms != TDM_OUTPUT_DPMS_OFF) {
754                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
755                 ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
756         }
757
758         ASSERT_EQ(_tc_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_ON), true);
759         while (dpms != TDM_OUTPUT_DPMS_ON)
760                 ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
761 }
762
763 TEST_P(TDMClient, ClientOutputRemoveChangeHandlerNullObject)
764 {
765         tdm_client_output_remove_change_handler(NULL, _tc_tdm_client_output_change_dpms_cb, NULL);
766 }
767
768 TEST_P(TDMClient, ClientOutputRemoveChangeHandlerNullOther)
769 {
770         ASSERT_EQ(PrepareClient(), true);
771         ASSERT_EQ(PrepareOutput(), true);
772
773         tdm_client_output_remove_change_handler(output, NULL, NULL);
774 }
775
776 /* tdm_client_output_get_refresh_rate */
777 TEST_P(TDMClient, ClientOutputGetRefreshRate)
778 {
779         unsigned int refresh = 0;
780
781         ASSERT_EQ(PrepareClient(), true);
782         ASSERT_EQ(PrepareOutput(), true);
783
784         ASSERT_EQ(tdm_client_output_get_refresh_rate(output, &refresh), TDM_ERROR_NONE);
785         ASSERT_GT(refresh, 0);
786 }
787
788 TEST_P(TDMClient, ClientOutputGetRefreshRateNullObject)
789 {
790         unsigned int refresh = (unsigned int)TDM_UT_INVALID_VALUE;
791
792         ASSERT_EQ(tdm_client_output_get_refresh_rate(NULL, &refresh), TDM_ERROR_INVALID_PARAMETER);
793         ASSERT_EQ(refresh, (unsigned int)TDM_UT_INVALID_VALUE);
794 }
795
796 TEST_P(TDMClient, ClientOutputGetRefreshRateNullOther)
797 {
798         ASSERT_EQ(PrepareClient(), true);
799         ASSERT_EQ(PrepareOutput(), true);
800
801         ASSERT_EQ(tdm_client_output_get_refresh_rate(output, NULL), TDM_ERROR_INVALID_PARAMETER);
802 }
803
804 /* tdm_client_output_get_mode */
805 TEST_P(TDMClient, ClientOutputGetMode)
806 {
807         unsigned int width = 0, height = 0;
808
809         ASSERT_EQ(PrepareClient(), true);
810         ASSERT_EQ(PrepareOutput(), true);
811
812         ASSERT_EQ(tdm_client_output_get_mode(output, &width, &height), TDM_ERROR_NONE);
813         ASSERT_GT(width, 0);
814         ASSERT_GT(height, 0);
815 }
816
817 TEST_P(TDMClient, ClientOutputGetModeNullObject)
818 {
819         unsigned int width = (unsigned int)TDM_UT_INVALID_VALUE;
820         unsigned int height = (unsigned int)TDM_UT_INVALID_VALUE;
821
822         ASSERT_EQ(tdm_client_output_get_mode(NULL, &width, &height), TDM_ERROR_INVALID_PARAMETER);
823         ASSERT_EQ(width, (unsigned int)TDM_UT_INVALID_VALUE);
824         ASSERT_EQ(height, (unsigned int)TDM_UT_INVALID_VALUE);
825 }
826
827 TEST_P(TDMClient, ClientOutputGetModeNullOther)
828 {
829         ASSERT_EQ(PrepareClient(), true);
830         ASSERT_EQ(PrepareOutput(), true);
831
832         ASSERT_EQ(tdm_client_output_get_mode(output, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
833 }
834
835 /* tdm_client_output_get_conn_status */
836 TEST_P(TDMClient, ClientOutputGetConnStatus)
837 {
838         tdm_output_conn_status status = (tdm_output_conn_status)TDM_UT_INVALID_VALUE;
839
840         ASSERT_EQ(PrepareClient(), true);
841         ASSERT_EQ(PrepareOutput(), true);
842
843         ASSERT_EQ(tdm_client_output_get_conn_status(output, &status), TDM_ERROR_NONE);
844         ASSERT_NE(status, (tdm_output_conn_status)TDM_UT_INVALID_VALUE);
845 }
846
847 TEST_P(TDMClient, ClientOutputGetConnStatusNullObject)
848 {
849         tdm_output_conn_status status = (tdm_output_conn_status)TDM_UT_INVALID_VALUE;
850
851         ASSERT_EQ(tdm_client_output_get_conn_status(NULL, &status), TDM_ERROR_INVALID_PARAMETER);
852         ASSERT_EQ(status, (tdm_output_conn_status)TDM_UT_INVALID_VALUE);
853 }
854
855 TEST_P(TDMClient, ClientOutputGetConnStatusNullOther)
856 {
857         ASSERT_EQ(PrepareClient(), true);
858         ASSERT_EQ(PrepareOutput(), true);
859
860         ASSERT_EQ(tdm_client_output_get_conn_status(output, NULL), TDM_ERROR_INVALID_PARAMETER);
861 }
862
863 /* tdm_client_output_get_dpms */
864 TEST_P(TDMClient, ClientOutputGetDpms)
865 {
866         tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
867
868         ASSERT_EQ(PrepareClient(), true);
869         ASSERT_EQ(PrepareOutput(), true);
870
871         ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
872         ASSERT_NE(dpms, (tdm_output_dpms)TDM_UT_INVALID_VALUE);
873 }
874
875 TEST_P(TDMClient, ClientOutputGetDpmsNullObject)
876 {
877         tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
878
879         ASSERT_EQ(tdm_client_output_get_dpms(NULL, &dpms), TDM_ERROR_INVALID_PARAMETER);
880         ASSERT_EQ(dpms, (tdm_output_dpms)TDM_UT_INVALID_VALUE);
881 }
882
883 TEST_P(TDMClient, ClientOutputGetDpmsNullOther)
884 {
885         ASSERT_EQ(PrepareClient(), true);
886         ASSERT_EQ(PrepareOutput(), true);
887
888         ASSERT_EQ(tdm_client_output_get_dpms(output, NULL), TDM_ERROR_INVALID_PARAMETER);
889 }
890
891 /* tdm_client_output_create_vblank */
892 TEST_P(TDMClient, ClientOutputCreateVblank)
893 {
894         tdm_error ret;
895
896         ASSERT_EQ(PrepareClient(), true);
897         ASSERT_EQ(PrepareOutput(), true);
898
899         vblank = tdm_client_output_create_vblank(output, &ret);
900         ASSERT_EQ(ret, TDM_ERROR_NONE);
901         ASSERT_NE(vblank, NULL);
902 }
903
904 TEST_P(TDMClient, ClientOutputCreateVblankNullObject)
905 {
906         tdm_error ret;
907
908         vblank = tdm_client_output_create_vblank(NULL, &ret);
909         ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
910         ASSERT_EQ(vblank, NULL);
911 }
912
913 TEST_P(TDMClient, ClientOutputCreateVblankNullOther)
914 {
915         ASSERT_EQ(PrepareClient(), true);
916         ASSERT_EQ(PrepareOutput(), true);
917
918         vblank = tdm_client_output_create_vblank(output, NULL);
919         ASSERT_NE(vblank, NULL);
920 }
921
922 /* tdm_client_vblank_destroy */
923 TEST_P(TDMClient, ClientVblankDestroy)
924 {
925         tdm_error ret;
926
927         ASSERT_EQ(PrepareClient(), true);
928         ASSERT_EQ(PrepareOutput(), true);
929
930         vblank = tdm_client_output_create_vblank(output, &ret);
931         ASSERT_EQ(ret, TDM_ERROR_NONE);
932         ASSERT_NE(vblank, NULL);
933
934         tdm_client_vblank_destroy(vblank);
935         vblank = NULL;
936 }
937
938 TEST_P(TDMClient, ClientVblankDestroyNullObject)
939 {
940         tdm_client_vblank_destroy(NULL);
941 }
942
943 /* tdm_client_vblank_set_name */
944 TEST_P(TDMClient, ClientVblankSetName)
945 {
946         ASSERT_EQ(PrepareClient(), true);
947         ASSERT_EQ(PrepareOutput(), true);
948         ASSERT_EQ(PrepareVblank(), true);
949
950         ASSERT_EQ(tdm_client_vblank_set_name(vblank, TDM_UT_VBLANK_NAME), TDM_ERROR_NONE);
951 }
952
953 TEST_P(TDMClient, ClientVblankSetNameTwice)
954 {
955         ASSERT_EQ(PrepareClient(), true);
956         ASSERT_EQ(PrepareOutput(), true);
957         ASSERT_EQ(PrepareVblank(), true);
958
959         ASSERT_EQ(tdm_client_vblank_set_name(vblank, TDM_UT_VBLANK_NAME), TDM_ERROR_NONE);
960         ASSERT_EQ(tdm_client_vblank_set_name(vblank, TDM_UT_VBLANK_NAME), TDM_ERROR_NONE);
961 }
962
963 TEST_P(TDMClient, ClientVblankSetNameNullObject)
964 {
965         ASSERT_EQ(tdm_client_vblank_set_name(NULL, TDM_UT_VBLANK_NAME), TDM_ERROR_INVALID_PARAMETER);
966 }
967
968 /* tdm_client_vblank_set_sync */
969 TEST_P(TDMClient, ClientVblankSetSync)
970 {
971         ASSERT_EQ(PrepareClient(), true);
972         ASSERT_EQ(PrepareOutput(), true);
973         ASSERT_EQ(PrepareVblank(), true);
974
975         ASSERT_EQ(tdm_client_vblank_set_sync(vblank, 1), TDM_ERROR_NONE);
976 }
977
978 TEST_P(TDMClient, ClientVblankSetSyncTwice)
979 {
980         ASSERT_EQ(PrepareClient(), true);
981         ASSERT_EQ(PrepareOutput(), true);
982         ASSERT_EQ(PrepareVblank(), true);
983
984         ASSERT_EQ(tdm_client_vblank_set_sync(vblank, 1), TDM_ERROR_NONE);
985         ASSERT_EQ(tdm_client_vblank_set_sync(vblank, 1), TDM_ERROR_NONE);
986 }
987
988 TEST_P(TDMClient, ClientVblankSetSyncNullObject)
989 {
990         ASSERT_EQ(tdm_client_vblank_set_sync(NULL, 1), TDM_ERROR_INVALID_PARAMETER);
991 }
992
993 /* tdm_client_vblank_set_fps */
994 TEST_P(TDMClient, ClientVblankSetFps)
995 {
996         ASSERT_EQ(PrepareClient(), true);
997         ASSERT_EQ(PrepareOutput(), true);
998         ASSERT_EQ(PrepareVblank(), true);
999
1000         ASSERT_EQ(tdm_client_vblank_set_fps(vblank, 30), TDM_ERROR_NONE);
1001 }
1002
1003 TEST_P(TDMClient, ClientVblankSetFpsTwice)
1004 {
1005         ASSERT_EQ(PrepareClient(), true);
1006         ASSERT_EQ(PrepareOutput(), true);
1007         ASSERT_EQ(PrepareVblank(), true);
1008
1009         ASSERT_EQ(tdm_client_vblank_set_fps(vblank, 30), TDM_ERROR_NONE);
1010         ASSERT_EQ(tdm_client_vblank_set_fps(vblank, 30), TDM_ERROR_NONE);
1011 }
1012
1013 TEST_P(TDMClient, ClientVblankSetFpsNullObject)
1014 {
1015         ASSERT_EQ(tdm_client_vblank_set_fps(NULL, 30), TDM_ERROR_INVALID_PARAMETER);
1016 }
1017
1018 /* tdm_client_vblank_set_offset */
1019 TEST_P(TDMClient, ClientVblankSetOffset)
1020 {
1021         ASSERT_EQ(PrepareClient(), true);
1022         ASSERT_EQ(PrepareOutput(), true);
1023         ASSERT_EQ(PrepareVblank(), true);
1024
1025         ASSERT_EQ(tdm_client_vblank_set_offset(vblank, 10), TDM_ERROR_NONE);
1026 }
1027
1028 TEST_P(TDMClient, ClientVblankSetOffsetTwice)
1029 {
1030         ASSERT_EQ(PrepareClient(), true);
1031         ASSERT_EQ(PrepareOutput(), true);
1032         ASSERT_EQ(PrepareVblank(), true);
1033
1034         ASSERT_EQ(tdm_client_vblank_set_offset(vblank, 10), TDM_ERROR_NONE);
1035         ASSERT_EQ(tdm_client_vblank_set_offset(vblank, 10), TDM_ERROR_NONE);
1036 }
1037
1038 TEST_P(TDMClient, ClientVblankSetOffsetNullObject)
1039 {
1040         ASSERT_EQ(tdm_client_vblank_set_offset(NULL, 10), TDM_ERROR_INVALID_PARAMETER);
1041 }
1042
1043 /* tdm_client_vblank_set_enable_fake */
1044 TEST_P(TDMClient, ClientVblankSetEnableFake)
1045 {
1046         ASSERT_EQ(PrepareClient(), true);
1047         ASSERT_EQ(PrepareOutput(), true);
1048         ASSERT_EQ(PrepareVblank(), true);
1049
1050         ASSERT_EQ(tdm_client_vblank_set_enable_fake(vblank, 1), TDM_ERROR_NONE);
1051 }
1052
1053 TEST_P(TDMClient, ClientVblankSetEnableFakeTwice)
1054 {
1055         ASSERT_EQ(PrepareClient(), true);
1056         ASSERT_EQ(PrepareOutput(), true);
1057         ASSERT_EQ(PrepareVblank(), true);
1058
1059         ASSERT_EQ(tdm_client_vblank_set_enable_fake(vblank, 1), TDM_ERROR_NONE);
1060         ASSERT_EQ(tdm_client_vblank_set_enable_fake(vblank, 1), TDM_ERROR_NONE);
1061 }
1062
1063 TEST_P(TDMClient, ClientVblankSetEnableFakeNullObject)
1064 {
1065         ASSERT_EQ(tdm_client_vblank_set_enable_fake(NULL, 1), TDM_ERROR_INVALID_PARAMETER);
1066 }
1067
1068 static void
1069 _tc_tdm_client_vblank_cb2(tdm_client_vblank *vblank,
1070                                                   tdm_error error,
1071                                                   unsigned int sequence,
1072                                                   unsigned int tv_sec,
1073                                                   unsigned int tv_usec,
1074                                                   void *user_data)
1075 {
1076         bool *done = (bool *)user_data;
1077         if (done)
1078                 *done = true;
1079 }
1080
1081 /* tdm_client_vblank_wait */
1082 TEST_P(TDMClient, ClientVblankWait)
1083 {
1084         bool done;
1085
1086         ASSERT_EQ(PrepareClient(), true);
1087         ASSERT_EQ(PrepareOutput(), true);
1088         ASSERT_EQ(PrepareVblank(), true);
1089
1090         done = false;
1091         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _tc_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
1092
1093         start = tdm_helper_get_time();
1094         while (!done)
1095                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1096         end = tdm_helper_get_time();
1097
1098         /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1099         ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval));
1100 }
1101
1102 TEST_P(TDMClient, ClientVblankWaitFewTime)
1103 {
1104         bool done1, done2, done3;
1105
1106         ASSERT_EQ(PrepareClient(), true);
1107         ASSERT_EQ(PrepareOutput(), true);
1108         ASSERT_EQ(PrepareVblank(), true);
1109
1110         done1 = done2 = done3 = false;
1111         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _tc_tdm_client_vblank_cb2, &done1), TDM_ERROR_NONE);
1112         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _tc_tdm_client_vblank_cb2, &done2), TDM_ERROR_NONE);
1113         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _tc_tdm_client_vblank_cb2, &done3), TDM_ERROR_NONE);
1114
1115         start = tdm_helper_get_time();
1116         while (!done1 || !done2 || !done3)
1117                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1118         end = tdm_helper_get_time();
1119
1120         /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1121         ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval));
1122
1123 }
1124
1125 TEST_P(TDMClient, ClientVblankWaitInterval0)
1126 {
1127         ASSERT_EQ(PrepareClient(), true);
1128         ASSERT_EQ(PrepareOutput(), true);
1129         ASSERT_EQ(PrepareVblank(), true);
1130
1131         ASSERT_EQ(tdm_client_vblank_wait(vblank, 0, _tc_tdm_client_vblank_cb2, NULL), TDM_ERROR_INVALID_PARAMETER);
1132 }
1133
1134 TEST_P(TDMClient, ClientVblankWaitInterval)
1135 {
1136         bool done;
1137
1138         ASSERT_EQ(PrepareClient(), true);
1139         ASSERT_EQ(PrepareOutput(), true);
1140         ASSERT_EQ(PrepareVblank(), true);
1141
1142         /* start from 1 */
1143         for (int t = 1; t < 10; t++) {
1144                 done = false;
1145                 ASSERT_EQ(tdm_client_vblank_wait(vblank, t, _tc_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
1146
1147                 start = tdm_helper_get_time();
1148                 while (!done)
1149                         ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1150                 end = tdm_helper_get_time();
1151
1152                 /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1153                 ASSERT_GT((end - start), (vrefresh_interval * (t - 1)));
1154                 ASSERT_LT((end - start), (vrefresh_interval * t + vrefresh_interval));
1155         }
1156 }
1157
1158 static void
1159 _tc_tdm_client_vblank_cb3(tdm_client_vblank *vblank,
1160                                                   tdm_error error,
1161                                                   unsigned int sequence,
1162                                                   unsigned int tv_sec,
1163                                                   unsigned int tv_usec,
1164                                                   void *user_data)
1165 {
1166         unsigned int *cur_seq = (unsigned int *)user_data;
1167         if (cur_seq)
1168                 *cur_seq = sequence;
1169 }
1170
1171 TEST_P(TDMClient, ClientVblankWaitSeq)
1172 {
1173         ASSERT_EQ(PrepareClient(), true);
1174         ASSERT_EQ(PrepareOutput(), true);
1175         ASSERT_EQ(PrepareVblank(), true);
1176
1177         for (int t = 0; t < 10; t++) {
1178                 unsigned int cur_seq = 0, temp = 0;
1179
1180                 ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _tc_tdm_client_vblank_cb3, &cur_seq), TDM_ERROR_NONE);
1181                 while (cur_seq == 0)
1182                         ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1183
1184                 start = tdm_helper_get_time();
1185                 ASSERT_EQ(tdm_client_vblank_wait_seq(vblank, cur_seq + 1, _tc_tdm_client_vblank_cb3, &temp), TDM_ERROR_NONE);
1186                 while (temp == 0)
1187                         ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1188                 end = tdm_helper_get_time();
1189
1190                 /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1191                 ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval));
1192         }
1193 }
1194
1195 TEST_P(TDMClient, ClientVblankWaitSeqInterval)
1196 {
1197         ASSERT_EQ(PrepareClient(), true);
1198         ASSERT_EQ(PrepareOutput(), true);
1199         ASSERT_EQ(PrepareVblank(), true);
1200
1201         /* start from 1 */
1202         for (int t = 1; t < 10; t++) {
1203                 unsigned int cur_seq = 0, temp = 0;
1204
1205                 ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _tc_tdm_client_vblank_cb3, &cur_seq), TDM_ERROR_NONE);
1206                 while (cur_seq == 0)
1207                         ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1208
1209                 start = tdm_helper_get_time();
1210                 ASSERT_EQ(tdm_client_vblank_wait_seq(vblank, cur_seq + t, _tc_tdm_client_vblank_cb3, &temp), TDM_ERROR_NONE);
1211                 while (temp == 0)
1212                         ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1213                 end = tdm_helper_get_time();
1214
1215                 /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1216                 ASSERT_GT((end - start), (vrefresh_interval * (t - 1)));
1217                 ASSERT_LT((end - start), (vrefresh_interval * t + vrefresh_interval));
1218         }
1219 }
1220
1221 TEST_P(TDMClient, ClientVblankWaitSetOffset)
1222 {
1223         bool done;
1224
1225         ASSERT_EQ(PrepareClient(), true);
1226         ASSERT_EQ(PrepareOutput(), true);
1227         ASSERT_EQ(PrepareVblank(), true);
1228
1229         ASSERT_EQ(tdm_client_vblank_set_offset(vblank, 100), TDM_ERROR_NONE);
1230
1231         done = false;
1232         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _tc_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
1233
1234         start = tdm_helper_get_time();
1235         while (!done)
1236                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1237         end = tdm_helper_get_time();
1238
1239         /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1240         ASSERT_GT((end - start), (0.1));
1241         ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval + 0.1));
1242 }
1243
1244 TEST_P(TDMClient, ClientVblankWaitSetFps)
1245 {
1246         bool done;
1247         double interval;
1248         unsigned int fps = 10;
1249
1250         ASSERT_EQ(PrepareClient(), true);
1251         ASSERT_EQ(PrepareOutput(), true);
1252         ASSERT_EQ(PrepareVblank(), true);
1253
1254         ASSERT_EQ(tdm_client_vblank_set_fps(vblank, fps), TDM_ERROR_NONE);
1255         interval = 1.0 / (double)fps;
1256
1257         done = false;
1258         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _tc_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
1259
1260         start = tdm_helper_get_time();
1261         while (!done)
1262                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1263         end = tdm_helper_get_time();
1264
1265         /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1266         ASSERT_GT((end - start), (interval - vrefresh_interval * 2));
1267         ASSERT_LT((end - start), (interval + vrefresh_interval));
1268 }
1269
1270 #if 0
1271
1272 TEST_P(TDMVblank, VblankWaitEnableDisableGlobalFps)
1273 {
1274         TDM_UT_SKIP_FLAG(has_outputs);
1275
1276         unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
1277         double vrefresh_interval;
1278         unsigned int cur_seq[3];
1279         unsigned int global_fps = 5;
1280         double start, end, interval;
1281
1282         ASSERT_EQ(TestPrepareOutput(), true);
1283         ASSERT_EQ(TestCreateVblanks3(), true);
1284         ASSERT_EQ(vblank_count, 3);
1285
1286         ASSERT_EQ(tdm_vblank_get_fps(vblanks[0], &fps), TDM_ERROR_NONE);
1287         ASSERT_TRUE(fps >= 30 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
1288         vrefresh_interval = 1.0 / (double)fps;
1289
1290         for (int v = 0; v < 3; v++)
1291                 ASSERT_EQ(tdm_vblank_set_fixed_fps(vblanks[v], 10 * (v + 1)), TDM_ERROR_NONE);
1292
1293         /* enable test */
1294         tdm_vblank_enable_global_fps(1, global_fps);
1295         interval = 1.0 / (double)global_fps;
1296
1297         for (int v = 0; v < 3; v++) {
1298                 cur_seq[v] = 0;
1299                 ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _tc_tdm_vblank_cb, &cur_seq[v]), TDM_ERROR_NONE);
1300         }
1301
1302         start = tdm_helper_get_time();
1303         while (cur_seq[0] == 0)
1304                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
1305         end = tdm_helper_get_time();
1306
1307         ASSERT_NE(cur_seq[1], 0);
1308         ASSERT_NE(cur_seq[2], 0);
1309
1310         /* "+- vrefresh_interval" consider the delay of socket communication between kernel and platform */
1311         ASSERT_GT((end - start), (interval - vrefresh_interval));
1312         ASSERT_LT((end - start), (interval + vrefresh_interval));
1313
1314         /* disable test */
1315         tdm_vblank_enable_global_fps(0, 0);
1316
1317         for (int v = 0; v < 3; v++) {
1318                 cur_seq[v] = 0;
1319                 ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _tc_tdm_vblank_cb, &cur_seq[v]), TDM_ERROR_NONE);
1320         }
1321
1322         while (cur_seq[0] == 0)
1323                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
1324         ASSERT_EQ(cur_seq[1], 0);
1325         ASSERT_EQ(cur_seq[2], 0);
1326
1327         while (cur_seq[1] == 0)
1328                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
1329         ASSERT_EQ(cur_seq[2], 0);
1330 }
1331
1332 TEST_P(TDMVblank, VblankWaitIgnoreGlobalFps)
1333 {
1334         TDM_UT_SKIP_FLAG(has_outputs);
1335
1336         unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
1337         unsigned int cur_seq[3];
1338         unsigned int global_fps = 5;
1339         double start, end, interval;
1340
1341         ASSERT_EQ(TestPrepareOutput(), true);
1342         ASSERT_EQ(TestCreateVblanks3(), true);
1343         ASSERT_EQ(vblank_count, 3);
1344
1345         ASSERT_EQ(tdm_vblank_get_fps(vblanks[0], &fps), TDM_ERROR_NONE);
1346         ASSERT_TRUE(fps >= 30 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
1347         interval = 1.0 / (double)fps;
1348
1349         /* 2nd vblank will ignore the global fps. */
1350         ASSERT_EQ(tdm_vblank_ignore_global_fps(vblanks[1], 1), TDM_ERROR_NONE);
1351
1352         tdm_vblank_enable_global_fps(1, global_fps);
1353
1354         for (int v = 0; v < 3; v++) {
1355                 cur_seq[v] = 0;
1356                 ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _tc_tdm_vblank_cb, &cur_seq[v]), TDM_ERROR_NONE);
1357         }
1358
1359         start = tdm_helper_get_time();
1360         while (cur_seq[1] == 0)
1361                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
1362         end = tdm_helper_get_time();
1363
1364         ASSERT_EQ(cur_seq[0], 0);
1365         ASSERT_EQ(cur_seq[2], 0);
1366
1367         /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1368         ASSERT_LT((end - start), (interval + interval));
1369
1370         while (cur_seq[0] == 0)
1371                 ASSERT_EQ(tc_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
1372         ASSERT_NE(cur_seq[2], 0);
1373 }
1374
1375 #endif
1376
1377 TEST_P(TDMClient, ClientVblankWaitNullObject)
1378 {
1379         unsigned int cur_seq = 0;
1380
1381         ASSERT_EQ(tdm_client_vblank_wait(NULL, 1, _tc_tdm_client_vblank_cb3, &cur_seq), TDM_ERROR_INVALID_PARAMETER);
1382 }
1383
1384 TEST_P(TDMClient, ClientVblankWaitNullOther)
1385 {
1386         ASSERT_EQ(PrepareClient(), true);
1387         ASSERT_EQ(PrepareOutput(), true);
1388         ASSERT_EQ(PrepareVblank(), true);
1389
1390         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
1391 }
1392
1393 TEST_P(TDMClient, ClientVblankWaitDpmsOff)
1394 {
1395         tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
1396
1397         ASSERT_EQ(PrepareClient(), true);
1398         ASSERT_EQ(PrepareOutput(), true);
1399         ASSERT_EQ(PrepareVblank(), true);
1400
1401         ASSERT_EQ(_tc_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_OFF), true);
1402         while (dpms != TDM_OUTPUT_DPMS_OFF)
1403                 ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
1404         ASSERT_EQ(dpms, TDM_OUTPUT_DPMS_OFF);
1405
1406         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _tc_tdm_client_vblank_cb2, NULL), TDM_ERROR_DPMS_OFF);
1407
1408         ASSERT_EQ(_tc_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_ON), true);
1409         while (dpms != TDM_OUTPUT_DPMS_ON)
1410                 ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
1411 }
1412
1413 TEST_P(TDMClient, ClientVblankWaitSetEnableFakeDpmsOff)
1414 {
1415         tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
1416         bool done;
1417
1418         ASSERT_EQ(PrepareClient(), true);
1419         ASSERT_EQ(PrepareOutput(), true);
1420         ASSERT_EQ(PrepareVblank(), true);
1421
1422         ASSERT_EQ(_tc_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_OFF), true);
1423         while (dpms != TDM_OUTPUT_DPMS_OFF)
1424                 ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
1425
1426         ASSERT_EQ(tdm_client_vblank_set_enable_fake(vblank, 1), TDM_ERROR_NONE);
1427
1428         done = false;
1429         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _tc_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
1430
1431         while (!done)
1432                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1433
1434         ASSERT_EQ(_tc_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_ON), true);
1435         while (dpms != TDM_OUTPUT_DPMS_ON)
1436                 ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
1437 }
1438
1439 /* tdm_client_vblank_wait */
1440 TEST_P(TDMClient, ClientVblankIsWaiting)
1441 {
1442         bool done;
1443         unsigned int waiting;
1444
1445         ASSERT_EQ(PrepareClient(), true);
1446         ASSERT_EQ(PrepareOutput(), true);
1447         ASSERT_EQ(PrepareVblank(), true);
1448
1449         done = false;
1450         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _tc_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
1451
1452         waiting = tdm_client_vblank_is_waiting(vblank);
1453         ASSERT_EQ(waiting, 1);
1454
1455         start = tdm_helper_get_time();
1456         while (!done)
1457                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1458         end = tdm_helper_get_time();
1459
1460         /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1461         ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval));
1462
1463         waiting = tdm_client_vblank_is_waiting(vblank);
1464         ASSERT_EQ(waiting, 0);
1465 }
1466
1467 /* tdm_client_vblank_wait */
1468 TEST_P(TDMClient, ClientVblankIsWaitingNullObject)
1469 {
1470         unsigned int waiting = tdm_client_vblank_is_waiting(NULL);
1471         ASSERT_EQ(waiting, 0);
1472 }
1473
1474 TEST_P(TDMClient, ClientCreateVOutput)
1475 {
1476         tdm_error ret;
1477         int virtual_conf = 0;
1478         const char name[TDM_NAME_LEN] = "Virtual Output";
1479
1480         virtual_conf = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0);
1481         if (virtual_conf == 0) {
1482                 ASSERT_EQ(virtual_conf, 0);
1483                 return;
1484         }
1485
1486         ASSERT_EQ(PrepareClient(), true);
1487
1488         voutput = tdm_client_create_voutput(client, name, &ret);
1489         ASSERT_EQ(ret, TDM_ERROR_NONE);
1490         ASSERT_NE(voutput, NULL);
1491
1492         tdm_client_voutput_destroy(voutput);
1493 }
1494
1495 class TDMVirtualOutput : public ::testing::Test
1496 {
1497 public:
1498         TDMVirtualOutput() {};
1499         ~TDMVirtualOutput() {};
1500
1501         static void SetUpTestCase();
1502         static void TearDownTestCase();
1503         static bool PrepareVOutput(void);
1504
1505 protected:
1506         static tdm_client *client;
1507         static tdm_client_voutput *voutput;
1508         const int MODE_COUNT = 2;
1509
1510 private:
1511         static pid_t server_pid;
1512
1513         /* 0: read, 1: write */
1514         static int pipe_parent[2];
1515         static int pipe_child[2];
1516
1517         static void ServerFork(void);
1518         static void ServerKill(void);
1519 };
1520
1521 pid_t TDMVirtualOutput::server_pid = -1;
1522 int TDMVirtualOutput::pipe_parent[2] = {-1, -1};
1523 int TDMVirtualOutput::pipe_child[2] = {-1, -1};
1524 tdm_client* TDMVirtualOutput::client = nullptr;
1525 tdm_client_voutput* TDMVirtualOutput::voutput = nullptr;
1526
1527 void TDMVirtualOutput::ServerKill(void)
1528 {
1529         if (pipe_child[0] >= 0)
1530                 close(pipe_child[0]);
1531         if (pipe_child[1] >= 0) {
1532                 if (server_pid > 0) {
1533                         bool ret = _tc_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_TERMINATE_SERVER);
1534                         if (ret) {
1535                                 if (waitpid(server_pid, NULL, 0) == server_pid)
1536                                         TDM_INFO("*** server terminated ***");
1537                                 else
1538                                         TDM_ERR("*** failed to terminate server ***");
1539                         } else {
1540                                 if (kill(server_pid, 9) < 0)
1541                                         TDM_ERR("*** failed to kill server ***");
1542                         }
1543                 }
1544                 close(pipe_child[1]);
1545         }
1546
1547         if (pipe_parent[0] >= 0)
1548                 close(pipe_parent[0]);
1549         if (pipe_parent[1] >= 0)
1550                 close(pipe_parent[1]);
1551
1552         server_pid = -1;
1553         pipe_parent[0] = pipe_parent[1] = -1;
1554         pipe_child[0] = pipe_child[1] = -1;
1555 }
1556
1557 void TDMVirtualOutput::ServerFork(void)
1558 {
1559         if (server_pid > 0)
1560                 return;
1561
1562         server_pid = _tc_tdm_client_server_fork(pipe_parent, pipe_child);
1563         ASSERT_GT(server_pid, 0);
1564 }
1565
1566 void TDMVirtualOutput::SetUpTestCase(void)
1567 {
1568         setenv("XDG_RUNTIME_DIR", "/run", 1);
1569         setenv("TBM_DISPLAY_SERVER", "1", 1);
1570
1571         if (server_pid == -1)
1572                 ServerFork();
1573
1574         ASSERT_EQ(PrepareVOutput(), true);
1575 }
1576
1577 void TDMVirtualOutput::TearDownTestCase(void)
1578 {
1579 //      TDM_UT_WAIT("check & press");
1580
1581         if (voutput)
1582                 tdm_client_voutput_destroy(voutput);
1583
1584         if (client)
1585                 tdm_client_destroy(client);
1586
1587         ServerKill();
1588
1589         unsetenv("XDG_RUNTIME_DIR");
1590         unsetenv("TBM_DISPLAY_SERVER");
1591 }
1592
1593 bool TDMVirtualOutput::PrepareVOutput(void)
1594 {
1595         tdm_error ret;
1596         int virtual_conf = 0;
1597         const char name[TDM_NAME_LEN] = "Virtual Output";
1598
1599         virtual_conf = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0);
1600         if (virtual_conf == 0) return true;
1601
1602         client = tdm_client_create(&ret);
1603         TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
1604         TDM_UT_RETURN_FALSE_IF_FAIL(client != NULL);
1605
1606         voutput = tdm_client_create_voutput(client, name, &ret);
1607         TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
1608         TDM_UT_RETURN_FALSE_IF_FAIL(voutput != NULL);
1609
1610 //      TDM_UT_WAIT("check & press");
1611
1612         return true;
1613 }
1614
1615 static void
1616 _tc_tdm_client_virutual_make_available_mode(tdm_client_output_mode *modes, int count)
1617 {
1618         int i;
1619
1620         for (i = 0; i < count; i++) {
1621                 modes[i].clock = 25200;
1622                 modes[i].hdisplay = 640;
1623                 modes[i].hsync_start = 656;
1624                 modes[i].hsync_end = 752;
1625                 modes[i].htotal = 800;
1626                 modes[i].hskew = 0;
1627                 modes[i].vdisplay = 480;
1628                 modes[i].vsync_start = 490;
1629                 modes[i].vsync_end = 492;
1630                 modes[i].vtotal = 525;
1631                 modes[i].vscan = 0;
1632                 modes[i].vrefresh = 30;
1633                 modes[i].flags = 0;
1634                 modes[i].type = 0;
1635                 snprintf(modes[i].name, TDM_NAME_LEN, "%dx%d_%d", modes[i].hdisplay, modes[i].vdisplay, i);
1636         }
1637 }
1638
1639 TEST_F(TDMVirtualOutput, SetAvailableModes)
1640 {
1641         tdm_error ret;
1642         tdm_client_output_mode modes[this->MODE_COUNT];
1643         int count = this->MODE_COUNT;
1644         int virtual_conf;
1645
1646         if (this->voutput == NULL) {
1647                 virtual_conf = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0);
1648                 ASSERT_EQ(virtual_conf, 0);
1649                 return;
1650         }
1651         _tc_tdm_client_virutual_make_available_mode(modes, count);
1652
1653         ret = tdm_client_voutput_set_available_modes(this->voutput, modes, count);
1654         ASSERT_EQ(ret, TDM_ERROR_NONE);
1655 }
1656
1657 TEST_F(TDMVirtualOutput, FailTestSetAvailableModes)
1658 {
1659         tdm_error ret;
1660         tdm_client_output_mode modes[this->MODE_COUNT];
1661         int count = this->MODE_COUNT;
1662         int virtual_conf;
1663
1664         if (this->voutput == NULL) {
1665                 virtual_conf = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0);
1666                 ASSERT_EQ(virtual_conf, 0);
1667                 return;
1668         }
1669
1670         ret = tdm_client_voutput_set_available_modes(NULL, modes, count);
1671         ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
1672
1673         ret = tdm_client_voutput_set_available_modes(this->voutput, NULL, count);
1674         ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
1675 }
1676
1677 TEST_F(TDMVirtualOutput, SetPhysicalSize)
1678 {
1679         tdm_error ret;
1680         unsigned int mmWidth = 1234, mmHeight = 1234;
1681         int virtual_conf;
1682
1683         if (this->voutput == NULL) {
1684                 virtual_conf = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0);
1685                 ASSERT_EQ(virtual_conf, 0);
1686                 return;
1687         }
1688
1689         ret = tdm_client_voutput_set_physical_size(this->voutput, mmWidth, mmHeight);
1690         ASSERT_EQ(ret, TDM_ERROR_NONE);
1691 }
1692
1693 TEST_F(TDMVirtualOutput, FailTestSetPhysicalSize)
1694 {
1695         tdm_error ret;
1696         unsigned int invalid_mmWidth = 0, invalid_mmHeight = 0;
1697         int virtual_conf;
1698
1699         if (this->voutput == NULL) {
1700                 virtual_conf = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0);
1701                 ASSERT_EQ(virtual_conf, 0);
1702                 return;
1703         }
1704
1705         ret = tdm_client_voutput_set_physical_size(this->voutput, invalid_mmWidth, invalid_mmHeight);
1706         ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
1707 }
1708
1709 static void
1710 _tc_tdm_client_voutput_commit_handler(tdm_client_voutput *voutput, tbm_surface_h buffer, void *user_data)
1711 {
1712         int *flag;
1713         flag = (int *)user_data;
1714         *flag = 1;
1715 }
1716
1717 TEST_F(TDMVirtualOutput, AddCommitHandler)
1718 {
1719         tdm_error ret;
1720         int flag_callback_called = 0;
1721         int virtual_conf;
1722
1723         if (this->voutput == NULL) {
1724                 virtual_conf = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0);
1725                 ASSERT_EQ(virtual_conf, 0);
1726                 return;
1727         }
1728
1729         ret = tdm_client_voutput_add_commit_handler(this->voutput,
1730                                                                                                 _tc_tdm_client_voutput_commit_handler,
1731                                                                                                 &flag_callback_called);
1732         ASSERT_EQ(ret, TDM_ERROR_NONE);
1733 //      ASSERT_EQ(flag_callback_called, 1);
1734
1735         tdm_client_voutput_remove_commit_handler(this->voutput,
1736                                                                                          _tc_tdm_client_voutput_commit_handler,
1737                                                                                          &flag_callback_called);
1738 }
1739
1740 TEST_F(TDMVirtualOutput, CommitDone)
1741 {
1742         tdm_error ret;
1743         int virtual_conf;
1744
1745         if (this->voutput == NULL) {
1746                 virtual_conf = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0);
1747                 ASSERT_EQ(virtual_conf, 0);
1748                 return;
1749         }
1750
1751         ret = tdm_client_voutput_commit_done(this->voutput);
1752         ASSERT_EQ(ret, TDM_ERROR_NONE);
1753 }
1754
1755 TEST_F(TDMVirtualOutput, GetClientOutput)
1756 {
1757         tdm_error ret;
1758         tdm_client_output *output;
1759         int virtual_conf;
1760
1761         if (this->voutput == NULL) {
1762                 virtual_conf = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0);
1763                 ASSERT_EQ(virtual_conf, 0);
1764                 return;
1765         }
1766
1767         output = tdm_client_voutput_get_client_output(this->voutput, &ret);
1768         ASSERT_EQ(ret, TDM_ERROR_NONE);
1769         ASSERT_NE(output, NULL);
1770 }
1771
1772 static void
1773 _tc_voutput_output_handler_cb(tdm_client_output *output, tdm_output_change_type type,
1774                                            tdm_value value, void *user_data)
1775 {
1776         bool *done = (bool *)user_data;
1777         tdm_output_conn_status status;
1778
1779         if (type == TDM_OUTPUT_CHANGE_CONNECTION) {
1780                 status = (tdm_output_conn_status)value.u32;
1781
1782                 if (status == TDM_OUTPUT_CONN_STATUS_CONNECTED)
1783                         if (done) *done = true;
1784         }
1785 }
1786
1787 static void
1788 _tc_voutput_output_handler_cb2(tdm_client_output *output, tdm_output_change_type type,
1789                                            tdm_value value, void *user_data)
1790 {
1791         bool *done = (bool *)user_data;
1792         tdm_output_conn_status status;
1793
1794         if (type == TDM_OUTPUT_CHANGE_CONNECTION) {
1795                 status = (tdm_output_conn_status)value.u32;
1796
1797                 if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
1798                         if (done) *done = true;
1799         }
1800 }
1801
1802 static void
1803 _tc_voutput_output_handler_cb3(tdm_client_output *output, tdm_output_change_type type,
1804                                            tdm_value value, void *user_data)
1805 {
1806         bool *done = (bool *)user_data;
1807         tdm_output_conn_status status;
1808
1809         if (type == TDM_OUTPUT_CHANGE_CONNECTION) {
1810                 status = (tdm_output_conn_status)value.u32;
1811
1812                 if (status == TDM_OUTPUT_CONN_STATUS_MODE_SETTED)
1813                         if (done) *done = true;
1814         }
1815 }
1816
1817 TEST_F(TDMVirtualOutput, ConnectDisconnect)
1818 {
1819         tdm_error ret;
1820         tdm_client_output *output;
1821         unsigned int mmWidth = 300, mmHeight = 150;
1822         tdm_client_output_mode modes[this->MODE_COUNT];
1823         int count = this->MODE_COUNT;
1824         int virtual_conf;
1825         bool done = false;
1826         bool done2 = false;
1827
1828         if (this->voutput == NULL) {
1829                 virtual_conf = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0);
1830                 ASSERT_EQ(virtual_conf, 0);
1831                 return;
1832         }
1833
1834         output = tdm_client_voutput_get_client_output(this->voutput, &ret);
1835         ASSERT_EQ(ret, TDM_ERROR_NONE);
1836         ASSERT_NE(output, NULL);
1837
1838         ret = tdm_client_output_add_change_handler(output, _tc_voutput_output_handler_cb, &done);
1839         ASSERT_EQ(ret, TDM_ERROR_NONE);
1840
1841         ret = tdm_client_output_add_change_handler(output, _tc_voutput_output_handler_cb2, &done2);
1842         ASSERT_EQ(ret, TDM_ERROR_NONE);
1843
1844         ret = tdm_client_voutput_set_physical_size(this->voutput, mmWidth, mmHeight);
1845         ASSERT_EQ(ret, TDM_ERROR_NONE);
1846
1847         _tc_tdm_client_virutual_make_available_mode(modes, count);
1848         ret = tdm_client_voutput_set_available_modes(this->voutput, modes, count);
1849         ASSERT_EQ(ret, TDM_ERROR_NONE);
1850
1851         ret = tdm_client_voutput_connect(this->voutput);
1852         ASSERT_EQ(ret, TDM_ERROR_NONE);
1853
1854         while (!done)
1855                 ASSERT_EQ(tdm_client_handle_events_timeout(this->client, 3000), TDM_ERROR_NONE);
1856
1857         ret = tdm_client_voutput_disconnect(this->voutput);
1858         ASSERT_EQ(ret, TDM_ERROR_NONE);
1859
1860         while (!done2)
1861                 ASSERT_EQ(tdm_client_handle_events_timeout(this->client, 3000), TDM_ERROR_NONE);
1862
1863         tdm_client_output_remove_change_handler(output, _tc_voutput_output_handler_cb, &done);
1864         tdm_client_output_remove_change_handler(output, _tc_voutput_output_handler_cb2, &done2);
1865 }
1866
1867 TEST_F(TDMVirtualOutput, SetMode)
1868 {
1869         tdm_error ret;
1870         tdm_client_output *output;
1871         unsigned int mmWidth = 300, mmHeight = 150;
1872         tdm_client_output_mode modes[this->MODE_COUNT];
1873         int count = this->MODE_COUNT;
1874         int virtual_conf;
1875         bool done = false;
1876         bool done2 = false;
1877         bool done3 = false;
1878
1879         if (this->voutput == NULL) {
1880                 virtual_conf = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0);
1881                 ASSERT_EQ(virtual_conf, 0);
1882                 return;
1883         }
1884
1885         output = tdm_client_voutput_get_client_output(this->voutput, &ret);
1886         ASSERT_EQ(ret, TDM_ERROR_NONE);
1887         ASSERT_NE(output, NULL);
1888
1889         ret = tdm_client_output_add_change_handler(output, _tc_voutput_output_handler_cb, &done);
1890         ASSERT_EQ(ret, TDM_ERROR_NONE);
1891         ret = tdm_client_output_add_change_handler(output, _tc_voutput_output_handler_cb2, &done2);
1892         ASSERT_EQ(ret, TDM_ERROR_NONE);
1893         ret = tdm_client_output_add_change_handler(output, _tc_voutput_output_handler_cb3, &done3);
1894         ASSERT_EQ(ret, TDM_ERROR_NONE);
1895
1896         ret = tdm_client_voutput_set_physical_size(this->voutput, mmWidth, mmHeight);
1897         ASSERT_EQ(ret, TDM_ERROR_NONE);
1898
1899         _tc_tdm_client_virutual_make_available_mode(modes, count);
1900         ret = tdm_client_voutput_set_available_modes(this->voutput, modes, count);
1901         ASSERT_EQ(ret, TDM_ERROR_NONE);
1902
1903         ret = tdm_client_voutput_connect(this->voutput);
1904         ASSERT_EQ(ret, TDM_ERROR_NONE);
1905
1906         while (!done)
1907                 ASSERT_EQ(tdm_client_handle_events_timeout(this->client, 3000), TDM_ERROR_NONE);
1908
1909         ASSERT_EQ(tdm_client_voutput_set_mode(this->voutput, count - 1), TDM_ERROR_NONE);
1910
1911         while (!done3)
1912                 ASSERT_EQ(tdm_client_handle_events_timeout(this->client, 3000), TDM_ERROR_NONE);
1913
1914         ret = tdm_client_voutput_disconnect(this->voutput);
1915         ASSERT_EQ(ret, TDM_ERROR_NONE);
1916
1917         while (!done2)
1918                 ASSERT_EQ(tdm_client_handle_events_timeout(this->client, 3000), TDM_ERROR_NONE);
1919
1920         tdm_client_output_remove_change_handler(output, _tc_voutput_output_handler_cb, &done);
1921         tdm_client_output_remove_change_handler(output, _tc_voutput_output_handler_cb2, &done2);
1922         tdm_client_output_remove_change_handler(output, _tc_voutput_output_handler_cb3, &done3);
1923 }
1924
1925 TEST_F(TDMVirtualOutput, SetModeNullObject)
1926 {
1927         tdm_error ret;
1928         unsigned int mmWidth = 300, mmHeight = 150;
1929         tdm_client_output_mode modes[this->MODE_COUNT];
1930         int count = this->MODE_COUNT;
1931         int virtual_conf;
1932
1933         if (this->voutput == NULL) {
1934                 virtual_conf = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0);
1935                 ASSERT_EQ(virtual_conf, 0);
1936                 return;
1937         }
1938
1939         ret = tdm_client_voutput_set_physical_size(this->voutput, mmWidth, mmHeight);
1940         ASSERT_EQ(ret, TDM_ERROR_NONE);
1941
1942         _tc_tdm_client_virutual_make_available_mode(modes, count);
1943         ret = tdm_client_voutput_set_available_modes(this->voutput, modes, count);
1944         ASSERT_EQ(ret, TDM_ERROR_NONE);
1945
1946         ret = tdm_client_voutput_connect(this->voutput);
1947         ASSERT_EQ(ret, TDM_ERROR_NONE);
1948
1949         tdm_client_handle_events_timeout(this->client, 50);
1950
1951         ASSERT_EQ(tdm_client_voutput_set_mode(NULL, 0), TDM_ERROR_INVALID_PARAMETER);
1952
1953         ret = tdm_client_voutput_disconnect(this->voutput);
1954         ASSERT_EQ(ret, TDM_ERROR_NONE);
1955
1956         tdm_client_handle_events_timeout(this->client, 0);
1957 }
1958
1959 TEST_F(TDMVirtualOutput, SetModeInvalidIndex)
1960 {
1961         tdm_error ret;
1962         unsigned int mmWidth = 300, mmHeight = 150;
1963         tdm_client_output_mode modes[this->MODE_COUNT];
1964         int count = this->MODE_COUNT;
1965         int virtual_conf;
1966
1967         if (this->voutput == NULL) {
1968                 virtual_conf = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_VIRTUAL_OUTPUT, 0);
1969                 ASSERT_EQ(virtual_conf, 0);
1970                 return;
1971         }
1972
1973         ret = tdm_client_voutput_set_physical_size(this->voutput, mmWidth, mmHeight);
1974         ASSERT_EQ(ret, TDM_ERROR_NONE);
1975
1976         _tc_tdm_client_virutual_make_available_mode(modes, count);
1977         ret = tdm_client_voutput_set_available_modes(this->voutput, modes, count);
1978         ASSERT_EQ(ret, TDM_ERROR_NONE);
1979
1980         ret = tdm_client_voutput_connect(this->voutput);
1981         ASSERT_EQ(ret, TDM_ERROR_NONE);
1982
1983         tdm_client_handle_events_timeout(this->client, 50);
1984
1985         ASSERT_EQ(tdm_client_voutput_set_mode(this->voutput, -1), TDM_ERROR_INVALID_PARAMETER);
1986
1987         ret = tdm_client_voutput_disconnect(this->voutput);
1988         ASSERT_EQ(ret, TDM_ERROR_NONE);
1989
1990         tdm_client_handle_events_timeout(this->client, 0);
1991 }
1992
1993 #ifdef TDM_UT_TEST_WITH_PARAMS
1994 INSTANTIATE_TEST_CASE_P(TDMClientParams,
1995                                                 TDMClient,
1996                                                 Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
1997 #else
1998 INSTANTIATE_TEST_CASE_P(TDMClientParams,
1999                                                 TDMClient,
2000                                                 Values(TDM_DEFAULT_MODULE));
2001 #endif
2002
2003 /* LCOV_EXCL_END */