package version up to 1.18.0
[platform/core/uifw/libtdm.git] / utests / src / ut_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 "ut_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 static int _ut_tdm_pipe_read_msg(int fd);
54 static bool _ut_tdm_pipe_write_msg(int fd, int reply_fd, int msg);
55 static pid_t _ut_tdm_client_server_fork(int *pipe_to_parent, int *pipe_to_child);
56
57 class TDMClient : public TDMEnv
58 {
59 public:
60         static pid_t server_pid;
61
62         /* 0: read, 1: write */
63         static int pipe_parent[2];
64         static int pipe_child[2];
65
66         tdm_client *client;
67         tdm_client_output *output;
68         tdm_client_vblank *vblank;
69
70         double vrefresh_interval, start, end;
71
72         TDMClient();
73
74         void SetUp(void);
75         void TearDown(void);
76         bool PrepareClient(void);
77         bool PrepareOutput(void);
78         bool PrepareVblank(void);
79
80         static void TearDownTestCase(void);
81         static void ServerFork(void);
82         static void ServerKill(void);
83 };
84
85 pid_t TDMClient::server_pid = -1;
86 int TDMClient::pipe_parent[2] = {-1, -1};
87 int TDMClient::pipe_child[2] = {-1, -1};
88
89 void TDMClient::TearDownTestCase(void)
90 {
91         ServerKill();
92 }
93
94 void TDMClient::ServerFork(void)
95 {
96         if (server_pid > 0)
97                 return;
98
99         server_pid = _ut_tdm_client_server_fork(pipe_parent, pipe_child);
100         ASSERT_GT(server_pid, 0);
101 }
102
103 void TDMClient::ServerKill(void)
104 {
105         if (pipe_child[0] >= 0)
106                 close(pipe_child[0]);
107         if (pipe_child[1] >= 0) {
108                 if (server_pid > 0) {
109                         bool ret = _ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_TERMINATE_SERVER);
110                         if (ret) {
111                                 if (waitpid(server_pid, NULL, 0) == server_pid)
112                                         TDM_INFO("*** server terminated ***");
113                                 else
114                                         TDM_ERR("*** failed to terminate server ***");
115                         } else {
116                                 if (kill(server_pid, 9) < 0)
117                                         TDM_ERR("*** failed to kill server ***");
118                         }
119                 }
120                 close(pipe_child[1]);
121         }
122
123         if (pipe_parent[0] >= 0)
124                 close(pipe_parent[0]);
125         if (pipe_parent[1] >= 0)
126                 close(pipe_parent[1]);
127
128         server_pid = -1;
129         pipe_parent[0] = pipe_parent[1] = -1;
130         pipe_child[0] = pipe_child[1] = -1;
131 }
132
133 TDMClient::TDMClient()
134 {
135         client = NULL;
136         output = NULL;
137         vblank = NULL;
138         vrefresh_interval = start = end = 0.0;
139 }
140
141 void TDMClient::SetUp(void)
142 {
143         TDMEnv::SetUp();
144
145         if (server_pid == -1)
146                 ServerFork();
147 }
148
149 void TDMClient::TearDown(void)
150 {
151         if (vblank)
152                 tdm_client_vblank_destroy(vblank);
153         if (client)
154                 tdm_client_destroy(client);
155
156         TDMEnv::TearDown();
157 }
158
159 bool TDMClient::PrepareClient(void)
160 {
161         tdm_error ret;
162         client = tdm_client_create(&ret);
163         TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
164         TDM_UT_RETURN_FALSE_IF_FAIL(client != NULL);
165
166         return true;
167 }
168
169 bool TDMClient::PrepareOutput(void)
170 {
171         tdm_error ret;
172
173         TDM_UT_RETURN_FALSE_IF_FAIL(client != NULL);
174
175         output = tdm_client_get_output(client, NULL, &ret);
176         TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
177         TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
178
179         return true;
180 }
181
182 bool TDMClient::PrepareVblank(void)
183 {
184         tdm_error ret;
185         unsigned int refresh;
186
187         TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
188
189         vblank = tdm_client_output_create_vblank(output, &ret);
190         TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
191         TDM_UT_RETURN_FALSE_IF_FAIL(vblank != NULL);
192
193         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_client_output_get_refresh_rate(output, &refresh) == TDM_ERROR_NONE);
194         TDM_UT_RETURN_FALSE_IF_FAIL(refresh > 0);
195
196         vrefresh_interval = 1.0 / (double)refresh;
197         TDM_UT_RETURN_FALSE_IF_FAIL(vrefresh_interval > 0);
198
199         return true;
200 }
201
202 static int
203 _ut_tdm_pipe_read_msg(int fd)
204 {
205         ssize_t len;
206         int msg;
207
208         do {
209                 len = read(fd, &msg, sizeof msg);
210         } while (len < 0 && errno == EINTR);
211
212         if (len <= 0)
213                 msg = TDM_UT_PIPE_MSG_NONE;
214
215         return msg;
216 }
217
218 static bool
219 _ut_tdm_pipe_write_msg(int fd, int reply_fd, int msg)
220 {
221         ssize_t len = write(fd, &msg, sizeof msg);
222         TDM_UT_RETURN_FALSE_IF_FAIL(len == sizeof msg);
223
224         if (reply_fd >= 0) {
225                 int reply = _ut_tdm_pipe_read_msg(reply_fd);
226                 TDM_UT_RETURN_FALSE_IF_FAIL(reply == TDM_UT_PIPE_MSG_REPLY);
227         }
228
229         return true;
230 }
231
232 static bool
233 _ut_tdm_server_set_output_dpms(tdm_display *dpy, int msg)
234 {
235         tdm_error ret;
236         tdm_output *output;
237         tdm_output_dpms dpms;
238
239         output = tdm_display_find_output(dpy, "primary", &ret);
240         TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE);
241         TDM_UT_RETURN_FALSE_IF_FAIL(output != NULL);
242
243         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_dpms(output, &dpms) == TDM_ERROR_NONE);
244
245         switch (msg) {
246         case TDM_UT_PIPE_MSG_DPMS_ON:
247                 if (dpms != TDM_OUTPUT_DPMS_ON)
248                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON) == TDM_ERROR_NONE);
249                 break;
250         case TDM_UT_PIPE_MSG_DPMS_OFF:
251                 if (dpms != TDM_OUTPUT_DPMS_OFF)
252                         TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE);
253                 break;
254         default:
255                 break;
256         }
257
258         return true;
259 }
260
261 static void
262 _ut_tdm_server_run(int *pipe_parent, int *pipe_child)
263 {
264         tdm_display *dpy = NULL;
265         tdm_error ret;
266         struct pollfd fds[2];
267         int tdm_fd, err;
268         int output_count = 0;
269
270         dpy = tdm_display_init(&ret);
271         TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed);
272         TDM_UT_GOTO_IF_FAIL(dpy != NULL, failed);
273
274         TDM_UT_GOTO_IF_FAIL(tdm_display_get_output_count(dpy, &output_count) == TDM_ERROR_NONE, failed);
275
276         for (int o = 0; o < output_count; o++) {
277                 tdm_output *output = tdm_display_get_output(dpy, o, &ret);
278                 TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, failed);
279                 TDM_UT_GOTO_IF_FAIL(output != NULL, failed);
280
281                 if (!ut_tdm_output_is_connected(output))
282                         continue;
283
284                 TDM_UT_GOTO_IF_FAIL(ut_tdm_output_prepare(dpy, output, true) == true, failed);
285         }
286
287         TDM_UT_GOTO_IF_FAIL(_ut_tdm_pipe_write_msg(pipe_parent[1], -1, TDM_UT_PIPE_MSG_SERVER_READY) == true, done);
288
289         TDM_INFO("*** server ready ***");
290
291         ret = tdm_display_get_fd(dpy, &tdm_fd);
292         TDM_UT_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, done);
293
294         fds[0].events = POLLIN;
295         fds[0].fd = tdm_fd;
296         fds[0].revents = 0;
297
298         fds[1].events = POLLIN;
299         fds[1].fd = pipe_child[0];
300         fds[1].revents = 0;
301
302         while (1) {
303                 /* make sure all events are flushed to clients before falling in sleep */
304                 tdm_display_flush(dpy);
305
306                 err = poll(fds, 2, -1);
307                 if (err < 0) {
308                         if (errno == EINTR || errno == EAGAIN) {
309                                 continue;
310                         } else {
311                                 TDM_ERR("server-process: poll failed: %m\n");
312                                 goto done;
313                         }
314                 }
315
316                 if (fds[0].revents & POLLIN)
317                         ret = ut_tdm_display_handle_events(dpy);
318
319                 if (fds[1].revents & POLLIN) {
320                         int msg = _ut_tdm_pipe_read_msg(pipe_child[0]);
321                         _ut_tdm_pipe_write_msg(pipe_parent[1], -1, TDM_UT_PIPE_MSG_REPLY);
322
323                         switch (msg) {
324                         case TDM_UT_PIPE_MSG_DPMS_ON:
325                         case TDM_UT_PIPE_MSG_DPMS_OFF:
326                                 _ut_tdm_server_set_output_dpms(dpy, msg);
327                                 break;
328                         case TDM_UT_PIPE_MSG_TERMINATE_SERVER:
329                                 goto done;
330                         default:
331                                 break;
332                         }
333                 }
334         }
335
336 done:
337         if (dpy)
338                 tdm_display_deinit(dpy);
339         return;
340
341 failed:
342         TDM_UT_GOTO_IF_FAIL(_ut_tdm_pipe_write_msg(pipe_parent[1], -1, TDM_UT_PIPE_MSG_SERVER_FAILED) == true, done);
343         TDM_INFO("*** server failed ***");
344
345         if (dpy)
346                 tdm_display_deinit(dpy);
347         return;
348
349 }
350
351 static void _ut_tdm_client_sig_handler(int sig)
352 {
353         TDM_UT_ERR("got signal: %d", sig);
354         kill(TDMClient::server_pid, 9);
355         abort();
356 }
357
358 static pid_t
359 _ut_tdm_client_server_fork(int *pipe_parent, int *pipe_child)
360 {
361         pid_t pid;
362         int msg;
363
364         TDM_UT_GOTO_IF_FAIL(pipe(pipe_parent) == 0, failed);
365         TDM_UT_GOTO_IF_FAIL(pipe(pipe_child) == 0, failed);
366
367         signal(SIGCHLD, SIG_IGN);
368         signal(SIGSEGV, _ut_tdm_client_sig_handler);
369
370         prctl(PR_SET_PDEATHSIG, SIGHUP);
371
372         pid = fork();
373         TDM_UT_GOTO_IF_FAIL(pid >= 0, failed);
374
375         if (pid == 0) {
376                 _ut_tdm_server_run(pipe_parent, pipe_child);
377                 close(pipe_child[0]);
378                 close(pipe_child[1]);
379                 close(pipe_parent[0]);
380                 close(pipe_parent[1]);
381
382 #ifdef TIZEN_TEST_GCOV
383                 __gcov_flush();
384 #endif
385
386                 exit(0);
387         }
388
389         msg = _ut_tdm_pipe_read_msg(pipe_parent[0]);
390         TDM_UT_GOTO_IF_FAIL(msg == TDM_UT_PIPE_MSG_SERVER_READY, failed);
391
392         TDM_INFO("*** server fork done ***");
393
394         return pid;
395
396 failed:
397         return -1;
398 }
399
400 TEST_P(TDMClient, ClientCreate)
401 {
402         tdm_error ret;
403
404         client = tdm_client_create(&ret);
405         ASSERT_EQ(ret, TDM_ERROR_NONE);
406         ASSERT_NE(client, NULL);
407 }
408
409 TEST_P(TDMClient, ClientCreateNullOther)
410 {
411         client = tdm_client_create(NULL);
412         ASSERT_NE(client, NULL);
413 }
414
415 TEST_P(TDMClient, ClientDestroy)
416 {
417         tdm_error ret;
418
419         client = tdm_client_create(&ret);
420         ASSERT_EQ(ret, TDM_ERROR_NONE);
421         ASSERT_NE(client, NULL);
422
423         tdm_client_destroy(client);
424         client = NULL;
425 }
426
427 TEST_P(TDMClient, ClientNullObject)
428 {
429         tdm_client_destroy(NULL);
430 }
431
432 /* tdm_client_get_fd */
433 TEST_P(TDMClient, ClientGetFd)
434 {
435         int fd = TDM_UT_INVALID_VALUE;
436
437         ASSERT_EQ(PrepareClient(), true);
438
439         ASSERT_EQ(tdm_client_get_fd(client, &fd), TDM_ERROR_NONE);
440         ASSERT_GE(fd, 0);
441 }
442
443 TEST_P(TDMClient, ClientGetFdNullObject)
444 {
445         int fd = TDM_UT_INVALID_VALUE;
446         ASSERT_EQ(tdm_client_get_fd(NULL, &fd), TDM_ERROR_INVALID_PARAMETER);
447         ASSERT_EQ(fd, TDM_UT_INVALID_VALUE);
448 }
449
450 TEST_P(TDMClient, ClientGetFdNullOther)
451 {
452         ASSERT_EQ(PrepareClient(), true);
453
454         ASSERT_EQ(tdm_client_get_fd(client, NULL), TDM_ERROR_INVALID_PARAMETER);
455 }
456
457 static void
458 _ut_tdm_client_vblank_cb(unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
459 {
460         bool *done = (bool *)user_data;
461         if (done)
462                 *done = true;
463 }
464
465 /* tdm_client_handle_events_timeout */
466 TEST_P(TDMClient, ClientHandleEvent)
467 {
468         bool done = false;
469
470         ASSERT_EQ(PrepareClient(), true);
471
472         ASSERT_EQ(tdm_client_wait_vblank(client, NULL, 1, 1, 0, _ut_tdm_client_vblank_cb, &done), TDM_ERROR_NONE);
473         ASSERT_EQ(done, false);
474
475         while (!done)
476                 ASSERT_EQ(tdm_client_handle_events(client), TDM_ERROR_NONE);
477 }
478
479 TEST_P(TDMClient, ClientHandleEventNullObject)
480 {
481         ASSERT_EQ(tdm_client_handle_events(NULL), TDM_ERROR_INVALID_PARAMETER);
482 }
483
484 /* tdm_client_wait_vblank, deprecated */
485 TEST_P(TDMClient, ClientWaitVblank)
486 {
487         bool done = false;
488
489         ASSERT_EQ(PrepareClient(), true);
490
491         ASSERT_EQ(tdm_client_wait_vblank(client, NULL, 1, 1, 0, _ut_tdm_client_vblank_cb, &done), TDM_ERROR_NONE);
492         ASSERT_EQ(done, false);
493
494         while (!done)
495                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
496 }
497
498 /* tdm_client_get_output */
499 TEST_P(TDMClient, ClientGetOutput)
500 {
501         tdm_error ret;
502
503         ASSERT_EQ(PrepareClient(), true);
504
505         output = tdm_client_get_output(client, NULL, &ret);
506         ASSERT_EQ(ret, TDM_ERROR_NONE);
507         ASSERT_NE(output, NULL);
508 }
509
510 TEST_P(TDMClient, ClientGetOutputPrimary)
511 {
512         tdm_error ret;
513
514         ASSERT_EQ(PrepareClient(), true);
515
516         output = tdm_client_get_output(client, (char*)"primary", &ret);
517         ASSERT_EQ(ret, TDM_ERROR_NONE);
518         ASSERT_NE(output, NULL);
519 }
520
521 TEST_P(TDMClient, ClientGetOutputDefault)
522 {
523         tdm_error ret;
524
525         ASSERT_EQ(PrepareClient(), true);
526
527         output = tdm_client_get_output(client, (char*)"default", &ret);
528         ASSERT_EQ(ret, TDM_ERROR_NONE);
529         ASSERT_NE(output, NULL);
530 }
531
532 TEST_P(TDMClient, ClientGetOutputInvalidName)
533 {
534         tdm_error ret;
535
536         ASSERT_EQ(PrepareClient(), true);
537
538         output = tdm_client_get_output(client, (char*)"invalid", &ret);
539         ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
540         ASSERT_EQ(output, NULL);
541 }
542
543 TEST_P(TDMClient, ClientGetOutputNullObject)
544 {
545         tdm_error ret;
546
547         output = tdm_client_get_output(NULL, NULL, &ret);
548         ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
549         ASSERT_EQ(output, NULL);
550 }
551
552 TEST_P(TDMClient, ClientGetOutputNullOther)
553 {
554         ASSERT_EQ(PrepareClient(), true);
555
556         output = tdm_client_get_output(client, NULL, NULL);
557         ASSERT_NE(output, NULL);
558 }
559
560 static void
561 _ut_tdm_client_output_change_dpms_cb(tdm_client_output *output,
562                                                                          tdm_output_change_type type,
563                                                                          tdm_value value,
564                                                                          void *user_data)
565 {
566         bool *done = (bool *)user_data;
567
568         switch (type) {
569         case TDM_OUTPUT_CHANGE_DPMS:
570                 if (done)
571                         *done = true;
572                 break;
573         default:
574                 break;
575         }
576 }
577
578 /* tdm_client_output_add_change_handler */
579 TEST_P(TDMClient, ClientOutputAddChangeHandler)
580 {
581         bool done = false;
582         tdm_output_dpms dpms;
583
584         ASSERT_EQ(PrepareClient(), true);
585         ASSERT_EQ(PrepareOutput(), true);
586
587         ASSERT_EQ(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, &done), TDM_ERROR_NONE);
588         ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_OFF), true);
589
590         while (!done)
591                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
592
593         ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
594         ASSERT_EQ(dpms, TDM_OUTPUT_DPMS_OFF);
595
596         ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_ON), true);
597         while (dpms != TDM_OUTPUT_DPMS_ON) {
598                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
599                 ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
600         }
601 }
602
603 TEST_P(TDMClient, ClientOutputAddChangeHandlerTwice)
604 {
605         ASSERT_EQ(PrepareClient(), true);
606         ASSERT_EQ(PrepareOutput(), true);
607
608         ASSERT_EQ(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL), TDM_ERROR_NONE);
609         ASSERT_EQ(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL), TDM_ERROR_BAD_REQUEST);
610 }
611
612 TEST_P(TDMClient, ClientOutputAddChangeHandlerNullObject)
613 {
614         ASSERT_EQ(tdm_client_output_add_change_handler(NULL, _ut_tdm_client_output_change_dpms_cb, NULL), TDM_ERROR_INVALID_PARAMETER);
615 }
616
617 TEST_P(TDMClient, ClientOutputAddChangeHandlerNullOther)
618 {
619         ASSERT_EQ(PrepareClient(), true);
620         ASSERT_EQ(PrepareOutput(), true);
621
622         ASSERT_EQ(tdm_client_output_add_change_handler(output, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
623 }
624
625 /* tdm_client_output_remove_change_handler */
626 TEST_P(TDMClient, ClientOutputRemoveChangeHandler)
627 {
628         ASSERT_EQ(PrepareClient(), true);
629         ASSERT_EQ(PrepareOutput(), true);
630
631         ASSERT_EQ(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL), TDM_ERROR_NONE);
632         tdm_client_output_remove_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL);
633 }
634
635 TEST_P(TDMClient, ClientOutputRemoveChangeHandlerDifferentData)
636 {
637         bool done = (bool)TDM_UT_INVALID_VALUE;
638
639         ASSERT_EQ(PrepareClient(), true);
640         ASSERT_EQ(PrepareOutput(), true);
641
642         ASSERT_EQ(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb, &done), TDM_ERROR_NONE);
643         tdm_client_output_remove_change_handler(output, _ut_tdm_client_output_change_dpms_cb, NULL);
644 }
645
646 static void
647 _ut_tdm_client_output_change_dpms_cb2(tdm_client_output *output,
648                                                                           tdm_output_change_type type,
649                                                                           tdm_value value,
650                                                                           void *user_data)
651 {
652         switch (type) {
653         case TDM_OUTPUT_CHANGE_DPMS:
654                 tdm_client_output_remove_change_handler(output, _ut_tdm_client_output_change_dpms_cb2, user_data);
655                 break;
656         default:
657                 break;
658         }
659 }
660
661 TEST_P(TDMClient, ClientOutputRemoveChangeHandlerInHandler)
662 {
663         tdm_output_dpms dpms = TDM_OUTPUT_DPMS_ON;
664
665         ASSERT_EQ(PrepareClient(), true);
666         ASSERT_EQ(PrepareOutput(), true);
667
668         ASSERT_EQ(tdm_client_output_add_change_handler(output, _ut_tdm_client_output_change_dpms_cb2, NULL), TDM_ERROR_NONE);
669         ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_OFF), true);
670         ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
671         while (dpms != TDM_OUTPUT_DPMS_OFF) {
672                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
673                 ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
674         }
675
676         ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_ON), true);
677         while (dpms != TDM_OUTPUT_DPMS_ON)
678                 ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
679 }
680
681 TEST_P(TDMClient, ClientOutputRemoveChangeHandlerNullObject)
682 {
683         tdm_client_output_remove_change_handler(NULL, _ut_tdm_client_output_change_dpms_cb, NULL);
684 }
685
686 TEST_P(TDMClient, ClientOutputRemoveChangeHandlerNullOther)
687 {
688         ASSERT_EQ(PrepareClient(), true);
689         ASSERT_EQ(PrepareOutput(), true);
690
691         tdm_client_output_remove_change_handler(output, NULL, NULL);
692 }
693
694 /* tdm_client_output_get_refresh_rate */
695 TEST_P(TDMClient, ClientOutputGetRefreshRate)
696 {
697         unsigned int refresh = 0;
698
699         ASSERT_EQ(PrepareClient(), true);
700         ASSERT_EQ(PrepareOutput(), true);
701
702         ASSERT_EQ(tdm_client_output_get_refresh_rate(output, &refresh), TDM_ERROR_NONE);
703         ASSERT_GT(refresh, 0);
704 }
705
706 TEST_P(TDMClient, ClientOutputGetRefreshRateNullObject)
707 {
708         unsigned int refresh = (unsigned int)TDM_UT_INVALID_VALUE;
709
710         ASSERT_EQ(tdm_client_output_get_refresh_rate(NULL, &refresh), TDM_ERROR_INVALID_PARAMETER);
711         ASSERT_EQ(refresh, (unsigned int)TDM_UT_INVALID_VALUE);
712 }
713
714 TEST_P(TDMClient, ClientOutputGetRefreshRateNullOther)
715 {
716         ASSERT_EQ(PrepareClient(), true);
717         ASSERT_EQ(PrepareOutput(), true);
718
719         ASSERT_EQ(tdm_client_output_get_refresh_rate(output, NULL), TDM_ERROR_INVALID_PARAMETER);
720 }
721
722 /* tdm_client_output_get_refresh_rate */
723 TEST_P(TDMClient, ClientOutputGetConnStatus)
724 {
725         tdm_output_conn_status status = (tdm_output_conn_status)TDM_UT_INVALID_VALUE;
726
727         ASSERT_EQ(PrepareClient(), true);
728         ASSERT_EQ(PrepareOutput(), true);
729
730         ASSERT_EQ(tdm_client_output_get_conn_status(output, &status), TDM_ERROR_NONE);
731         ASSERT_NE(status, (tdm_output_conn_status)TDM_UT_INVALID_VALUE);
732 }
733
734 TEST_P(TDMClient, ClientOutputGetConnStatusNullObject)
735 {
736         tdm_output_conn_status status = (tdm_output_conn_status)TDM_UT_INVALID_VALUE;
737
738         ASSERT_EQ(tdm_client_output_get_conn_status(NULL, &status), TDM_ERROR_INVALID_PARAMETER);
739         ASSERT_EQ(status, (tdm_output_conn_status)TDM_UT_INVALID_VALUE);
740 }
741
742 TEST_P(TDMClient, ClientOutputGetConnStatusNullOther)
743 {
744         ASSERT_EQ(PrepareClient(), true);
745         ASSERT_EQ(PrepareOutput(), true);
746
747         ASSERT_EQ(tdm_client_output_get_conn_status(output, NULL), TDM_ERROR_INVALID_PARAMETER);
748 }
749
750 /* tdm_client_output_get_dpms */
751 TEST_P(TDMClient, ClientOutputGetDpms)
752 {
753         tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
754
755         ASSERT_EQ(PrepareClient(), true);
756         ASSERT_EQ(PrepareOutput(), true);
757
758         ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
759         ASSERT_NE(dpms, (tdm_output_dpms)TDM_UT_INVALID_VALUE);
760 }
761
762 TEST_P(TDMClient, ClientOutputGetDpmsNullObject)
763 {
764         tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
765
766         ASSERT_EQ(tdm_client_output_get_dpms(NULL, &dpms), TDM_ERROR_INVALID_PARAMETER);
767         ASSERT_EQ(dpms, (tdm_output_dpms)TDM_UT_INVALID_VALUE);
768 }
769
770 TEST_P(TDMClient, ClientOutputGetDpmsNullOther)
771 {
772         ASSERT_EQ(PrepareClient(), true);
773         ASSERT_EQ(PrepareOutput(), true);
774
775         ASSERT_EQ(tdm_client_output_get_dpms(output, NULL), TDM_ERROR_INVALID_PARAMETER);
776 }
777
778 /* tdm_client_output_create_vblank */
779 TEST_P(TDMClient, ClientOutputCreateVblank)
780 {
781         tdm_error ret;
782
783         ASSERT_EQ(PrepareClient(), true);
784         ASSERT_EQ(PrepareOutput(), true);
785
786         vblank = tdm_client_output_create_vblank(output, &ret);
787         ASSERT_EQ(ret, TDM_ERROR_NONE);
788         ASSERT_NE(vblank, NULL);
789 }
790
791 TEST_P(TDMClient, ClientOutputCreateVblankNullObject)
792 {
793         tdm_error ret;
794
795         vblank = tdm_client_output_create_vblank(NULL, &ret);
796         ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
797         ASSERT_EQ(vblank, NULL);
798 }
799
800 TEST_P(TDMClient, ClientOutputCreateVblankNullOther)
801 {
802         ASSERT_EQ(PrepareClient(), true);
803         ASSERT_EQ(PrepareOutput(), true);
804
805         vblank = tdm_client_output_create_vblank(output, NULL);
806         ASSERT_NE(vblank, NULL);
807 }
808
809 /* tdm_client_vblank_destroy */
810 TEST_P(TDMClient, ClientVblankDestroy)
811 {
812         tdm_error ret;
813
814         ASSERT_EQ(PrepareClient(), true);
815         ASSERT_EQ(PrepareOutput(), true);
816
817         vblank = tdm_client_output_create_vblank(output, &ret);
818         ASSERT_EQ(ret, TDM_ERROR_NONE);
819         ASSERT_NE(vblank, NULL);
820
821         tdm_client_vblank_destroy(vblank);
822         vblank = NULL;
823 }
824
825 TEST_P(TDMClient, ClientVblankDestroyNullObject)
826 {
827         tdm_client_vblank_destroy(NULL);
828 }
829
830 /* tdm_client_vblank_set_name */
831 TEST_P(TDMClient, ClientVblankSetName)
832 {
833         ASSERT_EQ(PrepareClient(), true);
834         ASSERT_EQ(PrepareOutput(), true);
835         ASSERT_EQ(PrepareVblank(), true);
836
837         ASSERT_EQ(tdm_client_vblank_set_name(vblank, TDM_UT_VBLANK_NAME), TDM_ERROR_NONE);
838 }
839
840 TEST_P(TDMClient, ClientVblankSetNameTwice)
841 {
842         ASSERT_EQ(PrepareClient(), true);
843         ASSERT_EQ(PrepareOutput(), true);
844         ASSERT_EQ(PrepareVblank(), true);
845
846         ASSERT_EQ(tdm_client_vblank_set_name(vblank, TDM_UT_VBLANK_NAME), TDM_ERROR_NONE);
847         ASSERT_EQ(tdm_client_vblank_set_name(vblank, TDM_UT_VBLANK_NAME), TDM_ERROR_NONE);
848 }
849
850 TEST_P(TDMClient, ClientVblankSetNameNullObject)
851 {
852         ASSERT_EQ(tdm_client_vblank_set_name(NULL, TDM_UT_VBLANK_NAME), TDM_ERROR_INVALID_PARAMETER);
853 }
854
855 /* tdm_client_vblank_set_sync */
856 TEST_P(TDMClient, ClientVblankSetSync)
857 {
858         ASSERT_EQ(PrepareClient(), true);
859         ASSERT_EQ(PrepareOutput(), true);
860         ASSERT_EQ(PrepareVblank(), true);
861
862         ASSERT_EQ(tdm_client_vblank_set_sync(vblank, 1), TDM_ERROR_NONE);
863 }
864
865 TEST_P(TDMClient, ClientVblankSetSyncTwice)
866 {
867         ASSERT_EQ(PrepareClient(), true);
868         ASSERT_EQ(PrepareOutput(), true);
869         ASSERT_EQ(PrepareVblank(), true);
870
871         ASSERT_EQ(tdm_client_vblank_set_sync(vblank, 1), TDM_ERROR_NONE);
872         ASSERT_EQ(tdm_client_vblank_set_sync(vblank, 1), TDM_ERROR_NONE);
873 }
874
875 TEST_P(TDMClient, ClientVblankSetSyncNullObject)
876 {
877         ASSERT_EQ(tdm_client_vblank_set_sync(NULL, 1), TDM_ERROR_INVALID_PARAMETER);
878 }
879
880 /* tdm_client_vblank_set_fps */
881 TEST_P(TDMClient, ClientVblankSetFps)
882 {
883         ASSERT_EQ(PrepareClient(), true);
884         ASSERT_EQ(PrepareOutput(), true);
885         ASSERT_EQ(PrepareVblank(), true);
886
887         ASSERT_EQ(tdm_client_vblank_set_fps(vblank, 30), TDM_ERROR_NONE);
888 }
889
890 TEST_P(TDMClient, ClientVblankSetFpsTwice)
891 {
892         ASSERT_EQ(PrepareClient(), true);
893         ASSERT_EQ(PrepareOutput(), true);
894         ASSERT_EQ(PrepareVblank(), true);
895
896         ASSERT_EQ(tdm_client_vblank_set_fps(vblank, 30), TDM_ERROR_NONE);
897         ASSERT_EQ(tdm_client_vblank_set_fps(vblank, 30), TDM_ERROR_NONE);
898 }
899
900 TEST_P(TDMClient, ClientVblankSetFpsNullObject)
901 {
902         ASSERT_EQ(tdm_client_vblank_set_fps(NULL, 30), TDM_ERROR_INVALID_PARAMETER);
903 }
904
905 /* tdm_client_vblank_set_offset */
906 TEST_P(TDMClient, ClientVblankSetOffset)
907 {
908         ASSERT_EQ(PrepareClient(), true);
909         ASSERT_EQ(PrepareOutput(), true);
910         ASSERT_EQ(PrepareVblank(), true);
911
912         ASSERT_EQ(tdm_client_vblank_set_offset(vblank, 10), TDM_ERROR_NONE);
913 }
914
915 TEST_P(TDMClient, ClientVblankSetOffsetTwice)
916 {
917         ASSERT_EQ(PrepareClient(), true);
918         ASSERT_EQ(PrepareOutput(), true);
919         ASSERT_EQ(PrepareVblank(), true);
920
921         ASSERT_EQ(tdm_client_vblank_set_offset(vblank, 10), TDM_ERROR_NONE);
922         ASSERT_EQ(tdm_client_vblank_set_offset(vblank, 10), TDM_ERROR_NONE);
923 }
924
925 TEST_P(TDMClient, ClientVblankSetOffsetNullObject)
926 {
927         ASSERT_EQ(tdm_client_vblank_set_offset(NULL, 10), TDM_ERROR_INVALID_PARAMETER);
928 }
929
930 /* tdm_client_vblank_set_enable_fake */
931 TEST_P(TDMClient, ClientVblankSetEnableFake)
932 {
933         ASSERT_EQ(PrepareClient(), true);
934         ASSERT_EQ(PrepareOutput(), true);
935         ASSERT_EQ(PrepareVblank(), true);
936
937         ASSERT_EQ(tdm_client_vblank_set_enable_fake(vblank, 1), TDM_ERROR_NONE);
938 }
939
940 TEST_P(TDMClient, ClientVblankSetEnableFakeTwice)
941 {
942         ASSERT_EQ(PrepareClient(), true);
943         ASSERT_EQ(PrepareOutput(), true);
944         ASSERT_EQ(PrepareVblank(), true);
945
946         ASSERT_EQ(tdm_client_vblank_set_enable_fake(vblank, 1), TDM_ERROR_NONE);
947         ASSERT_EQ(tdm_client_vblank_set_enable_fake(vblank, 1), TDM_ERROR_NONE);
948 }
949
950 TEST_P(TDMClient, ClientVblankSetEnableFakeNullObject)
951 {
952         ASSERT_EQ(tdm_client_vblank_set_enable_fake(NULL, 1), TDM_ERROR_INVALID_PARAMETER);
953 }
954
955 static void
956 _ut_tdm_client_vblank_cb2(tdm_client_vblank *vblank,
957                                                   tdm_error error,
958                                                   unsigned int sequence,
959                                                   unsigned int tv_sec,
960                                                   unsigned int tv_usec,
961                                                   void *user_data)
962 {
963         bool *done = (bool *)user_data;
964         if (done)
965                 *done = true;
966 }
967
968 /* tdm_client_vblank_wait */
969 TEST_P(TDMClient, ClientVblankWait)
970 {
971         bool done;
972
973         ASSERT_EQ(PrepareClient(), true);
974         ASSERT_EQ(PrepareOutput(), true);
975         ASSERT_EQ(PrepareVblank(), true);
976
977         done = false;
978         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
979
980         start = tdm_helper_get_time();
981         while (!done)
982                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
983         end = tdm_helper_get_time();
984
985         /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
986         ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval));
987 }
988
989 TEST_P(TDMClient, ClientVblankWaitFewTime)
990 {
991         bool done1, done2, done3;
992
993         ASSERT_EQ(PrepareClient(), true);
994         ASSERT_EQ(PrepareOutput(), true);
995         ASSERT_EQ(PrepareVblank(), true);
996
997         done1 = done2 = done3 = false;
998         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done1), TDM_ERROR_NONE);
999         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done2), TDM_ERROR_NONE);
1000         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done3), TDM_ERROR_NONE);
1001
1002         start = tdm_helper_get_time();
1003         while (!done1 || !done2 || !done3)
1004                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1005         end = tdm_helper_get_time();
1006
1007         /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1008         ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval));
1009
1010 }
1011
1012 TEST_P(TDMClient, ClientVblankWaitInterval0)
1013 {
1014         ASSERT_EQ(PrepareClient(), true);
1015         ASSERT_EQ(PrepareOutput(), true);
1016         ASSERT_EQ(PrepareVblank(), true);
1017
1018         ASSERT_EQ(tdm_client_vblank_wait(vblank, 0, _ut_tdm_client_vblank_cb2, NULL), TDM_ERROR_INVALID_PARAMETER);
1019 }
1020
1021 TEST_P(TDMClient, ClientVblankWaitInterval)
1022 {
1023         bool done;
1024
1025         ASSERT_EQ(PrepareClient(), true);
1026         ASSERT_EQ(PrepareOutput(), true);
1027         ASSERT_EQ(PrepareVblank(), true);
1028
1029         /* start from 1 */
1030         for (int t = 1; t < 10; t++) {
1031                 done = false;
1032                 ASSERT_EQ(tdm_client_vblank_wait(vblank, t, _ut_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
1033
1034                 start = tdm_helper_get_time();
1035                 while (!done)
1036                         ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1037                 end = tdm_helper_get_time();
1038
1039                 /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1040                 ASSERT_GT((end - start), (vrefresh_interval * (t - 1)));
1041                 ASSERT_LT((end - start), (vrefresh_interval * t + vrefresh_interval));
1042         }
1043 }
1044
1045 static void
1046 _ut_tdm_client_vblank_cb3(tdm_client_vblank *vblank,
1047                                                   tdm_error error,
1048                                                   unsigned int sequence,
1049                                                   unsigned int tv_sec,
1050                                                   unsigned int tv_usec,
1051                                                   void *user_data)
1052 {
1053         unsigned int *cur_seq = (unsigned int *)user_data;
1054         if (cur_seq)
1055                 *cur_seq = sequence;
1056 }
1057
1058 TEST_P(TDMClient, ClientVblankWaitSeq)
1059 {
1060         ASSERT_EQ(PrepareClient(), true);
1061         ASSERT_EQ(PrepareOutput(), true);
1062         ASSERT_EQ(PrepareVblank(), true);
1063
1064         for (int t = 0; t < 10; t++) {
1065                 unsigned int cur_seq = 0, temp = 0;
1066
1067                 ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb3, &cur_seq), TDM_ERROR_NONE);
1068                 while (cur_seq == 0)
1069                         ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1070
1071                 start = tdm_helper_get_time();
1072                 ASSERT_EQ(tdm_client_vblank_wait_seq(vblank, cur_seq + 1, _ut_tdm_client_vblank_cb3, &temp), TDM_ERROR_NONE);
1073                 while (temp == 0)
1074                         ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1075                 end = tdm_helper_get_time();
1076
1077                 /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1078                 ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval));
1079         }
1080 }
1081
1082 TEST_P(TDMClient, ClientVblankWaitSeqInterval)
1083 {
1084         ASSERT_EQ(PrepareClient(), true);
1085         ASSERT_EQ(PrepareOutput(), true);
1086         ASSERT_EQ(PrepareVblank(), true);
1087
1088         /* start from 1 */
1089         for (int t = 1; t < 10; t++) {
1090                 unsigned int cur_seq = 0, temp = 0;
1091
1092                 ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb3, &cur_seq), TDM_ERROR_NONE);
1093                 while (cur_seq == 0)
1094                         ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1095
1096                 start = tdm_helper_get_time();
1097                 ASSERT_EQ(tdm_client_vblank_wait_seq(vblank, cur_seq + t, _ut_tdm_client_vblank_cb3, &temp), TDM_ERROR_NONE);
1098                 while (temp == 0)
1099                         ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1100                 end = tdm_helper_get_time();
1101
1102                 /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1103                 ASSERT_GT((end - start), (vrefresh_interval * (t - 1)));
1104                 ASSERT_LT((end - start), (vrefresh_interval * t + vrefresh_interval));
1105         }
1106 }
1107
1108 TEST_P(TDMClient, ClientVblankWaitSetOffset)
1109 {
1110         bool done;
1111
1112         ASSERT_EQ(PrepareClient(), true);
1113         ASSERT_EQ(PrepareOutput(), true);
1114         ASSERT_EQ(PrepareVblank(), true);
1115
1116         ASSERT_EQ(tdm_client_vblank_set_offset(vblank, 100), TDM_ERROR_NONE);
1117
1118         done = false;
1119         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
1120
1121         start = tdm_helper_get_time();
1122         while (!done)
1123                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1124         end = tdm_helper_get_time();
1125
1126         /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1127         ASSERT_GT((end - start), (0.1));
1128         ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval + 0.1));
1129 }
1130
1131 TEST_P(TDMClient, ClientVblankWaitSetFps)
1132 {
1133         bool done;
1134         double interval;
1135         unsigned int fps = 10;
1136
1137         ASSERT_EQ(PrepareClient(), true);
1138         ASSERT_EQ(PrepareOutput(), true);
1139         ASSERT_EQ(PrepareVblank(), true);
1140
1141         ASSERT_EQ(tdm_client_vblank_set_fps(vblank, fps), TDM_ERROR_NONE);
1142         interval = 1.0 / (double)fps;
1143
1144         done = false;
1145         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_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), (interval - vrefresh_interval));
1154         ASSERT_LT((end - start), (interval + vrefresh_interval));
1155 }
1156
1157 #if 0
1158
1159 TEST_P(TDMVblank, VblankWaitEnableDisableGlobalFps)
1160 {
1161         TDM_UT_SKIP_FLAG(has_outputs);
1162
1163         unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
1164         double vrefresh_interval;
1165         unsigned int cur_seq[3];
1166         unsigned int global_fps = 5;
1167         double start, end, interval;
1168
1169         ASSERT_EQ(TestPrepareOutput(), true);
1170         ASSERT_EQ(TestCreateVblanks3(), true);
1171         ASSERT_EQ(vblank_count, 3);
1172
1173         ASSERT_EQ(tdm_vblank_get_fps(vblanks[0], &fps), TDM_ERROR_NONE);
1174         ASSERT_TRUE(fps >= 30 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
1175         vrefresh_interval = 1.0 / (double)fps;
1176
1177         for (int v = 0; v < 3; v++)
1178                 ASSERT_EQ(tdm_vblank_set_fixed_fps(vblanks[v], 10 * (v + 1)), TDM_ERROR_NONE);
1179
1180         /* enable test */
1181         tdm_vblank_enable_global_fps(1, global_fps);
1182         interval = 1.0 / (double)global_fps;
1183
1184         for (int v = 0; v < 3; v++) {
1185                 cur_seq[v] = 0;
1186                 ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq[v]), TDM_ERROR_NONE);
1187         }
1188
1189         start = tdm_helper_get_time();
1190         while (cur_seq[0] == 0)
1191                 ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
1192         end = tdm_helper_get_time();
1193
1194         ASSERT_NE(cur_seq[1], 0);
1195         ASSERT_NE(cur_seq[2], 0);
1196
1197         /* "+- vrefresh_interval" consider the delay of socket communication between kernel and platform */
1198         ASSERT_GT((end - start), (interval - vrefresh_interval));
1199         ASSERT_LT((end - start), (interval + vrefresh_interval));
1200
1201         /* disable test */
1202         tdm_vblank_enable_global_fps(0, 0);
1203
1204         for (int v = 0; v < 3; v++) {
1205                 cur_seq[v] = 0;
1206                 ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq[v]), TDM_ERROR_NONE);
1207         }
1208
1209         while (cur_seq[0] == 0)
1210                 ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
1211         ASSERT_EQ(cur_seq[1], 0);
1212         ASSERT_EQ(cur_seq[2], 0);
1213
1214         while (cur_seq[1] == 0)
1215                 ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
1216         ASSERT_EQ(cur_seq[2], 0);
1217 }
1218
1219 TEST_P(TDMVblank, VblankWaitIgnoreGlobalFps)
1220 {
1221         TDM_UT_SKIP_FLAG(has_outputs);
1222
1223         unsigned int fps = (unsigned int)TDM_UT_INVALID_VALUE;
1224         unsigned int cur_seq[3];
1225         unsigned int global_fps = 5;
1226         double start, end, interval;
1227
1228         ASSERT_EQ(TestPrepareOutput(), true);
1229         ASSERT_EQ(TestCreateVblanks3(), true);
1230         ASSERT_EQ(vblank_count, 3);
1231
1232         ASSERT_EQ(tdm_vblank_get_fps(vblanks[0], &fps), TDM_ERROR_NONE);
1233         ASSERT_TRUE(fps >= 30 && fps != (unsigned int)TDM_UT_INVALID_VALUE);
1234         interval = 1.0 / (double)fps;
1235
1236         /* 2nd vblank will ignore the global fps. */
1237         ASSERT_EQ(tdm_vblank_ignore_global_fps(vblanks[1], 1), TDM_ERROR_NONE);
1238
1239         tdm_vblank_enable_global_fps(1, global_fps);
1240
1241         for (int v = 0; v < 3; v++) {
1242                 cur_seq[v] = 0;
1243                 ASSERT_EQ(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq[v]), TDM_ERROR_NONE);
1244         }
1245
1246         start = tdm_helper_get_time();
1247         while (cur_seq[1] == 0)
1248                 ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
1249         end = tdm_helper_get_time();
1250
1251         ASSERT_EQ(cur_seq[0], 0);
1252         ASSERT_EQ(cur_seq[2], 0);
1253
1254         /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1255         ASSERT_LT((end - start), (interval + interval));
1256
1257         while (cur_seq[0] == 0)
1258                 ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE);
1259         ASSERT_NE(cur_seq[2], 0);
1260 }
1261
1262 #endif
1263
1264 TEST_P(TDMClient, ClientVblankWaitNullObject)
1265 {
1266         unsigned int cur_seq = 0;
1267
1268         ASSERT_EQ(tdm_client_vblank_wait(NULL, 1, _ut_tdm_client_vblank_cb3, &cur_seq), TDM_ERROR_INVALID_PARAMETER);
1269 }
1270
1271 TEST_P(TDMClient, ClientVblankWaitNullOther)
1272 {
1273         ASSERT_EQ(PrepareClient(), true);
1274         ASSERT_EQ(PrepareOutput(), true);
1275         ASSERT_EQ(PrepareVblank(), true);
1276
1277         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, NULL, NULL), TDM_ERROR_INVALID_PARAMETER);
1278 }
1279
1280 TEST_P(TDMClient, ClientVblankWaitDpmsOff)
1281 {
1282         tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
1283
1284         ASSERT_EQ(PrepareClient(), true);
1285         ASSERT_EQ(PrepareOutput(), true);
1286         ASSERT_EQ(PrepareVblank(), true);
1287
1288         ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_OFF), true);
1289         while (dpms != TDM_OUTPUT_DPMS_OFF)
1290                 ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
1291         ASSERT_EQ(dpms, TDM_OUTPUT_DPMS_OFF);
1292
1293         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, NULL), TDM_ERROR_DPMS_OFF);
1294
1295         ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_ON), true);
1296         while (dpms != TDM_OUTPUT_DPMS_ON)
1297                 ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
1298 }
1299
1300 TEST_P(TDMClient, ClientVblankWaitSetEnableFakeDpmsOff)
1301 {
1302         tdm_output_dpms dpms = (tdm_output_dpms)TDM_UT_INVALID_VALUE;
1303         bool done;
1304
1305         ASSERT_EQ(PrepareClient(), true);
1306         ASSERT_EQ(PrepareOutput(), true);
1307         ASSERT_EQ(PrepareVblank(), true);
1308
1309         ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_OFF), true);
1310         while (dpms != TDM_OUTPUT_DPMS_OFF)
1311                 ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
1312
1313         ASSERT_EQ(tdm_client_vblank_set_enable_fake(vblank, 1), TDM_ERROR_NONE);
1314
1315         done = false;
1316         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
1317
1318         while (!done)
1319                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1320
1321         ASSERT_EQ(_ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_DPMS_ON), true);
1322         while (dpms != TDM_OUTPUT_DPMS_ON)
1323                 ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE);
1324 }
1325
1326 /* tdm_client_vblank_wait */
1327 TEST_P(TDMClient, ClientVblankIsWaiting)
1328 {
1329         bool done;
1330         unsigned int waiting;
1331
1332         ASSERT_EQ(PrepareClient(), true);
1333         ASSERT_EQ(PrepareOutput(), true);
1334         ASSERT_EQ(PrepareVblank(), true);
1335
1336         done = false;
1337         ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE);
1338
1339         waiting = tdm_client_vblank_is_waiting(vblank);
1340         ASSERT_EQ(waiting, 1);
1341
1342         start = tdm_helper_get_time();
1343         while (!done)
1344                 ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE);
1345         end = tdm_helper_get_time();
1346
1347         /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */
1348         ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval));
1349
1350         waiting = tdm_client_vblank_is_waiting(vblank);
1351         ASSERT_EQ(waiting, 0);
1352 }
1353
1354 /* tdm_client_vblank_wait */
1355 TEST_P(TDMClient, ClientVblankIsWaitingNullObject)
1356 {
1357         unsigned int waiting = tdm_client_vblank_is_waiting(NULL);
1358         ASSERT_EQ(waiting, 0);
1359 }
1360
1361 #ifdef TDM_UT_TEST_WITH_PARAMS
1362 INSTANTIATE_TEST_CASE_P(TDMClientParams,
1363                                                 TDMClient,
1364                                                 Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE)));
1365 #else
1366 INSTANTIATE_TEST_CASE_P(TDMClientParams,
1367                                                 TDMClient,
1368                                                 Values(TDM_DEFAULT_MODULE));
1369 #endif
1370
1371 /* LCOV_EXCL_END */