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