Reduce the verbose logging
[platform/framework/web/livebox.git] / src / livebox.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <errno.h>
19 #include <stdlib.h> /* malloc */
20 #include <string.h> /* strdup */
21 #include <libgen.h>
22 #include <unistd.h> /* access */
23
24 #include <dlog.h>
25 #include <livebox-service.h>
26 #include <provider.h>
27 #include <provider_buffer.h>
28 #include <livebox-errno.h>
29
30 #include "debug.h"
31 #include "livebox.h"
32 #include "dlist.h"
33 #include "util.h"
34
35 #define PUBLIC __attribute__((visibility("default")))
36
37 #define FILE_SCHEMA     "file://"
38
39 /*!
40  * \brief This function is defined by the data-provider-slave
41  */
42 extern const char *livebox_find_pkgname(const char *filename);
43 extern int livebox_request_update_by_id(const char *uri);
44
45 struct block {
46         unsigned int idx;
47
48         char *type;
49         char *part;
50         char *data;
51         char *option;
52         char *id;
53         char *file;
54         char *target_id;
55 };
56
57 struct livebox_desc {
58         FILE *fp;
59         int for_pd;
60
61         unsigned int last_idx;
62
63         struct dlist *block_list;
64 };
65
66 struct livebox_buffer_data {
67         int is_pd;
68         int accelerated;
69
70         /* for Buffer event wrapper */
71         int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *);
72         void *cbdata;
73 };
74
75 PUBLIC const int DONE = 0x00;
76 PUBLIC const int OUTPUT_UPDATED = 0x02;
77 PUBLIC const int USE_NET = 0x04;
78
79 PUBLIC const int NEED_TO_SCHEDULE = 0x01;
80 PUBLIC const int NEED_TO_CREATE = 0x01;
81 PUBLIC const int NEED_TO_DESTROY = 0x01;
82 PUBLIC const int NEED_TO_UPDATE = 0x01;
83
84 PUBLIC const int LB_SYS_EVENT_FONT_CHANGED = 0x01;
85 PUBLIC const int LB_SYS_EVENT_LANG_CHANGED = 0x02;
86 PUBLIC const int LB_SYS_EVENT_TIME_CHANGED = 0x04;
87 PUBLIC const int LB_SYS_EVENT_REGION_CHANGED = 0x08;
88 PUBLIC const int LB_SYS_EVENT_PAUSED = 0x0100;
89 PUBLIC const int LB_SYS_EVENT_RESUMED = 0x0200;
90 PUBLIC const int LB_SYS_EVENT_MMC_STATUS_CHANGED = 0x0400;
91
92 PUBLIC struct livebox_desc *livebox_desc_open(const char *filename, int for_pd)
93 {
94         struct livebox_desc *handle;
95         char *new_fname;
96
97         handle = calloc(1, sizeof(*handle));
98         if (!handle) {
99                 ErrPrint("Error: %s\n", strerror(errno));
100                 return NULL;
101         }
102
103         if (for_pd) {
104                 int len;
105                 len = strlen(filename) + strlen(".desc") + 1;
106                 new_fname = malloc(len);
107                 if (!new_fname) {
108                         ErrPrint("Error: %s\n", strerror(errno));
109                         free(handle);
110                         return NULL;
111                 }
112                 snprintf(new_fname, len, "%s.desc", filename);
113         } else {
114                 new_fname = strdup(filename);
115                 if (!new_fname) {
116                         ErrPrint("Error: %s\n", strerror(errno));
117                         free(handle);
118                         return NULL;
119                 }
120         }
121
122         DbgPrint("Open a file %s with merge mode %s\n",
123                                 new_fname,
124                                 access(new_fname, F_OK) == 0 ? "enabled" : "disabled");
125
126         handle->fp = fopen(new_fname, "at");
127         free(new_fname);
128         if (!handle->fp) {
129                 ErrPrint("Failed to open a file: %s\n", strerror(errno));
130                 free(handle);
131                 return NULL;
132         }
133
134         return handle;
135 }
136
137 PUBLIC int livebox_desc_close(struct livebox_desc *handle)
138 {
139         struct dlist *l;
140         struct dlist *n;
141         struct block *block;
142
143         if (!handle)
144                 return LB_STATUS_ERROR_INVALID;
145
146         dlist_foreach_safe(handle->block_list, l, n, block) {
147                 handle->block_list = dlist_remove(handle->block_list, l);
148
149                 fprintf(handle->fp, "{\n");
150                 if (block->type)
151                         fprintf(handle->fp, "type=%s\n", block->type);
152
153                 if (block->part)
154                         fprintf(handle->fp, "part=%s\n", block->part);
155
156                 if (block->data)
157                         fprintf(handle->fp, "data=%s\n", block->data);
158
159                 if (block->option)
160                         fprintf(handle->fp, "option=%s\n", block->option);
161
162                 if (block->id)
163                         fprintf(handle->fp, "id=%s\n", block->id);
164
165                 if (block->target_id)
166                         fprintf(handle->fp, "target=%s\n", block->target_id);
167                 fprintf(handle->fp, "}\n");
168
169                 free(block->type);
170                 free(block->part);
171                 free(block->data);
172                 free(block->option);
173                 free(block->id);
174                 free(block->target_id);
175                 free(block);
176         }
177
178         fclose(handle->fp);
179         free(handle);
180         return LB_STATUS_SUCCESS;
181 }
182
183 PUBLIC int livebox_desc_set_category(struct livebox_desc *handle, const char *id, const char *category)
184 {
185         struct block *block;
186
187         if (!handle || !category)
188                 return LB_STATUS_ERROR_INVALID;
189
190         block = calloc(1, sizeof(*block));
191         if (!block)
192                 return LB_STATUS_ERROR_MEMORY;
193
194         block->type = strdup(LB_DESC_TYPE_INFO);
195         if (!block->type) {
196                 free(block);
197                 return LB_STATUS_ERROR_MEMORY;
198         }
199
200         block->part = strdup("category");
201         if (!block->part) {
202                 free(block->type);
203                 free(block);
204                 return LB_STATUS_ERROR_MEMORY;
205         }
206
207         block->data = strdup(category);
208         if (!block->data) {
209                 free(block->type);
210                 free(block->part);
211                 free(block);
212                 return LB_STATUS_ERROR_MEMORY;
213         }
214
215         if (id) {
216                 block->id = strdup(id);
217                 if (!block->id) {
218                         free(block->data);
219                         free(block->type);
220                         free(block->part);
221                         free(block);
222                         return LB_STATUS_ERROR_MEMORY;
223                 }
224         }
225
226         block->idx = handle->last_idx++;
227         handle->block_list = dlist_append(handle->block_list, block);
228         return block->idx;
229 }
230
231 PUBLIC int livebox_desc_set_size(struct livebox_desc *handle, const char *id, int w, int h)
232 {
233         struct block *block;
234         char buffer[BUFSIZ];
235
236         if (!handle)
237                 return LB_STATUS_ERROR_INVALID;
238
239         block = calloc(1, sizeof(*block));
240         if (!block)
241                 return LB_STATUS_ERROR_MEMORY;
242
243         block->type = strdup(LB_DESC_TYPE_INFO);
244         if (!block->type) {
245                 free(block);
246                 return LB_STATUS_ERROR_MEMORY;
247         }
248
249         block->part = strdup("size");
250         if (!block->part) {
251                 free(block->type);
252                 free(block);
253                 return LB_STATUS_ERROR_MEMORY;
254         }
255
256         if (id) {
257                 block->id = strdup(id);
258                 if (!block->id) {
259                         free(block->part);
260                         free(block->type);
261                         free(block);
262                         return LB_STATUS_ERROR_MEMORY;
263                 }
264         }
265
266         snprintf(buffer, sizeof(buffer), "%dx%d", w, h);
267         block->data = strdup(buffer);
268         if (!block->data) {
269                 free(block->part);
270                 free(block->type);
271                 free(block);
272                 return LB_STATUS_ERROR_MEMORY;
273         }
274
275         block->idx = handle->last_idx++;
276         handle->block_list = dlist_append(handle->block_list, block);
277         return block->idx;
278 }
279
280 PUBLIC char *livebox_util_nl2br(const char *str)
281 {
282         int len;
283         register int i;
284         char *ret;
285         char *ptr;
286
287         if (!str)
288                 return NULL;
289
290         len = strlen(str);
291         if (!len)
292                 return NULL;
293
294         ret = malloc(len + 1);
295         if (!ret)
296                 return NULL;
297
298         ptr = ret;
299         i = 0;
300         while (*str) {
301                 switch (*str) {
302                 case '\n':
303                         if (len - i < 5) {
304                                 char *tmp;
305                                 len += len;
306
307                                 tmp = realloc(ret, len + 1);
308                                 if (!tmp) {
309                                         free(ret);
310                                         return NULL;
311                                 }
312
313                                 ret = tmp;
314                                 ptr = tmp + i;
315                         }
316
317                         strcpy(ptr, "<br>");
318                         ptr += 4;
319                         i += 4;
320                         break;
321                 default:
322                         *ptr++ = *str;
323                         i++;
324                         break;
325                 }
326
327                 str++;
328         }
329         *ptr = '\0';
330
331         return ret;
332 }
333
334 PUBLIC int livebox_desc_set_id(struct livebox_desc *handle, int idx, const char *id)
335 {
336         struct dlist *l;
337         struct block *block;
338
339         dlist_foreach(handle->block_list, l, block) {
340                 if (block->idx == idx) {
341                         if (strcasecmp(block->type, LB_DESC_TYPE_SCRIPT)) {
342                                 ErrPrint("Invalid block is used\n");
343                                 return LB_STATUS_ERROR_INVALID;
344                         }
345
346                         free(block->target_id);
347                         block->target_id = NULL;
348
349                         if (!id || !strlen(id))
350                                 return LB_STATUS_SUCCESS;
351
352                         block->target_id = strdup(id);
353                         if (!block->target_id) {
354                                 ErrPrint("Heap: %s\n", strerror(errno));
355                                 return LB_STATUS_ERROR_MEMORY;
356                         }
357
358                         return LB_STATUS_SUCCESS;
359                 }
360         }
361
362         return LB_STATUS_ERROR_NOT_EXIST;
363 }
364
365 /*!
366  * \return idx
367  */
368 PUBLIC int livebox_desc_add_block(struct livebox_desc *handle, const char *id, const char *type, const char *part, const char *data, const char *option)
369 {
370         struct block *block;
371
372         if (!handle || !type)
373                 return LB_STATUS_ERROR_INVALID;
374
375         if (!part)
376                 part = "";
377
378         if (!data)
379                 data = "";
380
381         block = calloc(1, sizeof(*block));
382         if (!block) {
383                 ErrPrint("Heap: %s\n", strerror(errno));
384                 return LB_STATUS_ERROR_MEMORY;
385         }
386
387         block->type = strdup(type);
388         if (!block->type) {
389                 ErrPrint("Heap: %s\n", strerror(errno));
390                 free(block);
391                 return LB_STATUS_ERROR_MEMORY;
392         }
393
394         block->part = strdup(part);
395         if (!block->part) {
396                 ErrPrint("Heap: %s\n", strerror(errno));
397                 free(block->type);
398                 free(block);
399                 return LB_STATUS_ERROR_MEMORY;
400         }
401
402         block->data = strdup(data);
403         if (!block->data) {
404                 ErrPrint("Heap: %s\n", strerror(errno));
405                 free(block->type);
406                 free(block->part);
407                 free(block);
408                 return LB_STATUS_ERROR_MEMORY;
409         }
410
411         if (option) {
412                 block->option = strdup(option);
413                 if (!block->option) {
414                         ErrPrint("Heap: %s\n", strerror(errno));
415                         free(block->data);
416                         free(block->type);
417                         free(block->part);
418                         free(block);
419                         return LB_STATUS_ERROR_MEMORY;
420                 }
421         }
422
423         if (id) {
424                 block->id = strdup(id);
425                 if (!block->id) {
426                         ErrPrint("Heap: %s\n", strerror(errno));
427                         free(block->option);
428                         free(block->data);
429                         free(block->type);
430                         free(block->part);
431                         free(block);
432                         return LB_STATUS_ERROR_MEMORY;
433                 }
434         }
435
436         block->idx = handle->last_idx++;
437         handle->block_list = dlist_append(handle->block_list, block);
438         return block->idx;
439 }
440
441 PUBLIC int livebox_desc_del_block(struct livebox_desc *handle, int idx)
442 {
443         struct dlist *l;
444         struct block *block;
445
446         dlist_foreach(handle->block_list, l, block) {
447                 if (block->idx == idx) {
448                         handle->block_list = dlist_remove(handle->block_list, l);
449                         free(block->type);
450                         free(block->part);
451                         free(block->data);
452                         free(block->option);
453                         free(block->id);
454                         free(block->target_id);
455                         free(block);
456                         return LB_STATUS_SUCCESS;
457                 }
458         }
459
460         return LB_STATUS_ERROR_NOT_EXIST;
461 }
462
463 /*!
464  * \note
465  * The last "data" argument is same with "user_data" which is managed by "provider_set_user_data).
466  */
467 static inline int event_handler_wrapper(struct livebox_buffer *buffer, enum buffer_event event, double timestamp, double x, double y, void *data)
468 {
469         const char *pkgname;
470         const char *id;
471         struct livebox_buffer_data *cbdata = data;
472         int ret;
473
474         pkgname = provider_buffer_pkgname(buffer);
475         id = provider_buffer_pkgname(buffer);
476
477         ret = cbdata->handler(buffer, event, timestamp, x, y, cbdata->cbdata);
478
479         switch (event) {
480         case BUFFER_EVENT_HIGHLIGHT:
481         case BUFFER_EVENT_HIGHLIGHT_NEXT:
482         case BUFFER_EVENT_HIGHLIGHT_PREV:
483         case BUFFER_EVENT_ACTIVATE:
484         case BUFFER_EVENT_ACTION_UP:
485         case BUFFER_EVENT_ACTION_DOWN:
486         case BUFFER_EVENT_SCROLL_UP:
487         case BUFFER_EVENT_SCROLL_MOVE:
488         case BUFFER_EVENT_SCROLL_DOWN:
489         case BUFFER_EVENT_UNHIGHLIGHT:
490                 if (ret < 0)
491                         (void)provider_send_access_status(pkgname, id, LB_ACCESS_STATUS_ERROR);
492                 else
493                         (void)provider_send_access_status(pkgname, id, ret);
494                 break;
495         default:
496                 break;
497         }
498
499         return ret;
500 }
501
502 static inline int default_event_handler(struct livebox_buffer *buffer, enum buffer_event event, double timestamp, double x, double y, void *data)
503 {
504         /* NOP */
505         return 0;
506 }
507
508 PUBLIC struct livebox_buffer *livebox_acquire_buffer(const char *filename, int is_pd, int width, int height, int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *), void *data)
509 {
510         struct livebox_buffer_data *user_data;
511         const char *pkgname;
512         struct livebox_buffer *handle;
513         char *uri;
514         int uri_len;
515         struct event_cbdata *cbdata;
516
517         if (!filename || !width || !height) {
518                 ErrPrint("Invalid argument: %p(%dx%d)\n", filename, width, height);
519                 return NULL;
520         }
521
522         user_data = calloc(1, sizeof(*user_data));
523         if (!user_data) {
524                 ErrPrint("Heap: %s\n", strerror(errno));
525                 return NULL;
526         }
527
528         user_data->is_pd = is_pd;
529         user_data->handler = handler ? handler : default_event_handler;
530         user_data->cbdata = data;
531
532         uri_len = strlen(filename) + strlen(FILE_SCHEMA) + 1;
533         uri = malloc(uri_len);
534         if (!uri) {
535                 ErrPrint("Heap: %s\n", strerror(errno));
536                 free(user_data);
537                 return NULL;
538         }
539
540         snprintf(uri, uri_len, FILE_SCHEMA "%s", filename);
541         pkgname = livebox_find_pkgname(uri);
542         if (!pkgname) {
543                 ErrPrint("Invalid Request\n");
544                 free(user_data);
545                 free(uri);
546                 return NULL;
547         }
548
549         handle = provider_buffer_acquire((!!is_pd) ? TYPE_PD : TYPE_LB, pkgname, uri, width, height, sizeof(int), event_handler_wrapper, user_data);
550         DbgPrint("Acquire buffer for PD(%s), %s, %p\n", pkgname, uri, handle);
551         free(uri);
552         if (!handle) {
553                 free(user_data);
554                 return NULL;
555         }
556
557         (void)provider_buffer_set_user_data(handle, user_data);
558         return handle;
559 }
560
561 PUBLIC int livebox_request_update(const char *filename)
562 {
563         int uri_len;
564         char *uri;
565         int ret;
566
567         if (!filename) {
568                 ErrPrint("Invalid argument\n");
569                 return LB_STATUS_ERROR_INVALID;
570         }
571
572         uri_len = strlen(filename) + strlen(FILE_SCHEMA) + 1;
573         uri = malloc(uri_len);
574         if (!uri) {
575                 ErrPrint("Heap: %s\n", strerror(errno));
576                 return LB_STATUS_ERROR_MEMORY;
577         }
578
579         snprintf(uri, uri_len, FILE_SCHEMA "%s", filename);
580         ret = livebox_request_update_by_id(uri);
581         free(uri);
582         return ret;
583 }
584
585 PUBLIC unsigned long livebox_pixmap_id(struct livebox_buffer *handle)
586 {
587         return provider_buffer_pixmap_id(handle);
588 }
589
590 PUBLIC int livebox_release_buffer(struct livebox_buffer *handle)
591 {
592         struct livebox_buffer_data *user_data;
593
594         if (!handle)
595                 return LB_STATUS_ERROR_INVALID;
596
597         user_data = provider_buffer_user_data(handle);
598         if (user_data) {
599                 free(user_data);
600                 provider_buffer_set_user_data(handle, NULL);
601         }
602
603         DbgPrint("Release buffer\n");
604         return provider_buffer_release(handle);
605 }
606
607 PUBLIC void *livebox_ref_buffer(struct livebox_buffer *handle)
608 {
609         struct livebox_buffer_data *user_data;
610         void *data;
611         int w, h, size;
612         int ret;
613
614         if (!handle)
615                 return NULL;
616
617         user_data = provider_buffer_user_data(handle);
618         if (!user_data)
619                 return NULL;
620
621         if (user_data->accelerated) {
622                 DbgPrint("H/W accelerated buffer is allocated\n");
623                 return NULL;
624         }
625
626         ret = provider_buffer_get_size(handle, &w, &h, &size);
627
628         data = provider_buffer_ref(handle);
629         if (data && !ret && w > 0 && h > 0 && size > 0) {
630                 memset(data, 0, w * h * size);
631                 provider_buffer_sync(handle);
632         }
633
634         DbgPrint("Ref buffer %ds%d(%d)\n", w, h, size);
635         return data;
636 }
637
638 PUBLIC int livebox_unref_buffer(void *buffer)
639 {
640         if (!buffer)
641                 return LB_STATUS_ERROR_INVALID;
642
643         DbgPrint("Unref buffer\n");
644         return provider_buffer_unref(buffer);
645 }
646
647 PUBLIC int livebox_sync_buffer(struct livebox_buffer *handle)
648 {
649         struct livebox_buffer_data *user_data;
650         const char *pkgname;
651         const char *id;
652
653         if (!handle)
654                 return LB_STATUS_ERROR_INVALID;
655
656         user_data = provider_buffer_user_data(handle);
657         if (!user_data) {
658                 ErrPrint("Invalid buffer\n");
659                 return LB_STATUS_ERROR_INVALID;
660         }
661
662         if (user_data->accelerated) {
663                 DbgPrint("H/W Buffer allocated. skip the sync buffer\n");
664                 return LB_STATUS_SUCCESS;
665         }
666
667         pkgname = provider_buffer_pkgname(handle);
668         if (!pkgname) {
669                 ErrPrint("Invalid buffer handler\n");
670                 return LB_STATUS_ERROR_INVALID;
671         }
672
673         id = provider_buffer_id(handle);
674         if (!id) {
675                 ErrPrint("Invalid buffer handler\n");
676                 return LB_STATUS_ERROR_INVALID;
677         }
678
679         provider_buffer_sync(handle);
680
681         if (user_data->is_pd) {
682                 if (provider_send_desc_updated(pkgname, id, NULL) < 0)
683                         ErrPrint("Failed to send PD updated (%s)\n", id);
684         } else {
685                 int w;
686                 int h;
687                 int pixel_size;
688
689                 if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0)
690                         ErrPrint("Failed to get size (%s)\n", id);
691
692                 if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0)
693                         ErrPrint("Failed to send updated (%s)\n", id);
694         }
695
696         return LB_STATUS_SUCCESS;
697 }
698
699 PUBLIC int livebox_support_hw_buffer(struct livebox_buffer *handle)
700 {
701         if (!handle)
702                 return LB_STATUS_ERROR_INVALID;
703
704         return provider_buffer_pixmap_is_support_hw(handle);
705 }
706
707 PUBLIC int livebox_create_hw_buffer(struct livebox_buffer *handle)
708 {
709         struct livebox_buffer_data *user_data;
710         int ret;
711
712         if (!handle)
713                 return LB_STATUS_ERROR_INVALID;
714
715         user_data = provider_buffer_user_data(handle);
716         if (!user_data)
717                 return LB_STATUS_ERROR_INVALID;
718
719         if (user_data->accelerated)
720                 return -EALREADY;
721
722         ret = provider_buffer_pixmap_create_hw(handle);
723         user_data->accelerated = (ret == 0);
724         return ret;
725 }
726
727 PUBLIC int livebox_destroy_hw_buffer(struct livebox_buffer *handle)
728 {
729         struct livebox_buffer_data *user_data;
730         if (!handle)
731                 return LB_STATUS_ERROR_INVALID;
732
733         user_data = provider_buffer_user_data(handle);
734         if (!user_data || !user_data->accelerated)
735                 return LB_STATUS_ERROR_INVALID;
736
737         user_data->accelerated = 0;
738
739         return provider_buffer_pixmap_destroy_hw(handle);
740 }
741
742 PUBLIC void *livebox_buffer_hw_buffer(struct livebox_buffer *handle)
743 {
744         struct livebox_buffer_data *user_data;
745
746         if (!handle)
747                 return NULL;
748
749         user_data = provider_buffer_user_data(handle);
750         if (!user_data || !user_data->accelerated)
751                 return NULL;
752
753         return provider_buffer_pixmap_hw_addr(handle);
754 }
755
756 PUBLIC int livebox_buffer_pre_render(struct livebox_buffer *handle)
757 {
758         struct livebox_buffer_data *user_data;
759
760         if (!handle)
761                 return LB_STATUS_ERROR_INVALID;
762
763         user_data = provider_buffer_user_data(handle);
764         if (!user_data)
765                 return LB_STATUS_ERROR_INVALID;
766
767         if (!user_data->accelerated)
768                 return LB_STATUS_SUCCESS;
769
770         /*!
771          * \note
772          * Do preprocessing for accessing the H/W render buffer
773          */
774         return provider_buffer_pre_render(handle);
775 }
776
777 PUBLIC int livebox_buffer_post_render(struct livebox_buffer *handle)
778 {
779         int ret;
780         const char *pkgname;
781         const char *id;
782         struct livebox_buffer_data *user_data;
783
784         if (!handle)
785                 return LB_STATUS_ERROR_INVALID;
786
787         user_data = provider_buffer_user_data(handle);
788         if (!user_data)
789                 return LB_STATUS_ERROR_INVALID;
790
791         if (!user_data->accelerated)
792                 return LB_STATUS_SUCCESS;
793
794         pkgname = provider_buffer_pkgname(handle);
795         if (!pkgname) {
796                 ErrPrint("Invalid buffer handle\n");
797                 return LB_STATUS_ERROR_INVALID;
798         }
799
800         id = provider_buffer_id(handle);
801         if (!id) {
802                 ErrPrint("Invalid buffer handler\n");
803                 return LB_STATUS_ERROR_INVALID;
804         }
805
806         ret = provider_buffer_post_render(handle);
807         if (ret < 0) {
808                 ErrPrint("Failed to post render processing\n");
809                 return ret;
810         }
811
812         if (user_data->is_pd == 1) {
813                 if (provider_send_desc_updated(pkgname, id, NULL) < 0)
814                         ErrPrint("Failed to send PD updated (%s)\n", id);
815         } else {
816                 int w;
817                 int h;
818                 int pixel_size;
819
820                 if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0)
821                         ErrPrint("Failed to get size (%s)\n", id);
822
823                 if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0)
824                         ErrPrint("Failed to send updated (%s)\n", id);
825         }
826
827         return LB_STATUS_SUCCESS;
828 }
829
830 /* End of a file */